2016年12月15日木曜日

tile splash

はじめに

ウェブ上で地図の配信を行う手法は、タイルに分割された地図画像をajaxにより書き換える方法と、ベクトルデータを全部・あるいは部分的に読み込む手法が主でした。近年、ベクトルデータをタイル分割し、ajax により書き換える方法が登場しました。それが VectorTileです。
 このVectorTileの配信を行うオープンソースのモジュールのうちのひとつがTileSplashです。TileSplash は node.js という javascript によるWebサーバのエンジン用ライブラリとして書かれています。プロジェクトは、GitHubで下記にて公開されています。

 https://github.com/faradayio/tilesplash

実行に必要なもの

TileSplash を実行させるには、以下のモジュールが必要です。 node.js npm PostgreSQL server PostGIS インストール方法については、割愛します。

TileSplash 環境の構築

コマンド・プロンプトにて、npm を利用して SplashTile をインストールします。
$ npm install tilesplash
尚、-g オプションを使用すると、グローバル環境にモジュールがインストールされますが、ここでは、コマンドを実行したディレクトリ上にモジュールがインストールされるようにします。
 PostgreSQL Server に図形テーブルを構築します。注意点として、図形の座標系は、EPSG4326 でないと動作しません。また、ST_Transform(geom,4326) と言った書き方をしてもエラーになるので注意してください。既存のgeometryフィールドが異なるSRIDで作成している場合は、以下のようにフィールドを追加すると良いでしょう。
 alter table target_table add column geom2 geometry(‘MultiPolygon’, 4326);
    update table target_table set geom2 = ST_Transform(geom,4326); 
