Mapnik rendert nur "leere" Kacheln


10

Ich bin neu in der faszinierenden GIS-Welt und habe in den letzten Tagen das gesamte Thema untersucht. Mein Ziel ist es, weltweite Karten mit OSM-Daten auf meinen eigenen Servern bereitzustellen.

Mein Stack ist:

Um OSM-Daten zu importieren und zu formatieren, verwende ich

Da die vollständige Planetendatei riesig ist, verwende ich derzeit einen Auszug aus Sao Paulo , der zum Testen gut / klein genug ist.

Bevor ich zu dem Problem komme, das ich habe, werde ich durch die Schritte führen, die ich bisher unternommen habe:

Was hat funktioniert

PostgreSQL und PostGIS sind ordnungsgemäß installiert. Ich benutze 9.6 für die erstere, 2.3 für die letztere. Ich habe auch die postgis_topologyund hstore-Erweiterungen hinzugefügt , die später verwendet werden.

Ich habe osm2pgsql 0.92.0 installiert. Um den Sao Paulo-Extrakt zu importieren, verwende ich

osm2pgsql -G U <user> -d <db> -C 1000 -W --hstore --style openstreetmap-carto.style --tag-transform-script openstreetmap-carto.lua <pbf>

Die hstore, styleund tag-transform-scriptArgumente sind für die ordnungsgemäße Nutzung der OSM Stil erforderlich, wie hier beschrieben .

Wie in der openstreetmap-carto-Installation beschrieben, habe ich auch benutzerdefinierte Indizes hinzugefügt und die erforderlichen Shapefiles und Schriftarten heruntergeladen (mit Ausnahme der Emoji-Indizes).

Ich habe mithilfe von QGIS überprüft, ob die Extraktdaten korrekt in die Datenbank geladen wurden. Ich konnte alle Punkte, Polygone, Linien und Straßen anzeigen und abfragen. Es ist alles da.

Probleme

Der nächste Schritt ist das Rendern der Kacheln, und dort habe ich Probleme. Ich habe Mapnik und Python-Mapnik 3.x sowie Carto 0.18.2.

Aus der project.mml des OSM habe ich meine eigene project.xml mit generiert carto. Ich habe die folgenden Änderungen am Ergebnis vorgenommen:

  1. Fügen Sie den Postgres-Benutzernamen hinzu (Parameter userin Mapniks XML ). Die verbleibenden Verbindungsinformationen werden von ~ / .pgpass abgerufen .
  2. Ersetzen Sie das relative Verzeichnis data/<shape>.shpdurch/full/path/data/<shape>.shp
  3. Ersetzen Sie das relative Verzeichnis symbols/<symbol>.svgdurch/full/path/symbols/<symbol>.svg

Ich habe diese Änderungen in einer Art Unit-Test durchgeführt: Falsche Verzeichnisse für Shapefiles und Symbole führen zu einem Fehler, wenn Mapnik versucht, den Stil zu laden. Gleiches gilt für falsche DB-Informationen.

Und hier ist das Problem: Jede von Mapnik gerenderte Kachel ist "leer" (blauer Hintergrund, der für OSM als Hintergrund definiert ist). Folgendes habe ich versucht, um dieses Problem zu beheben:

Dinge, die ich versucht habe

Möglicherweise ist der generierte Stil irgendwie ungültig. Vielleicht bedeckt ein Polygon / eine Form (die des Ozeans?) Eine andere.

Ich habe Kosmtik installiert und es hat gut funktioniert! Ich konnte den Auszug durchsuchen, Daten überprüfen, auf allen Ebenen vergrößern und verkleinern.

Vielleicht generiere ich Kacheln am falschen Ort

Ich habe TileStache mit Mapnik als Anbieter eingerichtet. Dann habe ich Umleitungsregeln http://[abc].tile.openstreetmap.orgfür die http://myserver/<layer>Verwendung von switcheroo eingerichtet, wie hier beschrieben . Dies bedeutet, dass beim Zugriff openstreetmaps.orgalle Kacheln auf meinem Server gerendert werden.

