Eigenen Server für Offlineverfügbarkeit aufsetzten

Guten Tag zusammen,

zu allerst einmal meine Absichten. Und zwar ist es so, das ich gerne einen Server aufsetzen möchte, um eine Karte von einer beliebigen Stadt offline für ein Netzwerk verfügbar mache.

Ich befasse mich seit gestern mit diesem Thema und habe auch schon ein paar Versuche gemacht. Ich habe schon erfolgreich auf meinem Windows Server 20008 R2 eine PostgreSQL (1.9) Datenbank installiert und mittels osm2pgsql die Düsseldorfer OSM Karte in die Datenbank importiert.

Dann habe ich mit mapnik 2.0.1 rc0 und Python 2.7.2 die beiliegende Python demo zum laufen gebracht.

Als nächtes möchte ich natürlich jetzt die Karte aus der Datenbank erstellen lassen.

Habe mir als vom SVN die OSM-Mapnik-Komponenten heruntergeladen. Dabei habe ich mich nach folgender Anleitung (Vielen Dank an Ajoessen) gerichtet.

Doch leider treten nun Fehler auf an denen ich mich schon den ganzen Tag dran aufhalte.

Hier nun zusammengefasst meine Konfigurationen:

Umgebungsvariablen:
PATH = c:\mapnik-2.0.1rc0\lib;C:\Python27;
PYTHONPATH = c:\mapnik-2.0.1rc0\python\2.7\site-packages;

datasource-settings.xml.inc

 <Parameter name="type">postgis</Parameter>
<Parameter name="password">osm</Parameter>
<Parameter name="host">localhost</Parameter>
<Parameter name="port">5432</Parameter>
<Parameter name="user">osmuser</Parameter>
<Parameter name="dbname">osmdb</Parameter>
<Parameter name="estimate_extent">false</Parameter>
<Parameter name="extent">-20037508,-19929239,20037508,19929239</Parameter>

fontset-settings.xml.inc

 
<FontSet name="book-fonts">
  <!--Font face_name="DejaVu Sans Book" --/>
  <Font face_name="unifont Medium" />
</FontSet>
<FontSet name="bold-fonts">
  <!--Font face_name="DejaVu Sans Bold" /-->
  <Font face_name="unifont Medium" />
</FontSet>
<FontSet name="oblique-fonts">
  <!--Font face_name="DejaVu Sans Oblique" /-->
  <Font face_name="unifont Medium" />
</FontSet>

settings.xml.inc


<!ENTITY symbols "symbols">

<!ENTITY osm2pgsql_projection "&srs900913;">

<!ENTITY dwithin_900913 "0.1">
<!ENTITY dwithin_4326 "0.00001">
<!ENTITY dwithin_node_way "&dwithin_900913;">

<!ENTITY world_boundaries "world_boundaries">
<!ENTITY prefix "planet">

Wenn ich nun die generate_image.py ausführe, erhalte ich folgende Meldung:


C:\OSM\mapnik>generate_image.py
c:\mapnik-2.0.1rc0\python\2.7\site-packages\mapnik2\__init__.py:27: DeprecationW
arning:  mapnik2 module has been deprecated,
        please use 'import mapnik'
  warnings.warn(msg, DeprecationWarning)
Traceback (most recent call last):
  File "C:\OSM\mapnik\generate_image.py", line 42, in <module>
    mapnik.load_map(m,mapfile)
RuntimeError: XML document not well formed:
Entity 'datasource-settings' not defined (encountered in file 'osm.xml' at line
6692)

etwas ähnliches auch bei der generate_xml.py


C:\OSM\mapnik>generate_xml.py osm.xml my_osm.xml --host localhost --user osmuser
 --dbname osmdb  --port 5432 --password osm --accept-none --inc=inc-de --prefix=
planet_osm
Traceback (most recent call last):
  File "C:\OSM\mapnik\generate_xml.py", line 201, in <module>
    serialize(template_xml,options)
  File "C:\OSM\mapnik\generate_xml.py", line 77, in serialize
    mapnik.load_map(m,xml,True)
