smellman's Broken Diary

クソみたいなもんです

Mapbox Android SDK で地理院地図を表示してみる

(追記) Mapbox Android SDKmapbox-gl-nativeベースのものに(無事)置き換えられたのでこの記事はもう役に立たなくなりました。古い実装がひつようなひとだけチェックしてね(はぁと

昨日の記事 に続いて Mapbox Android SDK でも地理院地図を表示してみようと思いました。

手順は以下の感じです。

  1. 適当にプロジェクトを作成。
  2. Mapbox Android SDKgradle の解説にそって app/build.gradle を編集。
  3. AndroidManifest.xmlネットワークアクセスなどの許可を書く。
  4. activity_main.xmlMapView を追加する。なお、 mapid 及び accesstoken は追加しない。
  5. プログラムを書く。

圧倒的に可愛い名前のプログラミング言語で書いたプログラムだけ貼っておきます。


mapbox sdk + gsimap (kotlin)

起動するとこんな感じ。

f:id:smellman:20150921075540p:plain

で、マルチタッチが何故か動かないので、実機で動かしてみたら普通にさくさく動きました。

mapbox-gl-native for ios で地理院地図を表示してみる

シミュレータの段階ですが、なんかできた。

手順はざっくり言うと以下でOKだった。

  1. xcodeで適当なSingle View Applicationを作成(今回はmapboxsdktestという名前で作った。雑だ)
  2. Podfileを作成して pod install を実行する。(参照)
  3. mapboxsdktest.xcworkspaceを開く
  4. Settings.bundle をプロジェクトに入れる。(参照)
  5. 地理院地図のタイルサーバはHTTPだけでしか配布してないのでApp Transport Securityを追加する(ios9以降)
  6. Mapbox GL Style Spec に沿ったjsonファイルを作成する。
  7. Viewにコードを書く。

ATSはこんな感じのものを書きます。

        <key>NSAppTransportSecurity</key>
        <dict>
                <key>NSExceptionDomains</key>
                <dict>
                        <key>cyberjapandata.gsi.go.jp</key>
                        <dict>
                                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                                <true/>
                        </dict>
                </dict>
        </dict>

jsonはこんな感じです。


raster for gsi

gistに貼っておけばrawでアクセス可能になってとても便利です。

最後にViewController.swiftを以下のようにします。


ViewController.swift for gsimap with mapbox-gl-nat ...

ビルドするとこんな感じになります。

f:id:smellman:20150920065617p:plain

でかすぎてなにがなんだかわかりません!!!!

地理院地図のソースコードを盛大にパクってLeafletのプラグインを作った

地理院地図に中心十字線っていうのがあるんだけど、お客さんからこれと同じものがあると嬉しいと言われて、だったらプラグイン化してしまえばイイのではと思ってやってみた。

github.com

Markerの実装を変えたり、わざわざimageディレクトリの位置を検出するのが面倒なので画像をBase64化したりしましたが、まぁいちおうLeaflet 0.7.5とLeaflet 1.0 beta1で動作確認して上手く動いたのでアップした。
コミットログが雑すぎるが、本当に初回のコミットなので仕方がない...

結構この中心十字線って便利だとは思うのでぜひ使ってみるもしくは弊社に仕事ください。

追記

何を思ったのかいきなりFactoryの実装を変更したりしています。
元々の実装がILayerっぽく出せなかったので仕方なくっていう感じです。
おかげで実装の見通しがよくなったので満足はしている。

すごいHaskellたのしく学ぼう!(第1版) 第3章のbmiの計算でハマった件について

タイトルどおりの感じですが、なかなか面白かったのでメモ。ちなみにうちの環境は以下のとおり。

$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 7.6.3

今回は最初に作ったbaby.hsにひたすら出てきた関数を書いていくようにして試していたのだけど、P.37 の訳注でこんな記述がありました。

.hs ファイルの先頭に {-# OPTIONS -Wall -Werror #-} を付けてコーディングすれば、意図せぬ動作やクラッシュの原因になりがちな箇所を GHC が指摘してくれるので、良い Haskell コードを書く訓練になりますよ!

とあったので追加してみました。

当然、今まで書いたものは型を定義してないので warning が出るのでひと通り型の定義を追加してしてから先に進めたのですが、 P.42 のガードで計算しているところでドはまりしました。

まず、このプログラム自体本に書いてある内容は古いようで、原著の記述では Double ではなく RealFloat を使うようになっています。

bmiTell :: (RealFloat a) => a -> a -> String  
bmiTell weight height  
    | weight / height ^ 2 <= 18.5 = "You're underweight, you emo, you!"  
    | weight / height ^ 2 <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"  
    | weight / height ^ 2 <= 30.0 = "You're fat! Lose some weight, fatty!"  
    | otherwise                 = "You're a whale, congratulations!"  

Syntax in Functions - Learn You a Haskell for Great Good!

これを読み込むと前述の OPTIONS を付けた状態だと warning が出て通らなくなります(もちろん、 OPTIONS を付けて無ければ通って動作します)。

Prelude> :l baby
[1 of 1] Compiling Main             ( baby.hs, interpreted )

baby.hs:80:23: Warning:
    Defaulting the following constraint(s) to type `Integer'
      (Integral b0) arising from a use of `^' at baby.hs:80:23
      (Num b0) arising from the literal `2' at baby.hs:80:25
    In the second argument of `(/)', namely `height ^ 2'
    In the first argument of `(<=)', namely `weight / height ^ 2'
    In the expression: weight / height ^ 2 <= 18.5

baby.hs:81:23: Warning:
    Defaulting the following constraint(s) to type `Integer'
      (Integral b0) arising from a use of `^' at baby.hs:81:23
      (Num b0) arising from the literal `2' at baby.hs:81:25
    In the second argument of `(/)', namely `height ^ 2'
    In the first argument of `(<=)', namely `weight / height ^ 2'
    In the expression: weight / height ^ 2 <= 25.0

baby.hs:82:23: Warning:
    Defaulting the following constraint(s) to type `Integer'
      (Integral b0) arising from a use of `^' at baby.hs:82:23
      (Num b0) arising from the literal `2' at baby.hs:82:25
    In the second argument of `(/)', namely `height ^ 2'
    In the first argument of `(<=)', namely `weight / height ^ 2'
    In the expression: weight / height ^ 2 <= 30.0

<no location info>:
Failing due to -Werror.
Failed, modules loaded: none.

ここで注目するのは以下の記述です。

    Defaulting the following constraint(s) to type `Integer'
      (Integral b0) arising from a use of `^' at baby.hs:80:23
      (Num b0) arising from the literal `2' at baby.hs:80:25

この記述では通常 Integer となるところが '^' を使ってるので Integral と推測されて、 2 から Num だと推測されてわからんっていう状態になるというものっぽいです。
ということは Integer 型として処理をしてくれと明示的に指定すればよいというものです。
以下のように修正すると無事通るようになります。

bmiTell :: (RealFloat a) => a -> a -> String  
bmiTell weight height  
    | weight / height ^ (2 :: Integer) <= 18.5 = "You're underweight, you emo, you!"  
    | weight / height ^ (2 :: Integer) <= 25.0 = "You're supposedly normal. Pffft, I bet you're ugly!"  
    | weight / height ^ (2 :: Integer) <= 30.0 = "You're fat! Lose some weight, fatty!"  
    | otherwise                 = "You're a whale, congratulations!"  

最後に今朝の僕の情報を入れて試してみましょう。

Prelude> :l baby
[1 of 1] Compiling Main             ( baby.hs, interpreted )
Ok, modules loaded: Main.
*Main> bmiTell 70.4 1.65
"You're fat! Lose some weight, fatty!"

うるせぇ、これでも今年だけで約10キロ減ってるんだよ!!!!

Sutegma / Drugs in the morning noon evening

www.otherman-records.com

忙しくてSNSかなにかでしか書けなかった話を日記の方に書くような感じのものです。

平たくいうとbreakcoreという音楽のジャンルで知らん人は最初にまずこの曲を聞きましょうっていうことです。

このEP自体最高なんですが、僕が推したいのがSutegmaさんのDrugs in the morning noon eveningです。

物ネタの曲全然わからないんけど、さっきミラクル9見てたらなんか流れてました。多分有名なやつなんだろうと思います。

本当にわかりやすい楽曲を使ってブレイクコアというジャンルの面白さをやってるっていうのがよくわかるんですよ。
物ネタ全然知らないけど、この楽曲はツボにハマりましてリリース当時何十回風呂場で聞いてたかわかりません。(なんで風呂場で永遠リピートしてたのかもわからない)
とにかく、ブレイクコアを知る上で初めての人にもわかりやすい上に死ぬほど最高の曲ですのでみんな聞いて倒れましょう!!!!!!

つーかブレイクコア聞いて倒れましょう!!!!!!!

あと、酔ってます。

Georepublicに入社してまる三年経ちました

本日の仕事が終わりまして、営業日的には次が6/1なので、丁度本日で入社まる三年が経ったことになりました。

昨日今日の仕事は20万件ぐらいのエクセルファイルを目でチェックしたり、ansibleのソースコードを探求したり、相変わらず「お前何やってるの」状態でありました。

先日、記憶がなくなるぐらい泥酔して気づいたら
最近の話 - smellman's Broken Diary とかいうタイトルで記事を書いてしまったのでまぁ最近の事は書いてあるわけですが、とりあえずこの三年の活動を振り返ってみようと思います。

一年目、まだ入社ばかりのころは「これから地理空間情報系をやっていくんだ」という気持ちを高めていたのですが、最初の仕事はなぜかお客さんがその手の実装をやってしまっていて、APIにアクセスするだけのiOSアプリの開発という微妙な仕事を担当しました。正直バックエンド俺に書かせろと思っていましたが、ぐっと我慢していたんですがなんとかしたあと、えーとどうなったか知らないです(ぉ

そんなタイミングで新しい仕事が舞い込みました。とある省庁->とある総研->弊社という流れで仕事が来ていたんですが、最初関さんに「Localwikiでサイトを作って欲しい」と言われ、なかなか面白い仕事が来たと思いながらさくっと構築までやってみてそこからお客さんとのやりとりに行くんですが、この仕事が僕がいままでやったなかで一番心に残る仕事になりました。
伊豆大島で観光や地域の文化などをLocalwikiにあげていくため、東海汽船のジェット船に乗って行って打ち合わせをしたり、泊まり込みでコンテンツをつくるためにお客さんたちと現地の女子高生と一緒に現地を回って行っていき、伊豆大島の魅力を個人的にも堪能しながら仕事をしていました。
中でも良かったのがコンテンツを作るためにちゃんと仕事として関わってくれた学生たちが書くコンテンツが非常に面白くていちいち感動していました。
もちろん、伊豆大島自体もすごく良くって、自然もいいし魚は旨いし、とくにくさやは工場見つけて見学させてもらうぐらいハマりました。
業務としてはLocalwikiのコンテンツ作り以外にも現地で行われたロゲイニングのアプリの開発や、ハッカソンとマッピングパーティーをやらせてもらったりと、一つの業務なのにいろんな経験をさせてもらいました。
マッピングパーティーの成果が少し悲しいことですが、2013年の災害時役立つ結果になったのも感慨深いものがあります。
あと、一緒にコンテンツ作りをやっていた学生たちは先日高校を卒業しました。彼女たちに輝かしい未来があることを祈っています。

もう一つ同じ時期に某社からとあるW3Cの仕様がらみで仕事が来ました。
最初はエクステンションを作るという話だったんだけど、途中で仕様が変わってしまい当時麹町にあった某ブラウザベンダーでミーティングで「これネイティブで書かないとまずいね」っていうのが出てしまい某ブラウザのコードとにらめっこする日々が発生したりしました。これはこれで大変でした。ドハマりが辛く、当時六本木に移転した新しいオフィスに自転車に行ってSVG周りのコードをいろいろ聞いたりしながらやったんですが、最終的に終わらず途中までのパッチを出して終了してしまった。技術不足を強く感じました。

あと、会社繋がり(関さんが当時代表やってた)で、2013年から連続でInternational Space Apps Challenge(ISAC) に参加させていただいています。
最初に一緒にチームを組んだのは実は伊豆大島の案件で当時とある省庁に居た方で、僕らが伊豆大島でやったハッカソンに影響を受けて参加したという面白い繋がりです。
そこで出来たTeam Debirsは今年はグローバル進出を果たすことができました。
本当に出会いって何に繋がるかわかりません。

二年目のチョット前からとあるゲーミフィケーション的なアプリの開発という仕事が来たのですが、当時お客さんが作っていたPythonで作られていたサーバが正直僕が今までみたコードの中ではワースト1位だなぁというぐらい破綻していて、半年ぐらいメンテナンスに頭を抱えたあげく、無理だと思って全部Ruby on Railsに書きなおしました。
なお、その元開発者は現在はPythonのコミュニティで活躍されていて、ちゃんと成長していっているんだなーと感じております。

あと、二年目に夏休みを兼ねてイギリスのカンファレンスをはしごしてきました。OSMのカンファレンスであるSotMではMapsMeの社長と煙草友達になったり、MapsMeの開発者が「内緒だよ」みたいなノリで表に出せないバージョンの開発物見せてくれたり、暗渠マニアとお話したりととてもおもしろ楽しくやれました。
あと、イギリスではQGISのイベントで大量のピザに卒倒したり、FOSS4Gで英語で30分発表するというなかなか大変な経験もしました。
英語についてはラングリッチさんにお友達ということで会社での契約を優遇していただいたりしてとても助かりました。最近会ってないのでまた飲みに行きたいです。

二年目の秋ごろにTeam Debrisのメンバーと一緒にマッシュアップアワードに出たりして、そこでたまたまAEDSOSを知って、なんだかんだあって今はCoaido株式会社のCTOを副業という形でやっていたりします。

あと、Laravelを使った謎業務をやったりしていたんだけど、これはもはや地図関係なかった(汗

あと、国土地理院の仕事で地球地図に関わるものをやっていたんですが、これが縁となりましてJICAの講師をやったり、FOSS4G Tokyoで地球地図に関する発表をしたりするという機会をいただきました。JICAの講師は今年もやる予定ですが、地球地図を整備するという国際的な取り組みが各国に広まるための掛け渡しとなる重要な仕事を任されているというのは非常に身が引き締まる思いだったりします。

そして三年目になるといろいろ入札で失敗したりしてあーあーみたいなのがあったりするんですが、そんな中で某大手ベンダーさんから仕事をいただきLeaflet.jsをめちゃくちゃ調べたり、プラグインを書いたりするような仕事が入ってなかなか楽しい業務をやることになりました。
なお、その大手ベンダーさんから追加の仕事が来たのですが、そっちは完全に赤字だってぐらい稼働して多方面に迷惑をかける結果となってしまいました。3Dに手をだすのは早すぎたかも...

あと、弊社がまだシナップさんのコワーキングスペースを使っていた時代に一緒のコワーキングスペースを使っていた会社さんからお仕事を紹介してもらいました。それが現在のVAL研究所さんのお仕事です。
デモが出ていますが、実はバックエンドにもまだまだ面白い実装をしていて、実装の仕方を含め、僕がXMLSVGにこじらせた学生時代の知恵や現在タイル三兄弟として怪しい活動をしてるところのノウハウを集めた集大成てきなものになっています。「技術で殴る(何」的な感じの動きができるのは非常にうれしくてエンジニアとしてもこれからどんどんやっていきたいと思う仕事です。

また、平行して国土地理院さんの地球地図関係のお仕事をしたり(お手伝いレベルですが)、OSMのレンタリングサーバ構築したり、たくさんあるOpenDocument形式のファイルをコンバートしてSphinxの一つのプロジェクトにまとめるような仕事をしたり、座標系が破滅してるShapefileを中のデータに潜んでる座標から正規化して地理院地図に重ねるようなものを作ったりと、それなりに変な業務をいっぱいこなしています。

他にも千葉市のオープンデータ関係にプライベートでお付き合いするようになったのもとてもよかったです。今は千駄ヶ谷に住んでるけど、地元にコードで貢献できるのはプログラマとして非常に嬉しいものです。

この三年間でやってきたことをさくっとまとめると、「今までやってきた趣味やインフラや開発の経験や、OSSコミュニティで得られたものをかなり活用しつつ、そこに地理空間系のエッセンスがまじって悪魔合体してる」という感じです。
つまり僕は悪魔です。
最近では「地球という概念を破壊しなければならない」などと言い出してますし、確実に悪魔ですね。

というわけで、いままでの経験も新しい経験も楽しみつつこれからも仕事をしていき、悪魔としての地位を上げていき地理空間界隈を悪魔的実装で攻めて行きたいと思います。

あと、とても重要ですが、弊社にお仕事くださいw