Hi,
... weil man ja sonst nix besseres zu tun hat ... ;-)
Ummodeln der o.a. Opengeodb-Postleitzahlenliste in ein JS-Array (Liebe Perl-Gurus: bitte nicht gleich wieder hauen! ;-):
#!/usr/bin/perl -w
use strict;
my $opengeodb = "opengeodb-0.2.3e-UTF8-text-plz.txt"; #$ARGV[0];
my $jsarray = "opengeodb-js-array.js"; #$ARGV[1];
my @line;
my $out;
my %entries;
my $zip = "";
my $city = "";
my $i = 0;
open OPENGEODB, "< $opengeodb" || die "can't open $opengeodb";
open JSARRAY, "> $jsarray" || die "can't open $jsarray";
keys %hash = 8000; # alloziert 8192 Plätze für 8181 Plz.
print JSARRAY "plz = new Array(\n";
while(<OPENGEODB>){
next if $_ =~ /^\x23/;
@line = split(/;/,$_);
$zip = $line[9];
$zip =~ s/[\n\r]//;
$city = $line[6];
$entries{$zip} = $city;
}
close OPENGEODB;
foreach $out (sort(keys %entries)) {
print JSARRAY '["', $entries{$out}, '","', $out, '"],',"\n";
}
print JSARRAY '["",""]);';
close JSARRAY;
Kurzes Beispiel zur Nutzung (Liebe Javascript-Gurus: betreffs der Prügelfrage bitte ich euch an die Perl-Gurus zu wenden.):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Die leidigen Postleitzahlen</title>
<!-- Das Array heißt "plz" -->
<script type="text/javascript" src="plz-array.js"></script>
<script type="text/javascript">
function binarySearch( needle, haystack){
var low = 0;
var high = haystack.length - 1;
var middle = 0;
var round = 0;
while(low <= high){
round++;
middle = Math.floor((low + high)/2);
if(needle < haystack[middle][1])
high = middle - 1;
else if (needle > haystack[middle][1])
low = middle + 1;
else
return middle;
}
return -1;
}
function linearSearchExactFirst(needle, haystack){
var len = haystack.length -1;
while(len--){
if (needle == haystack[len]){
return len;
}
}
return -1;
}
function linearSearchRegex(needle, haystack){
var len = haystack.length -1;
var regex = new RegExp(needle);
var ret = new Array();
var i = 0;
while(len--){
if (regex.test(haystack[len][0])){
ret[i++] = haystack[len][0];
}
}
if(ret.length > 0){
return ret;
}
return -1;
}
function searchPLZ(entry){
var inpCity = document.forms[0].city;
/*
Eigentlich ist es ja heilige Pflicht nur das
zu nehmen, was man benötigt und nicht das
wegzuschmeisen, was man _nicht_ benötigt.
Soll im Produktionscode geändert werden?
Ach, wird doch eh nie!
*/
entry = entry.value.replace(/[^0-9]*/g,"");
/* PLZ suchen */
if(entry.length != 5 && inpCity.value.length > 2){
/*
Aufgrund der Unsortiertheit der Ortsnamen
wäre es wohl besser diese Suche getrennt
durchzuführen. Evt sogar auf dem Server.
Für Experimentierfreudige trotzdem mal der
(ungeprüfte!) Code:
*/
/*
Um die Sache zumindest etwas zu beschleunigen
wurde oben die Mindestlänge des Ortsnamenanfanges
auf drei festgelegt.
Für soviele und auch jeden weiteren Buchstaben
wird das ganze Array durchsucht und das Ergebnis in
einem weiterem Array festgehalten. Ist das Ergebnis-
array leer wurde nichts gefunden, ansonsten wird
eine Auswahliste gefüllt.
*/
/*
linearSearchRegex() ist der Einfachheit halber
mittels eines Regex implementiert, wie auch der
Name schon anzudeuten versucht. Es wäre also
evt der Geschwindigkeit zuträglich vorher ein
wenig zu filtern.
*/
/*
var ret = linearSearchRegex(inpCity.value, plz);
if(typeof(ret) != "number" ){
*/
/*
document.forms[0].city sei bereits eine Auswahlliste.
Die Auswahlliste wird bei jedem Aufruf von searchPLZ()
neu überschrieben.
*/
/*
for(var i=0; i< ret.length;i++){
var newEntry = new Option(ret[i],ret[i],false,false);
inpCity.options[i] = newEntry;
}
*/
/*
Code den Klick in die Auswahliste auszwerten ist
in dieser Datei nicht enthalten.
*/
/*}
else{
return false;
}
*/
return false;
}
/* Ort suchen */
else{
if(entry.length == 5){
// ermöglicht Korrektur der Plz.
inpCity.value = "";
/* Hier wird jeweils nur der exakte Wert
gesucht. Es kann aber auch mittels
linearSearchRegex() ein Array gefüllt werden
das ähnlich der Beschreibung bei "PLZ suchen"
ausgegeben wird.
*/
var tmp = binarySearch(entry,plz);
if(tmp >= 0){
inpCity.value = plz[tmp][0];
return true;
}
else{
/* Aussagekräftige Fehlermeldung wäre
natürlich erheblich günstiger.
*/
return false;
}
}
else {
/* Wenn das PLZ-Array auf mehrere Dateien
aufgeteilt ist, kann hier das Laden erfolgen.
*/
return false;
}
}
}
function formSubmit(f,s,z,c){
alert( "Es wurde \"submitiert\":\n"
+ ((f.length > 0)?f:"kein Eintrag") + "\n"
+ ((s.length > 0)?f:"kein Eintrag") + "\n"
+ ((z.length > 0)?f:"kein Eintrag") + " "
+ ((c.length > 0)?f:"kein Eintrag") + "\n");
}
</script>
</head>
<style type="text/css">
fieldset{
padding: 1em;
margin-top: 1em;
width:25em;
border: 1px solid black;
}
legend {
border: 1px solid black;
color: black;
background-color:#c0c0c0;
}
</style>
<body>
<h1>Automatische Postleitzahlensuche</h1>
<form id="plzformular"
name="plzformular"
-- action="pfad/zum/bearbeitungscode" --
onsubmit="formSubmit();return false" >
<fieldset><legend>Adresse</legend>
Name<br>
<input name="fullname"
id="fullname"
type="text"
size="50"
maxlength="50" /><br>
Strasse<br>
<input name="streetname"
id="streetname"
type="text"
size="50"
maxlength="50" /><br>
Postleitzahl/Ort<br>
<input name="zip"
id="zip"
type="text"
size="5"
maxlength="5"
onkeyup="searchPLZ(this);" />
<input name="city"
id="city"
type="text"
size="40"
maxlength="40" />
</fieldset>
<fieldset><legend>Daten absenden</legend>
<input name="sendbutton"
id="sendbutton"
type="button"
value="Abschicken"
onclick="formSubmit(this.form.fullname.value,
this.form.streetname.value,
this.form.zip.value,
this.form.city.value);"/>
<input name="resetbutton"
id="resetbutton"
type="button"
value="Zurücksetzen"
onclick="this.form.reset()"/><br>
</fieldset>
</form>
</body>
</html>
Ajax:
Von Pallas Athene mit Wahnsinn belegt nahm er sich das Leben.
Ist das jetzt ein unpassender Name für das Zeug um XMLHttpRequest()? Nein, ich finde nicht >;->
so short
Christoph Zurnieden