Interessanterweise funktioniert Zoom 1 (der mit 4 Kacheln). Ich nehme an, es wird nur das Planet / World-Shapefile verwendet, das mit dem Stil heruntergeladen wurde. Alles andere wird unabhängig von Zoom oder Position auf "leer" gerendert. Selbst wenn Sie am Speicherort des Extrakts surfen, wird er nicht korrekt gerendert.

Beachten Sie, dass ich bei Verwendung von Kosmtik den Namen des Extrakts bereits ab Zoom 4 sehen konnte.

Vielleicht bin ich zu erzeugen Fliesen an der falschen Stelle

Projektionen sind schwer. Vielleicht wird irgendwo etwas "falsch übersetzt".

Also analysierte ich die Anfragen, die Kosmtik stellte (da diese funktionierten). Es verwendet die Modestmaps-Bibliothek, die in das Slippy-Format ( <zoom>/<x>/<y>) übersetzt wird, das auch von Leaflet, TileStache und verwendet wird openstreetmap.org.

Das Anfordern 17/48561/74357.pngvon Kosmtik funktioniert beispielsweise, aber dieselbe Kachel wird in TileStache als "leer" zurückgegeben. Meine Theorie war, dass TileStache es irgendwie in eine andere Koordinate außerhalb des Extraktbereichs übersetzte. (Obwohl TileStache "sphärischen Mercator" als Projektion verwendete).

Deshalb habe ich mich entschieden, Mapniks Python-Bindungen direkt zu verwenden. Bisher habe ich drei verschiedene Arten von Projektionen bearbeitet. Hier ist, was ich über sie weiß. Bitte korrigiere mich wenn ich falsch liege:

  • EPSG4326 / WGS84 - Übliche Lon / Lat-Projektion, wie bei GPS. Einheit ist Grad.
  • EPSG3857 / {Web, Google, Pseudo} mercator / 900913 - Wird auf den meisten gekachelten Webkarten verwendet. Die Einheit ist in Metern angegeben (keine "echten" Meter, da sie sich in der Nähe der Pole stark verzerrt).
  • "Slippy Format" - Keine Projektion, sondern ein weiteres zu übersetzendes Format.

Der Slippy 17/48561/74357wäre also in der Nähe -46.632(lon), -23.531(lat)von EPSG4326 und in der Nähe -5191050.49, -2696361.67von EPSG3875 / Google Mercator.

Mit Python habe ich die Kacheln dieser Koordinaten direkt bei Mapnik generiert. Das Ergebnis waren immer leere Kacheln. Ich glaube, ich verwende die richtigen Projektionen (dazu später mehr).

Zunächst eine Sache zu beachten. Es ist klar, dass das Problem weder in Mapnik noch im Stil liegt. Zum einen verwendet Kosmtik Mapnik als Backend und es funktioniert gut. Zweitens, wenn ich absichtlich eine Kachel außerhalb des Extraktbereichs auf Kostmik generiere, bekomme ich wie erwartet eine leere Kachel.

Dies lässt mich glauben, dass ich bei Mapniks Python-Skript und TileStache die falsche Projektion verwende. Bevor Sie den Code anzeigen, eine Bemerkung zu OSM (bitte korrigieren Sie mich erneut, wenn ich falsch liege):

  • OSM "native" Daten werden in EPSG4326 gespeichert
  • osm2pgsql importiert OSM-Daten als EPSG3857, und das ist die Projektion auf Postgis.
  • Mapniks Stil (XML) besteht aus zwei Projektionen, Eingabe und Ausgabe, die hier erläutert werden :
    • Die Eingabeprojektion wird am Kartenobjekt definiert und ist das "Koordinatensystem, in dem die Karte gerendert wird".
    • Die Ausgabeprojektion wird am Layer-Objekt definiert und muss mit meinen Daten übereinstimmen.

