osmfilter 1.2 released. Neu: and, or, =, !=, <, >, <=, >=, Klammern

Hallo,
das Filterprogramm osmfilter hab ich ein bisschen erweitert. Es versteht inzwischen Klammern (müssen mit Leerzeichen vom Rest getrennt werden) und neben “=” diese Operatoren: != < > <= >= and or

Verglichen wird grundsätzlich alphabetisch, allerdings vereinfacht, das heißt, nach UTF-8-Code. Bei Filter-Operanden, die mit einer Ziffer beginnen (oder mit Minus und Ziffer), wird numerisch verglichen. Damit sind zum Beispiel Konstrukte wie dieses möglich:


./osmfilter germany.o5m --keep="place=city or ( place=town and population>=10000 )" --ignore-dependencies -o=grosse_orte.osm

Vorerst will ich das Programm noch nicht als reguläre Version hochladen. Gibt es jemanden, der diese Beta-Version mit testen will?

EDIT am 2011-12-18: Thread-Titel angepasst, da die neue Version nun offiziell zum Download bereitsteht.

Cool, was ist bei numerischen Vergleichen wenn der Wert Buchstaben enthält?

Bsp. maxspeed <= 50
40 → true
35.5 → true
35,5 → true (Es sollte Punkt und Komma akzeptiert werden)
30km/h → true? (Einheiten eliminieren vor Vergleich)
none → false? (Sollte false liefern)

Der Vergleich läuft leider nur bei reinen Zahlen korrekt. Bei Mischungen aus Zahlen und Buchstaben wirds eh schwierig. Wie wäre zum Beispiel das Folgende zu behandeln?

50k (als 50000 lesen?)
50m (als 0,005 für “milli” lesen oder von der Einheit “Meter” ausgehen und den Buchstaben ignorieren?)
500l (von 500 Litern ausgehen und den Buchstaben ignorieren oder als 0,5 behandeln, weil die Einheit auch m³ sein könnte?)
50,000 (50000 nach amerikanischer Schreibweise, nach deutscher Schreibweise wärs 50)
50.000 (50000 nach deutscher Schreibweise, nach amerikanischer wärs 50)
50’000 (50000 nach schweizer Schreibweise)

Meiner Meinung nach gehören Einheiten gar nicht gespeichert, sondern einmal festgelegt und dann generell für das betreffende Tag verwendet. Trotzdem findet man sie natürlich immer wieder, das macht die Sache nicht immer leicht…

Doch einheiten sollten schon definierbar sein. Aber bitte als eigener tag etwa
maxspeed=50
unit:maxspeed=km/h

Alles andere wird einfach mit lokalen Gegebenheiten probs bereiten. Das 50.000 nur 50 bedeutet, sollte jedem klar sein. Schließlich haben wir brittische Schreibweise bei Tags… Am besten sollte aber festgelegt werden, dass . und , zur lesbarkeit nicht verwendet wird…

Der Vorschlag ist unbrauchbar. Denn es würde jeden auswerter verpflichten nach diesem Einheiten tag zu suchen.
Wohin das führt sieht man doch bei einem Vergelichen von ÖPNVkarte.de zu Mapnik. Seit es highway=service gibt, wird intensive davon gebraucht gemacht. Gleichzeitig gibt es aber auch highway=service und service=driveway. Da die ÖPNVKarte nur highway=service auswertet, werden alle diese Straßen gleichrangig dargestellt.
Das gleiche passiert dir wenn du maxspeed=50 angiebst. Der Auswerter findet 50 und geht davon aus das es wie vereinbart km/h sind. Von dem zweiten Tag hat er keine Ahnung. Du als Mensch gehst da anders vor!

Dem stimm ich zu. Aber ich hab bei der Beschreibung zu “maxspeed” grad gesehen, dass laut Wiki auch Angaben wie “30 mph” erlaubt sind. chris66 hat also zumindest zum Teil Recht. Deswegen sollten numerische Vergleiche besser nicht durcheinanderkommen, wenn eine Einheit angegeben ist, sie sollten die Einheit einfach ignorieren. Man könnte dann ja z.B. so abfragen:

maxspeed>50 or ( maxspeed=*mph and >30 )

Zumindest wäre es mkgmap-kompatibel wenn es so rechnen würde wie in meinem Beispiel.
Tausender Trennungen (100.000) habe ich in den Daten noch nie gesehen, ich denke die
kann man ignorieren.
Vorschlag:
String ab dem ersten Buchstaben abschneiden, Komma durch Punkt ersetzen, umwandeln in Decimal und Vergleichen.

Die Angabe von Einheiten als Teil des Wertes ist eine übliche Vorgehensweise und aus Sicht des Mappings auch wesentlich einfacher und intuitiver. Das ist eigentlich schon vor Jahren gründlich diskutiert worden und inzwischen nicht nur im Wiki, sondern auch in den Vorlagen von Potlatch so verankert.

