Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Umkreissuche: Behandlung von ungültigen Postleitzahlen, leeren und Nonsense Suchanfragen #105

Open
arno1979 opened this issue Jan 26, 2018 · 8 comments

Comments

@arno1979
Copy link

arno1979 commented Jan 26, 2018

Hallo Alexander,

wir sind beim durchtesten unserer Umkreissuche gerade auf ein paar Phänomene gestoßen.
Und zwar haben wir einfach mal eine Postleitzahl in das Suchfeld eingegeben von der wir wussten, dass sie tatsächlich nicht existiert. Also z.B. 74567.
Da würde man ja erwarten, dass man entsprechend entweder eine Fehlermeldung oder eben keine Ergebnisse angezeigt bekommt.
Dem ist aber nicht so: In unserem Fall bekommen wir einen Treffer zurück und zwar ein Ergebnis aus der Stadt Eisenach in Thüringen. Ich habe mir daraufhin mal die Request-Strings und deren Rückmeldung angeschaut, die an Google geschickt werden.

Hier mal zwei Beispiele, eins mit gültiger eins mit ungültiger Postleitzahl.

Ungültig:
https://maps.googleapis.com/maps/api/geocode/json?address=74567%2CDeutschland&key=AIzaSyCP87Cdoi4utRpu3AhY2l-zEF_PNBAEQEA&language=en&region=2
Antwort:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Germany",
               "short_name" : "DE",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "Germany",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 55.0815,
                  "lng" : 15.0418962
               },
               "southwest" : {
                  "lat" : 47.2701115,
                  "lng" : 5.8663425
               }
            },
            "location" : {
               "lat" : 51.165691,
               "lng" : 10.451526
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 55.0815,
                  "lng" : 15.0418962
               },
               "southwest" : {
                  "lat" : 47.2701115,
                  "lng" : 5.8663425
               }
            }
         },
         "place_id" : "ChIJa76xwh5ymkcRW-WRjmtd6HU",
         "types" : [ "country", "political" ]
      }
   ],
   "status" : "OK"
}

Gültig:
https://maps.googleapis.com/maps/api/geocode/json?address=22767%2CDeutschland&key=AIzaSyCP87Cdoi4utRpu3AhY2l-zEF_PNBAEQEA&language=en&region=2
Antwort:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "22767",
               "short_name" : "22767",
               "types" : [ "postal_code" ]
            },
            {
               "long_name" : "Hamburg",
               "short_name" : "Hamburg",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Hamburg",
               "short_name" : "HH",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "Germany",
               "short_name" : "DE",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "22767 Hamburg, Germany",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 53.561253,
                  "lng" : 9.963013999999999
               },
               "southwest" : {
                  "lat" : 53.5412251,
                  "lng" : 9.924121000000001
               }
            },
            "location" : {
               "lat" : 53.5488885,
               "lng" : 9.942607299999999
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 53.561253,
                  "lng" : 9.963013999999999
               },
               "southwest" : {
                  "lat" : 53.5412251,
                  "lng" : 9.924121000000001
               }
            }
         },
         "place_id" : "ChIJH_n5ynyPsUcRgPX5xPU9Jhw",
         "types" : [ "postal_code" ]
      }
   ],
   "status" : "OK"
}

In beiden Fällen werden ja Geo-Koordinaten von der Google API zurück geliefert, die dann vom Catalog Manager verarbeitet werden. Was die API nämlich offensichtlich macht ist, dass sie bei einer ungültigen Postleitzahl einfach den ungefähren Landesmittelpunkt (Land kennt sie ja) zurück liefert. Eisenach liegt nämlich echt ziemlich genau in der Mitte von Deutschland (wie ich gerade gelernt habe).

Ich frage mich, ob du es für möglich und sinnvoll hältst, diese Art von Ergebnissen abzufangen. Wenn man sich z.B. in den json Ergebnissen mal den Wert für den "types" Key ansieht, könnte man den u.U. abfragen und nur "postal_code" (für Postleitzahlen) und "locality" (für Ortsnamen) als gültig akzeptieren. Oder man schließt "country" aus?

Ich bin jetzt auch noch nicht so tief in das Thema eingestiegen. Mich interessiert natürlich auch deine Meinung dazu, kann ja sein, dass du an anderer Stelle auch schon mal mit dem Phänomen zu tun hattest.

Dazu kommen noch zwei weitere Fälle:

  1. Leere Suchanfragen
    Schickt man das Suchformular für die Umkreissuche leer ab, werden alle möglichen Ergebnisse zurückgeliefert. Dieses Verhalten würde ich eher nicht erwarten, sondern, dass dann keine Suchergebnisse zurückgeliefert werden. Ich habe das in der Funktion getCords nachverfolgt und festgestellt, dass in einem solchen Fall wohl auch gar kein Request an die Google API ausgeführt wird.
    Das sollte sich dann doch entsprechend auch in den Suchergebnissen mit einem leeren Ergebnis niederschlagen, oder?

  2. Nonsense Suchanfragen
    Schickt man z.B. einen Suchanfrage mit dem Begriff "ölkasdölkasd" ab, dann liefert die Google API folgendes JSON zurück:

