OpenStreetMap Part Medium:隠されたデータの可視化

私たちは皆、定住地、道路とその名前、その番号のある家を見るために、インターネット上の古典的なベース基板を見て慣れています。 ただし、これらのプロパティオブジェクトでさえ、名前や番号以上のものを持っています。 建物の場合、これは多くの階、道路の場合は多くの車線、都市の場合は多くの住民です。 しかし、これは氷山の一角にすぎません。OpenStreetMapにはさまざまな空間データが豊富に含まれているため、その一部は見たことがないでしょう。 そして、特殊なレンダリングなしでは、データを編集するときに、これが奇妙なタグのある行に興味がない限り、決して表示されません。 今日は、森林の近隣を表示するための、このような超特殊なレンダリングを作成します。







森林周辺







ステップ1.調査。

もちろん、空を指でどのように表示されるかを推測できますが、wiki-osmに行く方が安全です。 そして、以下を見つけることができます: boundary = forest_compartment







したがって、森林の近隣は、タグboundary=forest_compartment



ポリゴンで示されます。 確かに、最初はboundary=forestry_compartment



として指定されていたが、読み書きが少ないという明確な説明があります。 また、古い指定での使用数は重要であるため(taginfoによると約4000回)、割引はしません。







ステップ2.データ。

Geofabrikからデータを取得します。 ロシア全体のファイルrussia-latest.osm.pbf



ダウンロードします。 osmconvert



を使用して、後続のフィルタリングのためにo5m形式でデータを取得します。







 osmconvert russia-latest.osm.pbf -o=russia-latest.o5m
      
      





ここで、 osmfilter



を使用して必要なデータのみをフィルタリングしosmfilter









 osmfilter russia-latest.o5m --keep="boundary=forest_compartment =forestry_compartment" -o=forest_compartment-local.o5m
      
      





手順3.ベクトルタイル。

少し簡単な理論。 古いアプローチは、大規模なデータベースからいくつかのデータを要求し、それらから画像を取得し、将来クライアントに提供するために保存することです。 新しいデータベースでは、大規模なデータベースから少量のデータを要求し、その後クライアントに送信するために保存します。 そして、クライアントにそれらを絵に変えてもらいましょう。 顔の利益-そのままでは、クライアントの肩に画像をレンダリングする負担を移しました。 マイナスの点-コーヒーメーカーでは、マップを表示できない場合があります。WebGLサポートが必要です。







そのため、Mapboxは、ベクタータイルのフォーマットと、それらのコンテナーをsqliteデータベースの形式で提案しました。 したがって、現在はフォルダ内のファイルが散らばっているものではなく、きちんとした孤独なファイルです。 ベクタータイルには、ジオメトリと属性で構成される論理レイヤー(家、道路など)が含まれます。







ここで、私たちは彼らを私たちの森の近所に準備します。 TileMakerツールを使用します。 入力としてpbf形式のOSMデータを受け取るため、フィルタリング後にこの形式に変換する必要があります。







 osmconvert forest_compartment-local.o5m -o=forest_compartment-local.pbf
      
      





次に、 ドキュメントに従って、どのレイヤーとどの属性が必要かをTileMakerに説明する必要があります







ステップ4.レイヤー?

そして、どのレイヤーが必要ですか? そして、それは私たちが何を見せるかに依存します。 つまり まず第一に、視覚的な部分をどうにか想像しなければなりません。 そして、利用可能なデータからそれをどのように達成できますか。 OSMデータから、ポリゴンとその属性のグリッドが得られます。 属性には、森林の名前と四半期番号があります。







未加工のOSMデータ







これから、最も簡単な方法は四半期を表示し、番号で署名することです。 つまり ポリゴンレイヤーが必要です。ポリゴンの中心には、番号付きの碑文が表示されます。

そして、ベクタータイルの最初の機能が表示されます。 大きなソースポリゴンが異なるタイルに分類される場合、その一部のみがタイルに分類されます。 レンダリングすると、それぞれ2つの異なるポリゴンになります。それらのポリゴンの半分の中心には2つの署名があります。













したがって、ベクタータイルの場合、ジオメトリに関する必要な情報がすべて残っているときに、碑文のある別のレイヤーが準備されます。







結論:塗りつぶし用のポリゴンと署名用のドットの2つのレイヤーが必要です。 config.json



ファイルを作成します。







 { "layers": { }, "settings": { "minzoom": 11, "maxzoom": 11, "basezoom": 14, "include_ids": false, "author": "freeExec", "name": "Forest Compartment RUS", "license": "ODbL 1.0", "version": "0.1", "description": "Forest compartment from OpenStreetMap", "compress": "gzip", "metadata": { "attribution": "<a href=\"http://www.openstreetmap.org/copyright/\" target=\"_blank\">&copy;  OpenStreetMap</a>", "json": { "vector_layers": [ ] } } } }
      
      





レイヤーセクションで、必要なものを指定します







  "layers": { "forest_compartment": { "minzoom": 11, "maxzoom": 11 }, "forest_compartment_label": { "minzoom": 11, "maxzoom": 11 } },
      
      





レイヤーの名前が表示され、どの縮尺で表示されます。







  "json": { "vector_layers": [ { "id": "forest_compartment", "description": "Compartment", "fields": {}}, { "id": "forest_compartment_label", "description": "Compartment", "fields": {"ref":"String"}} ] }
      
      





メタデータでは、将来のビジュアライザーにどの属性が利用できるかを伝えます。 タグレイヤーについては、 ref



