Forum: Offtopic PLZ nach Entfernung sortieren


von Maik (Gast)


Lesenswert?

Ich wohne genau an zwei anderen Landesgrenzen mit (stark) 
unterschiedlichen PLZ -Anfangszahlen. Gibt irgendwo im Netz eine Seite 
wo man seine PLZ  und
dann einen Umkreis von z.B 100Km angibt und eine Liste aller PLZ im dem
Umkreis angezeigt bekommt?

von Uhu U. (uhu)


Lesenswert?


von Maik (Gast)


Lesenswert?

Gut: ich hätte noch schreiben sollen, das es auch Funktionieren soll.
Die ich bis jetzt gefunden habe waren bis zur Unbrauchbarkeit in Ihrer 
Funktion eingeschränkt. Da ich das nur einmal und nicht kommerziell
brauche ist ein Kauf für ein paar 100 Euro auch nicht die Lösung.

von Maik (Gast)


Lesenswert?

push

von pfft. (Gast)


Lesenswert?

Wie man das macht : Ein Karte nehmen, dort die Postleitzahlgebiete mit 
Farbe anmalen. Dann vom gewuenschten Ort in einer Spirale nach aussen 
wandern und die besuchten Zonen einschwaerzen. So schwierig ist das 
nicht.

von Maik (Gast)


Lesenswert?

@  pfft.
bei 70...100km Durchmesser aber recht aufwendig.

von pfft. (Gast)


Lesenswert?

Eine Alternative ?

von Jürgen W. (lovos)


Lesenswert?

Bei
http://fa-technik.adfc.de/code/opengeodb/PLZ.tab
gibt es eine Datei der Form

#loc_id  plz  lon  lat  Ort
5078  01067  13.7210676148814  51.0600336463379  Dresden
5079  01069  13.7389066401609  51.039558876083  Dresden
5080  01097  13.7439674110642  51.0667452412037  Dresden
5081  01099  13.8289798683304  51.0926193047084  Dresden

D.h. bei allen PLZ sind die Geo-(GPS)-Koordinaten angegeben.
PS: Die Entfernung zwischen Gps-Koordinaten berechnet sich mit

arccos(sin(B_lat)*sin(A_lat)+cos(B_lat)*cos(A_lat)*cos(B_lon - A_lon)) * 
Erdradius Mit dem Erdradius von etwa 6380 km.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Jürgen G. schrieb:

> D.h. bei allen PLZ sind die Geo-(GPS)-Koordinaten angegeben.
> PS: Die Entfernung zwischen Gps-Koordinaten berechnet sich mit

Na, du erst wieder.  Dabei hat Maik doch ausdrücklich geschrieben,
dass er was Fertiges haben will, das natürlich noch dazu auch nichts
kosten darf.

von Maik (Gast)


Lesenswert?

>Dabei hat Maik doch ausdrücklich geschrieben,
>dass er was Fertiges haben will

nö.. so ausdrücklich habe ich das nun nicht gesagt.

Das mit der Liste ist zwar etwas anders als ich mir das vorgestellt
habe, aber es ist auch eine Lösung.
überlege nur gerade mit was sich das am besten (einfachsten) berechnet.
(Kandidat Nummer 1 ist Matlab gerade...)

von Maik (Gast)


Lesenswert?

8270 PLZs in D. Nicht schlecht.  Sind da die Firmen auch schon dabei?

von Jürgen W. (lovos)


Lesenswert?

Habe gerade ein C-Prograemmchen geschrieben, was mir von einen 
beliebigen Ort benachbarte Orte ausgibt, z.B. im Umkreis von 20km.
Als Beispiel-Ort  Simmern/Hunsrück.
Das ging recht schnell mit der Formel
1
dist=acos(sin(nlat)*sin(lat)+cos(nlat)*cos(lat)*cos(nlon-lon)) * 6380;
Wenn Du willst, kann ich dir die Sourcen z.Verfuegung stellen.


