• Willkommen im Geoclub - dem größten deutschsprachigen Geocaching-Forum. Registriere dich kostenlos, um alle Inhalte zu sehen und neue Beiträge zu erstellen.

Toleranz des Koordinatenparsers

greiol

Geoguru
wir hatten ja schon in einer be die ergänzung, daß . und , in einer koordinate vorkommen dürfen.
ist es möglich auch bei den whitespaces toleranter zu werden.

Bug:

im moment (0.9m) führt
Code:
N 10 10.101  E 10 10.101
zu einem absturz weil unbedingt auf
Code:
N 10 10.101 E 10 10.101
bestanden wird.

Feature:

wo wir gerade dabei sind: könnten die von hand eingegeben koordinaten auch den beautifier bekommen und ggf. um ° und führende 0 ergänzt werden so wie es bei den eingelesenen koordinaten erfolgt?
 

pfeffer

Geowizard
ja, da hast Du recht.
Ich hätte es am liebsten so:
sobald man in der Details-Ansicht in das Koordinaten-Fel klickt, poppt ein Koo-Eingabefenster auf, das dem entspricht, das im Goto-Fenster erscheint. Allerdings sollte es noch erweitert werden um die Möglichkeit, die Koordinaten einfach in _einem_ Textfeld einzugeben.

Gruß,
Pfeffer.

PS: machst Du ein entsprechendes FR (mit Link hierher) auf? - danke!
 

Kalli

Geowizard
Daran hatte ich auch schon gedacht (die Sache mit dem Eingabedialog). Die Sache mit dem _einem_ Eingabefeld ist vielleicht nicht so glücklich, weil man dann wieder parsen muss (Bilbowolf hat irgendwo mal was mit Regex gezaubert).
Ansonsten ist es recht einfach umzusetzen, da es für dieses Eingabefeld eine eigene Klasse gibt.
 
OP
G

greiol

Geoguru
also fürs erste würde es mir schon reichen, wenn statt auf ein einzelnes whitespace auf "ein oder mehrere" whitespaces als trenner geprüft würde. allerdings kenne ich die java regex enige nicht ghut genug um beurteilen zu können ob das geht.
 

Kalli

Geowizard
Bisher geschieht das Parsen in einer Methode, die alles andere als stabil läuft und sehr zickig reagiert, wenn die Eingabedaten nicht korrekt sind. Habe gerade mal in den Code geschaut, pfeffer hat schon mal den Vorschlag gemacht, diesen Code durch regex zu ersetzten, Bilbowolf hatte die Idee schon vor längerer Zeit, damals hatten wir die regex-Klasse noch nicht.

Der Regex-String, der woanders benutzt wird, sieht so aus (ich habe einen Zeilenumbruch wegen der Lesbarkeit eingefügt):
Code:
(N|S).*?([0-9]{1,2}).*?([0-9]{1,3})(,|.)([0-9]{1,3}).*?
(E|W).*?([0-9]{1,2}).*?([0-9]{1,3})(,|.)([0-9]{1,3})
Ich würde mal sagen, dass sieht nach normalem Regex aus (soweit man bei Regex von "normal" sprechen kann). Beim genaueren draufschauen müsste da auch noch ein Fehler drin sein, da die Ost-West-Koordinaten ja dreistellig werden können.

Ich habe mir den Featurerequest mal gegriffen. Ich würde es so umsetzen, dass es zum einen ein Eingabedialog wie bei Goto gibt, zum anderen aber auch die Koordinaten per Copy and Paste rübergezogen werden können.

Dazu gleich eine Frage:
Wäre es da nicht geschickt, gleich einen Button "Einfügen" bei dem Dialog unterzubringen, anstatt ein Feld zu machen, in dem man die Koordinaten per Copy einfügen muss?
 

pfeffer

Geowizard
ja, Du hast recht. wer will schon alles tippen - man braucht das Eingabefeld nur zum einfügen - und: evtl. zum kopieren.
Also zwei Buttons im Dialog wären voielleicht gut: Koos einfügen und Koos kopieren.

Gruß,
Pfeffer.
 

Reini

Geocacher
Ich würde den RegEx wie folgt modifizieren (wieder mit eingefügtem Zeilenumbruch):
Code:
(N|S)[^0-9]*?([0-9]{1,2})[^0-9]*?([0-9]{1,3})[,\.]([0-9]{1,3})[^0-9EW]*?
(E|W)[^0-9]*?([0-9]{1,3})[^0-9]*?([0-9]{1,3})[,\.]([0-9]{1,3})