RuntimeError: XML document not well formed:
Entity 'datasource-settings' not defined (encountered in file 'osm.xml' at line
6692)

Ich habe schon etliche sachen ausprobiert, leider bin ich zu keinem Erfolg gekommen. Könnt ihr mir weiter helfen? Ist mapnik überhaupt das richtige für mich?

Für eure Hilfe wäre ich sehr dankbar.

Gruß
mvollmer

Im Prinzip schon. Nur: Mein Workflow ist (noch) auf Mapnik 0.7.1 ausgerichtet. Das neue Mapnik2 erwartet dummerweise komplett überarbeitete Stylefiles, und wahrscheinlcih noch ein paar andere Details.

Für dich als Einsteiger wäre es also am besten, wenn du dich strikt an meine Anleitung hältst, und nur die Versionen von PostgreSQL,Postgis, python und mapnik herunterlädst, die ich auch benutzt hatte.

Gruß,
ajoessen

Hallo ajoessen,

vielen Dank für die schnelle Antwort!

Ich habe mir schon gedacht, das es eventuell an der Versions inkompatibilität liegt. Ich werde dann wohl einen neuen Versuch starten. Aber gut zu wissen, das ich schonmal in die richtige Richtung gehe :wink:

Gruß
mvollmer

wenn du auch noch osm.xml posten würdest, wäre es etwas einfacher. :wink:
oder zuminstest die umgebung von zeile 6692

Gruss

walter

p.s. die umstellung auf mapnik2 ist nicht soooo schlimm

Hallo wmbacher,

klar gerne hier ist der auschnitt aus der osm.xml


<Layer name="theme_park" status="on" srs="&osm2pgsql_projection;">
    <StyleName>theme_park</StyleName>
    <Datasource>
      <Parameter name="table">
      (select way,name,tourism from &prefix;_polygon where tourism='theme_park') as theme_park
      </Parameter>
      &datasource-settings;
    </Datasource>
</Layer>

So ich bin nun genau nach der Anleitung gegangen(Was ich vorher auch versucht habe, aber es wahrscheinlich Probleme mit der 32/64 Bit Version gibt).

Nun hab ich es mit der 32Bit Version probiert und ich kann mir von Mapnik ein Image ausgeben lassen.

Sehe ich das richtig, das in der duesseldorf.osm.bz2 die ganzen Daten sind, um den Kartenauschnitt von Düsseldorf erstellen zu lassen.
Und in der generate_image.py gebe ich einen Bereich aus diesem Kartenauschnitt aus, der dann zur Image.png erstellt wird?

Edit: Ok ich habe grade mit den bounds ein wenig rumgespielt. Das ist mir nun klar.

Wozu genau ist in der datasource-settings.xml.inc dann der Parameter extent?

Desweiteren stellt sich mir jetzt die Frage, wie kann ich nun mit Mapnik arbeiten? Kann ich das ganze als Service laufen lassen? Oder Ist es so, das ich mir z.B. eine Javascript Anwendung schreiben muss, die auf Mapnik zugreif um dann eine Karte anzuzeigen, in die man zoomen und weitere Funktionen anzeiegn lassen kann?
Letztendlich möchte ich aus einer anderen Anwendung eine OSM Karte anzeigen lassen und offline verfügbar ist.

Über antworten auf diese Fragen würde ich mich sehr freuen :slight_smile:

Gruß
mvollmer

In der duesseldorf.osm.bz2 sind alle Daten enthalten, die im Regierungsbezirk Düsseldorf liegen. Wenn du nur Düsseldorf brauchst würde ich vor dem Import ein Rechteck ausschneiden das den benötigen Bereich enthält.

Mit Mapnik musst du dir Tiles berechnen lassen. Anschließend brauchst du einen Webserver (Apache, evtl. auch IIS). Wenn du die Tiles über den Webserver erreichen kannst, schreibst du dir eine kleine html-Datei, die die Tiles dann in einem Browser im Vollbild anzeigt (Beispiele findest du im wiki). In deinem Programm fügst du dann ein Web-Steuerelement hinzu und fütterst es mit der html-Datei.