Die technische Aufgabe, mit Werten + Einheit umgehen zu können, ist also nun einmal da und man sollte sich lieber Gedanken machen, wie man sie sinnvoll löst.

viw & Tordanik:
OK, kann ich nachvollziehen. Dann, wenn unterschiedliche Einheiten gebräuchlich sind, wie z.B. km/h und mph, kann ich mir vorstellen, sie im gleichen Feld mitzuführen, quasi als Faktor. Das von chris66 angesprochene Problem ist ja auch lösbar.

Stimmt, wäre eine brauchbare Lösung. Vorerst will ich aber bei dem Verfahren ohne Zahlensystemumwandlung bleiben, das heißt, ich vergleiche die einzelnen Zeichen direkt.

Der Algorithmus im Groben:
Zuerst führende Nullen überspringen, dann Ziffer für Ziffer vergleichen, bis entweder ein ‘.’ oder ein fremdes Zeichen kommt (Sonderzeichen, Leerzeichen, Buchstabe). Nach einem ‘.’ weiter vergleichen. Für die, die sich mit dem Code erschrecken wollen: die Prozedur heißt fil__cmp().

Neu eingebaut habe ich jetzt, dass der Vergleich ab dem ersten Sonderzeichen, Leerzeichen oder Buchstaben abgebrochen wird, das heißt, die angehängte Einheit verursacht keine “Störungen” und kann durch einen eigenen Vergleich ausgewertet werden - sofern benötigt (siehe mein letzter Beitrag).

Die Beta-Version ist hier: m.m.i24.cc/osmfilter_new.c
Fertig für Windows (für 32 Bit, aber auf 64 Bit lauffähig): m.m.i24.cc/osmfilter_new.exe

Das ist jetzt aber nur die Programmlösung für die erste Näherung oder?
Ich meine wenn ich versuche nach Maxspeed<50 (km/h) zu filtern und er mit 49 mph durchwinkt wäre das doch nicht das erwünschte Ergebnis.

Also viw, gerade von Dir hätt’ ich da jetzt mehr erwartet :wink:

Man kann jetzt nicht verlangen, dass das osmfilterproggie sämliche Einheitensysteme dieser Welt und vergangener Zeiten beherrscht.
Schaut nur mal das an:
97625 4. Dez 05:05 bin/osmfilter
2856275 15. Dez 07:26 osmfilter

Wenn das so weiter geht mit Markus Programmen, muss ich ernsthaft an externe Festplatte für mein Netbook denken.
Oder gleich 'ne Cloud-Lösung :wink:

Wenn Du bei den Einheiten unsicher bist, dann kannst sie ja zur sicherheit gleich mal “vorfiltern” und ggf. korrigiern :slight_smile:

Was Besseres ist mir nicht eingefallen. :wink:
Ne, mal im Ernst: was soll das Programm machen, wenn die möglichen Einheiten vom User nicht vorgegeben werden? Im Programm einen Katalog mitzuführen, der für jeden Tag die zulässigen Einheiten enthält, ist aus meiner Sicht zu aufwändig und auch kaum pflegbar.

Für dein Abfragebeispiel wäre es dann eben notwendig, den Filter etwas ausführlicher zu definieren:

--keep="( maxspeed<50 and maxspeed!=*mph ) or maxspeed<30"

Wenn es sich um eine Abfrage für rein deutsche Daten handelt, kann man sich diese Verrenkung vermutlich sparen.

Uff, ich sehs auch grad. Wie konnte das passieren? Der Quellcode ist gar nicht sooo viel größer geworden. Gefällt mir nicht.

Wahrscheinlich kann man sich das oft sparen. Wichtig wäre nur für den Nutzer, dass er darüber eine Information erhält. Wie “ich konnte beim vergleich nicht alle Zeichen berücksichtigen, da es unerwartete Werte gab.” Nächste Schritt wäre, wenn man sicher sagen kann das es Einheiten sind das Kind so zu nennen oder die Werte konkrett zu benennen. Wenn das nicht zu lasten des Speichers gehen soll schiebst du das am Besten in ein Log rein, wo der User das nachlesen kann welche Elemente nicht vollständig vergleichbare Elemente haben.
Aber du musst das nicht alles machen. Es sind einfach nur Ideen, was man von einem Programm vielleicht erwarten würde. Besonders wenn es ohne Fehler durchläuft hielte ich den Vergleich für schlicht falsch.

@viw
Nenn mir bitte mal ein (Standard-)Programm uner Lin/Win/Mac, welches das kann, innerhalb eines value-strimgs!
Excel macht es nicht. Und wenn ich nur an die x-moeglichkeiten denke, dass Datum zu schreiben …