エディタで、sptile.js を作成し編集します。
var Tilesplash = require('tilesplash');
// username に postgresql へ接続するユーザ名を指定
// localhost にpostgresql server ホスト名を指定
// dbname に postgresql のデータベース名を指定
var app = new Tilesplash('postgres://username@localhost/dbname);

// layer_name はレイヤ名で、ajax によるリクエストの一部として扱われる
// table_name は図形テーブル名
// geom は図形フィールド名
// ここではシンプリファイをかけていますが、tile パラメータの x 値により
// シンプリファイをかけるパラメータを変更する必要があると思われます
app.layer('layer_name', function(tile, render){
  render('SELECT ST_AsGeoJSON(ST_Simplify(geom,0.005)) as the_geom_geojson’
     ‘FROM target_table WHERE ST_Intersects(St_Simplify(geom,0.005), !bbox_4326!)');
});
// ポート3000にて、Webサーバを起動します
app.server.listen(3000);
このまま稼働させると、レスポンスが javascript になるため、違うサイト間でのリクエストで CORS(Cross Origin Resource Sharing)の制約にひっかかって動作しない可能性があります。具体的には「No 'Access-Control-Allow-Origin' header is present」といったエラーがブラウザにより返されます。これを解消するには、以下のモジュールを利用します。
http://www.slideshare.net/kitfactory/web-api-34814937
$npm install corser

でモジュールをインストールし、
node_mojules/tilesplash/lib/index.js
ファイルに以下の修正を施します。
  this.server.use(pgMiddleware(dbOptions));

  var corser = require("corser");      // 以下の2行を CORS 対策として挿入
  this.server.use(corser.create());

  this.cacheOptions = cacheOptions || {};
  this._cache = new Caching(cacheType || 'memory', cacheOptions);
これは、レスポンス・ヘッダに
  Access-Control-Allow-Origin: *

を付加する事になります。

クライアント実装例

ローカルホストの node サーバに対して、アクセスする例です。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>GSI Tiles on OpenLayers 3</title>
<link rel="stylesheet" href="http://openlayers.org/en/v3.10.1/css/ol.css" type="text/css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="http://openlayers.org/en/v3.10.1/build/ol.js" type="text/javascript"></script>


<style>
  body {padding: 0; margin: 0}
  html, body, #map {height: 100%; width: 100%;}
</style>
</head>
<body>
  <div id="page">
    <div id="head"></div>
    <div id="main">  
      <div id="map" style="float:right"; width:640px; margin:0; padding:0; ></div>
      <div id="left" style="float:left; width:300px; margin:0; padding:0;"></div>
    </div>
  </div>       
<script>
var map = new ol.Map({
  target: "map",
  renderer: ['canvas', 'dom'],
  layers: [
    // 地理院タイル・レイヤ
    new ol.layer.Tile({
      source: new ol.source.XYZ({
        attributions: [
          new ol.Attribution({
            html: "<a href='http://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>"
          })
        ],
        url: "http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
        projection: "EPSG:3857"
      })
    }),
    
    // topoJson レイヤ (splashtile から引く)
    new ol.layer.Vector({
      source: new ol.source.TileVector({
        format: new ol.format.TopoJSON(),
        projection: 'EPSG:3857',
        tileGrid: new ol.tilegrid.createXYZ({
          maxZoom: 19
        }),
        url: 'http://localhost:3000/' +
          'test_layer/{z}/{x}/{y}.topojson'
        }),
       style: new ol.style.Style({
         fill: new ol.style.Fill({ color: '#9db9e8' }),
         stroke: new ol.style.Stroke({ color: '#FF0000' })
       })
    })
  ],
  controls: ol.control.defaults({
    attributionOptions: ({
      collapsible: false
    })
  }),
  view: new ol.View({
    projection: "EPSG:3857",
    center: ol.proj.transform([138.7313889, 35.3622222], "EPSG:4326", "EPSG:3857"),
    maxZoom: 18,
    zoom: 5
    })
});
</script>
</body>
</html>
実行すると、こんな感じになります。 file:/// 上から実行すると、CORSにひっかかります。chrome ではなく、safari で実行しました。 CORS対策の部分は、もうちょい真面目にやらないとダメかもしれません。

2016年8月24日水曜日

digest 作成備忘録

OpenSSL の SHA-256 を利用してダイジェスト文字列を作る備忘録です。
英数字を小文字にするのどうやるんだっけ?ってあたりから、激しくドレインしてます。
#include <fstream>
#include <iostream>
#include <iterator>
#include <algorithm> // transform
#include <string>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <boost/algorithm/hex.hpp>
#include <boost/algorithm/string/case_conv.hpp>

namespace {
  const char heading[] = "heading";
}


void show_usage() {
  std::cout << "make_digest [string]" << std::endl;
}

std::string digest( const char* str ) {
  unsigned char hash[SHA256_DIGEST_LENGTH];
  SHA256_CTX ctx;
  SHA256_Init(&ctx);
  SHA256_Update(&ctx, str, strlen(str));
  SHA256_Final(hash, &ctx);
  std::string result( (const char*)hash, SHA256_DIGEST_LENGTH );
  return result;

}

int main(int argc, char* argv[]) {

 if( argc != 2 ) {
  show_usage();
  return 1;
 }
 std::string charange( heading );
 charange += std::string( argv[1] );
 std::string hoge = digest( charange.c_str() );
 std::string digest;
 boost::algorithm::hex( hoge, std::back_inserter( digest ) );
 boost::algorithm::to_lower( digest );
 //std::transform( digest.begin(), digest.end(), digest.begin(), ::tolower );
 std::cout << digest << std::endl;

  return 0;
}

2016年8月13日土曜日

70-200レンズ

 Sigma 70 - 200 mm F2.8 を売ろうかと考えてます。
というのも、室蘭の夜景でブレないで撮れた試しもなく。マニュアルフォーカスしても、微妙にピントがズレる事も多く。オートフォーカスは遅くて、おまけにシャッターが下りなくてシャッターチャンスは無いに等しい。Merrill で撮影しても、撮れるシーンなんて、ほぼ限られる。このレンズで撮影して、やった!って思った写真は、考えてみても、ほぼゼロ。倍率も中途半端で、イマイチ。
 あと、予定外の出費が嵩んだのもあります。

2泊3日の弾丸キャンプ

 家族で2泊3日の東北に行ってきました。午前3時起床、午前4時出発、高速飛ばして函館北斗へ。そして新幹線に乗って盛岡まで。本当は新青森の予定だったのですが、日産レンタカーが予約を受付しておいて、車ありませんでした攻撃を食らったため変更でした。直前までレンタカーを探しまくっても見つからず。探しても探しても空車無し。タイムズレンタカーの厨川駅でやっとこさ予約。
 昼に盛楼閣で飯を食って、イザ恐山へ。いやーーーーー遠いですわ。ハードスケジュールに意識が飛びそうになりながら、矢立温泉でバンガローを借りる。朝活する体力もなく朝を迎えて、恐山へ。そして、十和田市現代美術館に。車返す事を考えたら、盛岡近辺でキャンプしないと…でも、星が綺麗なキャンプ場が良いな?と思って、種山高原星座の森へ向かうも、時間切れで八幡平から妻の神キャンプ場へ。本当は白神山地も寄りたかったんですが、時間的に全然無理でした。そして運転もハード。
 あんまり星が綺麗に見えなかったけど、流星群が凄くて、火球とかに大満足。ここではタイムラプスを撮って放置したけど、バッテリー切れで撮れてるのか撮れてないのか、さっぱりわかりません。11時ぐらいに早々に寝て、翌朝少しだけ朝活。と言っても、どこで撮影したものか?全然わかりません。ここら辺、意外に開けて見える場所が少ないのだ。
 そして、帰りの新幹線もあるのでレンタカー屋さんへ。電車に乗り遅れたら大変なので、レンタカー屋さんからダッシュ!滑り込みセーフで、あたふたしながら盛岡で焼き肉を食べて、新幹線&函館北斗から車だったのだ。
 写真は無い。

2016年7月26日火曜日

MinGW sqlcipher build 忘備録

まず、Mingw のインストール

MinGW(gcc) の Windows へのインストールと使い方 を参考にインストールします。

MSYSのシェルを起動するショートカットを作成します。
参照は C:\MINGW\msys\1.0\msys.bat です。

MSYSのシェルを起動します。

ライブラリの探し方は
$ mingw-get list | openssl
とします。

mingw-libopenssl を入れてみます。
$mingw-get install msys-libopenssl

SQLCipher をダウンロードして展開します。

$ configure

.... はい、エラーになります。

OpenSSL をダウンロードしてビルドします。

$ Configure --prefix=$PWD/dist no-idea no-mdc2 no-rc5 shared mingw
$ make depend && make && make install
です。

ようやく build に入ります。主にこちらを参考にしました。

sqlcipher と openssl のソースが home 下に作成されているとします。
$ configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -I../openssl-1.0.2h/dist/include 
        ../openssl-1.0.2h/dist/bin/libeay32.dll -L../openssl-1.0.2h/dist/lib -static-libgcc" DLFLAGS="-leay32"
make claen
make sqlite3.c
make
make dll

2016年7月21日木曜日

生産性の低いモバイル・アプリケーション開発


 近年、自分が感じているモバイル・アプリケーション開発に対する状況を書いてみよう。(自分はB2B系のシステム開発をしているので、コンシューマ向けの事業を行っている方面の方にはマッチしない考察である可能性があります)

 発売されているモバイル端末は多岐にわたる。iOS をはじめとする iPhone, iPad。Android をはじめとする Android 端末、タブレット端末、将来的には ウェアラブル端末。Windowsをはじめとする Windows Phone、Surface、得体のしれないタブレット端末類。どの端末をとってみても、これで開発しておけば安泰なんていう時代じゃなくなってます。少し前まであったAndroidタブレットは、現在生産しているのが数社に狭まり、今後、市場として成立するかどうかは全くの不透明。どの部分が明日には廃れていくか決め打ちするのもリスクが高すぎて選択できません。逆もまた然り。

 よって、全方位で製品を提供できる事が理想です。Microsoft社も、このように考えているようです。ひとつの解決策としては Xamarin があります。しかし、考えるに、Xamarin って生産性高いの?という疑問が付きまといます。HTML5も進化して、どんどんとネイティブ・アプリとブラウザ・アプリの差が縮まっているように感じています。札幌で行われたW3C会議のDeveloper Meetup に参加して思ったのは、Worker Service や Universal Payments など、野心的な開拓と提案で、この先も、どんどんと進化していく流れは続きそうだという事です。Google は Native の有用性と Browser の有用性は、それぞれにあり、どちらも必要性を認めていますが、両者の垣根は、だんだんと曖昧になってきていると考えているようです。

 ウェブは終わったと煽る記事もありますが、自分は、ウェブをベースにアプリを作成するのが幸せだと考えてます。もちろん Native コードじゃないと話にならない事もあります。アプリのパーツを考えた時、ウェブをベースとした作り方ができれば、生産性は高まります。レイアウトもコードも楽ですし、再利用できるコードも多いですし、なんならウェブ・アプリケーションとして提供するのもコストが少なくて済みます。調べてみると WebViewの出来は最悪みたいで、Android Kitkat 4.4 以上であれば ChromeViewが使えるようです。他には Crosswalk というものもあり、これなら Android と iOS、Windows Phone もプロジェクトがあるので使えそうです。

 ここから先の考え方は、現在無いように思う事項です。サーバーを端末内の node.js のようなもので代用できれば最高だと思いませんか?ポートを介して接続したりするので、モバイル端末等におけるセキュリィティの概念が必要でしょうが、VirtualHost的な考え方と認証を組み合わせれば大丈夫でしょう。サーバをローカルにするメリットは、まだあります。WebStorageで頑張らなくてもサーバサイドに機能を寄せる事ができます。フォッグ・コンピューティング的な考え方等を導入する場合でも、ローカル・サーバ・サイドの機能として隠蔽する事が可能なので幅が広がります。残念ながら Android に node.js を入れようと思ったら root化が必要そうではあります。変なサービス・アプリケーションを一生懸命開発するぐらいなら、ローカル・サーバ・サイドの機能として実装するのもアリだと思いませんか?

 こうやって、アプリケーション内を部分的にでもWebView的なもので置き換える事ができたら、グッと生産性が上がるんじゃないかな〜?どうでしょう?


 

2016年6月25日土曜日

macbook pro retina mid 2012 SSD 交換

macbook pro retina display MID 2012 モデルのSSD 256Gで使ってましたが、さすがにディスク容量が足りなくて、交換する事にしました。

mSATA 512G と ebay から macbook pro 用の mSATA Adapter の組み合わせです。
後に判明したのは、星型ドライバーが足りないという事で
macbook pro retina display MID 2012 をバラすのに必要な星形ドライバ
それと、SSD を外すのに必要な星形ドライバ を買いました。

交換し終えた後ですが、こんな感じ。






Timecapsule を持っていたので、楽観視してましたが、付け替えた SSD 512G を "Case Sensitive FS" でフォーマットしたら、ハマりました。
Case Sensitve FS とは、大文字小文字を区別するファイル・システムの事なんですが、こいつを選択すると、Timemachine が見えなくなります。この状況が理解できなくて、SSD 256G に戻したら、このSSDが交換作業で飛んじゃって、元のデータがどこにも無い状態で、焦りまくり。
なんとか、新しく mac os x をインストールして、ディスク・ユーティリティのFast AID で Timemachine を復元して、必要なファイルだけを Timemachine に入って取り出す事に成功しました。Timemachine からの復元は失敗する状況です。
Adobe Creative Cloud Photographer を契約しているので、Creative Cloud をインストールしようとしたところ、「Case Sensitive FS はサポートしていません」と怒られました。調べてみると、Case Sensitive FS をサポートしているアプリケーションは少ないとの事。
泣きながら、普通のファイル・システムで SSD 512G を初期化し直したら、なんて事もなく Timemachine から前回使用していた環境を復元できるじゃないですか!!!!!

いや、もう参りました。
という事で、2万円かけずに 256G から 512G の環境に移行する事ができました。
ディスク容量があるって、幸せです。

2016年6月16日木曜日

固定小数点クラス

ずっと昔64ビット長の固定小数点クラスがほしくて、書いたやつ。 今なら、8ビット長の固定小数点クラスなんですかねー。
#pragma once
/*!
 @file fixed_float.hpp
 @brief 固定精度浮動小数点クラス・ヘッダ
*/

#include <boost/assert.hpp>
#include <boost/operators.hpp>
#include <limits>


//! 64ビット長固定精度浮動小数点クラス
class fixed64 :
 private boost::addable<fixed64>,
 private boost::subtractable<fixed64>,
 private boost::multipliable<fixed64>,
 private boost::dividable<fixed64>,
 private boost::equivalent<fixed64>,
 private boost::partially_ordered<fixed64>
{
public:
 static const int exponent_ = 16; //!< 指数部長
private:
 int64_t value_; //!< 値
public:
 //! コンストラクタ
 inline fixed64() : value_() {}
 //! コンストラクタ
 inline explicit fixed64( 
  int64_t value //!< [in] 値
 ) : value_(value << exponent_) {
  BOOST_ASSERT( value <= (std::numeric_limits<int64_t>::max() >> exponent_) );
  BOOST_ASSERT( (std::numeric_limits<int64_t>::min() >> exponent_) <= value );
 }
 //! コンストラクタ
 inline explicit fixed64( 
  double value //!< [in] 値
// ) : value_(static_cast<int64_t>(value * (1LU << exponent_))) {
 ) : value_(static_cast<int64_t>(value * pow(2.0,exponent_))) { 
  //BOOST_ASSERT( value <= (static_cast<double>(std::numeric_limits<int64_t>::max() >> exponent_) );
  //BOOST_ASSERT( (static_cast<double>(std::numeric_limits<int64_t>::min()) >> exponent_) <= value );
 }
 //! コピーコンストラクタ
 inline fixed64( 
  const fixed64& value //!< [in] 値
 ) : value_(value.value_) {}

 //! オペレータ +=
 inline fixed64& operator += (const fixed64& rhs) {
  value_ += rhs.value_;
  return *this;
 }
 //! オペレータ -=
 inline fixed64& operator -= (const fixed64& rhs) {
  value_ -= rhs.value_;
  return *this;
 }

 //! オペレータ *=
 inline fixed64& operator *= (const fixed64& rhs) {
  value_ = static_cast<int64_t>( 
   (
    (
     ((static_cast<int64_t>(value_)) * (static_cast<int64_t>(rhs.value_)))
     // 切り上げを行う
     //& pow( 2.0, exponent_ - 1 )
    )
    >> exponent_
   )
  );
  return *this;
 }
 //! オペレータ /=
 inline fixed64& operator /= (const fixed64& rhs) {
  value_ = static_cast<int64_t>(
   (static_cast<int64_t>(value_) << exponent_) / static_cast<int64_t>(rhs.value_)
  );
  return *this;
 }
 //! オペレータ =
 inline fixed64& operator = (const fixed64& rhs) { value_ = rhs.value_; return *this; }
 //! オペレータ ==
 inline bool operator == (const fixed64& rhs) const { return value_ == rhs.value_; }
 //! オペレータ <
 inline bool operator < (const fixed64& rhs) const { return value_ < rhs.value_; }

 inline double get(){
  return static_cast<double>(value_ / pow(2.0, exponent_));
 }

 inline operator double() const 
  { 
    //return double(value_ * (1 >> exponent_)) ; 
  return double(value_ / pow(2.0, exponent_));
  //return double(value_ * (static_cast<int64_t>(1) >> exponent_)) ;
  } 
 //! オペレータ =
 inline fixed64& operator = (const double& rhs) {
  value_ = static_cast<int64_t>(rhs * pow(2.0, exponent_));
  return *this; 
 }
};

2016年5月27日金曜日

気質

幼稚園の頃の記憶は5シーンぐらいしか残っていません。
その中のひとつ。
車が走ってくるところ(そんなにスピードは出ていない)に、道路の真ん中に大の字に立って通せんぼする私。
当然、運転手にカンカンに怒られる。
そこで「やってみたかってん」という自分。
運転手は「やってみたかったんならショウガナイな」と呆れ顔で言う。

大人しい性格だったが、試してみたいと思うと衝動を抑えられない。
そんな一面があると思う。

だからこそ、試行錯誤するプログラミングの世界が性に合っているのかもしれない。

逆に日本語は、とても苦手だった。人とは、どこか感覚が異なるのかもしれない。知的ジョークの類は、ツボに嵌まらなければ、とことん何が面白いのか理解できない。その点、コードはクリアだ。結果に現れる。

そんな事を思い出した。


2016年5月18日水曜日

windows unistd.h 忘備録

OpenCV を Windows でコンパイルしようとしたり、何かにつけて、引っかかるので、忘備録。


ここを参照しろ。

http://d.hatena.ne.jp/tt_clown/20100602/1275457123

http://d.hatena.ne.jp/deraw/20070517/1179334643


winsock2.h を include してる部分で嵌るので、unistd.h は



#ifdef NEED_GETHOSTNAME
#ifndef _WINDOWS_
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#endif
#pragma comment( lib, "ws2_32" )
#include <winsock2.h>
#endif

と、修正する事。

今後、コンパイルエラーで
gethostname を使用している箇所があれば、

#define NEED_GETHOSTNAME
#include <unistd.h>
#undef NEED_GETHOSTNAME

としてやれば良い。
面倒でも、こうしないと、あちこちエラーで悩まされるだろう。


3rdparth 中の zlib ライブラリの
zconf.h
ここで、Z_HAVE_UNISTD_H の定義を消す事

#ifndef ZCONF_H
#define ZCONF_H
/* #undef Z_PREFIX */
//#define Z_HAVE_UNISTD_H



ACCESS_MASK が winnt.h と、namespace cv::ACCESS_MASK でバッティングしている。
test_grfmt.cpp はテストユニットみたいなんで、コンパイルのターゲットから外してしまうか、
// using namespace cv;
のように、コメントアウトして、地道に cv::Mat みたいに namespace を付けて回るか?

以上。


補足:
 cmake-gui でエラーとか、com をコンパイルでエラーとか、全部、管理者権限が脳足りんのじゃ。


追記:

VC11とか、include dir の設定が共通化でけん。

ここを参照しろ。
http://d.hatena.ne.jp/taiyakisun/20130406/1365248215

VC11 は、こんな感じ。
よく無いって怒られる。cstdint とか、unistd.h とかを入れといたった。

<?xml version="1.0" encoding="utf-8"?> 

<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <IncludePath>$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);$(WindowsSdkDir)include;D:\Libs\cstdint</IncludePath>
    <LibraryPath>$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86);$(WindowsSdkDir)lib;</LibraryPath>
  </PropertyGroup>

