mikrocontroller.net

Forum: Offtopic PLZ nach Entfernung sortieren


Autor: Maik (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Maik (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Maik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
push

Autor: pfft. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Maik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  pfft.
bei 70...100km Durchmesser aber recht aufwendig.

Autor: pfft. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Alternative ?

Autor: Jürgen W. (lovos)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Maik (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...)

Autor: Maik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
8270 PLZs in D. Nicht schlecht.  Sind da die Firmen auch schon dabei?

Autor: Jürgen W. (lovos)
Datum:

Bewertung
0 lesenswert
nicht 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
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

Autor: Gast (Gast)
Datum:

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

Autor: Gast (Gast)
Datum:

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

Autor: Jürgen W. (lovos)
Datum:

Bewertung
0 lesenswert
nicht 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
gcc -Wall -lm  -o /usr/local/bin/gps_plz gps_plz.c
Es besteht nur aus dieser Datei.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//sudo gcc -Wall -lm -o /usr/local/bin/gps_plz gps_plz.c
//
//This file needed:
//http://fa-technik.adfc.de/code/opengeodb/PLZ.tab
//5078  01067  13.7210676148814  51.0600336463379  Dresden

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <tgmath.h>
#ifndef max
#define min(a1,a2) ((a1)<(a2)?(a1):(a2))
#define max(a1,a2) ((a1)>(a2)?(a1):(a2))
#endif


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*--------------------------*/
//Searches in the char array s[] for a character in array
//  'charr'. When the first match is found, string position
//  in *is will be updated, the index of the found character
//  (charr[]) will be returned.
//  If no match, -1 is returned
char str_searchch2(const char *s, int *is,
 const char *charr) {
int i,j,lcharr;
char ret;

i= is==NULL? 0:*is;
lcharr=strlen(charr);
ret=-1;
while (s[i]!=0) {
  char ch=s[i];
  for (j=0;j<lcharr;j++) {
    if (charr[j]==ch) break;
  }  
  if (j!=lcharr) {ret=j; break;} //found
  i++;
}
if (is!=NULL) *is=i;
return ret;
}

// - - - - - - - - - - - - - -
//Database constants

//angles (lat,lon) will be stored as ints.
//they will be multiplied by 100000, i.e.
// 90Degree = 9000000

//LENGTH of each entry (int's)
#define DBLEN1 (3+8)

//Maximum number of entries
#define DBLEN2 8300

// - - - - - - - - - - - - - -
// this loads the geo-DB into a int-array
void load_db(int *plzdb, FILE *fh) {
char s[0x100]; int is,is2;
int ientr, idb;
double hdbl;
int i,h1;
char s2[0x40];

is=0; h1=0; ientr=0; idb=0;
while (fgets(s,sizeof(s), fh)!=NULL) {
  //printf("%s\n",s);
  if (s[0]=='#') continue;
  is=0;
  if (str_searchch2(s,&is,"\t\n")==1) continue;
    // search for \t or \n.
    // if a \n is found, proceed next line
  is++;
  for (i=0;i<4;i++) {
    is2=is;
    if (str_searchch2(s,&is2,"\t\n")==1) {
      if (i<3) break;
    }
    strncpy(s2,s+is,is2-is); s2[is2-is]=0;
    //printf("%s,",s2);
    if (i==1 || i==2) {
      hdbl=atof(s2); //printf("%d,",(int)(hdbl*100000));
      plzdb[idb+i]=(int)(hdbl*100000);
    }
    else if (i==0) {
      plzdb[idb+0]=atoi(s2);
      //printf("%d,",plzdb[idb+0]);
    }
    else if (i==3) {
      h1=max(h1,is2-is);
      strcpy((char*)&plzdb[idb+3],s2);
      //printf("%s",s2);
    }
    is=is2+1;
  }
  //printf("\n");
  if (i<3) {
    printf("#%s\n",s); 
    continue;
  }
  ientr++; idb+=DBLEN1;
}
plzdb[idb+0]=0;
printf("maxlen=%d, num_plz=%d\n",h1,ientr);
}

// - - - - - - - - - - - - - -
int main(int argc, char *argv[] ) {
FILE *fh;
int *plzdb;

plzdb=malloc(DBLEN2*DBLEN1*sizeof(int));
if ((fh=fopen(argv[1],"r"))==NULL) {
  fprintf(stderr,"file not found.\n");
  exit(1);
}
load_db(plzdb,fh);


{
float lat=4999716*M_PI/18000000;
float lon=753259*M_PI/18000000;
float nlat,nlon, dist;
int idb;

idb=0;
while (plzdb[idb+0]!=0) {
  nlat=plzdb[idb+2]*M_PI/18000000;
  nlon=plzdb[idb+1]*M_PI/18000000;
  dist=acos(sin(nlat)*sin(lat)+cos(nlat)*cos(lat)*cos(nlon-lon)) * 6380;
  if (dist<20) printf("%05d %s, dist=%.3f\n",
    plzdb[idb+0],(char*)&plzdb[idb+3],dist);
  idb+=DBLEN1;
}


}
return 0;
}

Autor: Jürgen W. (lovos)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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. ;-)

Autor: Jürgen W. (lovos)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jürgen W. (lovos)
Datum:

Bewertung
0 lesenswert
nicht 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)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//sudo gcc -Wall -lm -o /usr/local/bin/gps_plz gps_plz.c
//
//This file needed:
//http://fa-technik.adfc.de/code/opengeodb/PLZ.tab
//5078  01067  13.7210676148814  51.0600336463379  Dresden

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <tgmath.h>
#ifndef max
#define min(a1,a2) ((a1)<(a2)?(a1):(a2))
#define max(a1,a2) ((a1)>(a2)?(a1):(a2))
#endif