{
   "results" : [],
   "status" : "ZERO_RESULTS"
}

Der Catalog Manager zeigt aber wieder alle Einträge an. Auch hier würde ich von einer leeren Ergebnisliste ausgehen.

Viele Grüße
Arno

@arno1979 arno1979 changed the title Umkreissuche: Behandlung von ungültigen Postleitzahlen Umkreissuche: Behandlung von ungültigen Postleitzahlen, leeren und Nonsense Suchanfragen Jan 26, 2018
@alnv
Copy link
Owner

alnv commented Jan 29, 2018

Um die Umkreissuche einzuschränken kannst du weitere Ortseingabe im einem Verstecktem-Feld übergeben. Beim "Freizeitparks" Beispiel auf der Demoseite wird das Land ("Deutschland") zusätzlich zu der Postleitzahl mit übergeben. Damit soll eine ungültige PLZ abgefangen werden.

Vor kurzem habe ich ein Bugfix hochgeladen, da wird ein Problem mit dem "Verstecktem-Feld" gelöst.

Leere Suchanfrage werden vom Catalog Manager nicht berücksichtigt. Schließlich ist es ein Filter und keine Suche… Eine Option kann ich dennoch implementieren.

Nonsense = leere Suchanfrage. Hier wäre eine Validierung ganz sinnvoll, denke ich.

@arno1979
Copy link
Author

Hallo Alexander,
danke für deine Antworten!

Ich habe das mit dem versteckten Feld ausprobiert: Das macht keinerlei Unterschied. Der Request String für die API bleibt auch gleich und wie du in meinem Beispiel oben sehen kannst ist "Deutschland" ja auch schon Teil des Request Strings.

Was sich allerdings durch einen deiner letzten Commits geändert zu haben scheint:
Die Suche nach der nicht existierenden Postleitzahl "74567" ergibt jetzt keine Ergebnis mehr. Das ist super! Die Suche nach "00000" ergibt allerdings immer noch das eine Ergebnis "Eisenach", obwohl es die Postleitzahl natürlich auch nicht gibt. Vielleicht kannst du da ja noch mal nachsehen?

Leere Suchanfrage werden vom Catalog Manager nicht berücksichtigt. Schließlich ist es ein Filter und keine Suche… Eine Option kann ich dennoch implementieren.

Okay, der Argumentation kann ich folgen. Eine Option wäre natürlich super.

Ich habe versucht eine Validierung für das Feld zu aktivieren, aber das funktioniert nicht.
Das Formular für die Umkreissuche kommt bei mir ja aus Contao Formulargenerator und wenn ich da eine Validierung nach z.B. Alphanumerischen Zeichen aktiviere, reicht er das auch durch, wenn man das Feld leer abschickt. Aber das ist ja eine Contao-Sache und hat nichts mit dem Catalog-Manager zu tun.

Vielen Dank erstmal!
Arno

@Schmidty2
Copy link

Ich fände es gut, wenn bei ungültigen Postleitzahlen oder im Falle, dass kein Filterergebnis vorhanden ist, eine (frei definierbare) Meldung ausgegeben wird und der Focus der Karte stehen bleibt und nicht auf den Deutschland-Mittelpunkt gesetzt wird.

@alnv
Copy link
Owner

alnv commented Jan 31, 2018

So ganz funktioniert die Google API nicht. Wenn du "0000 Deutschland" abfragst, sagt Google:
ich weiß zwar nicht was du mit "0000" meinst aber hey hier ist "Deutschland" :)
Dementsprechend gibt Google die Koordinaten für Deutschland zurück. Catalog Manager übernimmt diese und startet seinen Abfrage.

Um Postleitzahlen nach Gültigkeit zu prüfen ist die Google Api nicht geeignet. Hierfür benötigen wir einen anderen Service bzw. Datenbank mit allen möglichen Postleitzahlen.

@Schmidty2 Die Meldung gibt es ja bereits. Nur es kommen immer irgendwelche Ergebnisse, da Google in den meisten Fällen Koordinaten zurück gibt.

@arno1979
Copy link
Author

arno1979 commented Feb 2, 2018

Ich hatte jetzt noch mal Zeit mir die Responses der Google API nach deinen Änderungen anzusehen.
Ich habe nämlich bemerkt, dass meine Aussage, dass jetzt bei nicht existierenden Postleitzahlen auch keine Ergebnisse angezeigt werden leider nicht ganz stimmt.