Ich habe folgende Änderungen gemacht:

  • Die Leerzeichen konsumierenden Punkte ersetzt durch
    Code:
    [^0-9]
    bzw durch
    Code:
    [^0-9EW]
    Dadurch wird vermieden, daß Strings mit zu vielen Ziffern geparst werden (weil die überzählige Ziffer durch den Punkt gematcht wird)

  • Weiters die Dezimaltrennzeichen
    Code:
    (,|.)
    ersetzt durch
    Code:
    [,\.]
    Durch die eckige Klammer wird das Dezimaltrennzeichen nicht gespeichert. Weiters muß der Punkt durch ein vorgestelltes \ "escaped" werden, da er sonst jedes Zeichen matcht.

  • Schlußendlich die von Kalli vorgeschlagene Änderung mit den drei Ziffern für die östliche/westliche Länge.
Habe es noch nicht ausführlich getestet - bitte um Rückmeldung.
 

pfeffer

Geowizard
jou, RegEx sieht gut aus.
Ich würde nur mehr Nachkommastellen zulassen, also:
Code:
(N|S)[^0-9]*?([0-9]{1,2})[^0-9]*?([0-9]{1,3})[,\.]([0-9]{1,8})[^0-9EW]*?(E|W)[^0-9]*?([0-9]{1,3})[^0-9]*?([0-9]{1,3})[,\.]([0-9]{1,8})

schön wäre es natürlich, wenn man alternativ auch rein dezimal eingeben könnte oder mit Sekunden... (vielleicht sogar UTM, aber das ist mir eigentlich wurscht)

Auf jeden Fall sollte eine Meldung erscheinen, wenn die Koos nicht interpretiert werden konnten, die angibt, in welchem Format die Koos eingegeben werden müssen (ich glaub, irgendwo schon so eine Messagebox eingebaut zu haben)

Gruß,
Pfeffer.
 

Reini

Geocacher
EIgentlich müßte es möglich sein diesen RegEx in eine nicht speichernde Klammer zu setzen also
Code:
(?:dieserRegEx)
dann dahinter ein ODER
Code:
|
und die weiteren Muster für dezimal, UTM usw., alle jeweils innerhalb einer nicht speichernden Klammer und durch ein ODER getrennt.

Die Unterscheidung welche Art von Koordinaten eingegeben wurden kann anhand der Anzahl der Ergebnisse bzw. des Typs der Ergebnisse erfolgen.

So kann ein Regexp alle gewünschten Koordinatenformate parsen.
 

Carsten

Geowizard
Reini schrieb:
Code:
(E|W)[^0-9]*?([0-9]{1,3})[^0-9]*?([0-9]{1,3})[,\.]([0-9]{1,3})

Das läßt aber Ost-West-Koordinaten von 000 bis 999 zu. Sollte eher so sein, oder? (ohne jetzt in ein schlaues Regex-Buch geguckt zu haben *g*)

Code:
(E|W)[^0-9]*?([0]{0,1}[0-9]{1,2}|[1][0-7][0-9]|[1][8][0])[^0-9]*?([0-9]{1,3})[,\.]([0-9]{1,3})
 

Kalli

Geowizard
Boah, da bin ich richtig froh, die Regex gepostet zu haben (ohne Scherz). Gott-Sei-Dank habe ich hier ein Tool, um die Regex ausprobieren zu können. Ich baue auf alle Fälle mal das Grundgerüst, so dass schon mal was funktioniert, Verfeinerungen können dann durch die Regex-Könige vorgenommen werden :D
 

Reini

Geocacher
@Carsten: Du hast natürlich recht, daß man mit der RegEx auch noch weitere Plausibilitätsprüpfungen machen kann (ginge auch für N|S Werte über 90 Grad). Ich mache das aber lieber im Programm, weil es doch deutlich übersichtlicher ist.

Da Du dich bei den RegExen offensichtlich auskennst, könntest Du vielleicht den RegEx so erweitern, daß er auch das Dezimal und UTM Format parsen kann und das Ergebnis hier posten?
 

Carsten

Geowizard
Reini schrieb:
Da Du dich bei den RegExen offensichtlich auskennst,