// - - - - - - - - - - - - - -
//Database constants

//angles (lat,lon) will be stored as ints.
//they will be multiplied by 100000, i.e.
// 90Degree = 9000000

//LENGTH of each entry (int's)
#define DBLEN1 (3+8)

//Maximum number of entries
#define DBLEN2 8300

// - - - - - - - - - - - - - -
// this loads the geo-DB into a int-array
void load_db(int *plzdb, FILE *fh) {
char s[0x100]; int is;
int ientr, idb;
double f1, f2;
int h1,h2;
char s2[0x40];

is=0; h1=0; ientr=0; idb=0;
while (fgets(s,sizeof(s), fh)!=NULL) {
  if (s[0]=='#') continue;
  if (sscanf(s,"%d %d %lf %lf %[^\n\r]s",
     &h2,&h1,&f1,&f2,s2)!=5) {
    printf("**%s\n",s);
    continue;
  }
  plzdb[idb+0]=h1;
  plzdb[idb+1]=(int)(f1*100000);
  plzdb[idb+2]=(int)(f2*100000);
  strcpy((char*)&plzdb[idb+3],s2);
  ientr++; idb+=DBLEN1;
}
plzdb[idb+0]=0;
}

// - - - - - - - - - - - - - -
int main(int argc, char *argv[] ) {
FILE *fh;
int *plzdb;

plzdb=malloc(DBLEN2*DBLEN1*sizeof(int));
if ((fh=fopen(argv[1],"r"))==NULL) {
  fprintf(stderr,"file not found.\n");
  exit(1);
}
load_db(plzdb,fh);

{
float lat=4999716*M_PI/18000000;
float lon=753259*M_PI/18000000;
float nlat,nlon, dist;
int idb;

idb=0;
while (plzdb[idb+0]!=0) {
  nlat=plzdb[idb+2]*M_PI/18000000;
  nlon=plzdb[idb+1]*M_PI/18000000;
  dist=acos(sin(nlat)*sin(lat)+cos(nlat)*cos(lat)*cos(nlon-lon)) * 6380;
  if (dist<20) printf("%05d %s, dist=%.3f\n",
    plzdb[idb+0],(char*)&plzdb[idb+3],dist);
  idb+=DBLEN1;
}
}
return 0;
}

Autor: pfft.. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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, Yahoo oder Facebook? Keine Anmeldung erforderlich!
Mit Google-Account einloggen | Mit Yahoo-Account einloggen | Mit Facebook-Account einloggen
Noch kein Account? Hier anmelden.