Mein resultierendes Mapnik-XML hat:

<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">

So wie ich das sehe, sind sowohl die Eingabe- als auch die Ausgabeprojektion in "merc" (3857), und das ist richtig! Meine Daten werden mit 3857 gespeichert, und die resultierende Karte wird voraussichtlich 3857 sein.

Zum Schluss noch die verschiedenen Mapnik-Aufrufe, die ich ausprobiert habe:

Box2d mit 3857 Koordinaten:

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

Box2d mit 4326 in 3857 transformierten Koordinaten

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

Ich habe es auch mit verschiedenen Stilen versucht. Das Ergebnis ist immer leer, aber das ist unerwartet, da ich glaube, dass diese Koordinaten in meinem Auszug enthalten sind. Wenn Sie versuchen, Koordinaten außerhalb des Extrakts zu rendern, wird dies korrekt als leer dargestellt.

Wie auch immer, ich bin verloren und habe mich gefragt, ob jemand etwas Licht ins Dunkel bringen könnte. Ich muss etwas vermissen. Aber bis jetzt habe ich mehr als 24 Stunden mit diesem Problem gekämpft und ich habe keine Ahnung, was falsch sein könnte.


Möglicher Test: Erstellen Sie einige Daten in EPSG3857 in Ihrem Interessengebiet in einer "Postgis" -Ebene (z. B. mit QGIS) und versuchen Sie, sie in Ihrer Mapnik-XML-Datei
bereitzustellen

Antworten:


1

Ich kann Ihnen keine Antwort geben, da ich nicht sehe, was in Ihrer Konfiguration falsch ist. Ich habe einen ähnlichen Stapel erstellt (Postgis + Mapnik + Mapproxy + Apache).

Ich sehe, dass Ihr Zoom = 1 funktioniert. Ich denke ich könnte sein:

  • ein defekter CartoCSS, wenn Sie einen höheren Zoom aufrufen
  • Eine Quelldatei (z. B. eine .SHP-Datei), die im höheren Zoom angezeigt werden muss, auf die jedoch von renderd nicht zugegriffen werden kann (oder die keine Leserechte hat).
  • ein Problem in TileStach. Ich weiß es nicht, aber mit MapProxy hatten wir Speicherprobleme mit zu großen Kacheln (2048 x 2048, weil wir Kacheln für 4k-Bildschirme erstellen wollten). Schauen Sie sich vielleicht seine Protokolle an.
  • eine andere Sache, ich bin auch relativ neu in GIS!

Ich empfehle Ihnen, es mit einem einfacheren Stapel zu versuchen, wie ich es bei leeren oder rosa Kacheln tue:

  • Verwenden Sie ein getestetes Projekt, das bereits funktioniert hat (ich verwende https://github.com/mapbox/osm-bright ).
  • Ignorieren Sie Tilestach und verbinden Sie Ihren Client direkt mit mapnik (renderd). Der Cache erschwert den Debugging-Vorgang. Vergessen Sie nicht, ihn jedes Mal zu leeren, wenn Sie Ihr CartoCSS-Projekt aktualisieren.

Entschuldigung für diese "verschwommene" Antwort!


1

Möglicherweise muss Ihr Rendering-Dienst neu gestartet werden oder es dauert nur einige Zeit, bis die Kacheln anfänglich gerendert sind.

Ich denke, eine andere Möglichkeit ist, dass Sie den falschen Ort haben.

Sie können zuerst ein anderes Frontend wie z. B. eine Broschüre ausprobieren, indem Sie die Anweisungen unten auf dieser Seite verwenden:

https://www.linuxbabe.com/linux-server/openstreetmap-tile-server-ubuntu-16-04

Alternativ können Sie die vollständige Anleitung im Link verwenden. Es ist sehr einfach, ich konnte in ein paar Stunden einen funktionierenden Kachelserver damit einrichten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.