Sorry, aber da hast du einen falschen Eindruck von mir gekriegt ;) Ein paar Basics verstehe ich, aber das wars dann (leider) auch. Wenn ich bei Opencaching was damit mache, artet es regelmäßig in eine elendige Rumprobierei aus.
 

Kalli

Geowizard
Passend zum Thema: Ich bin mal auf Kodos gestossen, damit kann man ganz gut seine Regex ausprobieren, bevor man das mühselig im Programm macht.
 

Reini

Geocacher
Ich habe mich gestern Nacht noch etwas gespielt. Hier ist jetzt der definitive (?) RegEx
Code:
 (?:^
    ([NSns])\s*([0-9]{1,2})[\s°]+([0-9]{1,3})[,.]([0-9]{1,8})
         \s*
    ([EWew])\s*([0-9]{1,3})[\s°]+([0-9]{1,3})[,.]([0-9]{1,8})
 $)|
 (?:^
    ([+-]?[0-9]{1,2})[,.]([0-9]{1,6})
         (?:(?=\+)|(?=-)|\s+|\s*°\s*)
    ([+-]?[0-9]{1,3})[,.]([0-9]{1,6})\s*[°]?
 $)|
 (?:^
    ([0-9]{1,2}[C-HJ-PQ-X])
         \s*
    ([0-9]{1,7})
         \s+
    ([0-9]{1,7})
$)
Zur besseren Lesbarkeit habe ich Zeilenumbrüche und Leerzeichen eingefügt. Im Java code müssen die \ noch durch \\ ersetzt werden.

Dieser RegEx kann folgende Angaben parsen
Code:
N1 12.123 E34.345               Standard 
N1 12.123 E34,345				   Mit anderem Dezimaltrennzeichen
S99 60.2345 W180 65.34534	    Gradwerte über 89, Minuten über 59 im Programm eliminieren
n1 1.0 E12 34.344563  		    Kleinschrift ist erlaubt
N1 12.1234    E12 34.3456       Zusätzliche Leerzeichen
N1 12.1234E12 34.3456           Keine Leerzeichen
N1° 12.1234 E12°34.345          Mit Gradangabe
N1° 12.1234E12°34.345           Mit Gradangabe ohne Leerzeichen
12.3456 23.4567					  Dezimalgradangabe
12.3456° 23.4567° 				  Dezimalgradangabe mit Grad
12.3456°23.4567  ° 				 Dezimalgradangabe mit Grad ohne Leerzeichen
-12.3456 23.4567				    Dezimalgradangabe
12.3456 -23.4567				    Dezimalgradangabe
-12.345668 -23,456734			  Dezimalgradangabe mit Komma
12.3456-23.4567					  Dezimalgradangabe ohne Leerzeichen
12.3456+23.4567					  Dezimalgradangabe ohne Leerzeichen
91.2345 180.23456				   Gradwerte auf Plausibilität prüfen
91.2345    180.23456            Zusätzliche Leerzeichen
32U 2345234 8902345				 UTM Koordinaten
32U   2345234  8902345			 UTM Koordinaten zusätzliche Leerzeichen
14X 1 2							    Auch OK

Folgende Koordinatenangaben führen zu einem Fehler
Code:
N1 1.0 E12 34.345634563  		 Zu viele Nachkommastellen
1 1.0 E12 34.345634563  		  Keine Nord/Südangabe
E12 34.3456 N1 12.1234 			Breite und Länge vertauscht
S199 60.2345 W180 65.34534		Südliche Breite hat zuviele Stellen
S99 60.2345 W1180 65.34534		Westliche Länge hat zuviele Stellen
  N1 12.123 E34.345				 Leerzeichen am Anfang
12.3456 - 23.4567				   Leerzeichen zwischen Minus und Zahl
N12.3456 E32.2345				   Mischform zwischen Standard und Dezimalschreibweise
32I 2345234 8902345				 I ist nicht erlaubt
32U 2345234 89023456			   UTM Koordinaten zuviele Stellen
32U 23452344 8902345			   UTM Koordinaten zuviele Stellen
32x 23452344 8902345			   Kleinschrift nicht erlaubt
32 U 2345234 8902345			   Extra Leerzeichen vor U
32U 2345234°  8902345			  Überzähliges Gradzeichen
Wichtig ist führende und nachfolgende Leerzeichen zu entfernen ehe man den String an den RegEx übergibt (da ging mir dann die Zeit aus).