wenn du bei mapnik 2 bleiben willst, musst du unter Anderem überall underscore _ durch minus - ersetzen.

Das datasource-problem sollte an

            <Parameter name="estimate_extent">false</Parameter>  in datasource-settings.xml.inc liegen: 

hier muss false stehen.

da das nicht die einzige mit mapnik2 notwendige Änderung ist, solltest du dich entscheiden und deine Entscheidung klar stellen.
Sonst redet man aneinander vorbei.

Gruss
walter

Na siehste, geht doch :wink:

Nicht nur Düsseldorf, sondern der ganze Regierungsbezirk.

Ja. Du kannst aber auch nik2img verwenden. Macht im prinzip das gleiche, nur wird die Begrenzung als Parameter übergeben. Man braucht also nicht in der .py zu editieren.

Die Verarbeitung soll damit angeblich schneller gehen. Dürfte aber eher bei niedrigen Zoomstufen notwendig sein, wenn man viele Daten verarbeiten muß.

Ich habe es so gemacht, dass ich alle Tiles in einem Durchgang rendern lasse, und mit openlayers auf die Verzeichnisstruktur per file:/// zugreife:
http://wiki.openstreetmap.org/wiki/User:Ajoessen/Osmviewer_und_GPXviewer

Dann braucht man keinen Webserver dazu. Man kann dann aber später immer noch einen lokalen Apache-Server aufsetzen, und auf die tiles per http://localhost zugreifen.

Rendern-on-demand mit tirex oder renderd lohnt sich eigentlich nur, wenn man ganz Europa oder die Welt abdecken will. Dann dauert das Vorrendern nämlich Ewigkeiten, und das meiste davon ist Meer, was niemanden im Detail interessiert.

Gruß,
ajoessen

Guten Morgen zusammen,

nochmals Vielen Dank für eure Antworten!

Das hört sich schonmal sehr gut an. Es wird wahrscheinlich auch darauf hinauslaufen, da nur ein bestimmter Bezirk benötigt wird und nicht mehr. Daher wäre das Render-on-demand überflüssig.

Ich hab dies mal kurz getestet, der fehler bleibt allerdings.

Ich weiß nicht ob sich es in meinem Fall lohnt bei mapnik2 zu bleiben bzw. darauf umzusteigen. Gibt es gravierende Änderungen, bei denen man sagen würde “Nie mehr ohne mapnik2” :slight_smile: ?

Ich gehe mal davon aus, das du es bereits mit mapnik2 zum laufen gebracht hast.

Würde es vorrausichtlich nur bei den ersetzungen von _ zu - bleiben? Oder würde man noch viel tiefer eingreifen müssen?

Wenn sich der mehraufwand nicht lohnt, würde ich jetzt erstmal bei der vorherigen Version bleiben.

Gruß
mvollmer

Wenn es doch bei dir jetzt läuft: “Never change a running system”

In nem Jahr oder so sieht die Entscheidung mit Sicherheit anders aus.

Gruß,
ajoessen

Gut, ich werde dann mit dieser Version weiter arbeiten. Es klappt ja :wink:

Noch eine andere Frage. Wie komm ich am besten an die bbox Koordinaten die man in die generate_tiles.py einträgt?
Wie geht man am besten vor? Kann man die Koordinaten nehmen? z.B. (Koordinaten: 51° 20′ N, 6° 34′ O für Krefeld) Nicht das man nachher etwas rendert und es ist nicht das drauf was ich möchte.
Beim Zoom gilt doch umso größer der Zoom, desto näher ist der Kartenauschnitt. ? Also beim Zoom 16 würde das rendern einiges mehr Zeit beantspruchen als bei einem niedrigerem Zoom.

Und mit wie viel Speicherplatz muss man für die Tiles rechnen z.B. für die ~ 80MB osm Datei.