</Project>
2016/07/28追記:$(WindowsSDK_IncludePath); では、SDKのパスが取れず、$(WindowsSdkDir)include を追加した。lib も同様

2016年5月13日金曜日

巡回セールスマン問題なつかしい

もう、かれこれ7年前の事になるのか・・・。

2016年5月3日火曜日

帰省

昨年末から、ずーっと休日出勤してたのもあり、2日と6日に休みをもらって実家に帰省してます。

父親の癌が発覚して、手術を2回ほど。そろそろ、いつぽっくり逝ってもおかしくないので、顔を見られるうちに見ておこうという感じです。でも、元気そうでした。
ポリープをとったり、まだ手術が続くそうです。

母親の方がストレス溜まってたのか、帰省してると、嬉しそうです。
日帰りで温泉に連れて行ったら喜んでました。

長期で帰省しといて良かったです。親孝行は、できるうちにやっておかないと後悔してもしょうがないですからね。

2016年4月16日土曜日

写真プリント3

今日も、せっせとプリント、A3ノビだと、なんぼも印刷できないので、A4で印刷してみた。印刷してみると、もう少しコントラストを強くしないと、のっぺりしてるな〜とかあって、やり直したい衝動にかられるけど、やり直ししてる時間は無さそうだ。
そこそこプリントでけた。