Ich weiß jetzt nicht worauf du dich beziehst. Aber ich denke das Excel/openoffice/libreoffice schon sehr viel kann. Dannw erden mir jedenfalls keine falschen Werte geliefert sondern die Werte einfach ignoriert. Das ist ein Unterschied zu der hier eingebauten Variante wo nur die Einheiten bzw. alles was wie string aussieht ignoriert wird und der davor liegende nummeriesche Wert den Ausschlag gibt. Erst dann kommt es nämlich zu dem geschilderten Verhalten.
Was das Datum angeht, sind diese beiden Programme sehr weit was die Erkennung angeht. Manchmal sogar zuweit, so dass sie ein Datum erkennen was keines ist. Intern wiederum wird ein Datum aber als Zahl gespeichert und in einem anderen String eine Formatierung. Das eigentliche zu vergleichszwecken herangezogene Datum ist dann aber standardisiert. Von mir aus sollte OSM das auch gerne so machen. Einen Formatstring und ein Value. Aber einen standardiserten Value, bei dem sich jeder auf den Inhalt verlassen kann und keinen Schiffbruch erleidet, wenn man den Formatstring nicht kennt.
Im ürbrigen wäre es ein leichtes für Editoren, die CI Einheiten in Standardeinheiten für den Nutzer umzurechnen. Wenn man das denn will.

Genau dafür gibts aber die Statistik-Funktion von osmfilter. Ich hab spaßhalber grad ein Beispiel durchlaufen lassen:

$ ./osmfilter germany.o5m --out-count=maxspeed
     330274    30
     157533    50
      33148    100
      28008    70
      10630    60
       9198    80
       8474    none
       7104    10
       6181    20
       5850    120
       2647    signals
       2466    40
       2374    7
       1508    130
        940    160
        850    5
        592    300
        552    no
        474    250
        440    200
        437    6
        341    15
        277    walk
        218    230
        194    DE:urban
        160    90
         95    8
         85    280
         82    25
         60    DE:zone:30
         55    DE:living_street
         49    DE:rural
         47    3
         44    2
         42    AT:urban
         40    5 mph
         40    variable
         34    4
         33    moderate
         31    1
         28    0
         28    unknown
         21    30km
         13    de:urban
         12    6.5
         10    10 mph
         10    110
         10    30 km/h
         10    DE:motorway
         10    DE:zone30
          9    6 Knoten
          8    undefined
          7    dynamic
          6    de:rural
          6    moderat
          5    12
          5    220
          5    30mph
          4    100;60;80
          4    30; 50
          4    30;50
          4    50; 30
          4    50; 30; 50
          4    50km
          4    7.4
          4    <unterschiedlich>
          4    Spielstraße
          4    default
          3    100;50
          3    11
          3    20 mph
          3    3.5
          3    50 km/h
          3    50; 100
          3    6,5
          3    DE:walk
          3    fixme
          2    100;60
          2    100;70
          2    2.5
          2    30 mph
          2    39
          2    4-7 km/h
          2    50;70
          2    50mph
          2    80; 100
          2    a
          1    %=
          1    (30km/h)
          1    -
          1    /
          1    07
          1    1.50
          1    100; 50
          1    100;30
          1    15 mph
          1    15kmh
          1    21
          1    24
          1    3.0
          1    30; 50; 30
          1    34
          1    35
          1    45
          1    50/70
          1    50; 70
          1    50; 80
          1    50?
          1    600
          1    60; 70
          1    7 kmh
          1    70; 50; 50; 50
          1    70;100
          1    =30
          1    ?
          1    FIXME
          1    living_street
          1    open
          1    signal
          1    urban
          1    workday 06:00-19:00 30; 50

Ich hoffe, ihr kommt nicht auf die Idee, dass das Programm alle diese 121 verschiedenen Werte “korrekt” auswerten können muss… :slight_smile:

Also alle diese Werte muss man sicher nicht auswerten. Aber die Keys “none” und “no” halte ich für interessant, genauso wie DE:urban. Weiter unten scheinen ja nur noch versprengte Ausnahmen zu sein.
Aber vielleicht ließe sich das auch anders machen. Nämlich wie bei den Garmin Styles wo es Ersetzungen gibt. Denn Maxspeed ist vielleicht nur eines der uns jetzt einfallenden Baustellen. Wahrscheinlich gibt es noch andere.

maxspeed=600? Wo gibt es dieses Paradies für Porschefahrer? :smiley:

edit: Es handelt sich um einen Parkplatzweg:
http://www.openstreetmap.org/browse/way/57818304

Klar, kann man alles machen, aber ich überleg immer noch, um welchen Anwendungsfall es geht. Das Programm ist zum Filtern von Dateien da. Wenn man wirklich einen Key (z.B. maxspeed) umfassend berücksichtigen will, kann man sich dafür ohne Weiteres einen Filter mit Hilfe der Booleschen Operatoren bauen, und zwar exakt so wie man ihn haben will.

Damit will ich nicht sagen, dass deine Ideen schlecht sind! Das sind sie ja absolut nicht. Ich mein aber, osmfilter ist nicht die beste Plattform, das alles umzusetzen.