Bei meinem Versuch eine Stadtbereich zu rendern, sind viele “Empty Tiles” dabei. Was wahrscheinlich daran liegt, das die bbox Koordinaten nicht optimal sind.

Hab z.B. folgende Daten genommen:


    minZoom = 1
    maxZoom = 16
    #bbox = (-2, 50.0,1.0,52.0)
    bbox = (6.50, 51.3001, 6.991, 52.3)
    render_tiles(bbox, mapfile, tile_dir, minZoom, maxZoom, "Krefeld")

Gruß,
mvollmer

Ich nehme meinen OSMviewer, der hat unten rechts die aktuellen Koordinaten der Mausposition eingeblendet :wink:

Nicht ganz. In Zoomstufe 16 werden nur die Daten eines kleinen Bereichs von der Datenbank abgerufen, in Zoomstufe 0 dagegen von der ganzen Welt. Der optimale Wert für ein bestimmtes Gebiet liegt etwa bei Zoomstufe 9. Bei kleineren Zoomstufen hat die Datenbank mehr zu schaufeln, bei höheren ist das Dateisystem mit den tausenden von Tiles der Flaschenhals.

Schwer zu sagen. Ganz NRW hat bei mir in Zoomstufe 15 aktuell 668MB. Jede Stufe höher sind viermal so viele Dateien, aber mit weniger Inhalt.

52.3 ist natürlich schon weit aus dem Regbez heraus. Daher die leeren Tiles.
Zoomstufen 1 bis 7 lasse ich sowieso weg: da sieht man nichts Interessantes mehr. Zur Not kannst du dir die auch vom OSM-Server holen. Für eine Stadt ist das ja maximal einer pro Zoomstufe.

Gruß,
ajoessen

Natürlich ist mapnik2 besser als mapnik - sonst wäre die Entwicklung ja nicht notwendig gewesen.

Klar. Ich hab im Herbst umgestellt, weil ich einige Features unbedingt verwenden wollte - und das jetzt auch mache :slight_smile:

Warum mein kleiner Tip mit dem Underscore nichts brachte, müsste man mal sehen. Zumindest ist das nicht die einzige Änderung, da kommen noch Kleinigkeiten dazu.

mir hat es einiges gebracht:

z.B. Variablen in Regeln:

      
<PointSymbolizer base="presets" file="[icon]" transform="scale(0.2)" 
                       allow-overlap="true" />
...
<Parameter name="table">
      (select geom, 
              n.tags->'addr:postcode' "plz",
              'c'||wno_modulo10(n.tags->'addr:postcode')||'.svg' "icon"   <----- hier wird icon gesetzt           
         from nodes n
        where n.tags ? 'addr:postcode'
       ) as foo</Parameter>

[icon] im PointSymbolizer wird durch das Ergebnis eine sql-Abfrage ersetzt. Somit fallen die ewigen Abfragen in den Rules weg, da bereits die Datenbank die passenden Informationen liefern kann.

Variablen gehen noch nicht überall, aber das wird definitiv kommen. So könnten unterschiedliche Grössen von Symbolen/Texten/… in Abhängigkeit vom Zoom-Level oder anderen arithmetische Beechnungen machbar sein. Auch verschieden Farben könnten direkt aus der DB kommen.

Gruss
Walter

p.s. die DB hat das osmosis-snapshot Schema.

Für das Upgrade alter Stylesheets müsste es im Mapnik2 Installationsordner ein “upgrade_map_xml.py” Script geben, siehe Mapnik2 - Upgrade Guide.

Da dieses Script Entities (inc-Files) nicht berücksichtigt, müssten diese mit “generate_xml.py” vorher eingebunden werden, z.B.:

(ACHTUNG: überschreibt bestehende Konfigurationsdateien (*settings.inc), ggf. vorher sichern)


generate_xml.py osm.xml osm-all-inc.xml --host localhost --user osmuser --dbname osmdb --port 5432 --password osm --accept-none --inc=inc --prefix=planet_osm

upgrade_map_xml.py osm-all-inc.xml osm-mapnik2.xml