55413 Weiler bei Bingen, dist=18.949
55422 Bacharach, dist=15.261
55430 Oberwesel, dist=15.102
55432 Niederburg, dist=14.940
55442 Stromberg, dist=16.336
55444 Seibersbach, dist=15.885
55469 Simmern / Hunsrück, dist=0.000
55471 Tiefenbach, dist=4.406
55481 Kirchberg (Hunsrück), dist=11.232
55483 Dickenschied, dist=15.261
55487 Sohren, dist=17.484
55490 Gemünden, dist=13.032
55494 Rheinböllen, dist=8.242
55496 Argenthal, dist=7.631
55497 Ellern (Hunsrück), dist=7.631
55499 Riesweiler, dist=7.631
55595 Hargesheim, dist=19.204
55618 Simmertal, dist=19.825
55619 Hennweiler, dist=19.947
55629 Seesbach, dist=16.037
56281 Emmelshausen, dist=17.760
56288 Kastellaun, dist=9.346
56290 Beltheim, dist=16.484
56291 Leiningen, dist=12.065
56329 Sankt Goar, dist=19.702
56858 Peterswald-Löffelscheid, dist=19.579
56865 Blankenrath, dist=18.298
56869 Mastershausen, dist=14.777

von Gast (Gast)


Lesenswert?

ja, her damit bitte!
ich hätte das jetzt in einer access datenbank gemacht und eine Abfrage 
geschrieben, die dann sortiert

von Gast (Gast)


Lesenswert?

Nachtrag: Was ich gebrauchen könnte, wäre eine sortierte Liste, die aber 
nicht nach Luftdistanz geoeordnet ist, sondern nach Anfahrzeit.

von Jürgen W. (lovos)


Lesenswert?

Absolut quick and dirty.
Habe ich nur zum Spass so schnell mal programmiert, da mir die Aufgabe 
(benachbarte Orte finden) interessant erschien.
90% des Codes handelt das Einlesen der Datei
http://fa-technik.adfc.de/code/opengeodb/PLZ.tab
in ein int-Array.
Haette man viel besser loesen koennen mit struct ...
Aber ich wollte keinen Preis in 'sauber programmieren' gewinnen, sondern 
ganz schnell etwas loesen.

Die Datei PLZ.tab muss man als erstes Argument mitgeben.
Compiliert wird es mit dem Befehl
1
gcc -Wall -lm  -o /usr/local/bin/gps_plz gps_plz.c
Es besteht nur aus dieser Datei.
1
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2
//sudo gcc -Wall -lm -o /usr/local/bin/gps_plz gps_plz.c
3
//
4
//This file needed:
5
//http://fa-technik.adfc.de/code/opengeodb/PLZ.tab
6
//5078  01067  13.7210676148814  51.0600336463379  Dresden
7
8
#include <stdlib.h>
9
#include <stdio.h>
10
#include <string.h>
11
#include <math.h>
12
#include <tgmath.h>
13
#ifndef max
14
#define min(a1,a2) ((a1)<(a2)?(a1):(a2))
15
#define max(a1,a2) ((a1)>(a2)?(a1):(a2))
16
#endif
17
18
19
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20
/*--------------------------*/
21
//Searches in the char array s[] for a character in array
22
//  'charr'. When the first match is found, string position
23
//  in *is will be updated, the index of the found character
24
//  (charr[]) will be returned.
25
//  If no match, -1 is returned
26
char str_searchch2(const char *s, int *is,
27
 const char *charr) {
28
int i,j,lcharr;
29
char ret;
30
31
i= is==NULL? 0:*is;
32
lcharr=strlen(charr);
33
ret=-1;
34
while (s[i]!=0) {
35
  char ch=s[i];
36
  for (j=0;j<lcharr;j++) {
37
    if (charr[j]==ch) break;
38
  }  
39
  if (j!=lcharr) {ret=j; break;} //found
40
  i++;
41
}
42
if (is!=NULL) *is=i;
43
return ret;
44
}
45
46
// - - - - - - - - - - - - - -
47
//Database constants
48
49
//angles (lat,lon) will be stored as ints.
50
//they will be multiplied by 100000, i.e.
51
// 90Degree = 9000000
52
53
//LENGTH of each entry (int's)
54
#define DBLEN1 (3+8)
55
56
//Maximum number of entries
57
#define DBLEN2 8300
58
59
// - - - - - - - - - - - - - -
60
// this loads the geo-DB into a int-array
61
void load_db(int *plzdb, FILE *fh) {
62
char s[0x100]; int is,is2;
63
int ientr, idb;
64
double hdbl;
65
int i,h1;
66
char s2[0x40];
67
68
is=0; h1=0; ientr=0; idb=0;
69
while (fgets(s,sizeof(s), fh)!=NULL) {
70
  //printf("%s\n",s);
71
  if (s[0]=='#') continue;
72
  is=0;
73
  if (str_searchch2(s,&is,"\t\n")==1) continue;
74
    // search for \t or \n.
75
    // if a \n is found, proceed next line
76
  is++;
77
  for (i=0;i<4;i++) {
78
    is2=is;
79
    if (str_searchch2(s,&is2,"\t\n")==1) {
80
      if (i<3) break;
81
    }
82
    strncpy(s2,s+is,is2-is); s2[is2-is]=0;
83
    //printf("%s,",s2);
84
    if (i==1 || i==2) {
85
      hdbl=atof(s2); //printf("%d,",(int)(hdbl*100000));
86
      plzdb[idb+i]=(int)(hdbl*100000);
87
    }
88
    else if (i==0) {
89
      plzdb[idb+0]=atoi(s2);
90
      //printf("%d,",plzdb[idb+0]);
91
    }
92
    else if (i==3) {
93
      h1=max(h1,is2-is);
94
      strcpy((char*)&plzdb[idb+3],s2);
95
      //printf("%s",s2);
96
    }
97
    is=is2+1;
98
  }
99
  //printf("\n");
100
  if (i<3) {
101
    printf("#%s\n",s); 
102
    continue;
103
  }
104
  ientr++; idb+=DBLEN1;
105
}
106
plzdb[idb+0]=0;
107
printf("maxlen=%d, num_plz=%d\n",h1,ientr);
108
}
109
110
// - - - - - - - - - - - - - -
111
int main(int argc, char *argv[] ) {
112
FILE *fh;
113
int *plzdb;
114
115
plzdb=malloc(DBLEN2*DBLEN1*sizeof(int));
116
if ((fh=fopen(argv[1],"r"))==NULL) {
117
  fprintf(stderr,"file not found.\n");
118
  exit(1);
119
}
120
load_db(plzdb,fh);
121
122
123
{
124
float lat=4999716*M_PI/18000000;
125
float lon=753259*M_PI/18000000;
126
float nlat,nlon, dist;
127
int idb;
128
129
idb=0;
130
while (plzdb[idb+0]!=0) {
131
  nlat=plzdb[idb+2]*M_PI/18000000;
132
  nlon=plzdb[idb+1]*M_PI/18000000;
133
  dist=acos(sin(nlat)*sin(lat)+cos(nlat)*cos(lat)*cos(nlon-lon)) * 6380;
134
  if (dist<20) printf("%05d %s, dist=%.3f\n",
135
    plzdb[idb+0],(char*)&plzdb[idb+3],dist);
136
  idb+=DBLEN1;
137
}
138
139
140
}
141
return 0;
142
}

