GDALライブラリをAndroid、iOS用にビルドする方法をこちらにまとめました。
github.com
これを利用してReactNative用のモジュールを作成したので、EcorisMapからGeospatial PDFを投影変換して読み書きできるようになりました。
位置座標付きのGeospatial PDFは、QGISから簡単に作成できます。
Geospatial PDFを読み書きできるEcorisMapは、近々公開予定です。
GDALライブラリをAndroid、iOS用にビルドする方法をこちらにまとめました。
github.com
これを利用してReactNative用のモジュールを作成したので、EcorisMapからGeospatial PDFを投影変換して読み書きできるようになりました。
位置座標付きのGeospatial PDFは、QGISから簡単に作成できます。
Geospatial PDFを読み書きできるEcorisMapは、近々公開予定です。
野外調査のための地図アプリ「EcorisMap」を作ってます。そのアプリでPMTilesを読み込めるようにしたので、それについてのお話です。
調査で使う地図は、地理院地図のような下図に調査地点など必要なデータを重ねて持っていきます。下図は、地理院さんが全国レベルでタイル配信しており、ありがたくアプリでも利用させてもらっています。一方、調査地点などのデータは、自分で用意するもので、ファイルサイズも大きくならないのでGeoJSONにしてアプリにインポートすることで利用することができます。
しかし、問題はそのどちらでもないデータで、ファイルサイズもある程度大きいもののタイル配信されていないデータです。例えば、植生図のポリゴンとか河川距離標のラインデータなどです。こういうデータは市町村〜県レベルの範囲で整備されており、そのままGeoJSONとしてインポートすると重くてアプリが動作しなくなってしまいます。調査に必要な範囲だけを切り出せば良いのですが、調査範囲が広い場合はそうもいきません。
そういう場合はどうするかと言うと、ベクタデータをラスタ形式の地図タイルに変換します。手順としては、まず、ベクタデータをQGISで色を付けたりラベルを表示させたりしてスタイリングします。次にそれを一枚のGeoTIFFとして書き出します(地図は重ねずデータ以外は透過)そしてgdal2tilesで必要なズームレベルでタイルに切り出し、サーバーにアップします。この方法でデータを地図タイルとして読むことはできますが、ファイルの数とサイズが増えてしまいサーバーのストレージも消耗してしまいます。
そこでPMTilesの出番です。PMTilesとは、簡単に言うとズームレベルごとにベクタデータをベクタ形式のままタイル状に切り出して一つのファイルにまとめたものです。似たようなものにmbtilesと言うものがあるのですが、mbtilesはデータの配信に専用のタイルサーバーが必要になりますが、PMTilesはファイルサーバーに置くだけで良いです。
PMTilesだとベクタ形式のままなのでファイルサイズは大きくならずファイル数も一つなので取り扱いも簡単です。そして専用のサーバーも不要なのでホームページ用のファイルサーバーやGithub PagesやAmazon S3のような静的ホスティングサービスだけで配信できます。
アプリではPMTilesから表示範囲だけのベクタタイルを取得してレンダリングの処理をすれば良いので、広範囲のデータであっても重くなりません。さらに、色やラベルなどのスタイルはユーザー側で設定できるようになります。
気になるのは、ベクタタイルをPMTilesから取得する仕組みですが、HTTP Range RequestsというHTTPでファイルの一部分だけを取得する方法を利用しています。PMTilesは、各ズームレベルのX,Yタイルをヒルベクト曲線に基づいてバイナリファイルに配置しています。なので、z/x/yが分かれば、逆にバイナリの位置を計算することができ、それをRange Requestで取得しています。
https://docs.protomaps.com/pmtiles/
https://github.com/protomaps/PMTiles/blob/main/spec/v3/spec.md
前置きはこれぐらいにして、スマホでPMTilesを使ってみましょう。使用するデータはこちらです。GeoJSONのデータをPMTilesに変換して、Github Pagesに置いてあります。
github.com
1. EcorisMapを起動して、左下のボタンを押します。
3. 地図の名称とpmtilesのURLとスタイルファイルのURLを入力してOKを押します。(スタイルファイルを指定しないとデフォルトの色になります。)
https://tmizu23.github.io/santa/santa.pmtiles
https://tmizu23.github.io/santa/style.json
4. これでサンタクロースのPMTIlesを読み込むことができました。クリックすると、属性を表示できます。
スタイルを変更したい場合は、上記のstyle.jsonをコピーして、色などを変更したのち、自分のサイトに置いてスタイルファイルのURLを変更してください。
ということで良いクリスマスを!
PMTilesのデータは、go-pmtilesを使ってmbtilesから変換するか、tippecanoeを使ってGeoJSONから変換して作成します。GeoJSONからPMTilesへの変換は、以下のコマンドでできます。データによっては、変換オプションを指定して最適化する必要があります。詳しい説明は、また期を改めて。
tippecanoe -o santa.pmtiles santa.geojson
ちなみに、GeoJSONのデータは「サンタの絵を書いて、それをポリゴンにして、スケールと座標は、東北地方ぐらいの仙台付近、GeoJSONでダウンロードしたい!」とChatGPTに言って作ってもらいました。
スタイルファイルは、ベクタタイルに色やラベルをつけるための設定ファイルです。そのルールは基本的にはMapLibre Style Spec
に準拠していますが以下の点が異なります。
(今後、少しずつ色々なfilterに対応するように実装しようと思ってます)
EcorisMapはreact-native-mapsを利用して作成しています。しかしreact-native-mapsはPMTilesはもとより、ベクタータイルもサポートしていません。なので、新機能が欲しければ自分で実装するしかありません。React Nativeは、Typescriptを書けばAndroid用とiOS用のアプリを同時に作成できるのが良いところなのですが、裏を返せば新機能を追加するためには、Android用のJavaとiOS用のObjective-Cの両方のコードを書く必要が出てきます。Objective-Cは見たこともないし、Javaは25年前にアプレットを作ったきりです。
こういう状況なので、去年までならPMTilesを実装しようなどとは、露ほども考えなかったのですが、ChatGPTが状況を変えました。PMTilesのGithubには、Cとjavascriptの実装コードと仕様(spec)が置いてあります。これらを関数ごとにコピペして「javaとObjective-Cに移植して!」とお願いすることでコードが作成されます。それをコンパイルしてエラーが出たら再びChatGPTに修正してもらいます。これを繰り返すことでなんとか実装できました。
ベクタータイルの実装も同様の方法ですが、Maplibreのようにグラフィックライブラリで高速に描画を行う工夫がされているのではなく、単純にCanvasへの描画です。ただ、野外調査で使うデータのように少ないレイヤに色やラベルを付けるだけで良い場合は、十分速く描画することができます。
MapLibre GL JSでWeb用のサイトを作ってスマホのブラウザで見る方法です。もしかすると、これでも良いかもしれません。ただ、アプリじゃないとできないこととか、パフォーマンスが気になります。あと、地理院地図以外の地図や衛星画像を使うためにはアクセス数に応じて課金が発生するサービスの利用が必要になります。(もしくは、自分で配信)
以前ビルドしたものがpixel7aで起動できなくなってたので修正しました。pixel7シリーズからは64bitのアプリのみの対応になった影響です。
修正したapkはこちらからダウンロードできます。pixel7a以外の動作検証はしていません。64bitに対応していないものは、以前のリリースを利用ください。
コードはこちら
github.com
armeabi-v7aとなっている部分をarm64-v8aに変更
File-->Settings-->Build Tools で Download JDK...で選択
古いJDKだとrelease用のビルドで署名のときにエラーになるため
2022年冬、野外調査アプリが群雄割拠しています。DXの掛け声のもと、仕事で使う野外調査アプリを探していた私は、四角い車輪を再発明したのでした。
これはFOSS4G Advent Calendar 2022の記事です。
野外調査の必須アイテムと言えば、紙の野帳と図面、GPS、デジカメでした。スマホの普及とともに、数々の野外調査アプリがそれに取って代わろうと、しのぎを削っています。アプリの使い勝手は一長一短、淘汰されるものもあるでしょうが、多様性があることは健全です。
Mergin Maps Input
- github: https://github.com/MerginMaps/input
- ドキュメント: https://merginmaps.com/docs/
- 開発フレームワーク: Qt(C++、QML)
QField
- github: https://github.com/opengisch/qfield
- ドキュメント: https://qfield.org/docs/ja/
- 開発フレームワーク: Qt(C++、QML)
SMASH
- github: https://github.com/geopaparazzi/smash
- ドキュメント: https://www.geopaparazzi.org/smash/
- 開発フレームワーク: Flutter(Dart)
FOSS4GのAdventCalendarなので、オープンソースのものをピックアップしました。どのアプリも現在進行形で開発が進んでいます。
注目ポイントは、利用している開発フレームワークです。Mergin Maps Input とQFieldは「Qt」、SMASHは「Flutter」です。採用しているフレームワークでどれぐらい開発効率やアプリのパフォーマンスが違うのか気になるところです。
DXの掛け声のもと、野外調査アプリの導入を検討していたつもりが...
突然ですが、既存のものを自前で作り直すことを車輪の再発明と言います。さらに作ったものが役に立たない場合は、四角い車輪と揶揄されます。
これだけ野外調査アプリがある中、素人が似たようなものを作るのは、四角い車輪の再発明に他ならないかもしれません。
でも、まあいいか、スペアタイヤのつもりで自前の野外調査アプリを作ってみました。名前は「EcorisMap」です。React Native Mapsを利用していて、アプリもオープンソースです。
EcorisMap
- ホームページ: https://ecoris-map.web.app
- github: https://github.com/ecorismap/ecorismap
- ドキュメント: https://ecoris-map.web.app/manual_ja.html
- 開発フレームワーク: React Native(TypeScript)
まずは、アプリをインストールしましょう。iOS、Android、Web版があります。
操作は直感で分かるように、それっぽいアイコンになっています。直感で分かると言っておきながらボタンの説明をします。上から、ヘディングアップ切り替え、ズーム、GPS、下にいって左から、地図選択、トラックログの記録、レイヤ表示、データ追加、各種設定になってます。
データをインポートして確認する方法を説明します。
1.レイヤ表示ボタンを押して、2.レイヤ一覧の画面になったら、3.左下のデータ読み込みボタンを押して、4.スマホに保存されているGeoJSONやGPXのデータを指定するとインポートできるので、5.レイヤ一覧からレイヤを選択したあと、6.データ一覧からデータを選択して、7.左下の飛行機ボタンを押すとデータの場所にジャンプするので、8.読み込んだデータを確認します。
言葉だと上手く言えないけど思いは伝えました。色とかラベルも設定できます。
現地が圏外の場合は、ネット環境がある場所で事前に地図をダウンロードしておきます。地図選択画面でダウンロードボタンを押して、必要な範囲を選択してダウンロードします。
地図は自前のタイル地図も登録できます。例えばドローンから作成したオルソ画像をQGISでタイル地図にして、それをGitHubにあげてURLを登録すると読み込めます。
現地ではGPSをオンにして目的地にでかけます。素敵なお花を見つけたら現在地にポイントを落とします。お花の写真を上手に撮ったら、その名前と写真を入力します。入力したい項目は、レイヤの設定で変更できます。トラックをオンにしておけば、花の種をこぼして帰らなくても歩いた軌跡を残せます。
エクスポートしたいデータを選択して、エクスポートボタンを押すとzipファイルが作成されます。スマホ内に保存したり、Google Driveに保存したり、Slackで飛ばしたりすると便利です。でもGmailはzipファイルをブロックするから使えません。
必要な操作はスマホで全部できますが、データの準備はパソコンからWeb版を利用すると簡単です。Web版で、調査に必要なデータをインポートして、色やラベルを設定しておきます。設定画面で「データをファイルに保存」とすると拡張子ecorismapの設定ファイルを書き出します(中身はデータと設定をzipで保存したもの)。このecorismapファイルをスマホに送って設定画面から「データファイルを読み込み」とすると、そっくりそのまま開きます。あら便利。
Web版のセキュリティが気になるかもしれませんが、データはすべてブラウザ側だけで処理してます。サーバーにデータを送ってません。でも、今後はクラウド対応も考えてたり。
React Native
EcorisMapの開発に利用しているフレームワークは、React Nativeです。React Nativeは、Meta(旧Facebook)とコミュニティによって開発されているモバイル用のフレームワークで、ReactでネイティブコードをラップすることでTypeScript(JavaScript)でAndroidとiOSのアプリ開発ができます。最近は、Flutterに人気が押されがちでMetaさんも元気がないので、ちょっと心配です。ソースコードは、基本的にはTypeScriptなので、JavaScriptになじみがあれば、始めやすいかも(?)
React Native Maps
GoogleのMaps SDK for Android ・iOSと、AppleのMapKitをラップしてReact Nativeで使えるようにしたライブラリです。EcorisMapでは、MapKitは使わずに、Android版、iOS版ともにMaps SDKでGoogle Mapsの地図を利用しています。モバイル用だとGoogle Mapsの地図データや衛星データを無課金で利用できるのでありがたいです。
EcorisMapのWeb版
Web版は、React Native for Webを利用してスマホ用のコードからWeb版を生成しています。もともとWebの技術であったReactをNativeに適用して、それをまたWebに戻すという加工貿易的なイメージ?の技術です。ただ、Web版はスマホ版と少しコードが違う部分があって、地図ライブラリにMapLibreを使っています。その関係で、デフォルトの地図はGoogle Mapsではなく、MapTilerの地図と地形データを読み込んでいます。そのためMapTilerの無料枠を超えると地図が表示されなくなるかもしれません...という意味で現在Web版はお試し中です。MapLibreも3Dの地形表示ができるようになったのでコミュニティーに感謝です。(MapBoxも嫌いじゃないよ)
国際化
一応、国際化してあります。現時点では、日本語と(つたない)英語です。世界中のみんなが使ってくれる妄想を抱きながら作業しました。現時点のダウンロード数は36人です(笑
地図データはネット経由のタイルの読み込みだけ対応してるので、ローカルで持っているGeoTIFFとかMBTilesとかGeoPDFを読み込めるようにできたら便利かなーと思ってます。
ラインの編集は今も一応できますが、いまいちです。お絵描きアプリみたいに、さら、さら、さらーと描けるようにしたいです。ポリゴンにも対応したいです。できることならトポロジーも考慮して。
Firebaseを利用したクラウド対応は、社内用のテストアプリでは実装済みで、すでに利用しています。でも、みんなが使うサービスとして公開するにはセキュリティの面でハードルが高いなーと怖気付いてます。
当然のことながら仕事で扱う位置情報は、漏洩したらタダじゃ済まないものばかりです。アプリとFirebase間をEnd to Endで暗号できるVirgil SecurityのE3Kitを導入してますが、利用人数増えたらお安くないし、暗号化するとアプリの輸出制限に引っかかって、アプリを公開するには色々と手続きが必要になり大変そうです。
Mergin MapsやQFieldはクラウドサービスもありますが、そのあたりどう考えてるのか気になります(利用者側も)。クラウドのサーバー側もオープンソースで公開してるので、気になる人は自分でサーバー立ててねってことですかね。
課金ねぇ......先立つものは必要ですよね.....
スマホを出して現在地を確認するのは面倒なので、スマートウォッチで確認できるようにしたいです。スマートウォッチは持ってません。
サンタさんにお願いするスマートウォッチの画像を張っておきます。
最後になりましたが、バグは色々あると思いますので、不具合、ご要望があれば以下に書き込むなり、Pull Requestを送るなり、よろしくお願い致します。
ドローン画像のフォトグラメトリで作成した点群データをブラウザで快適に表示できるCOPC形式の点群データの作成と表示をやってみました。
地理座標系(緯度、経度)以外で書き出したlasファイルもしくはlazファイルの点群データを用意します。高度は楕円体高です。(標高になっている場合は補足で説明している方法で変換します。)
変換方法は2通りあります。
QGIS3.26以降を用意します。las、lazファイルを画面にドラッグするとxxx.copc.lazのようなファイルが出来上がります。今のところファイル名に日本語は使えません。
PDALを使用します。WindowsならQGIS3.26をインストールした際に入るOSGeo4Wで利用できます。
OSGeo4Wで以下のコマンドを実行しするとlazをcopcに変換できます。
pdal translate -i xxx.laz -o xxx.copc.laz --writers.copc.forward=all
どこかのWEBサーバーにCOPCに変換したファイルをアップロードします。WEBサーバーではCORSを受け付けるように.htaccessを以下のように設定しておきます。
Header set Access-Control-Allow-Origin "https://viewer.copc.io"
https://viewer.copc.io
にアクセスしてデータボタンからAdd point cloudを押してcopcファイルのURLを貼り付けます。
もしくは以下のように直接URLを指定してアクセスします。
https://viewer.copc.io/?copc=https://www.example.com/xxx.copc.laz
以下によるとオープンソースではないようです。見た目はなんとなくCesiumっぽいので、そのCOPC対応版なのかな?と思ってみたり。
https://hobu.co/copc-viewer.html
手元にある点群データが平面直角座標系10で高さは標高値となっている場合の変換方法です。COPC Viewerの地形データは楕円体高となっているため高さを合わせるためにはcopcのデータも楕円体高に変換しておく必要があります。(点群データの高さは一般的には楕円体高なんですかね?知りません)
PDALのパイプライン用のファイルを以下のように作成します。
pipeline.json
[
{
"type" : "readers.las",
"filename" : "xxx.laz"
},
{
"type":"filters.reprojection",
"in_srs":"+proj=tmerc +lat_0=40 +lon_0=140.833333333333 +k=0.9999 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +geoidgrids=D:/PDAL/jp_gsi_gsigeo2011.gtx",
"out_srs":"EPSG:6667"
},
{
"type":"filters.reprojection",
"in_srs":"EPSG:6667",
"out_srs":"EPSG:6678"
},
{
"type" : "writers.copc",
"filename" : "xxx.copc.laz"
}
]
pdal pipeline pipeline.json で変換を実行します。
1. プロポとPCをUSBで接続します。
2. GS RTK アプリを起動して、画面を上からスワイプします。
3. USB ストレージを接続する ボタンを押します。
4. PCのエクスプローラでD:\DJI\dji.prof.mg.gsp\LOG\tcp_769にアクセスします。
5. フォルダ内の飛行ログをコピーします。
6. DJI Flight Log Viewer | Phantom Help このサイトに飛行ログをアップロードしてKMZファイルに変換します。
なんだか楕円体高のdemデータが欲しくなるときがあります。
そんな時のために取得方法を紹介します。
2022.8.19追追記
Phantom4 RTKの地形認識モード使用時にPPKの場合(D-RTK 2を使用しない)は、高度は気圧計で算出されるため、標高やその日の天気で誤差が大きくなってしまうようです。で、やっぱり楕円体高でDEMを用意する必要があるようです。
https://forum.dji.com/forum.php?mod=redirect&goto=findpost&ptid=264115&pid=2734061
↓ジオイド高の分だけ高く飛んだというのは、偶然それぐらいの誤差が出ていただけだった可能性が高いので取り消し
2021.10.19追記
Phantom4 RTKの地形認識モードのDSMは、普通に標高で良いのかもしれません....実際に飛ばしたら、ジオイド高の分だけ高く飛んでいました...
C:\Program Files\QGIS 3.20.3\share\proj に入っている jp_gsi_gsigeo2011.tifを作業フォルダにコピーします。
OSGeo4W shellを起動して作業フォルダに移動します。
日本のgeoidモデルのtifをgtx形式に変換します。
gdal_translate -ot Float32 jp_gsi_gsigeo2011.tif jp_gsi_gsigeo2011.gtx
※ジオイドモデルの元データは、国土地理院で提供されています。使用に関する許可申請等は国土地理院のサイトおよびprojファイルに入っているjp_gsi_README.txtを確認ください。
jp_gsi_gsigeo2011.gtxをC:\Program Files\QGIS 3.20.3\share\projのフォルダにコピーします。
gdalwarpで楕円体高になるようにパラメータを指定して変換します。
gdalwarp -s_srs "+init=epsg:6668 +geoidgrids=jp_gsi_gsigeo2011.gtx" -t_srs epsg:6667 merge.tif merge_ellipsoidal.tif
※ Warning 1: +init=epsg:XXXX syntax is deprecated. と出ますが気にしません。