2016年4月13日水曜日

写真プリント2

今日も、せっせと写真プリント。A3ノビで出してみたものの、気に入らなくてプリントし直しとか…。ボツとか…。
プリントは大変だ。
パープルフリンジにグリーンフリンジに、色合いが気に入らなくてボツにしようか悩み中のものもあったり…。
そのうち、またインク交換しないといけなくなってきそう。
色々と金のかかる趣味だ

2016年4月11日月曜日

写真プリント

今年は自分の写真をプリントする事に力を入れると決めたけども、気がつけば、もう4月。仕事に追われて全然プリントできていない事に愕然とする。
慌ててL版で、せっせとプリントしてたら、こんな時間になった。
いやはや、L版で60枚ぐらい印刷したのに、まだ最近の写真だけ…。
候補を絞って印刷してるのに、どんだけ撮ってんだよ?って話です。
そして、未だにプリンタのカラーマネージメントに微妙に満足していないんです。
道のりは長いなぁ

2016年4月7日木曜日

人工知能研究会でした

とりあえず、なんかわかんないけど、集まった。
そんな感じでスタートした人工知能研究会。

答えがわからない問題を解くには、ディープラーニングがいいのか?クラスタリングによる分析をした方がいいのか?そんな質問を投げてみた。
やっぱりクラスタリングをした方が良さそうですね~という事だった。ただ、オートラーニングを行うと、次元下げを行う事ができる。これはクラスタリングをやりやすくするのではないか?という見解をいただいた。研究者の方は、専門にやってるだけあって、切れる。