von Jürgen W. (lovos)


Lesenswert?

Gast schrieb:
> Nachtrag: Was ich gebrauchen könnte, wäre eine sortierte Liste, die aber
> nicht nach Luftdistanz geoeordnet ist, sondern nach Anfahrzeit.

Kein Problem.
Obiger Code darf erweitert werden.
Die Ordnung nach Anfahrzeit erscheint mir unmoeglich, da die Datei keine 
Information darueber enthaelt.

Aber ich weiss wie man das machen kann:
Bei openstreetmap.org gibt es freie Daten, wo nicht nur Ort mit PLZ und 
Geo-Koordinaten abgespeichert sind, sondern auch Strassen.
Mit den Strassen-Infos laesst sich die Fahrtzeit muehelos berechnen.

von (prx) A. K. (prx)


Lesenswert?

Jürgen G. schrieb:

> Mit den Strassen-Infos laesst sich die Fahrtzeit muehelos berechnen.

"Mühelos" ist gut. Und wenn du damit fertig bist will er bestimmt auch 
noch die aktuellen Staumeldungen drin eingebaut wissen. ;-)

von Jürgen W. (lovos)


Lesenswert?

> "Mühelos" ist gut. Und wenn du damit fertig bist will er bestimmt auch

Ne, ne, ich werde mich da nicht an die Arbeit machen.
1. Openstreetmap ist noch nicht flaechendeckend. Noch nicht alle Orte 
sind eingetragen.
2. Vermutlich sind Hoechstgeschwindigkeiten bei den Strassen nicht 
eingetragen, dann wird die Fahrtzeit sehr ungenau.
3. Man muesste einen Router selbst programmieren (ein riesen Aufwand) 
oder den bestehenden vom OSM-Projekt ins Programm einbinden. Dazu habe 
ich einfach keine Lust. Das Programmieren soll ja zunaechst Spass 
machen.

