Closed usagi closed 6 years ago
GSI sample:
サンプルURLの場所は羊蹄山の山頂から北東側のタイル。
名称 | key | z | sample-url |
---|---|---|---|
単写真 | pp | 14 |
https://cyberjapandata.gsi.go.jp/xyz/pp/14/14600/6029.geojson |
基準点 | cp | [ 7 .. 12 ] |
https://cyberjapandata.gsi.go.jp/xyz/cp/12/3650/1507.geojson |
指定緊急避難場所(洪水) | skhb01 | 10 |
https://cyberjapandata.gsi.go.jp/xyz/skhb01/10/912/376.geojson |
指定緊急避難場所(崖崩れ、土石流及び地滑り) | skhb02 | 10 |
https://cyberjapandata.gsi.go.jp/xyz/skhb02/10/912/376.geojson |
指定緊急避難場所(高潮) | skhb03 | 10 |
https://cyberjapandata.gsi.go.jp/xyz/skhb03/10/912/376.geojson |
指定緊急避難場所(地震) | skhb04 | 10 |
https://cyberjapandata.gsi.go.jp/xyz/skhb04/10/912/376.geojson |
指定緊急避難場所(津波) | skhb05 | 10 |
https://cyberjapandata.gsi.go.jp/xyz/skhb05/10/912/376.geojson |
指定緊急避難場所(大規模な火事) | skhb06 | 10 |
https://cyberjapandata.gsi.go.jp/xyz/skhb06/10/912/376.geojson |
指定緊急避難場所(内水氾濫) | skhb07 | 10 |
https://cyberjapandata.gsi.go.jp/xyz/skhb07/10/912/376.geojson |
指定緊急避難場所(火山現象) | skhb08 | 10 |
https://cyberjapandata.gsi.go.jp/xyz/skhb08/10/912/376.geojson |
type
-> FeatureCollection
, Feature
の再帰構造に対応geometry
-> Point
, LineString
, Polygon
, MultiPoint
, MultiLineString
, MultiPolygon
, GeometryCollection
に対応
Point
に対応LineString
に対応Polygon
に対応G4 の GeoObject システムは Point には現在の実装で対応できるが、 LineString を表現する実装、 Polygon を三角形に分割する実装と内側に穴を開ける実装、複数の GeoObject をグループ化する実装(タグ機能でも実現は可能だが、異なる GeoObject からなる群ではなく、同じ GeoObject からなる群を扱うためにグループ機能を追加した方がスマート)、がそれぞれ無いので、この実装には少しコストがかかる。そこで、本チケットでは Point のみ対応し、他のジオメトリーデータは段階的に別チケットとして実装を進める。
Properties
は G4 GeoObject の文字列-文字列プロパティーシステムへ入れる。
できるだけ低レベルの API を先ずは用意する方針のなか、 GeoJSON から GeoObject 群を生成する扱いの善い API 仕様を検討している。
現在の案:
/// @param geo_json GeoJSON 文字列
/// @return 生成された GeoObject の id 群
[ <number:id> ] GeoObject.NewObjectFromGeoJSON( string geo_json );
オプショナルなパラメーターとして [<string>] tags
を入れるなどしようかとも検討したが、できるだけシンプルな方がユーザーが扱いやすかろうと考え、そうした必要があれば return から別途 AddTag などして貰うのが善いだろうと判断している。
標準で Local Address Mode で生成するか、標準で Global Address Mode で生成するか、選択肢をパラメーター化するか、 API メソッドレベルで分けて用意するか検討。結果、標準で Global Address Mode で生成する事にした。
理由
coordinates
は Global Address で与えられる事。Point の場合は Local Address モードで生成し、任意のメッシュやビルボード化を行う用途が多いと考えたが、 LineString や Polygon の場合は Global Address で生成した方が素直であり、 Point とそれ以外で Local / Global が異なる状態で生成される事はユーザーに複雑な生成ルールを学ばせる事になりバグの原因にもなるだろうと考え、結果、望むならば Local / Global 変換 API を別途叩いて貰えばよい、あるいはユーザーニーズが多くあれば将来的に高レベル API で別途対応するのが善いと判断した。
GeoObject に DefaultRendering 機能を追加する事にした。この機能はメッシュとして有効な情報を設定されていないが、点、または接続した線分の集合としては有効な頂点群が与えられている場合に、簡易的な点または線の描画を行う機能で、ユーザーが GeoObject にメッシュやマテリアルを未設定の状態でも点と接続した線分の集合については簡易的に表示するお手軽機能である。
具体的には、 Global Address Mode
かつ Indices
数が 0
、 Vertices
数が 1 つ以上
与えられており、 bool DefaultRendering
フラグが true
の場合に動作し、 Vertices
数が 1
の場合は点、 1
より大きな場合は連続した接続する線分として簡易描画する。
また、 G3 でも地物を実寸で実装した直後からユーザーから「カメラの距離によらず画面上で一定の大きさを保つよう自動的にスケーリングされる機能が欲しい」と要望があった事を踏まえ、 GeoObject に bool FixedScaling
フラグ、 float Scaling
を追加する事とした。
追加 APIs:
void GeoObject.SetDefaultRendering( <number> id, <bool> enabling );
bool GeoObject.IsDefaultRenderingEnabled( <number> id ) const;
void GeoObject.SetFixedScaling( <number> id, <bool> enabling );
bool GeoObject.IsFixedScalingEnabled( <number> id ) const;
void GeoObject.SetScaling( <number> id, <float> scaling );
float GeoObject.GetScaling( <number> id ) const;
DefaultRendering の場合で、 GeoObject の Properties
に name
キーが存在する場合はその値を表示する実装を加えてみるとしよう。
Properties
に name
がある場合の表示例:
もっと視認性良く、などはさしあたりの実装をしたあとで対応する事にする。
name
プロパティーの表示機能は DefaultRendering の Point ( LineString ) 以外の GeoObject 全般でも少なくとも機能実装がまだ未熟な現時点ではとても有用と思うので、 GeoObject に新たに bool ShowName
プロパティーを追加して制御可能にする事にした。
もっと見やすく、あるいは tags もクラウドで表示したい、などのニーズは予想されるけれど、開発リソースの都合、そうした拡張はおいおいニーズとリソースを考慮して、という事にする。
地図画像やワイヤーフレーム、空模様によっては実用性がかなり低く感じられる程度まで見難くなってしまうようだ。
このため、視認性を向上する工夫も一緒に実装したい。いくらかの簡単なアイデアを試みて、良好そうならば採用する。
さしあたり、デバッグ用の機能を用いて簡易的に実装した段階ということもあり、その機能回りでは視認性を向上する工夫を低コストに実装するのは難しかった。視認性の向上は本チケットからは分離して後で行う事とし、本チケットの本質である GeoJSON の Point へのデータ的な対応を優先する事とした。残念。
GeoJSON の座標データは GSI の現実のサンプルでも [ <float:lon>, <float:lat> ]
形式で定義されている。 G4 GeoObject では altitude に NaN
値を入れ、 altitude が NaN
の座標値は G4 の空間内では Terrain の altitude を読み出して採用する仕様が便利だろうと考えた。この仕様は G3 の地物システムでも同様で、使い勝手に問題は報告されなかった。 G4 の実装をすすめる現時点でも特に問題となる事は無いか、十分に回避する実装を施せるであろうと推量するので、 altitude = NaN
の場合の挙動は altitude = Terrain としてひとまず実装し、 CBT ユーザーからのフィードバック等あれば徐々に改善していくこととした。
cat new_from_geojson.json
:
{ "jsonrpc": "2.0"
, "id": null
, "method": "GeoObject.NewFromGeoJSON"
, "params":
{ "GeoJSON":
{ "type": "Feature"
, "geometry":
{ "type": "Point"
, "coordinates": [ 140.811389, 42.826667 ]
}
, "properties":
{ "name": "羊蹄山"
}
}
}
}
curl -Ss -i http://127.0.0.1:50080/api/json-rpc-2.0/ -X POST -d @new_from_geojson.json
:
HTTP/1.1 200 OK
Content-Length: 91
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": null,
"result":
{
"ids": [ 0 ],
"errors": []
}
}
GeoJSON から G4 の GeoObject を生成する NewFromGeoJSON
API を本チケットの範囲である Point への対応と暫定的な点、名称の表示の対応で完了した。 altitude = NaN における自動的な地形システムの標高採用も絵の通り意図したとおりに動作している。
視認性について検討した際に、次の仕様を盛り込んでおいた。
DefaultRendering
が有効な場合に、
VertexColors[0]
が有効ならば、点と名称の表示色に採用するVertexColors[1]
が有効ならば、名称の表示色に採用する(この場合は [0]
は点の表示色にのみ採用する)curl -Ss -i http://127.0.0.1:50080/api/json-rpc-2.0/ -X POST --data '{ "jsonrpc": "2.0", "id": null, "method": "GeoObject.SetVertexColor", "params": { "id": 0, "vertexcolors": [ 1,1,1,1, 0,0,0,1 ] } }'
GeoJSON にエラーがあった場合のレポートも何個目の要素にどんなエラーがあったのか通知されるように実装した。
HTTP/1.1 200 OK
Content-Length: 160
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": null,
"result":
{
"ids": [],
"errors": [
"Feature[0]: count of `geometry` are must be 2 in `Point` type"
]
}
}
cat new_from_geojson_b.json
:
{ "jsonrpc": "2.0"
, "id": null
, "method": "GeoObject.NewFromGeoJSON"
, "params":
{ "GeoJSON":
{"type":"FeatureCollection","features":[
{"type":"Feature","geometry":{"type":"Point","coordinates":[140.73248811749,43.039277047092]},"properties":{"name":"銀山小学校グランド","address":"北海道仁木町銀山2丁目446番地","disaster1":1,"disaster4":1,"disaster6":1}},
{"type":"Feature","geometry":{"type":"Point","coordinates":[140.72563244118,43.042264096845]},"properties":{"name":"銀山中学校グランド","address":"北海道仁木町銀山2丁目113番地","disaster1":1,"disaster2":1,"disaster4":1,"disaster6":1}},
{"type":"Feature","geometry":{"type":"Point","coordinates":[140.76213107485,43.03786777423]},"properties":{"name":"長沢会館前","address":"北海道仁木町長沢南464番地2","disaster1":1,"disaster2":1,"disaster4":1,"disaster6":1}},
{"type":"Feature","geometry":{"type":"Point","coordinates":[140.78652844805,43.037552143532]},"properties":{"name":"尾根内会館前","address":"北海道仁木町尾根内221番地4","disaster1":1,"disaster2":1,"disaster4":1,"disaster6":1}},
{"type":"Feature","geometry":{"type":"Point","coordinates":[140.83610217177,43.049954911592]},"properties":{"name":"赤井川村立都小学校校舎","address":"北海道余市郡赤井川村字都113","disaster2":1,"disaster4":1,"disaster6":1,"disaster7":1}},
{"type":"Feature","geometry":{"type":"Point","coordinates":[140.83558718765,43.049954911592]},"properties":{"name":"赤井川村立都小学校体育館","address":"北海道余市郡赤井川村字都113","disaster2":1,"disaster4":1,"disaster6":1,"disaster7":1}},
{"type":"Feature","geometry":{"type":"Point","coordinates":[140.83681027496,43.050299879043]},"properties":{"name":"赤井川村立都小学校グラウンド","address":"北海道余市郡赤井川村字都113","disaster2":1,"disaster4":1,"disaster6":1,"disaster7":1}},
{"type":"Feature","geometry":{"type":"Point","coordinates":[140.83290467531,43.051110200296]},"properties":{"name":"赤井川村都住民センター","address":"北海道余市郡赤井川村字都127-15","disaster2":1,"disaster4":1,"disaster6":1,"disaster7":1}},
{"type":"Feature","geometry":{"type":"Point","coordinates":[140.84440948051,43.051395167595]},"properties":{"name":"村の駅あかいがわ","address":"北海道余市郡赤井川村字都190-16","disaster1":1,"disaster2":1,"disaster4":1,"disaster6":1,"disaster7":1}}
]}
}
}
curl -Ss -i http://127.0.0.1:50080/api/json-rpc-2.0/ -X POST -d @new_from_geojson_b.json
:
HTTP/1.1 200 OK
Content-Length: 115
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": null,
"result":
{
"ids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
"errors": []
}
}
実際に GSI が提供している GeoJSON タイル ( サンプルとして「指定緊急避難場所(地震)」より https://cyberjapandata.gsi.go.jp/xyz/skhb04/10/912/376.geojson を使用 ) の .geojson データも意図通り G4 地物システムへ API で読み込める事を確認できた。
以上までは実装試験の目的のため LOD=10 に固定していた。 wiki やリリースノート用に LOD=14 の綺麗なスクリーンショットを撮影した:
spec.: https://tools.ietf.org/html/rfc7946