それにしても、いろんな方と話をできて楽しかった。

2016年4月3日日曜日

仕事のこと

こんな事ブログに書かなくても良い気がするのですが・・・
立場上は、やっぱり会社に利益をもたらすような事を考えて実践していかないといけなんです。
でも現実は、受託案件を回すので目いっぱい働いてる状態です。
そんな中で、時間を割いて技術的な事も一通りおさえておかなければならないんで、積読気味ではありますが、手を動かしたりとかもします。あと趣味の時間を入れたら、残りの時間なんて、なんぼもないんですわ。本を買って読めとか言われるけど、読んでるジャンルが違うだけで、読んでないわけじゃない。新聞を読めとか言われて、世間の動向ぐらいは目を通しておかなければならないんでしょうけど、当座の新聞より納期の迫る仕事に追われてます。
今の会社は経営という面では難しいですわ。企業って、経営理念があるはずなんですが、理念を振りかざすと食べていけないから、食べていけるものに食らいつくしかないという事。自治体中心でシステムの受託をやってきたけど、少子高齢化で財政緊縮方向に動いているので、市場が狭まっているのと、仕事単価が下がっている。
北海道は支社経済で、何か提案しても、それは本社のミッションだと一蹴される。
何か無いかと考えても、直接的な顧客が自治体以外には無いので、製品の需要がわからない。そんな状態で市場を想像して(本を読んだり、人脈を広げたり)、新たな価値観を創造しビジネス展開するミッションを考えなさいと命題を与えられても、雲を掴むような話しで難しい。
経営側の人間は、働いたら負けってわかってるけど、どの事業領域に何をリーチするのか?ってのが、五里霧中。地図システムを作ってきたから、地図をメインに…って事になるんでしょうけど、フリーソフトのQGIS、国土地理院のウェブGIS、GoogleMaps…、安い方に流れるのでキッツイですわ。
要素技術的には、CartoDB みたいなもんは、できたと思うんですが…。
技術革新も速くて、これから先は、もっと大変ですわ。

市場調査って、リーン・スタートアップとか、もっと手法に頼るべきで、DeepLearning の勉強なんて放っておいて、自分が、こっちもやるべきなんですかね?

とりあえず、IoT と 自動学習 を組み合わせて、付加価値のある製品を提供できるように勉強しとこうと思う。

細かい話を言えば、Docker を導入させたい、Subversion から Git に移行したい、とかあるんですけど、導入大変ですわ…。

2016年3月30日水曜日

さっそく Chainer バージョンアップの洗礼をうけてま

かる~く、チュートリアルをこなそうとおもったけど、バージョンアップの洗礼をうけて、いろいろハマりました。 deprecated って、冷たくあしらわれて、なんとか、チュートリアル(本家のチュートリアルじゃありません)をこなしました。
この次は、CNN, LTSM, RNN あたりをクリアしていきたいところです(適当)。
それが終わったら、伝達関数を少し工夫してみたいです。
あと余裕があれば、学習モードと忘却モードのモデルを切り替えて、過学習気味に学習をさせて、忘却だけの伝達関数を使って忘却学習を実践してみたい。ニューロンが繋がって構築されたところに忘却学習でシナプスを弱らせ、不要な枝葉を孤立させてしまうと…。もしかしたら、それを何回か繰り返して、その後、通常の学習をさせると良いとか?いろいろ妄想してます。

追伸:孤立と言っても、本当に孤立するわけじゃなくて、その経路への信号が細るだけです。再度学習すれば、また繋がるかもしれないし、途中で分流して、そこへの信号は来ないままかもしれないし。

