GISCloudのようなレンダリングパフォーマンスでベクターポリゴンを作成しますか?


59

私は、ホバーイベントで各ポリゴンを異なる色で表示できるようにすることを目的に、そのようなデータを永遠にロードすることなく、Webマップ作成し、ベクトルポリゴンをオーバーレイできる堅牢なソリューションを探していました。

私の知る限り、キャンバス、SVG、Flashのいずれかでこれを達成するための3つの特定のオプションがあります。

Flashは、最速のレンダリングと最もクリーンな表示を提供するように思えるので、Apple iphone / ipadsで動作する場合、最良のソリューションになるようです。Canvasは2番目に最適な選択肢のように見えますが、マップ上に何百ものポリゴンが表示されている場合は非常に時間がかかりますが、SVGのレンダリングにはさらに時間がかかります。

私はほとんどこの問題の解決策を見つけることに希望を失ったが、今日、私はGISCloudという会社に出会いましたhttp://www.giscloud.com(現在は無料登録してベータ版)。

この会社は、SOMEHOWが地図上に数百のベクターをほぼリアルタイムでレンダリングする驚くべき方法を見つけ出しました。私は彼らのアプローチに驚き、コミュニティへの私の質問は、リーフレット、オープンレイヤー、ワックスなどの既存のテクノロジーで使用するために彼らのアプローチをどのように複製できるかに関するものです...

この素晴らしいデモを見て、自分自身を見てみましょう:http : //www.giscloud.com/map/284/africa

ページ上の任意のポリゴンにカーソルを合わせ、ズームコントロールをテストして、これらのポリゴンが実際にベクトルであることを確認してください。

firebugでリクエストを見ると、マップが特定のjsonファイルをリクエストしていることに気付きました。ズームレベル/エリアによっては、複数のjsonファイルが要求されているようです。


また、giscloudがページ上のデータを読み込むと、ベクター上にホバーすると、新しいリクエストを作成せずにすぐに色が変更されることをここで言及する必要があります。

例:

url構造は標準のタイルサービスロジック(たとえば、ズームレベルである3番目から最後のフォルダー)に従うと仮定しています。

いずれにせよ、これらのjsonファイルの実際のデータを分析しましたが、使用しているロジックは、これらのデータ値に基づいてベクターを作成する何らかのタイプのロジックに従っているようです。

  • 幅/高さ:各JSON要求で提供されるデータの幅と高さを定義します
  • ピクセル:ここでは、一般化されたポイントレベルの一般的なx / yピクセル座標に何らかの関係があると想定しているピクセル値を定義しますか?私は彼らが何らかの方法でズームレベルに応じて自動的に領域を単純化する方法を持っていると推測しています。私は、ピクセル座標を使用して、緯度/経度データと比較してロードする必要のあるデータのサイズを劇的に削減していると推測しています。
  • スタイル:ここでは、2つのRGB css値を定義します。「F」はポリゴンファイルの色を表し、「S」はポリゴンの境界線の色を表します。
  • geom:ここでは、マップコンテナウィンドウに基づいてデータが定義されている場所で、読み込まれているタイル内の各ポリゴンを明確に定義していると推測しています。また興味深いのは、各エントリがオプションの属性または機能リンク値として使用されると想定している「S」値を持ち、各エントリの最後に特定のベクトルごとのIDを定義するように見える領域があることです私が推測しているレイヤーIDは、呼び出されている各jsonタイルリクエストからのデータを何らかの形で結合するために利用されます。

また、要求されたタイルにロードする必要があるデータのサイズに応じて、各タイルにロードする必要があるデータを自動的に決定および分割する方法を何らかの方法で見つけたと想定しています。

以下は、これらのリクエストの内の1つを抽出した内訳です。