Gruß,
ikonor

P.S.: Der Fehler beim generate_xml.py oben könnte am Parameter --inc=inc-de gelegen haben, da es dieses Verzeichnis nur beim deutschen Stil gibt?

Das es sich verbessert hat will ich doch hoffen, hab ich ja nicht abgestritten :wink:

Aber ich denke bis jetzt reicht die alte Version noch. Ich bin dabei jetzt mal die Komplette Deutschlandkarte von Geofabrik importieren.
Der Import läuft schon seit ~ 2 Stunden und wird sicher noch etwas brauchen.

Beim rendern werde ich dann wohl vom Zoom 8 bis 15 und den Koordinaten
( 5.8 , 47.2 , 15.1 , 55.1)
(links, unten, rechts, oben)
die tiles erstellen lassen.

Ist das Okay? Oder kann man das ganze noch optimieren.

Ich habe ein wenig in der genrate_tiles.py rumgespielt und hab jetzt in der einen Prozedure nur noch folgendes stehen:

        def loop(self):
        while True:
            #Fetch a tile from the queue and render it
            r = self.q.get()
            if (r == None):
                self.q.task_done()
                break
            else:
                (name, tile_uri, x, y, z) = r
            if not os.path.isfile(tile_uri):
                self.render_tile(tile_uri, x, y, z)        
            self.q.task_done()

Ich denke das sollte das ganze doch ein wenig optimieren. Da die ausgabe in der Console jetzt wegfällt und direkt gerendert wird, falls die Datei nicht vorhanden ist.

Hoffentlich hast du genug RAM. Mir ist der beim Erstellen des Index am zweiten Tag irgendwann abgeschmiert…

Mit Numthreads lässt sich die Parallelbearbeitung steuern.

So weit hab ich mich in das Python nicht eingearbeitet.

gruß,
ajoessen

Ich hab 4 GB RAM. Des Weiteren habe ich ja die Parameter --slim --cache 1536 benutzt. Damit sollte doch nichts passieren.

Reading in file: C:\osm\Geofabrik\germany.osm.bz2
Processing: Node(89779k) Way(2326k) Relation(0k)
Ich weiß nicht wann es endet. Es wird vermutlich mehrere Tage dauern oder?

Ich habe einen 2 Kern CPU. Daher wie im Kommentar auch geschrieben NUM_THREADS auf 2 gesetzt.

Ist die Frage. Ich habe bei 2GB soviel RAM zugewisen, und bin mit DE irgendwann abgestürzt. Die 3GB für 32-bit-Systeme solltest du schonungslos ausnutzen…

Das ist ja nur das Einlesen. Den Index aufbauen dauert dann erst mal richtig lange.

Ja, hatte ich auch gedacht, ist bei mir aber doch gescheitert. Womöglich will das Betriebssystem nicht auf eine eigene CPU verzichten.

Gruß,
ajoessen

Guten Tag,

das importieren der Deutschlandkarte hat ohne Probleme funktioniert. Aber folgendes war nicht wie beim letzten mal.
Beim ausführen der generate_image sowie tiles kam die Fehlermeldung:

RuntimeError: C:/osm/mapnik/world_boundaries/* does not exist (encountered during parsing of layer *)

Ich habe darauf hin die Fehlenden Dateien runtergeladen.
z.B. http://tile.openstreetmap.org/shoreline_300.tar.bz2

Dannach funktionierte das Rendern der tiles. Aber als ich mir dann das Ergebnis anschaute, waren es nur beige farbende Bilder.
Und nicht wie zuvor eine vernünftige Karte.

Woran kann das liegen? (Ich habe die Deutschlandkarte auf einem anderen Rechner importiert. Also alles nochmal neu installiert.)

Gruß
mvollmer

Also wenn du nur Beigefarbene Karten hast, spricht das für fehlende Daten oder Datenverbindungen. Denn diese Farbe ist für Landmasse und wird aus den Shps für Küstenlinien erstellt. Zusätzliche Informationen kommen erst durch weitere Daten ins Spiel.