2016年3月29日火曜日

写真ブログ分離

http://grayholephoto.blogspot.jp/
とりあえず、Google+辞めたので、写真だけのブログを立ち上げてみました。
気まぐれに、引っ越しするかもしれないし、続かないかもしれないけど。

2016年3月28日月曜日

Close でけん(#-ω-)


何回も Google+ をダウングレードしているが、500 Internal Server Error になって削除でけん。

中途半端やわー。飼い殺し?

2016年3月27日日曜日

Closed

 自分の感覚が繊細すぎるのでしょう。
 感じの悪いものばかり拾ってしまいます。

 思えばBBS時代にもデジタルのコミュニケーションには
嫌な思いをした事がありました。

 リアルじゃ言えない事を 書く罵倒合戦。

 共通しているのは、他人に対する思いやりが欠けている事だと感じました。

 そうそう。
 造語を思いつきました。

 デジタリアン。

「自分は短気で気まぐれで、優柔不断な所があって、悪い面では嫌味な所もあったでしょう。でも、たとえ誰であろうとも、その人を尊重したいと心がけてきたつもりです。どう映ったかは、わかりませんが…。デジタルだけのコミュニケーションは、もう懲り懲りです。」

 Google+のアカウントを閉じる事にしました。

追伸:コミュニティーに投稿したポストも消えてしまいました。オーナーさん、ごめんなさい…

2016年3月16日水曜日

Android開発、それは果てしなきメモリとの戦い

Android 開発、難しいですね〜。
超絶に難しいですね〜。
アホか?ちゅうぐらい難しいですね〜。
バランスを考えない機能競争、標準の写真サイズが、どんどん大きくなっている。
シビアにメモリを利用しているアプリだと、最近の機種では、ストーンと写真まわりで落ちるんですわ。

BitmapFactory.OptionsのinSampleSizeを指定して画像を縮小した状態で読み込む

これですわ。まさに、これですわ。
極限までメモリを利用していると、

  Bitmap org = BitmapFactory.decodeFile(imageFilename_,opt);
こいつが null になるんですわ。
こんな BADノウハウが満載。

つうか、落ちてたのは、画像サイズを小さくするコードなんですけどね。
Stack Overflow には、

http://stackoverflow.com/questions/28391597/bitmapfactory-unable-to-decode-stream-java-io-filenotfoundexception-in-android

こんなBADノウハウがあります。
なんなんですかね…

追記(2016/05/24): BADノウハウの注意点として new URL( filePath ) にパス '/storage/..."  を渡したらダメで、頭に "file://" を付けないといけない。 なんで、new URL( "file://" + filePath ) が正解。

2016年3月4日金曜日

DeepLearning本読んだ


とりあえず、何か手をつけていかないといけないなぁと思って、本を読んでみる事にしました。
深層学習

ニューロンとか、一応知識があるつもりでしたが、読んでみると難しい。
で、何に応用できんのよ?って部分で、考え違いしてたんじゃないかと思いました。

分析と学習は別物であるという事。

大量データをクラスタリングをして、分析にかけ、モデルを考えるのが第1ステージだとしたら、Deep Learning は、どのような入力から、どのような応答が欲しいか?を考えてモデルを構築して、学習させる事。これが完成して、初めて実務のサポートに使える。

Deep Learning は、第2ステージに相当するんだって事。

という訳で、もうちょっと第1ステージの事を先に考えるべきなのか?
いやいや、そんな理論をすっ飛ばして、未知なる入力から、無理矢理、欲しい応答を用意して、当たるも八卦当たらぬも八卦で試行錯誤を行うべきなのか?

いや、ほんと、わかんねぇっすわ。

2016年3月1日火曜日

SNS雑感

デジタルは残るのでキッツイですわ。
Facebookは、現実世界に近すぎて、あまり面白くない。
Google+の方も難儀してますわ。
先日、あまりに鬱陶しいので、意を決して人をブロックしました。利害が無い関係だと、とても良い人なんでしょうけど、ダーティな面が許せなくなりました。露骨に当たりが強い人も、自分は、そんなに悪く思ってないんですけど、セットでブロックしました。
これ以外にも自分の意思とは関係なく、いろいろあって、自分でもコントロールできてない。正直辛いですわ。
自分もコミュニケーションが下手なんで、お手上げです。もう、降参。

ハッカソンあれこれ

サッポロ・オープンデータ・GIS大賞とかいうハッカソンのファシリテータをやっぱりやれ。
とか指名を受けたけども、元来、人を動かすのは苦手だし・・・という事で、司会進行は、慣れている他の方にお願いして、影の補佐役として参加しました。

蓋を開けてみると、コーダーが足りなくて、おもいっきりコード書くはめになりました。

運営側に、実は、あまりコードをわかる人がいない。だから、いろいろふられるけど、なかなか難しいものがある。作品は、コードよりも、どれぐらいコンセプトに沿って動くか?の方が重要なんじゃないかと考えてます。

結構、参加者も顔見知りが多いので、審査は正直やりづらい。今回、自分が手を動かしたものは評価を口にできませんでした。審査してみて、思ったのは、見てくれよりも、ちゃんと動作する事と、コンセプトがしっかりしている事。いろいろ要素があるので、どう評価するかは難しいけども・・・。

正直、いろんな方が関わるので、それなりに、いろんな方の思惑が入り乱れて、やりづらい感じはあります。それでも、自分は、まじめなんで、公正に運営したつもりです。

 いろんなジャンルの人とコラボレーションできるのが、ハッカソンの魅力ではないかと思います。
そこに尽きる。

 あとは、些細なことかな?

2016年2月24日水曜日

ぼやっきー

仕事に関する、ぼやきです。
クラウドうんぬん言う前に、北海道はITの仕事が、あまりない。
なんでか?民間で言えば、本社が東京にあって支店経済なんで、何か提案があっても「それは我々のミッションじゃない」って事で消えます。
そんな事情は置いても、基本、受託の価格が安い傾向にありますよね。高いのは派遣の人件費だけ。
ネットワークが地方との距離を無くした!と言っても、現実は、そうでもない所があります。縁がありそうな仕事も、距離が遠いから辞めますって断られることもありました。

Android …期待してたんだけど、地雷が多すぎて、このままじゃダメでしょうね。業務に使用しようと思っても、どこかしこにアプリケーションの問題が発生して、それがOSの根深い所や、ベンダー固有の根深い所に問題があって、ちゃんと動作しているものが、バージョンアップと共に、いつ動作しなくなるのかヒヤヒヤもんですわ。

ここ最近、であった Android の問題を列挙すると


  • JNI から Java への Callback 関数のポインタが動作しなくなってアボーン(Android 5.0系)
  • セキュリティ仕様の変更で、Sqlite3データベースに書き込みできなくなってアボーン(Android 5.0系)
  • アプリケーションからカメラアプリを起動して戻る時に原因不明のアプリケーション終了(Android 5.1.1のShield Tablet のみの現象)
  • アプリケーション起動時にログイン・ダイアログを表示すると 1/2 の確率でアプリケーションがハング:OpenGL のレンダリング系の問題くさい(Android 5.1.1 Experia Z2 Tablet のみ)
  • だいぶ前の機種 Regza は方位センサの返す値がダメダメ
まずは、モーダル系のAPIがほしいですわ。ま、Google はコンシューマがターゲットなんで画一的なプラットフォームを提供できないCloud&Web以外は、ビジネス用途には使えないでしょう。

 Android アプリ開発、生産性が低いので積極的には関わりたくなくなってきてます。

 時間があればね。AIとか突っ込んでみたいんですわ。Chainerが気になってます。H2Oも試してみたいし、GCPで色々とかやってみたかったんですけど、試してる時間が無い。これは、あまり良い状況じゃないですね。

2016年2月13日土曜日

東京出張パート2

車を戻して、少し仮眠をとった。また、ここだ。どっとくる。やけに晴れ渡っているのが癪に障るぐらいの天気だ。結局、何も変わっちゃいない。


どこへ向かおうか?どこでもいい。一人気ままな、ぶらり旅

都内は自然豊かだ…。朝日が眩しい。


猫飼うようになってから、猫センサーの感度上がったのかな?


浜離宮、一度行ってみたかったんだ。




















本当にキラキラと輝かしい朝
























気がつけば10時だ…。弱ったな…。どこへ向かえば良いというのだろう?
壁に向かって聞いてみようか?
築地市場に向かってみたが、開いてなかった・・・。


宛もなく彷徨う東京


Tu me manques

あとは、東京駅に寄り
参ったな・・・スマフォの写真の方が冴えてる・・・。

Cafe Vannier に寄った。
写真展、とても良かった。築地は自分も案内されて撮影したので、よくわかるけど、フリンジとか発生しててもクオリティが高い作品が並ぶ。こんな風に仕上げられるって、物凄い。自分が撮影したのと比べてみれば、よくわかる。
他の写真もフルサイズで撮ったかのようなボケ味に、理想に近い仕上がり。
来てよかった。ちょっとだけ救われた気がした。


桜色のライトが綺麗だ。

Welcome to TOKYO. I'm here.

思い出もかすれ、疎外感だけが残る。

Goodbye TOKYO.



東京出張パート1

仕事で東京出張でした。
帰りの飛行機が新千歳空港が大荒れで遅れました。飛行機をキャンセルして、翌日に帰る事にしました。
いつもは、ついでに写真を撮りに出かけるのですが、今回は写真が目的では無かったので、三脚は持ってきませんでした。
それでも、一応カメラは持ってきました。でもレンズは、オールド・レンズだけ。もっと広角のレンズがあるつもりでしたが、どれも50mm前後のものばかり。



というのは嘘で、三脚と標準レンズを忘れました。

東京は札幌に比べれば穏やかでした。

海を撮影しましたが、風は冷たく体も冷えて震えてきました。本州は底冷えして存外寒いもの。海に話しかけても、返ってくるのは風の音ばかり。退避する場所もなく、段々と寒さに耐えれなくなり撤収する事にしました。

もたもたしたお陰で、レンタカーの空きが近くに見つかりません。つい2時間ぐらい前までは空いてたのにな


三脚も無いけど、どこへ行こうか?眠らない街、東京。たくさん人はいるのに寂しい街だ。
水江町に向かったけど、落とし物に気がついて戻るはめに
探したけれど暗くて見つかりませんでした。
水江町に来たものの連日の仕事の疲れで動けませんでした。工場は静けさに満ちて、明け方の色は、いつになく綺麗

三脚とレンズ、忘れなければ良かったな・・・。

切り取れる世界が見つからなかった。

2016年1月29日金曜日

boost::geometry 自己交差解消

boost::geometry では、自己交差しているポリゴン図形の入力はエラーとして受け付けません。 関連:boost::geometry でもハマった とは言っても、人間の手を介して入力される限り、自己交差しているような図形は後を絶ちません。 やっぱり、これを解消する手段は、是非とも欲しいところであります。 参考:http://boost-geometry.203548.n3.nabble.com/How-to-repair-self-intersections-td4025893.html 参考URLによりますと、開発バージョンの中には、extensions というヘッダが構築されておりまして、その中にありました。
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.

// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

#include <algorithm> // for reverse, unique
#include <iostream>
#include <string>

#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/adapted/c_array.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>

#include <boost/geometry/extensions/algorithms/dissolve.hpp>

// dissolve.hpp の中で省略系の namespace が宣言なしに使用されていたので追加
namespace bg = boost::geometry;


BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)