{"width":256,"height":256,"tile":
{"pixels":
[0,6461,-1,0,5,148,0,509,-1,10715,-1,1,-1,251,-1,1,-1,1,-1,251,-2,3,-1,255,-1,249,-2,5,-2,247,-1,509,-3,251,-1,2,-2,253,-2,252,-2,254,-1,255,-1,254,-1,255,-1,1276,-2,13,-1,233,-1,2,-1,253,-1,1,-1,255,-1,247,-1,1306,-1,1533,-1,1269,-1,1276,-1,2303,-1]},

"styles":
[{"f":"rgb(99,230,101)","s":"rgb(5,148,0)","lw":"0"}],

"geom":
[
{"s":0,"p":[4,143,5,144,3,146,1,146,2,143,4,143],"c":"layer1156_5098"},
{"s":0,"p":[-2,143,0,140,2,141,2,144,1,146,-2,144,-2,143],"c":"layer1156_5067"},
{"s":0,"p":[7,143,5,144,4,143,2,143,2,141,5,138,6,139,5,141,7,143],"c":"layer1156_5051"},
{"s":0,"p":[10,141,11,137,12,137,14,137,12,142,9,143,9,142,10,141],"c":"layer1156_5041"},
{"s":0,"p":[1,136,0,140,-2,143,-2,136,1,136],"c":"layer1156_5038"},
{"s":0,"p":[8,143,5,141,5,137,8,136,10,137,10,141,8,143],"c":"layer1156_5033"},
{"s":0,"p":[5,137,2,141,0,140,1,136,1,136,2,135,3,136,5,137],"c":"layer1156_5028"},
{"s":0,"p":[10,134,12,136,11,138,8,135,10,134],"c":"layer1156_5020"},
{"s":0,"p":[-2,133,0,136,-2,136,-2,133],"c":"layer1156_5005"},
{...}
...
]
}

postgisを使用して同じ(または同様の)速度をどのように複製できますか(私も同じように使用しているようです)。


あ!JSONファイルを見るのではなく、他の見かけ上重要でない画像を見てください:)以下の私の答えをご覧ください。
ラギヤセルバーフム

...だからSilverlightは何である、「3つの固有のオプションがあります」みじん切り肝臓は
カーククイケンダル

Silverlightが機能するにはプラグインが必要であり、実際にはgiscloudが使用するソリューションよりも高速だとは思わないが、直接比較は行っていない。
NetConstructor.com

2
この質問は、通常のQ&A形式に適合しない、多くの興味深い話題をもたらします。Webマップの世界でベクター
マットウィルキー

@RagiYaserBurhumこれは、同様の技術を使用しての走行等時マッピングに使用されたかの素敵な説明があります:mysociety.org/2012/11/08/...は
djq

回答:


56

過去にこの手法が使用されているのを見てきました。これは、Michal MigurskiがTileStacheを作成していたときに入力を提供してくれたZain Memon(Truliaから)によって説明されました。Zainは、以前のSF GeoMeetup会議の 1つで、この手法を使用するTruliaデモを説明ている間に、先に進みました。実際、あなたが来週SFにいる場合(これはプラグの私の不完全な試みです、彼はこれ触れますので、気軽に現れてください:)

では、説明に移りましょう。

最初に、上記のjsonファイルを見るときに、間違った場所を少し見ています。

理由を(できるだけ短く)説明させてください。

タイルは通常のレンダリングされたタイルと同じように渡されますが、大したことはありません。その方法はわかっているので、説明する必要はありません。

Firebugで調べてみると、このように空白のように見える画像も大量にあることがわかります。

なぜ空白ですか?そうではない。ピクセルにはデータが含まれています-従来の可視画像データではありません。彼らは非常に巧妙な手法を使用して、ピクセル自体にエンコードされたデータを渡します。

過去10年間に起こったことは、ストレージの効率を犠牲にして、人々がフォーマットの可読性と移植性のデータをトレードオフしているということです。

このxmlサンプルデータの例をご覧ください。

<data>

  <feature>
    <point>
      <x> -32.1231 </x>
      <y> 10.31243 </y>
    </point>
    <type> 
      sold
    </type>
   </feature>

  <feature>
    <point>
      <x> -33.1231 </x>
      <y> 11.31243 </y>
    </point>
    <type> 
      available
    </type>
   </feature>

</data>

OK、これを何回噛むのですか?utf8(このコンテンツを処理するときは文字ごとに1バイト)であると仮定します。まあ、約176文字(タブやスペースをカウントしない)があり、これが176バイトになります(これは、簡単にするために省略しますが、さまざまな理由で楽観的です)。気をつけて、これは2ポイントです!

