私は魅力的なGISの世界に慣れていないため、この数日間、トピック全体を調査してきました。私の目標は、自分のサーバーでOSMデータを使用して地球規模のマップを提供することです。
私のスタックは:
- Postgres + Postgis -GISデータの保存、変換、処理用。
- Mapnik-タイルをレンダリングするためのライブラリ
- Tilestache-タイルの提供とキャッシュ
- Nginx -Tilestacheへのリバースプロキシ
- リーフレット(Slippyマップクライアント)
OSMデータをインポートしてスタイルを設定するために、私は
- PBFファイル(抽出/プラネット)
- osm2pgsql
- CartoCSS
- openstreetmap-carto
- Kosmtik-開発/デバッグ用のマップGUI
完全な惑星ファイルは大きいので、私は現在、サンパウロの抽出を使用しています。これは、テストするのに十分な大きさです。
私が抱えている問題に到達する前に、これまでに行った手順を説明します。
うまくいったこと
PostgreSQLとPostGISが正しくインストールされている。前者には9.6、後者には2.3を使用しています。postgis_topology
とのhstore
拡張機能も追加しました。これらは後で使用します。
osm2pgsql 0.92.0がインストールされています。サンパウロ抽出物をインポートするために、私は使用します
osm2pgsql -G U <user> -d <db> -C 1000 -W --hstore --style openstreetmap-carto.style --tag-transform-script openstreetmap-carto.lua <pbf>
hstore
、style
およびtag-transform-script
として引数は、OSMのスタイルの適切な利用のために必要とされるここで説明します。
openstreetmap-cartoのインストールで説明したように、カスタムインデックスを追加し、必要なシェープファイルとフォントをダウンロードしました(絵文字を除く)。
QGISを使用して、抽出データがデータベースに正しくロードされていることを確認しました。すべてのポイント、ポリゴン、ライン、道路を表示してクエリを実行できました。それだけです。
問題
次のステップはタイルのレンダリングです。そこで問題が発生します。mapnikとpython-mapnik 3.x、carto 0.18.2があります。
OSMのproject.mmlから、を使用して独自のproject.xmlを生成しましたcarto
。結果に次の変更を加えました。
- Postgresのユーザ名(パラメータの追加
user
にMAPNIKのXMLを)。残りの接続情報は〜/ .pgpassから取得されます。 - 相対ディレクトリ
data/<shape>.shp
を/full/path/data/<shape>.shp
- 相対ディレクトリ
symbols/<symbol>.svg
を/full/path/symbols/<symbol>.svg
私はこれらの変更をユニットテストでソートしました。シェープファイルとシンボルの不正なディレクトリは、Mapnikがスタイルをロードしようとするとエラーを発生させます。不適切なDB情報についても同様です。
そしてここに問題があります:Mapnikによってレンダリングされたすべてのタイルは「空白」(青っぽい背景、OSMに定義された背景)です。これが私がこの問題を修正しようとしたものです:
私が試したもの
生成されたスタイルが何らかの理由で無効である可能性があります。たぶん、いくつかのポリゴン/形状(海のもの?)が別のものを覆っています。
Kosmtikをインストールしましたが、うまくいきました!抽出の閲覧、データの検査、すべてのレベルのズームインとズームアウトができました。
多分私は間違った場所にタイルを生成しています
MapnikをプロバイダーとしてTileStacheをセットアップしました。次に、ここで説明するように、switcheroo http://[abc].tile.openstreetmap.org
をhttp://myserver/<layer>
使用するからへのリダイレクトルールを設定しました。これは、アクセスopenstreetmaps.org
するとすべてのタイルがサーバーにレンダリングされることを意味します。
興味深いことに、ズーム1は機能します(4タイルのズーム)。スタイルでダウンロードされたplanet / worldシェイプファイルのみを使用していると思います。他のすべては、ズームや場所に関係なく、「空白」にレンダリングされます。したがって、抽出の場所を参照しても、正しくレンダリングされません。
なお、Kosmtikを使用すると、ズーム4から抽出の名前を確認できました。
多分私は間違った場所にタイルを生成しています
予測が難しい。多分どこかに「誤訳」されているものがあります。
そこで、Kosmtikが行った要求を分析しました(これらが機能していたため)。これは、<zoom>/<x>/<y>
Leaflet、TileStache、およびで使用されているのと同じ形式のSlippy形式()に変換されるModestmapsライブラリを使用しopenstreetmap.org
ます。
たとえば、17/48561/74357.png
Kosmtik でのリクエストは機能しますが、同じタイルがTileStacheで「空白」として返されます。私の理論は、どういうわけかTileStacheがそれを抽出領域の外の別の座標に変換していたというものでした。(TileStacheが投影として「球形メルカトル」を使用していたとしても)。
そこで、Mapnikのpythonバインディングを直接使用することにしました。これまで、3種類の投影法を扱ってきましたが、これらについて私が知っていることは次のとおりです。私が間違っている場合は修正してください:
- EPSG4326 / WGS84-GPSで使用されるのと同じ、通常の経度/緯度投影。単位は度です。
- EPSG3857 / {Web、Google、Pseudo} mercator / 900913-ほとんどのタイルWebマップで使用されます。単位はメートルです(極の近くで大きく歪むため、「実際の」メートルではありません)。
- 「スリッピー形式」-投影ではなく、翻訳するための別の形式。
したがって、Slippy 17/48561/74357
は-46.632(lon), -23.531(lat)
EPSG4326に近く-5191050.49, -2696361.67
、EPSG3875 / Googleメルカトルに近くなります。
Pythonを使用して、これらの座標のタイルをMapnikで直接生成しました。結果は常に空白のタイルでした。私は正しい予測を使用していると思います(これについては後で詳しく説明します)。
まず、1つ注意する点があります。問題はMapnikにもスタイルにもないことは明らかです。まず、KosmtikはMapnikをバックエンドとして使用しており、正常に動作します。次に、意図的にKostmikの抽出領域の外にタイルを生成すると、空白のタイルが表示されます。
これは、私がMapnikのpythonスクリプトとTileStacheで間違ったプロジェクションを使用していると信じるようにさせます。コードを表示する前に、OSMについて1つ説明します(ここでも、間違っている場合は修正してください)。
- OSM「ネイティブ」データはEPSG4326に保存されます
- osm2pgsqlはOSMデータをEPSG3857としてインポートします。これがPostgisでの予測です。
- Mapnikのスタイル(XML)には、入力と出力の2つの予測があります。ここで説明します。
- 入力投影はMapオブジェクトで定義され、「マップがレンダリングされる座標系」です
- 出力プロジェクションはLayerオブジェクトで定義され、データと同じである必要があります。
私の結果としてのMapnikのXMLは次のとおりです。
<Map srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over" background-color="#b5d0d0">
#snip#
<Layer name="world" #snip# srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over">
だから、私がそれを見ると、入力と出力の両方のプロジェクションは「merc」(3857)にあり、それは正しいです!私のデータは3857で保管されており、結果のマップは3857であると予想されます。
最後に、私が試したさまざまなMapnik呼び出しを以下に示します。
3857座標のBox2d:
map = mapnik.Map(800, 800)
bbox = Box2d(-5191050.49, -2696361.67, -5191059.49, -2696370.70)
mapnik.load_map(map, '/path/to/style.xml')
map.zoom_to_box(bbox)
mapnik.render_to_file(map, 'output.png') # Blank
4326座標が3857に変換されたBox2d
merc = mapnik.Projection('+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over')
longlat = mapnik.Projection('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
bbox = mapnik.Box2d(-23.53, -46.63, -24.03, -47.03)
transform = mapnik.ProjTransform(longlat, merc)
merc_bbox = transform.forward(bbox)
# load, zoom, render -> Blank
私もさまざまなスタイルで試しました。結果は常に空白ですが、これらの座標は抽出内にあると考えられるため、これは予想外です。抽出の外で座標をレンダリングしようとすると、正しく空白としてレンダリングされます。
とにかく、私は失われていると私は、誰もがいくつかの光を当てることができれば、私は思っていたしなければならない何かが欠けていること。しかし、これまでのところ、私はこの問題に24時間以上取り組んできましたが、何が問題なのかわかりません。