von Jürgen W. (lovos)


Lesenswert?

Erste verbesserte Version.
Durch Verwendung von 'sscanf' verkuerzte sich der Code von 142 auf 87 
Zeilen.

Der Bezugs-Ort ist noch hart-kodiert (z.B. Simmern). (Er sollte durch 
eine Eingabefunktion beliebig sein, aber was kann man bei 87 Zeilen 
erwarten)
1
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2
//sudo gcc -Wall -lm -o /usr/local/bin/gps_plz gps_plz.c
3
//
4
//This file needed:
5
//http://fa-technik.adfc.de/code/opengeodb/PLZ.tab
6
//5078  01067  13.7210676148814  51.0600336463379  Dresden
7
8
#include <stdlib.h>
9
#include <stdio.h>
10
#include <string.h>
11
#include <math.h>
12
#include <tgmath.h>
13
#ifndef max
14
#define min(a1,a2) ((a1)<(a2)?(a1):(a2))
15
#define max(a1,a2) ((a1)>(a2)?(a1):(a2))
16
#endif
17
18
19
// - - - - - - - - - - - - - -
20
//Database constants
21
22
//angles (lat,lon) will be stored as ints.
23
//they will be multiplied by 100000, i.e.
24
// 90Degree = 9000000
25
26
//LENGTH of each entry (int's)
27
#define DBLEN1 (3+8)
28
29
//Maximum number of entries
30
#define DBLEN2 8300
31
32
// - - - - - - - - - - - - - -
33
// this loads the geo-DB into a int-array
34
void load_db(int *plzdb, FILE *fh) {
35
char s[0x100]; int is;
36
int ientr, idb;
37
double f1, f2;
38
int h1,h2;
39
char s2[0x40];
40
41
is=0; h1=0; ientr=0; idb=0;
42
while (fgets(s,sizeof(s), fh)!=NULL) {
43
  if (s[0]=='#') continue;
44
  if (sscanf(s,"%d %d %lf %lf %[^\n\r]s",
45
     &h2,&h1,&f1,&f2,s2)!=5) {
46
    printf("**%s\n",s);
47
    continue;
48
  }
49
  plzdb[idb+0]=h1;
50
  plzdb[idb+1]=(int)(f1*100000);
51
  plzdb[idb+2]=(int)(f2*100000);
52
  strcpy((char*)&plzdb[idb+3],s2);
53
  ientr++; idb+=DBLEN1;
54
}
55
plzdb[idb+0]=0;
56
}
57
58
// - - - - - - - - - - - - - -
59
int main(int argc, char *argv[] ) {
60
FILE *fh;
61
int *plzdb;
62
63
plzdb=malloc(DBLEN2*DBLEN1*sizeof(int));
64
if ((fh=fopen(argv[1],"r"))==NULL) {
65
  fprintf(stderr,"file not found.\n");
66
  exit(1);
67
}
68
load_db(plzdb,fh);
69
70
{
71
float lat=4999716*M_PI/18000000;
72
float lon=753259*M_PI/18000000;
73
float nlat,nlon, dist;
74
int idb;
75
76
idb=0;
77
while (plzdb[idb+0]!=0) {
78
  nlat=plzdb[idb+2]*M_PI/18000000;
79
  nlon=plzdb[idb+1]*M_PI/18000000;
80
  dist=acos(sin(nlat)*sin(lat)+cos(nlat)*cos(lat)*cos(nlon-lon)) * 6380;
81
  if (dist<20) printf("%05d %s, dist=%.3f\n",
82
    plzdb[idb+0],(char*)&plzdb[idb+3],dist);
83
  idb+=DBLEN1;
84
}
85
}
86
return 0;
87
}

von pfft.. (Gast)


Lesenswert?

>Nachtrag: Was ich gebrauchen könnte, wäre eine sortierte Liste, die aber
>nicht nach Luftdistanz geoeordnet ist, sondern nach Anfahrzeit.

Sowas taugt aber hoechstens fuer Flachlaender. Bei uns hat's hin und 
wieder ein Huegel, oder ein See dazwischen

von Sven P. (Gast)


Lesenswert?

Mann, dann schreibt man halt ein kleines Perl-Skript und füttert damit 
Google-Maps. Und das lässt man dann mal die Nacht über laufen

weglauf

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.