# suche über PLZ/Umkreis



## lifehunter (15. Juni 2005)

Ich habe gesucht aber nichts richtiges gefunden.
Ich möchte bei mir eine Suchfunktion einbauen mit der man Leute über die PLZ suchen kann. Einfach nur über PLZ ist einfach, ich will aber das im Umkreis den man angeben kann (5/20/50/100/175/250km) in dem geuscht werden soll.
Wie muss das programmiert werden?
Ich habe gesehen das man es irgendwie so gemacht kann das jede PLZ in dem Umkreis einzeln abgefragt wird. Aber das geht auch einfacher oder?
Wenn jemand weiß wies geht wäre es super wenn hier ma so ne kleine Beschreibung reingeposted werden wird 

MfG


----------



## hpvw (15. Juni 2005)

Du musst natürlich wissen, an welchen geographischen Koordinaten die einzelnen Postleitzahlen stehen. Dazu gibt es zum Beispiel die OpenGeoDB.

Dann musst Du die Entfernung berechnen und mit der vorgegebenen Distanz vergleichen.
Dazu kannst Du Dir mal diesen Thread durchlesen.
Das ist jedoch ziemlich rechenzeitaufwändig.
Du könntest Dir mit so einer Funktion auch eine Entfernungsmatrix berechnen und das Ergebnis cachen.
Evtl. sind die Entfernungen sogar über die OpenGeoDB effizienter zu ermitteln.

Gruß hpvw


----------



## lifehunter (15. Juni 2005)

Muss OpenGeoDB nicht PEARL oder sowas unterstützt werden?


----------



## Dr Gonzzo (7. September 2005)

Hi Leutz,

Ich hab jetzt bald das ganze Forum nach diesem Thema durchsucht und der Vorschlag mit der Entfernungsmatrix scheint mir bis jetzt der erste elegante Ansatz zu sein.
Die meisten Beiträge zu dem Thema schweifen irgendwie von der Umkreissuche ab und laufen im Endeffekt auf die Distanzberechnung zwischen zwei Orten hinaus. :suspekt: 

Ich benutze auch die OpenGeoDB und das mit der Entfernungsberechnung haut auch schon hin, aber wie bekomm ich die Liste mit den Datentuppeln die im Umkreis liegen.
Bisher habe ich noch keinen wirklich konkreten Lösungsvorschlag gefunden.
Könntest du deine Idee vielleicht etwas genauer Ausführen? 

Vielen Dank schon mal 

PS: Damit mir keine Klagen kommen, ich benutze MS SQLServer2000 als DBMS


----------



## hpvw (7. September 2005)

Wie angedeutet, erhältst Du so eine Liste mit irgendeiner Art von Caching-Mechanismus.
Wenn sich ein neuer User mit PLZ anmeldet, wirst Du wohl oder übel die Distanz zu allen anderen Usern berechnen müssen und kannst diese in einer Tabelle mit drei Feldern (User1, User2, Distanz) ablegen.
Wenn Du sehr viele User hast, kann das Anlegen eines neuen auf diese Weise natürlich unglaublich lange dauern.
Eine weitere Möglichkeit wäre, dass Du ein Raster über die Karte legst, zum Beispiel alle 50km entsprechend der Geokoordinaten zu der Postleitzahl. In einer Tabelle (PLZ, GeoLat, GeoLon, RasterX,RasterY) ordnest Du jede PLZ in einen Quadranten ein. Wenn Du nun eine Umkreissuche machst, suchst Du zunächst nur die PLZ heraus, die nach dem Raster überhaupt in Frage kommen. Damit hättest Du schon eine verhältnismäßig geringe Zahl von Postleitzahlen, zu denen Du die exakte Entfernung bestimmen mußt. Diese kannst Du dann live berechnen und ggf. zusätzlich cachen.

Vielleicht helfen Dir diese Anregungen ja weiter.

Gruß hpvw


----------



## Dr Gonzzo (7. September 2005)

Hi Leutz,

Der Vorschlag ist ganz gut. Allerdings brauche ich keine Abfrage nach Usern sondern nur die Orte im Umkreis. Ich verwende auch keine Map sondern brauch nur die Einträge aus der DB. Quasi genau das was hier angeboten wird. 
Nach deinem ersten Vorschlag müsste ich danach eine Tabelle mit (Ort1, Ort2, Entfernung) aufbauen, was allerdings (wie du schon erwähnt hast) nicht praktikabel ist, da die OpenGeoDB bereits fast 18000 Einträge hat! 
Hab mir auch schon überlegt so eine Art Vorselektion bzw. Rasterung durchzuführen z.B. nur im selben Bundesland+benachbarte Bundesländer suchen (ich weiß, das ist nicht gerade der Weisheit letzter Schluß) was ja schon mal eine Entlastung bringen würde. Ich denk da find ich schon noch eine gute Lösung.
Allerdings habe ich auch beim Rastern das Problem: was mach ich mit Orten, die nahe am Rand des Rasters liegen? Dann muss ich auch wieder die "Nachbarn" miteinbeziehen oder hab ich dich falsch verstanden?
Kannst du mir das mit dem Caching-Mechanismus noch erklären? Hab noch nicht so viel praktische Erfahrungen mit DBs und bin dementsprchend etwas  

Grüße


----------



## hpvw (7. September 2005)

Du hast recht, wenn Du ein 50km-Raster hast und Orte im Umkreis von 50 Kilometern suchst, mußt Du auch benachbarte berücksichtigen. Angenommen, Dein Ort (Ort 0) liegt im Quadranten 3/4, dann musst Du mit den Orten aus den Quadranten 2/3, 3/3, 4/3, 2/4, 4/4, 2/5, 3/5 und 4/5 prüfen. Die Orte aus 3/4 kannst Du direkt übernehmen, wenn Du in Kauf nimmst, dass von der Ecke des Quadranten zur gegenüberliegenden Ecke etwas mehr als 50km liegen.

Nun hast Du eine Liste mit zu prüfenden Orten, nehmen wir Ort 1, Ort 2 und Ort 3.

Aus der angesprochen Cache-Tabelle holst Du Dir die Distanz zu den Ortepaaren Ort 0/Ort 1, Ort 0/Ort 2, Ort 0/Ort 3, vorrausgesetzt, es gibt sie schon und vergleichst sie mit dem gegebenen Umkreis. Die Ortepaare, die Du nicht aus der Tabelle holen konntest, berechnest Du und schreibst sie in die Tabelle.

Gruß hpvw


----------



## low-group (7. September 2005)

wenn du die Geo-Daten in der DB hast könntest du doch diese Daten irgendwie ausrechnen. Die Entfernung kann man so berechnen, wie in diesem Beispiel erklärt:

http://www.dl-qrp-ag.de/pdf/locator2.pdf


----------



## hpvw (7. September 2005)

Was mir noch einfällt: Du musst gar kein Raster bilden, Du kannst die zu prüfenden Orte auch wie folgt ermitteln (in Kürze, weil ich gleich weg muss):

```
latMin=Ort0Lat - 50km;
latMax=Ort0Lat + 50km;
lonMin=Ort0Lon - 50km;
lonMax=Ort0Lon + 50km;

SELECT Lat,Lon,PLZ 
FROM Orte 
WHERE Lat>latMin
  AND Lat<latMax
  AND Lon>lonMin
  AND Lon<lonMax
```
Was dann zu tun ist (Distanz bererchnen und cachen) bleibt wie oben.

Gruß hpvw


----------



## Mik3e (7. September 2005)

Diese Logik der Distanzmessung müsste sich ja eigentlich auch auf mein Sitzplatz Problem anwenden lassen, oder?
Nur die Erdkrümmung kann man vernachlässigen...
http://www.tutorials.de/tutorials219794.html


----------



## Dr Gonzzo (7. September 2005)