それでも、どこかで彼が何を話しているのか理解していないスマートなロバは、「jsonがより高い圧縮を提供する」と主張するでしょう。

それでは、jsonと同じXMLナンセンスを付けましょう。

{ "data": [
            "feature" : { "x" : -32.1231, "y" : 10.31243 , "type": "sold" },
            "feature" : { "x" : -33.1231, "y" :11.31243, "type": "avail" },
          ]
}

ここに何バイト?〜115文字と言います。私も少しだまして、小さくしました。

領域が256x256ピクセルをカバーし、ズームレベルが非常に高いため、各機能が1ピクセルとしてレンダリングされ、非常に多くの機能があり、いっぱいになっているとします。65,536個の機能を表示するにはどのくらいのデータが必要ですか?

「機能」エントリx 65,536 = 3,538,944または約3.3MBを掛けたものごとに54文字(またはutfバイト-および他のことも無視しています)

あなたは写真を撮ると思います。

しかし、これがサービス指向アーキテクチャでデータを転送する方法です。読みやすい肥大化したがらくた。

自分で発明したバイナリスキームですべてを転送する場合はどうなりますか?代わりに、その情報をシングルバンドイメージ(つまり、白黒)にエンコードしました。そして、0は販売済み、1は販売可能、2はわからないことを意味します。ヘック、1バイトで、使用できる256個のオプションがあります-この例では、そのうちの2つまたは3つしか使用していません。

そのストレージコストはいくらですか?256x256x 1(1バンドのみ)。65,536バイトまたは0.06MB。そして、これは、数十年にわたる画像圧縮の研究から無料で得られる他の圧縮技術も考慮していません。

この時点で、なぜjsonにシリアル化するのではなく、バイナリ形式でエンコードされたデータを単に送信しないのかを自問するべきです。まず最初に、javascriptはバイナリデータの転送多大な時間を費やします。そのため、人々は歴史的にこれを行っていないのです。

HTML5の新機能、特にcanvasが登場したときに、すばらしい回避策が一部の人々によって使用されています。この素晴らしい回避策は何ですか?結局のところ、画像のように見えるものにエンコードされたワイヤを介してデータを送信し、その画像をHTML5キャンバスに押し込めば、ピクセルを直接操作できます!これで、そのデータを取得し、クライアント側でデコードし、クライアントでjsonオブジェクトを生成することができます。

ちょっと待って、これについて考えてください。

膨大な量の意味のある地理参照データを高度に圧縮された形式でエンコードし、Webアプリケーションで従来行われていたものよりも桁違いに小さく、JavaScriptで操作する方法があります。

HTMLキャンバスは描画に使用する必要さえありません。バイナリデコードメカニズムとしてのみ使用されます。

これが、Firebugに表示されるすべての画像の目的です。ダウンロードされる各タイルごとにデータがエンコードされた1つの画像。それらは非常に小さいですが、意味のあるデータがあります。

サーバー側でこれらをどのようにエンコードしますか?サーバー側でデータを一般化し、データがエンコードされているズームレベルごとに意味のあるタイルを作成する必要があります。現在、これを行うには、独自のロールを作成する必要があります-すぐに使えるオープンソースソリューションは存在しませんが、これを行うために必要なすべてのツールが用意されています。PostGISはGEOSを通じて一般化を行います。TileCacheを使用してキャッシュし、タイルの生成をトリガーできます。クライアント側では、HTML5 Canvasを使用して特別な「偽のタイル」を渡す必要があります。その後、OpenLayersを使用して、マウスオーバー効果でベクターを表す実際のクライアント側javascriptオブジェクトを作成できます。

より多くのデータをエンコードする必要がある場合は、ピクセルごとにいつでもRGBAイメージを生成できることに注意してください(ピクセルごとに4バイトまたはピクセルごとに表現できる4,294,967,296の数値が得られます)。私はそれを使用するいくつかの方法を考えることができます:)

更新:以下のQGIS質問に答えます。

他のほとんどのデスクトップGISのようなQGISには、ズームレベルの固定セットがありません。任意の縮尺でズームし、レンダリングするだけの柔軟性があります。WMSまたはタイルベースのソースからのデータを表示できますか?確かにできますが、ほとんどの場合、それについて本当に馬鹿げています:別の範囲にズームし、バウンディングボックスを計算し、必要なタイルを計算し、それらを取得し、表示します。ほとんどの場合、彼らは他のことを無視します。たとえば、HTTPヘッダーキャッシュを使用すると、再取得する必要がなくなります。時には、単純なキャッシュメカニズムを実装します(タイルを保存します。タイルを要求する場合は、タイルを確認し、要求しないでください)。しかし、これでは十分ではありません。

この手法では、ズームレベルごとにタイルとベクターを再取得する必要があります。どうして?なぜなら、ベクトルはズームレベルに合わせて一般化されているからです。

バッファーにアクセスできるようにタイルをHTML5キャンバスに配置するという全体的なトリックに関しては、そのすべては必要ありません。QGISを使用すると、PythonとC ++でコードを記述できます。どちらの言語もバイナリバッファーの処理に優れたサポートを提供しているため、この回避策はこのプラットフォームにはまったく関係ありません。

*更新2 **:

そもそも一般化されたベクタータイルを作成する方法について質問がありました(結果を画像にシリアル化できるようになる前のステップ1の赤ちゃん)。おそらく私は十分に明確にしなかった。Tilestacheを使用すると、ズームレベルごとにデータの効果的な「ベクタータイル」を作成できます(タイルの境界を通過するときにデータをクリップするかどうかを選択できるオプションもあります)。これにより、さまざまなズームレベルでベクターがタイルに分割されます。「クリップしない」オプションを選択します(ただし、より多くの領域をカバーする任意のタイルを選択します)。次に、GEOSの一般化オプションを使用してすべてのベクトルを大きな数でフィードできます。実際、ポリラインとポリゴンがそれ自体に折りたたむのに十分な大きさにする必要があります。無関係です。Tilestacheでは、このロジックを配置できる簡単なpythonicデータプロバイダーを作成することもできます。その段階で、それらをjsonファイル(一部のアフリカのマップサンプルで行うように)として提供するか、上記の別のサンプル(またはTruliaのもの)で行うように、PNGにシリアル化されたジオメトリとして提供するかを選択できます。


2
これまでのところ、この手法を使用して見たすべての人がコードを投稿したわけではありません。私見、重要な部分は実際にサーバー上で行われており、これには「標準」がないため、各ピクセルの意味(1 =販売、2 =使用可能など)を選択するのは現在のマップに固有であるため、このコードはほとんどの場合「ジェネリック」ではありません。
ラギヤセルバーフム

1
QGISに関する限り、答えはもう少し複雑です。仕事の進め方について答えを更新します。驚かないでください、私は電車に乗るので、GIS.SEに返信する間は運転しません:)
ラギヤセルバーフム

12
+1この非常に読みやすい応答を圧縮しないでいただきありがとうございます:)
カークカイケンドール

1
あなたは確かにSilverlightまたはFlashでこれを行うことができます。それにもかかわらず、FlashやSilverlightがのではないでしょうので、重要な部分は、サーバー上で起こっていることを覚えている助けの多く。
ラギヤセルバーフム

2
4年後、進化した多くの事柄があり、このテキストボックスには、説明するために〜500文字しかありません。要約すると、WebGLは成熟しており、シリアル化技術を超えて、人々はTopojsonのような形式で(60年代に使用していたような)固定精度のデルタエンコーディングを適用しています。これは良いことです。OGCの標準でこれらのことをいくつか見たいと思っていますが、OGCをめぐる政治は最近非常に複雑になっています。2年前の私の気持ちは次のとおり
Ragi Yaser Burhum

23

開発者のDino Ravnicから最近のメーリングリストの投稿に直接アクセスしてください

