Postleitzahl/Ort - Umkreissuche

  • Hi,

    habe mir eine Umkreissuche gebastelt, da alle im Web angebotenen maximal 500 Einträge ausgeben und man nur bis zu 150km suchen kann.

    Anfangs wird eine *.txt eingelesen, mit den Daten (Plz, Ort, Koordinaten) und dann einzeln ausgerechnet und am Ende angezeigt.

    Eine Suche mit 1000km (alles ;)) dauert keine 10 Sekunden, schätze das ist verkraftbar!

    Spoiler anzeigen
    [autoit]

    €dit

    [/autoit]

    Die "Datenbank" einfach ins selbe Verzeichnis werfen :)

    P.S.: Die Daten sind etwas unglücklich exportiert geworden. Das heisst, dass 'lat' und 'lng' vertauscht sind, ist im Script aber berücksichtigt!
    PP.S.: Ich weiss, SQL wäre sehr viel schneller, hatte aber keine Lust wieder alles umzubasteln :rolleyes:

    Fixes:
    - Bei keiner Eingabe erfolgt eine Fehlermeldung
    - Suche kann jetzt nur 1x angeklickt werden, bis die Suche abgeschlossen ist.
    - Bei mehrfacher Suche wird das Ausgabefeld geleert.

    Edit: Quelle -> http://fa-technik.adfc.de/code/opengeodb/

    Gruß
    x0r

  • Habe leider keinen RAR-Packer, sonst würde ich ja gerne helfen. Kannst Du es mal als ZIP_Datei zur Verfügung stellen? Vielen Dnak.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Hi Alina,

    danke für den Tip mit zip statt rar, habs aktualisiert :)

    Helfen brauchst du hier nichts, das Teil ist fertig (bis auf vielleicht kleinere Bugs).
    Bastel grade an einer Version für komplett Europa - das kann ich dann allerdings nicht hochladen, weil die Datenbank viel zu groß wird :)

    Danke dir trotzdem! :D

    Gruß
    x0r

    Simon nörgelt, Simon nervt - aber Simon verbessert die Welt. Glaubt er.

  • Verbesserungsvorschläge:

    1.)
    Die Ausgabe des Suchergebniss so aufbauen, das alle Orte und Distanzen untereinander sind.

    2.)
    Das man sortieren kann nach Distanzen (z. B. kleinste als erstes).

    3.)
    Das man die Orte nach dem ABC sortieren kann.


    Fehler:

    Gibst Du z. B. als Ort "Tarup" ein, dann zeigt er folgendes an, wobei die roten alle falsch sind. Die roten sind Stadtteile von Flensburg.
    PLZ: Ort: Distanz:
    24939 Neustadt 3.97 km
    24939 Nordstadt 4.79 km
    24937 Friesischer Berg 4.66 km
    24941 Friesischer Berg 4.66 km
    24941 Südstadt 2.92 km
    24937 Südstadt 2.92 km
    24943 Sandberg 1.48 km
    24941 Sandberg 1.48 km
    24937 Sandberg 1.48 km
    24943 Jürgensby 1.65 km
    24937 Jürgensby 1.65 km
    24943 Fruerlund 2.46 km
    24937 Fruerlund 2.46 km
    24944 Mürwik 3.35 km
    24943 Engelsby 1.33 km
    24943 Tarup 0 km
    24943 Twedt 1.61 km
    24975 Ruhnmark 4.47 km
    24975 Rüllschau 3.6 km
    24999 Oxbüll 4.4 km
    24999 Rosgaard 4.73 km
    24999 Wees 4.11 km
    24999 Weesries 3 km

    Dieser Fehler ist überall, wo STädte mit mehr als eine Postleitzahl sind.

    Wo hast Du die Tabelle her? Ich kann Dir die PLZ-DVD von der Deutschen Post AG empfehlen und es da raus zu ziehen.

    Aber ansonsten, von der Idee eine schöne Sache.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • Hi Alina,

    die genannten Verbesserungsvorschläge hab ich mir auch schon überlegt, wird vermutlich in der nächsten "ganz Europa"-Version kommen :)

    Aber wieso sollte das ein Fehler sein?
    Wenn du "Tarup" und "5" eingibst, bringt er dir alle Ortschaften (inklusive Ortsteile, da andere Plz) im UMKREIS von 5km um Tarup, somit ist das doch in Ordnung?

    Danke & Gruß
    x0r

    Simon nörgelt, Simon nervt - aber Simon verbessert die Welt. Glaubt er.

  • Nein, es ist nicht okay, da es nicht "24939 Neustadt" heißen sollte, sondern "24939 Flensburg Neustadt".
    Es gibt Stadtteile, die irgendwo in Deutschland auch Ortsnamen sind und somit ist es dann falsch. ;)


    EDIT:
    In der Anlage eine Datei mit den PLZ und den Orten dazu.
    Leider fehlt bei den PLZ mit einer "0" vorne, diese. Also sind da die PLZ nur vierstellig, was aber schnell via Autoit zu ergänzen wäre. Selbiges für Vorwahlen, so Du diese haben möchtest.
    Evtl. kannst Du dadurch die Stadtteilen die Orte zuweisen?!

    Dateien

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

    2 Mal editiert, zuletzt von Alina (20. Juni 2012 um 13:17)

  • Hi,

    Fehler?
    Theoretisch ja, praktisch nein, denn in Verbindung mit der Plz ist der Stadtteil auch kein Ortsname irgendwo in Deutschland.
    Du darfst aber selbstverständlich deine eigene - vollständige - Datenbank hernehmen :D

    Gruß
    x0r

    Simon nörgelt, Simon nervt - aber Simon verbessert die Welt. Glaubt er.

  • Habe gerade meinen letzten Beitrag für Dich noch mal und eine Datei erweitert, die evtl. helfen könnte.

    Lieben Gruß,
    Alina

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Geheime Information: ;)
    OuBVU5ebLhHu5QvlnAyQB4A7SzBrvWulwL7RLl2BdH5tI6sIYspeMKeXMSXl

  • So einfach ist das leider nicht, mit Daten nachträglich hinzufügen oder aktualisieren, da müsste ich die komplette Datenbank nochmal neu aufbauen und könnte somit direkt die neue nehmen (wie gesagt, ich hatte die Spalte einfach nur raus, der übersichtlichkeit halber ;)).

    Danke trotzdem! :)

    Simon nörgelt, Simon nervt - aber Simon verbessert die Welt. Glaubt er.

  • In die Datenbank etwas einzufügen ist doch relativ einfach.
    AutoIt Nudelt jede Zeile durch und der Käs ist gegessen.

    Habe ich eben mal testweise ein Skript geschrieben was die Datenbank etwas verkleinert.
    (Wegen der Dateigröße)

    Ich hatte mir aber vorher mehr davon versprochen^^
    Das Zip oder Rar Format holt schon viel raus ohne die Struktur zu kennen.
    Da sind nur noch ca. 10% drin.^^

    Einstellbar ist die Genauigkeit mit der Kommazahlen behandelt werden (wie viele Bits der Zahl zur Verfügung stehen sollen)
    Bei z.B. 16 Bit sind die ersten beiden Nachkommastellen idr richtig und die dritte weicht wenn überhaupt nur sehr wenig ab.

    Für Übersicht ist es Sinnvoll Größen mit Variabler Länge (z.B. Namen) immer zum Schluss an eine Zeile zu setzen.
    Sämtliche Zahlen kann man durch führende Nullen auf die gleiche Länge bringen und Kommastellen (nach der 5ten ist das sowieso egal) abschneiden.

    Spoiler anzeigen
    [autoit]


    Global $pInput = 'coords.txt'
    Global $pOutput = 'Comp_' & $pInput

    [/autoit] [autoit][/autoit] [autoit]

    Global $iBitsFuerFloat = 4 * 4 ; Muss durch 4 Teilbar sein.

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $sRead = FileRead($pInput)
    Global $sComp = _Comp($sRead)

    [/autoit] [autoit][/autoit] [autoit]

    FileDelete($pOutput)
    FileWrite($pOutput, $sComp)

    [/autoit] [autoit][/autoit] [autoit]

    Global $sDecomp = _DeComp($sComp)

    [/autoit] [autoit][/autoit] [autoit]

    FileDelete('Decomp_' & $pInput)
    FileWrite('Decomp_' & $pInput, $sDecomp)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ ConsoleWrite($sComp & @CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _DeComp($sData)

    [/autoit] [autoit][/autoit] [autoit]

    ;~ Local $iBitsFuerFloat = 4*3 ; Bits für die Genauigkeit der Koords. Muss durch 4 Teilbar sein.
    Local $iMaximalwert = 90 ; Maximalwert für die Koordinatenangaben. ( 90 ? )
    Local $aSplit, $sRet, $sDatum

    [/autoit] [autoit][/autoit] [autoit]

    ;~ $sData = StringReplace($sData, @CR, '')
    $aSplit = StringSplit($sData, @LF) ; Man weiß nicht wie viele Werte hier sind...

    [/autoit] [autoit][/autoit] [autoit]

    ; Aufbau
    ;~ 20|20|12|12|Text

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $aSplit[0] - 1 Step 1

    [/autoit] [autoit][/autoit] [autoit]

    $sDatum = $aSplit[$i]

    [/autoit] [autoit][/autoit] [autoit]

    $sRet &= Int('0x' & StringMid($sDatum, 1, 5)) & @TAB
    $sRet &= Int('0x' & StringMid($sDatum, 6, 5)) & @TAB
    $sRet &= StringTrimLeft($sDatum, 10 + 2 * $iBitsFuerFloat/4) & @TAB

    [/autoit] [autoit][/autoit] [autoit]

    $sRet &= Round((Int('0x' & StringMid($sDatum, 11, $iBitsFuerFloat/4)) / 2^$iBitsFuerFloat)*$iMaximalwert, Round($iBitsFuerFloat/5,0)) & @TAB
    $sRet &= Round((Int('0x' & StringMid($sDatum, 11 + $iBitsFuerFloat/4, $iBitsFuerFloat/4)) / 2^$iBitsFuerFloat)*$iMaximalwert, Round($iBitsFuerFloat/5,0)) & @TAB

    [/autoit] [autoit][/autoit] [autoit]

    $sRet &= @CRLF

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $sRet

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _Comp($sData)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aSplit, $aDatum, $sRet, $sBits
    ;~ Local $iBitsFuerFloat = 4*3 ; Bits für die Genauigkeit der Koords. Muss durch 4 Teilbar sein.
    Local $iMaximalwert = 90 ; Maximalwert für die Koordinatenangaben. ( 90 ? )

    [/autoit] [autoit][/autoit] [autoit]

    $sData = StringReplace($sData, @CR, '')
    $aSplit = StringSplit($sData, @LF) ; Man weiß nicht wie viele Werte hier sind...

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $aSplit[0] -1 Step 1
    $aDatum = StringSplit($aSplit[$i], @TAB, 2) ; Aufbau ist: Nr|PLZ|Ort|X|Y
    ; Nr ist kleiner als 2^18. -> wir nehmen (suboptimal) erstmal 2^20
    ; PLZ ist kleiner als 2^17 -> wir nehmen (suboptimal) 2^20
    ; X|Y (Maximalwert 90°) ist kleiner als 2^7 ist aber Float.
    ; Genutzt wird (90/255) * 2^8 Die Genauigkeit ist dann nur 0,35
    ; Ort hat eine variable Größe. Er kommt immer ans Ende der Zeile.

    [/autoit] [autoit][/autoit] [autoit]

    $sBits = ''
    $sBits &= Hex($aDatum[0],5) ; 20Bit
    $sBits &= Hex($aDatum[1],5) ; 20Bit
    $sBits &= Hex(Int(Round(($aDatum[3]*2^$iBitsFuerFloat)/$iMaximalwert,0)),$iBitsFuerFloat/4) ; Genauigkeit oben einstellbar.
    $sBits &= Hex(Int(Round(($aDatum[4]*2^$iBitsFuerFloat)/$iMaximalwert,0)),$iBitsFuerFloat/4)

    [/autoit] [autoit][/autoit] [autoit]

    $sRet &= $sBits & $aDatum[2] & @LF; Text

    [/autoit] [autoit][/autoit] [autoit]

    ; 2*20Bit + 2*12 Bit + Text
    ; = 64Bit für die Daten + Text

    [/autoit] [autoit][/autoit] [autoit]

    ;~ $sRet &= @CRLF

    [/autoit] [autoit][/autoit] [autoit]

    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $sRet

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit]
  • Hi Marsi,

    sieht echt cool aus das Teil, allerdings hab ich schon die neue Version gebaut, mit sämtlichen EMEA-Ländern drin
    ...und diesmal komplett ohne Ortsteile, also wirklich nur die Städte.

    Denk mal, dass es so passen müsste, trotzdem thx! :D

    Gruß
    x0r

    Simon nörgelt, Simon nervt - aber Simon verbessert die Welt. Glaubt er.

    • Offizieller Beitrag

    Nur mal zur Anmerkung:

    Es wäre sinnvoll, wenn du die Quelle deiner Daten angibst. Denn du darfst nur Daten verwenden (bzw. verbreiten), die du selber ermittelt hast ( :rofl: ) oder die vom Ersteller lizenzfrei zur Veröffentlichung angeboten werden. (was bei der Deutschen Post definitiv nicht der Fall ist)
    Soweit ich weiß, könnte OpenStreetMap da eine gute Anlaufstelle sein.