Das ist natürlich eine sehr simple Lösung ;-] 
So weit war ich allerdings auch schon. Leider ist mir das zu ungenau. Soll schon eine Umkreissuche und keine "Umquadratsuche"    
Trotzdem THX

Dr Gonzzo


----------



## hpvw (8. September 2005)

Dr Gonzzo hat gesagt.:
			
		

> Leider ist mir das zu ungenau. Soll schon eine Umkreissuche und keine "Umquadratsuche"


Ich wollte auch keine "Umquadratsuche" machen. Es ist nur so, dass vier Additionen bzw. Substraktionen plus vier größer/kleiner Vergleiche in der Datenbank relativ einfach zu implementieren sind, im Gegensatz zu der Geschichte mit den Quadranten.
Die "Umquadratsuche" soll nur dazu dienen, die PLZs einzugrenzen, die man genauer unter die Lupe nehmen muss, da die Berechnung der geografischen Distanz mit viel Sinus und Kosinus relativ langsam ist und durch die Eingrenzung nicht so häufig gemacht werden muss.



			
				Mik3e hat gesagt.:
			
		

> Diese Logik der Distanzmessung müsste sich ja eigentlich auch auf mein Sitzplatz Problem anwenden lassen, oder?
> Nur die Erdkrümmung kann man vernachlässigen...


Ich wüßte nicht wie. Dein Problem ist ein komplexes Optimierungsproblem, während hier nur zwei Orte miteinander verglichen werden. Ich habe ja versucht, Deine Bedingungen in der Distanzmatrix zu berücksichtigen, aber die Distanzen sind bei Dir das kleinste Problem.

Gruß hpvw


----------



## Mik3e (8. September 2005)

@hpvw:
Ich gehe das Problem nun anders (simpler) an...
Ich versuche immr nebeneinanderliegende Plätze zu finden....

Angenommen der User möchte 8 Plätze->
1. System prüft, ob in einer Reihe noch 8 Plätze nebeneinander vorhanden sind.
Wenn nicht wird die Anzahl halbiert
8 -> 4 / 4

2. System prüft, ob 4 Plätze in einer Reihe nebeneinander vorhanden sind. Wenn nicht, werden wieder beide Zahlenwerte halbiert usw...
Das geht dann hinuter bis auf 1...

Also
Suche 8
Suche 4 | 4
Suche 2 | 2 | 2 | 2
Suche 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1

Von der Lösung her ist das absolut ok..
Nur mit der Performance muss ich mir noch etwas überlegen (im schlechtesten Fall muss er bei 8 gesuchten Plätzen den array 14x durchlaufen...).

Was hältst Du von der Logik?

LG
Mike


----------



## Dr Gonzzo (9. September 2005)

Hi Leutz,

@lifehunter
Vielleicht hilft dir dieser thread weiter
http://www.tutorials.de/tutorials217768.html 

bis denne
Dr. Gonzzo


----------



## diggity (9. September 2005)

Mik3e hat gesagt.:
			
		

> (im schlechtesten Fall muss er bei 8 gesuchten Plätzen den array 14x durchlaufen...).
> 
> Mike



Und wie lange dauert das in deinem Fall? Wird wohl noch minimal sein, oder?


----------



## peterhammer70 (1. Oktober 2010)

Hallo,
für den professionellen Einsatz halte ich allerdings die opengeodb nicht für ausreichend, da der Datenbestand weit davon entfernt ist vollständig zu sein und auch einige falsche Koordinaten enthält.
Habe mir einige kommerzielle Anbieter angeschaut: http://www.plz-umkreis.com war zwar nicht der günstigste, dafür der einzige dessen daten vollständig und auch korrekt zu sein scheinen. (in zusammenarbeit mit den de / at / ch post behörden). und man bekommt noch freie scripts und updates sind ebenfalls unbegrenzt frei.
Günstiger ist noch geopostcodes.com, allerdings fehlten postleitzahlen und viele verschiedene plz verfügen über die gleichen long/werte, sind also ganz offensichtlich falsch. und mit updates war da auch nix.
Liebe Grüße Jens


----------