私たちがどのようにそれをしたかは大きな秘密ではないので、あなたとそれを共有したいと思います..鍵は2つのことです:

  1. タイルから、見えるように小さいすべてのベクトル、つまりピクセルに計算されたときの面積が1px未満のベクトルをすべて削除します。そのため、そのようなベクトルをドロップし、ピクセルを配置する代わりに、jsonタイルに「ピクセル」プロパティがあります

  2. 実際に表示されるベクトルは一般化され、ピクセル単位の座標でタイルに書き込まれます

クライアント部分では、これらの静的ピクセルと可視ベクトルをキャンバスにレンダリングします。ベクトルに加えて、マウスイベント処理を実装してホバリング、つまり対話性を実現しました。以上です。

バックエンドマップエンジンは、プリキャッシングを使用せず、すべてのタイルがオンザフライで生成されるため、すべての重量物を持ち上げます。すばやく更新できる地図を用意することが非常に重要です。

そのため、クライアント側が簡単な部分のようです。データがキャッシュなしでレンダリングされるのは印象的です。

彼はまたあなたに興味があるかもしれないホスティングサービスに言及します。これを再作成しようとするコストと既製のサービスを使用するコストを比較検討することもできます。


ここで私を混乱させる部分は、リクエストがpostgisに送信されており、lat / long値を持つ標準geojsonを取得するのではなく、lat / long値をxyz座標に変換して吐き出しているように見えることです必要なズームレベルとマップタイルに基づきます。これらの速度を得るために何が使われていると思いますか?
NetConstructor.com

@netconstructorジオメトリはすでにxyzジオメトリに格納されているので、変換する必要はないでしょうか?
geographika

相対xyz座標は、相対緯度/経度よりも短い可能性があり、必要な帯域幅は小さくなります。
マシュースネイプ

正しいが、そのデータをオンザフライで変換しています
-NetConstructor.com

17

OSGeoリストで説明したように、サブピクセルジオメトリのピクセルと、特定のレベルで実際に表示される機能の一般化されたジオメトリを持つベクターJSONタイルとしてデータを配信することが重要です。この手法は、すべての不要なベクトル情報を排除し、実際にマップに視覚的な影響を与えるベクトルのみを残すため、パフォーマンスが優れています。ピクセルは、それらのサブピクセルベクトルの代わりにギャップを埋めるために配置されます。それはタイル形式に関するものです。

バックエンド側には真の重荷があります。TileStacheやその他のマップエンジンは使用していません。これは、多くの最適化を行うことで、このようなベクターグラフィックスをリアルタイムで生成できる独自のエンジンを作成したためです。

まず、マップタイルをSWFとして提供することから始め、最近JSONの出力を有効にして、HTML5 Canvasを使用してグラフィックをレンダリングできるようにしました。この種のベクターテクノロジーとラスターテクノロジー(mapnik)を比較したベンチマークを以下に示します。公正な比較のために、CGIモードでのみ結果を探します。

http://www.giscloud.com/blog/realtime-map-tile-rendering-benchmark-rasters-vs-vectors/

このテクノロジーをマップタイルホスティングサービスとして提供する予定です。クラウド上で地理データをホストし、HTML5を介して、タイルを事前キャッシュする必要なく、高速で地図クライアントに配信するという考え方です。このベータ版への参加に興味がある場合は、こちらからお気軽にお問い合わせください:http : //www.giscloud.com/contact/


1
ベクトルデータにタイルを使用するというアイデアは非常に興味深い(「空間インデックス」の別の表現のように見える)。複数のタイルにまたがるフィーチャをどのように扱いますか?彼らはカットされていますか?
ジュリアン

3
はい、ベクトルはタイルに対してクリップされます
Dino Ravnic

14

最近、OSGeo Open Layersフォーラムで非常によく似た質問が寄せられたようです。GISCloud開発者は、GeoJSONジオメトリと静的ピクセルの興味深い組み合わせであるアプローチを説明しています。GeoJSONファイルの事前に構築されたキャッシュを使用する代わりに、実際にすべてのベクタータイルをその場で生成します。

Esriは、ArcGIS ServerとFeature Layersを使用して同様のアプローチを実装しました。これにより、ジオメトリをオンザフライで一般化し、JSONとしてワイヤで送信できます。