int main(void)
{
    using namespace boost::geometry;

    typedef model::d2::point_xy<double> point_2d;
    typedef model::polygon<point_2d> polygon_2d;
    typedef model::box<point_2d> box_2d;
    typedef model::multi_polygon<polygon_2d> multi_polygon_2d;

    // Define a polygon and fill the outer ring.
    // In most cases you will read it from a file or database
    polygon_2d poly;
    {
        const double coor[][2] = {
          { -162.277344, -684.941406 },
          { -154.300781, -684.707031 },
          { -147.291016, -768.253906 },
          { -148.601562, -752.630859 },
          { -156.675781, -753.292969 },
          { -155.425781, -768.546875 }
      };
      assign_points(poly, coor);
    }

    // Polygons should be closed, and directed clockwise. If you're not sure if that is the case,
    // call the correct algorithm
    correct(poly);

    // 自己交差を解消するためには、出力先はマルチポリゴンである必要があります。
    multi_polygon_2d solved;
    // ポリゴンを入れて、自己交差を解消し、分解して solved に入れます。
    dissolve(poly, solved);
  
  
    // Polygons can be streamed as text
    // (or more precisely: as DSV (delimiter separated values))
    std::cout << dsv(poly) << std::endl;
  
    multi_polygon_2d v;

    try {
      // intersection(poly, poly, v); では例外が発生しますが…
      intersection(solved, solved, v);
    } catch(const std::exception& e) {
      std::cerr << e.what() << std::endl;
    }
    // 大丈夫!

    std::cout << "Clipped output polygons" << std::endl;
    for (multi_polygon_2d::const_iterator it = v.begin(); it != v.end(); ++it)
    {
        std::cout << dsv(*it) << std::endl;
    }
  
    return 0;
}