@Kalli: Ich schicke Dir per PN eine RegExTester Klasse, die alle diese Muster automatisiert testet, falls Du noch zusätzliche Testdaten prüfen willst.
 

Kalli

Geowizard
@Reini: Habe deine PN erhalten, vielen Dank. Ich werde wie gesagt das Framework machen und deine RegEx einbauen. Dann kann noch verfeinert werden.
 

Reini

Geocacher
Es gibt halt nichts Definitives. Daher hier noch eine verbesserte Version der RegEx
Code:
(?:
([NSns])\s*([0-9]{1,2})[\s°]+([0-9]{1,2})(?:\s+([0-9]{1,2}))?[,.]([0-9]{1,8})\s*
([EWew])\s*([0-9]{1,3})[\s°]+([0-9]{1,2})(?:\s+([0-9]{1,2}))?[,.]([0-9]{1,8})
)|(?:
  ([+-]?[0-9]{1,2})[,.]([0-9]{1,6})(?:(?=\+)|(?=-)|\s+|\s*°\s*)([+-]?[0-9]{1,3})[,.]([0-9]{1,6})\s*[°]?
)|(?:
   ([0-9]{1,2}[C-HJ-PQ-X])\s*[Ee]?\s*([0-9]{1,7})\s+[Nn]?\s*([0-9]{1,7})
)

Diese Version kann jetzt die Formate DD.DDD (=Dezimal), DD MM.MMM (=CW Standard), DD MM SS.SSS und UTM parsen. Sie müßte auch (noch nicht getestet) in der Lage sein aus dem HTML Code einer Webseite alle Koordinaten herauszufiltern.


@Kalli: Update vom RegexTester per PN unterwegs.

Ich würde gerne in CW sehen, daß wir überall wo Koordinaten verwendet werden, den CWPoint Typ einsetzen (anstatt von 6 oder mehr Variablen). Wenn dann die Eingabe über nur mehr ein Feld erfolgt, würde das einiges vereinfachen (die Anzeige kann ja immer im vom Benutzer bevorzugten Format erfolgen).
 

Kalli

Geowizard
Reini schrieb:
Ich würde gerne in CW sehen, daß wir überall wo Koordinaten verwendet werden, den CWPoint Typ einsetzen (anstatt von 6 oder mehr Variablen). Wenn dann die Eingabe über nur mehr ein Feld erfolgt, würde das einiges vereinfachen (die Anzeige kann ja immer im vom Benutzer bevorzugten Format erfolgen).
Ich auch :D Ich hatte auch schon mal etwas aufgeräumt, an die Präferenzen hatte ich mich nicht so richtig rangetraut. Sowie ich ein gutes Gefühl mit der Regex habe, würde ich innerhalb von ParseLatLon.java auch auf den Typ CWPoint umstellen. Besser wäre natürlich, ParseLatLon zu eleminieren, habe gerade mal nachgeschaut, es betrifft haupsächlich die Exporter.
 

pfeffer

Geowizard
Code:
(?:
([NSns])\s*([0-9]{1,2})[\s°]+([0-9]{1,2})(?:\s+([0-9]{1,2}))?[,.]([0-9]{1,8})\s*
([EWewOo])\s*([0-9]{1,3})[\s°]+([0-9]{1,2})(?:\s+([0-9]{1,2}))?[,.]([0-9]{1,8})
)|(?:
  ([+-NnSs]?[0-9]{1,2})[,.]([0-9]{1,8})(?:(?=\+)|(?=-)|\s+|\s*°\s*)([+-WwEeOo]?[0-9]{1,3})[,.]([0-9]{1,8})\s*[°]?
)|(?:
   ([0-9]{1,2}[C-HJ-PQ-X])\s*[EeOo]?\s*([0-9]{1,7})\s+[Nn]?\s*([0-9]{1,7})
)
so akzeptiert er auch im Dezimalformat statt +- auch N/S und W/E und O für deutsch Osten. Außerdem habe ich die Anzahl der maximal akzeptierten Dezimalstellen auf immer 8 erhöht.
Ich hoffe dabei keinen Fehler eingebaut zu haben...

Gruß,
Pfeffer.
 
Oben