現在実際に実装できる簡単な方法の場合、TilestachePostGISをサポートしている)を使用してベクタータイルを構築し、Polymapsでそれらを使用できます。PolymapsはSVGを使用しますが、パフォーマンスは非常に良好であり、CSSはマップ要素のスタイルを決定するため、機能のレンダリングは完全にユーザー次第です。 これは、あなたが求めているものと似たようなことを行っているブログ投稿です。


1
@wwnick-回答ありがとうございます。GisCloud.comは、すべてがリアルタイムであることを意味する要素をキャッシュすることなく、このような驚くべき処理能力を可能にする追加の方法を利用しているようです。質問に報奨金を追加し、詳細なソリューションの提供に参加していただけると思います。これまでのご回答ありがとうございます!
NetConstructor.com

6

Canvasを使用してOpenLayersでプレイし、妥当な結果を得ました。

他の回答で述べたように、ベクターを即座に配信および表示するには、各ズームレベルおよび各データセットに対してベクトルを一般化する必要があります。また、Googleポリラインエンコーディングを使用して、サイズを大幅に削減できます。

シンプルな配信メカニズムを使用しました。各ジオメトリは、JavaScript HTTP応答内のJavaScript関数でした。タイルベースのベクター配信ほど高度ではありませんが、シンプルでオープンソースです!

CanvasでGoogle Maps v3を試すことはできませんでしたが、 印象的なNew York Timesのデモを見ました。


このアプローチの問題50万個のポリゴンとIEのパフォーマンスを扱うとき、それは彼らのソリューションとしての速ふてくされ本当に悪いされていないということです
NetConstructor.com

追加された報奨金に注意してください。可能であれば詳細な解決策を提供してください。ちなみに、New York Timesは非常にクールでありながら、giscloud.comが使用しているソリューションとは異なり、フラッシュを利用しています。
NetConstructor.com

リンクがオフラインです
-NetConstructor.com

はい、ごめんなさい-私の「趣味」は、ポリゴンで4年間いじくり回した後、今や終わりました!GISCloudは、数年前に私の国勢調査のデモが公開されて以来、この技術がどの程度進歩したかを示しています。上記のコメントでその参照を削除しました。
-minus34

1
遅刻することはありません!できる限り「箱から出して」となるように物事を更新し、クライアント側のコードをGitHubに投稿しました。新しいコードのセットアップはブログに掲載されています。現在、PostGISから直接ポリゴンを直接読み取り、PostGIS RESTful Webサービスフレームワーク(PRWSF)を介してリーフレットJavascript APIクライアントに間引きを適用します。バックエンドのコーディングはほとんど必要ありません!
-minus34

6

この会社でどのソリューションが使用されているのか正確にはわかりません(直接問い合わせることもできます)が、アイデアはあります。

ベクトルデータのネットワーク転送とレンダリング速度を改善するための重要なソリューションは、ズームレベルに従ってそれらを一般化することです:高ズームレベルでの転送とレンダリングは、はるかに低いズームレベル用に設計された何千ものオブジェクトは、多くの場合非常に時間がかかります最終的な表示は通常読みにくいため、役に立たない-たとえば、この画像を参照)。これを実装するには、postgisサーバーデータベースをマルチスケールにする必要があります。ズームレベルごとに、このズームレベルに適したオブジェクトの表現が1つ必要です。これらの異なる表現は、一般化手法を使用して自動的に計算できます。さらに、サーバーからクライアントに送信されるベクターデータは、空間範囲だけでなくズームレベルにも依存する必要があります。サーバーは、ズームレベルに応じて適切なデータを送信します。これは、この優れた論文で守られているアプローチです:-)


0

Stanford Visualization Groupが開発したソフトウェアのデモとソースコードという興味深い論文があります。これは、各地理的データセットを視覚化して調査するために各タイルにデータキューブを使用しています。これはポイントデータセットにのみ使用できますが、興味深い方法です。

http://vis.stanford.edu/papers/immens

CartoDBプラットフォームとTorqueと呼ばれるライブラリのVizzualityも、大量のデータを描画する方法を何らかの形で実験しています。

http://cartodb.github.io/torque/
https://github.com/CartoDB/torque/tree/new_torque

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.