Ich bekomme bei der Suche nach "11111" manchmal keine Ergebnisse und manchmal eben doch noch "Eisenach".

Das liegt daran, dass die Response leider bei gleicher Suchabfrage nicht immer identisch ist.
Es gibt zwei Varianten:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "11111",
               "short_name" : "11111",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Germany Road",
               "short_name" : "Germany Rd",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Fenton",
               "short_name" : "Fenton",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Tyrone Township",
               "short_name" : "Tyrone Township",
               "types" : [ "administrative_area_level_3", "political" ]
            },
            {
               "long_name" : "Livingston County",
               "short_name" : "Livingston County",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "Michigan",
               "short_name" : "MI",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "United States",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "48430",
               "short_name" : "48430",
               "types" : [ "postal_code" ]
            },
            {
               "long_name" : "9467",
               "short_name" : "9467",
               "types" : [ "postal_code_suffix" ]
            }
         ],
         "formatted_address" : "11111 Germany Rd, Fenton, MI 48430, USA",
         "geometry" : {
            "location" : {
               "lat" : 42.7156133,
               "lng" : -83.7411554
            },
            "location_type" : "RANGE_INTERPOLATED",
            "viewport" : {
               "northeast" : {
                  "lat" : 42.7169622802915,
                  "lng" : -83.73980641970849
               },
               "southwest" : {
                  "lat" : 42.71426431970851,
                  "lng" : -83.74250438029151
               }
            }
         },
         "partial_match" : true,
         "place_id" : "EicxMTExMSBHZXJtYW55IFJkLCBGZW50b24sIE1JIDQ4NDMwLCBVU0E",
         "types" : [ "street_address" ]
      }
   ],
   "status" : "OK"
}
{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "Germany",
               "short_name" : "DE",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "Germany",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 55.0815,
                  "lng" : 15.0418962
               },
               "southwest" : {
                  "lat" : 47.2701115,
                  "lng" : 5.8663425
               }
            },
            "location" : {
               "lat" : 51.165691,
               "lng" : 10.451526
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 55.0815,
                  "lng" : 15.0418962
               },
               "southwest" : {
                  "lat" : 47.2701115,
                  "lng" : 5.8663425
               }
            }
         },
         "place_id" : "ChIJa76xwh5ymkcRW-WRjmtd6HU",
         "types" : [ "country", "political" ]
      }
   ],
   "status" : "OK"
}

Bei der ersten Response wird dann kein Ergebnis angezeigt, was aber nur daran liegt, dass die API da ein Ergebnis aus den USA zurück liefert und bei einem Umkreis von 25km dann natürlich nichts gefunden wird.

Bei der zweiten Response wird dann wieder Deutschland richtig erkannt und entsprechend bei nicht valider Postleitzahl auf die geografische Mitte gemappt.

Was ich nicht verstehe: Wie können überhaupt Suchergebnisse von der API zurück geliefert werden, wenn als Land fest "Deutschland" angegeben ist?

@alnv
Copy link
Owner

alnv commented Feb 5, 2018

Ich denke, google hat sich was dabei gedacht :)

@arno1979
Copy link
Author

arno1979 commented Feb 7, 2018

Ich habe mir jetzt noch mal die API Dokumentation bei Google angesehen (https://developers.google.com/maps/documentation/geocoding/intro?hl=de#ComponentFiltering) und dort ist mir aufgefallen, dass man den Parameter components verwenden kann, um die Filterung eindeutig auf ein Land einzuschränken. Ein Request String würde dann z.B. so aussehen:

https://maps.googleapis.com/maps/api/geocode/json?address=11111,Deutschland&components=country:DE&key=API_KEY&language=en&region=2

Ich habe mir auch noch mal die Konfigurationsmöglichkeiten im Catalog Manager angesehen und in den Einstellungen meines Moduls vom Typ "Catalog Listenansicht" kann ich ja im Feld "Land" in der Legende "Umkreissuche-Einstellungen" eindeutig ein Land festlegen in dem von der Umkreissuche gesucht werden soll.

In der aktuellen Fassung deiner Klasse GeoCoding wird aber nur der Parameter address gesetzt. Damit wird es der Automatik der Google API überlassen genauer heraus zu finden, was mit dieser Angabe gemeint sein könnte. Und das führt aktuell zu nicht verlässlichen, weil variierenden Suchergebnissen.

Mein Vorschlag wäre also, dass WENN das Feld tl_module.catalogRadioSearchCountry gesetzt ist bzw. rs_cntry mit einer Landesangabe aus dem Formular übergeben wird, der Request String entsprechend um den Parameter components=country:COUNTRY erweitert wird.

@alnv
Copy link
Owner

alnv commented Feb 8, 2018

Vielen Dank für deine Mühe, dass werde ich nochmals prüfen und gegebenenfalls implementieren.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants