Osmconverter ausschneiden funktioniert nicht

Du kannst hier nachlesen, warum das eher keine gute Idee ist: https://lists.openstreetmap.org/pipermail/dev/2021-February/031084.html

Ich sehe das wie Flo, der Code ist in seiner veröffentlichten Form leider kaum bis gar nicht wartbar.

Also für eine Vergrößerung der Hashcode-Table halte ich mich schon für fähig, auch wenn dazu vermutlich komplett auf 64-bit-Indizes (eventuell auch auf 64-bit-Hashcodes) umgestiegen werden muß. Allerdings ist der Quellcode - sagen wir mal - “historisch” gewachsen, mit entsprechendem Wildwuchs - leider. Das kann man dem Autor aber nicht vorwerfen, da er es hauptsächlich für seinen Eigenbedarf entwickelt hat und es wohl eher zufällig in der Öffentlichkeit gelandet ist. Nichtsdestotrotz ist es ein handliches Tool, auf das ich nicht mehr verzichten möchte.

Übrigens: Die Änderung von 10241024 zu 1024u1024u führt nur zu einer Verdoppelung der maximal möglichen Hashcodegröße von 2^31-1 zu 2^32-1. Funktioniert auch ohne die Änderung, da das Vorzeichen bei Typkonvertierungen in C einfach ignoriert wird → Integer overflow.

Man kann wohl langsam aber sicher auf einen Support on 32-bit Systemen verzichten, falls das ein Hindernis ist. Man könnte aber evtl. auch short* oder int* anstelle von char* verwenden, um die Elemente um Hash zu adressieren?

Gibt es eigentlich irgendeinen mir vielleicht unbekannten Grund, warum man für sowas nicht einfach osmium tool verwendet?

Ich habe irgendwann mal versucht, ein Windows Binary zu finden und bin gescheitert.

Lösung hatte ich hier mal eingereicht, wurde aber nicht übernommen, weil eigentlich niemand freiwillig mit Windows arbeiten will: https://github.com/osmcode/osmium-tool/pull/105

Ich denke mal, das mindestens die Hälfte aller mkgmap Hobby-Anwender Windows benutzen. Das o5m Format ist auch am besten als Eingabe für das zugehörige Programm splitter geeignet. Osmium kann kein o5m schreiben, oder?

Falls osmconvert tatsächlich mal nicht mehr funzt und nicht mehr gewartet würde, dann würde ich vermutlich eher ein Java replacement kodieren für die Funktionen, die man für mkgmap braucht.

Ja, Osmium kann im Moment nur lesend auf o5m zugreifen. Die Frage ist natürlich, ob sich der Aufwand für ein Schreiben überhaupt lohnt. Gibt es dazu Erfahrungswerte, wie sich o5m im Vergleich zu pbf mit dem Splitter schlägt? Ich hatte zuletzt vor vielen Jahren mit splitter gearbeitet und kann mich nicht mehr so recht an die Details erinnern.

Bei grossen Dateien lohnt es sich auf jeden Fall, erst mit osmconvert nach o5m zu wandeln, das kann einigen Minuten sparen. Weltbewegend ist der Unterschied nicht mehr. Splitter muss die Datei einige Male lesen und braucht nicht immer alles, z.B. nur die Wege oder nur die Relationen. Es gibt aber beim pbf Format keine Möglichkeit, direkt zu den Wegen zu springen. Man nudelt jedes mal ales durch und das kostet Zeit.
Splitter könnte auch beim ersten Lesen die Wege und Relationen in temp. Dateien schreiben, dann wäre das Problem gelöst, aber einfacher ist mit dem o5m Format. Da merkt man sich beim ersten Lesen den Offset, an dem es mit Ways losgeht und kann dann beim nächsten Lesen direkt dort hinspringen.

Das wäre super :wink:

Sobald man das PBF einmal durchgenudelt hat, sollte man zumindest die Offsets der jeweiligen Blobs kennen, in denen zum ersten mal Ways oder Relationen auftauchen (Annahme: PBF ist sortiert nach Nodes, Ways, Relations). Ich kenne aber auch keine Implementierung, die diese Information bewusst berücksichtigt, um größere Teile des PBF zu überspringen.

Zufällig entdeckt: https://github.com/peermaps/random-access-osm-pbf bietet die Option, irgendwo mittendrin im PBF einzusteigen und dann ab einem passenden Synchronisationspunkt aus Daten zurückzuliefern. Ob das wirklich wie versprochen funktioniert, müsste man sich mal genauer anschauen.

splitter merkt sich die Blöcke und was drin ist und gibt in der skipBlock() Methode entsprechende Werte zurück. Das ist aber immer noch viel langsamer als die direkte Positioniering.
Der Link ist interessant. Ist halt die Frage, ob man das selber strickt oder ob das in die osmpbf.jar gehört.
Zumindest bei der jetzigen Implementierung von splitter hat die osmpbf.jar die Kontrolle und ruft Funktionen von splitter auf. Da habe ich gar keine Chance, irgendeinen Offset anzugeben.
Habe mich aber auch schon lange nicht mehr damit beschäftigt.

Habe mal einen experimentellen Zweig für splitter angefangen, mit dem man eine osm Datei nach o5m konvertieren kann. Siehe auch
https://www.mkgmap.org.uk/websvn/revision.php?repname=splitter&rev=604

Das binary gibt es unten auf der Download Seite: https://www.mkgmap.org.uk/download/splitter.html
Beispiel:


java -cp dist\splitter.jar uk.me.parabola.splitter.Converter niedersachsen-latest.osm.pbf niedersachsen.o5m

Macht ziemlich genau das, was bei


osmconvert --drop-version --drop-author niedersachsen-latest.osm.pbf -o=niedersachsen.o5m

rauskommt, allerdings nicht besonders optimiert und daher langsamer (vielleicht Faktor 1.5).
Wirft allerdings zusätzlich auch noch alle created_by tags weg, die wurden von splitter schon immer “verschluckt” und auch der timestamp der Datei wird noch ignoriert.

Einen vollstängen Ersatz vom osmconverter will ich da aber eh nicht bauen, vielleicht noch die Ausschneide-Funktionen. Im Prinzip ist das ja in splitter schon drin, aber halt optimiert für das Aufteilen in mehrere (viele) Kacheln.
Eigentlich finde ich Idee interessanter, damit on-the-fly eine temporäre Datei zu schreiben, die dann nach dem ersten Lesen verwendet werden kann.

Mal eine andere Frage: Denkst du, es wäre clever, statt das lokale extrakt upzudaten, die change-files zusätzlich splitter zur Verfügung zu stellen und splitter merged das on-the-fly beim erstellen der von dir vorgeschlagenen temp-datei?

Tja, da wären wir dann doch dabei, dass splitter die Aufgaben von osmconvert bzw. osmupdate übernimmt. Ich müsste mir erst mal anschauen, wie das Mergen in diesen Programmen funktioniert, aber auf Anhieb würde ich sagen, dass es keinen Vorteil bringt, wenn man das mit splitter macht. Schneller als die osm* Programme kann man nur werden, wenn es man es schafft, mehrere Prozessoren zu beschäften
UND nicht der I/O den Flaschenhals darstellt.

Nunja, den planet um einen Tag upzudaten dauert bei mir auf aktueller Hardware rund 2h. osc laden und mergen, Planet lesen, und mit osc mergen, schreiben in osmupdate und dann neuen planet lesen + splitten in splitter. Einmal 60gb schreiben und lesen kann man sich sparen.

Man könnte das mergen auch in den tiles nach splitter machen, dann sollte es sich parallelisieren lassen.

Keine gute Idee. Es könnten sich Relationen geändert haben, so dass sich Mitglieder gar nicht mehr im zu aktualisierenden Tile befinden, oder Straßen, deren Punkte sich nicht mehr im aktuellen Tile befinden.

Nicht zu vergessen auch, dass der Splitter Elemente in die benachbarten Tiles hineinragen lässt (für Routing-Nodes, intakte Flächen etc.), welche bei der Aktualisierung zusätzlich zu beachten wären.

Edit:
Noch etwas spricht dagegen: Die Größe neuer/geänderter/gelöschter Elemente könnte nicht mehr zur kalkulierten Tile-Größe passen (max-nodes).

Oder aber manche Ersteller filtern nicht benötigte Daten für Spezialkarten heraus, man kann dann nicht mehr unterscheiden, welche Daten neu hinzugekommen sind und welche sich geändert haben. Dann müsste man den gleichen Filter anwenden wie für den individuellen Extrakt. Ich glaube, das sprengt den Rahmen.

Also ich könnte mir vorstellen, dass es schneller wird, wenn man planet einmal mit splitter in z.B. 4 Teile aufteilt und dann diese 4 Teile parallel updated, jeweils mit Angabe der bbox. Zu prüfen ist halt, ob dabei alle Relationen intakt bleiben.
Dann sollte man auch mehrere splitter parallel laufen lassen können. Insgesamt dürfte das auf Maschinen mit vielen Kernen und mehreren Platten/SSD halbwegs gut skalieren, aber I/O bleibt das Problem.

Warum sollte das nicht gehen? Ich kann doch auch ein planet diff auf Germany anwenden und das Ergebnis ist korrekt.

Mein Ansatz war: Wenn ich ein 60gb Planet update um einen Tag bedeutet das:Ich muss weil 100mb anders sind, 60gb auf der Platte schreiben. Anschließend liest splitter die 60gb und schreibt sie erneut auf die Platte. Und die Erfahrung zeigt, der planet wird nicht kleiner :wink: Aber ist auch nur eine Idee, wie man es anders machen könnte. Lediglich finde ich, dass das aktuelle System zur Kartenerstellung so langsam an seine Grenzen stößt. Wenn es schneller ist, die 60gb per torrent zu laden als 100mb zu laden und lokal upzudaten, sollte man sich gedanken machen, wie man den Prozess beschleunigen kann. Was aber wie gesagt nicht heißt, dass meine Idee das non-plus-ultra ist.

Hallo Henning,

es wird funktionieren, wenn man vom Planet-File mehrere Splits pflegt. Das heißt, einmal gesplittet und dann auf jeden dieser Splits alle Change-Files anwendet und jeweils neu schneidet (mit genau den Bounding-Boxes wie bei der Erstellung dieser Splits). Das was nicht in die jeweilige Box gehört, wird dann wieder verworfen und was nach neuem Stand in die Box gehört (z.B. Relation vom Rand der Nachbar-Box ragt jetzt in die aktuelle Box) kommt zusätzlich hinzu. Wichtig ist, dass alle Nodes schon da sind, wenn ein veränderter Way (aus der Nachbar-Box) diese nach neuem Stand benutzt und dass die Nodes und Ways schon da sind, die eine veränderte Relation nach neuem Stand nun benutzt.

Was ich meine, was nicht funktioniert, ist, diesen Import nach dem Splitvorgang für die Kartenerstellung mit mehreren hundert Tiles anzuwenden. Die Kalkulation der Tilegrenzen beruht auf den aktuellen Daten, während die Changes dann vieles verändern. Die Anzahl der Nodes in den Tiles ändert sich, Nodes die schon da waren gehören zu einem verlängerten Way der nun hineinragt, die Vorausberechnung für “–keep-komplete” war “falsch” usw.

Meinetwegen kann der Splitter die Pflege von Portionen des Planet-File übernehmen, der Splitvorgang für die Tile-Erstellung für mkgmap sollte aber mit den kompletten Daten im Ist-Zustand erfolgen.

Grüße
Mario