2016年1月28日木曜日

subversion svnsync お引越し備忘録

subversion で svnsync コマンドを使って、バックアップ構成を構築していますが、日本語ファイルが不味いのか、たまーに invalid XML なんたらとか吐いて同期が取れない場合があります。 そんな時の対処法。 まずは、元のリポジトリからダンプを取ります。
$ svnadmin dump /var/srv/svn/foo_project > foo_project.svndump
自分の環境だと面倒なんで
$ mv foo_project.svndump /var/www/html
とかしておいて、パソコンから
Z:\svn_back> c:\usr\bin\wget http://svnserv/foo_project.svndump
とファイルをコピーしてきて
Z:\svn_back> svnadmin create foo_project
Z:\svn_back> copy pre-revprop-change.bat foo_project\hooks
Z:\svn_back> svndmin load foo_project < foo_project.svndump
Z:\svn_back> svnsync init file:///foo_project http://svnserv/foo_project --allow-non-empty 
ってやれば、引っ越し完了です。 foo_project はプロジェクト名に svnserv は subversion のサーバ名に 置き換えてやってみてください。 関連項目: Subversion バックアップ構成

2016年1月19日火曜日

ウィンドウズのバッチファイルで曜日を取得する

参考:バッチで日付の操作 Linux でシェルスクリプトを書くよりも、Windows のバッチファイルは曲者で苦労します。 今回は、定期で PostgreSQL のバックアップファイルをとりたいので、曜日でローテションする事を考えました。
@echo off
REM 日付の曜日を求める
REM 日付はYYYY/MM/DD 形式とする。結果は環境変数 yobi へ返す。
REM 引数がないときは本日とする。
if "%1"=="" (  
    set orgdate=%date:~-10,10%
) else (
    set orgdate=%1
)

:年月日の分割
set yy=%orgdate:~-10,4%
set mm=%orgdate:~-5,2%
set dd=%orgdate:~-2,2%
set dayfile=%yy%%mm%%dd%

:月日の数値化(8進数対策)
set /a mm=1%mm%-100
set /a dd=1%dd%-100
if "%mm%" LEQ "2" (set /a yy=yy-1&&set /a mm=mm+12)
set /a ans=yy + yy/4 - yy/100 + yy/400 + (13*mm+8)/5 + dd
set /a wday=ans %% 7
if %wday%==0 (
 set youbi=日曜日
 set syoubi=日
) else if %wday%==1 (
 set youbi=月曜日
 set syoubi=月
) else if %wday%==2 (
 set youbi=火曜日
 set syoubi=火
) else if %wday%==3 (
 set youbi=水曜日
 set syoubi=水
) else if %wday%==4 (
 set youbi=木曜日
 set syoubi=木
) else if %wday%==5 (
 set youbi=金曜日
 set syoubi=金
) else if %wday%==6 (
 set youbi=土曜日
 set syoubi=土
)
:echo %wday%
:echo %youbi%
バックアップは、こんな感じ
REM 環境変数のスコープをバッチ内に限定
Setlocal
set PGPASSWORD=%1%
set CURPATH=%~dp0
REM PostgreSQL インストール・ディレクトリ
set PGPATH=C:\Program Files\PostgreSQL\9.4\bin
REM バックアップ先ディレクトリ
set BKDIR=C:\DatabaseBackup
call %CURPATH%youbi.bat
REM mydb のバックアップを取る
"%PGPATH%\pg_dump.exe" -h localhost -p 5432 -U postgres -Fc -v -f%BKDIR%\%youbi%backup.dmp mydb 2> %BKDIR%\%youbi%backup.log
:"%PGPATH%\pg_dump.exe" -h localhost -p 5432 -U postgres -Fc -v -f%BKDIR%\%dayfile%backup.dmp mydb 2> %BKDIR%\%dayfile%backup.log
古いファイルを削除する手段がわかった
set BKDIR=C:\DatabaseBackup
forfiles /p %BKDIR% /m "*.dmp" /d -30 /c "cmd /c del /Q @file"
forfiles /p %BKDIR% /m "*.log" /d -30 /c "cmd /c del /Q @file"