四半期番号があります。







ステップ5.データ処理。

この目的のために、 lua



言語のスクリプトが使用されます。これは、必要なOSMデータのオブジェクト、送信するレイヤー、および属性を決定します。







process.lua



ファイルテンプレートから始めましょう。







 -- Nodes will only be processed if one of these keys is present node_keys = { } -- Initialize Lua logic function init_function() end -- Finalize Lua logic() function exit_function() end -- Assign nodes to a layer, and set attributes, based on OSM tags function node_function(node) end -- Similarly for ways function way_function(way) end
      
      





ここにあるもの:







node_keys-OSMデータには多くのポイントがあります。それぞれこのスクリプトを突くと、処理に非常に長い時間がかかります。 これは、どのキーが私たちにとって重要かを伝えるフィルターです。







function node_function(node)-関数は、前の段落から興味のあるすべてのポイントで呼び出されます。 ここで、それをどうするかを決めなければなりません。







function way_function(way)-任意の行で、マルチポリゴンおよび境界タイプとの関係で呼び出される関数。 それらは面オブジェクトと見なされます。







コードを書き始めます。 まず、必要なポイントを示します。







 node_keys = { "boundary" }
      
      





次に、それらを処理する関数を作成します。







 function node_function(node) local boundary = node:Find("boundary") if boundary == "forestry_compartment" or boundary == "forest_compartment" then local ref = node:Find("ref") if ref ~= "" then node:Layer("forest_compartment_label", false) node:Attribute("ref", ref) end end end
      
      





ここで何が起こるか: node:Find("")



を介してboundary



キーの値を読み取りnode:Find("")



。 これがforest_compartment



場合、 ref



タグから四半期番号を読み取ります。 空でない場合、このオブジェクトはLayer("_", ___)



介してラベル付きでレイヤーに追加されます。 レイヤー属性ref



、四半期番号を保存します。

正方形ブロックの場合とほぼ同様:







 function way_function(way) local boundary = way:Find("boundary") if way:IsClosed() and ( boundary == "forestry_compartment" or boundary == "forest_compartment" ) then way:Layer("forest_compartment", true) way:AttributeNumeric("nomerge", way:Id()) local ref = way:Find("ref") if ref ~= "" then way:LayerAsCentroid("forest_compartment_label", false) way:Attribute("ref", ref) end end end
      
      





ここで、ラインが閉じていることをさらに確認します。 タグが単にセグメント上に存在することが起こります。 forest_compartment



レイヤーforest_compartment



area(したがって、 Layer("", true))



関数の2番目の引数Layer("", true))



であり、 LayerAsCentroid



中心として署名の場所を取ることにLayerAsCentroid



するLayerAsCentroid









config- nomerge



で指定していませんが、追加する属性にも注意を払う価値があります。 別の機能を無効にする必要がありますが、今回は既にTileMakerコンバーターです(無効にするためのパラメーターは新しいバージョンに含まれています)。







特殊性は、最適化のために、1つのレイヤーに同じ属性を持つ多くのオブジェクトがある場合、それらのコンバーターがジオメトリを1つに結合することです。 たとえば、3つの別々のセグメントで構成される道路があり、最終的にレンダリングのために3回送信されます。 これは、1つのオブジェクトをレンダーに送信するという考えに比べて長いですが、少し複雑な(それらすべてを結合する)ジオメトリを使用します。







この場合、隣接するすべての区画は1つの大きなポリゴンに統合されますが、これは必要ありません。 したがって、オブジェクト番号を追加して、それらが異なるようにし、結合しないようにします。







次に、ベクタータイルの作成プロセスを開始します。







 tilemaker forest_compartment-local.pbf --output forest_compartment-local.mbtiles
      
      





結果として、ファイルforest_compartment-local.mbtiles









ステップ6.スタイルを作成します。

mapbox.comでアカウントを作成します。 Mapbox Studioの[タイルセット]セクションで、以前に作成したファイルをダウンロードウィンドウにドラッグして、新しいタイルを作成します。 1分以内に処理され、リストに追加されます。







次に、[スタイル]セクションに移動し、完成したライトに基づいて新しいものを作成します。これにより、道路、集落などのマップの主要な要素を確認できます。 森林ブロックが見られたので、チェボクサルイに向かいます。







スケールのレベル11に移動し(彼のためにタイルのみを作成しました)、[レイヤーの追加]ボタンをクリックします。 [データソース]タブで、 forest_compartment-local-XXXXX



データソースを見つけ、その中でポリゴンレイヤーを選択します。 右側の緑色で強調表示されます。







レイヤー追加







次に、[スタイル]タブで、塗りつぶしの色を緑に、ストロークを茶色に設定します。







色調整







ここで、署名を追加します。 新しいレイヤーを追加します。 forest_compartment_label



はデータでforest_compartment_label



を選択し、タイプsymbol



を選択すると、数字が右側に表示されます。







ラベルレイヤーを追加します。







[スタイル]タブで、 ref



属性を表示する必要があることを指定します。







署名の属性







それだけです、それだけです。公開画面の右側をクリックすると、他の人が私たちの作品を見ることができるようにリンクを共有できます。 ただし、カードの表示は他の場所のように無料ではないため、habr効果に陥らないようにリンクは提供しません。







PS:おそらく追加の記事で、含まれているブロックのグループの森林の名前で署名の場所をどのように達成したかを説明します。








All Articles