PLZ von Gemeinden - Datenbankabfrage?

is_in wird aber doch nicht funktionieren, wenn sich z.B. 2 Gemeinden eine PLZ teilen, oder?

nö, und ausserdem ist is_in am Aussterben und auf keinen Fall komplett.

Gruss
walter

Wie bitte?

Ich rede hiervon: http://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL#Query_for_areas_.28is_in.29

Beispiel: http://overpass-turbo.eu/s/6iu

Ok, war auf dem falschen Dampfer. weitermachen :wink:

Gruss
walter

Das klingt so ähnlich wie “intersect”. Funktioniert aber nicht, wenn die boundary/exterior-Punkte auch gelten.

Naja, das kommt auf die Query an. In Post #9 / #13 habe ich die Ränder ja auch explizit rausgeworfen.

Ah, dann wäre das ja ok. Für mich ist Overpass leider weitgehend Kauderwelsch.

Gut, ich habe im Post #9 noch die Kommentare ergänzt. War vorgestern zu faul.

Danke schonmal für die zahlreiche Hilfe. Ich habe das Problem gleich mal als Anlass genommen mich in die Overpass QL einzuarbeiten :wink: Aber verstehe natürlich noch nicht alles…

Die Idee, die Rand nodes aus dem set zu nehmen und auf den Rest is_in anzuwenden klingt gut. Leider funktionierts aber bei couchmapper’s Vorschlägen (Post #9 und #13) noch nicht vollständig richtig.
Für die Gemeinde Merchweiler (“de:amtlicher_gemeindeschluessel”=“10043113”) erhält man in beiden Fällen die PLZ 66589, 66299, 66287. Laut Wikipedia ist 66589 richtig. Zunächst dachte ich, dass es sich hier um eine lokale Mapping Ungenauigkeit handelt, also dass die “Nachbar-PLZ-area” die Gemeindegrenze an einer Stelle nur um wenige Meter überschneidet. Ich habe mir dieses Beispiel in JOSM angesehen. Dem ist aber nicht so. Die Grenze zwischen PLZ 66589 und 66299 verläuft über die identischen nodes wie auch die Grenze der Gemeinde. Der Logik entsprechend sollte 66299 also nicht gefunden werden.
Wo steckt der Fehler?

Das liegt an folgendem Knoten: http://www.openstreetmap.org/node/652433309

Dummerweise überlebt der die (.n2; - .n1;) Geschichte und zieht dann zwei benachbarte postal_areas mit in das Ergebnis.

Edit: klassisches User too stupid problem. Hab heute beim Kommentieren ein “>” durch ein “node(r)” ersetzt. Das war Blödsinn, ist gefixt.

Ah ok gut, ich hatte mich auch schon gefragt ob ich völlig blöd bin und erst (vor deinem hilfreichen Kommentieren) andere Ausgaben gesehen hatte :wink:

Nun gibt es noch solche Fälle, wie ich sie schon angesprochen habe:

Eppelborn (“de:amtlicher_gemeindeschluessel”=“10043111”) liefert die PLZ 66571 und 66822. Nur 66571 ist vermutlich richtig. Das liegt daran, dass lediglich das Gebiet einer Shell Tankstelle (ID 139856533), welche sich innerhalb der Eppelborn Fläche befindet, der PLZ 66822 zugeordnet ist. Der Rest dieser PLZ liegt außerhalb von Eppelborn.
Kann man diese “kleinen Ungenauigkeiten” herausfiltern, indem man verlangt, dass z.B. mindestens 50 nodes des sets innerhalb einer area mit dem tag “boundary”=“postal_code” liegen müssen?

Filtern geht nicht, aber wie wär’s mit Zählen: http://overpass-turbo.eu/s/6jb


/* 
   Zur administrativen Grenze von Eppelborn alle Postal_code boundaries samt
   Zahl der jeweils dort enthaltenen Knoten ausgeben          - couchmapper 301114
*/   

[timeout:300]
[out:csv( postal_code, ::count)];

area["boundary"="administrative"]["de:amtlicher_gemeindeschluessel"="10043111"]->.a1;
rel(pivot.a1); > -> .n1;
node[~"."~"."](area.a1) -> .n2;
(.n2; - .n1;)->.n0;
.n0 is_in;
area._["boundary"="postal_code"];
foreach->.pc (
  .pc out;
  node[~"."~"."](area.pc)->.pcn;
  (.pcn; .n0;)->.alles;
  (.pcn; - .n0;)->.pcn_ohne_n0;
  (.n0; - .pcn;)->.n0_ohne_pcn;
  ((.alles; - .pcn_ohne_n0;) - .n0_ohne_pcn;);
  out count;
);  


postal_code	@count
66571	
	851
66822	
	1

Geht natürlich auch für alle Gemeinden im Saarland: http://overpass-turbo.eu/s/6j9

Ist aber alles nicht mehr so ganz im sweet spot von Overpass API: hier hätte ich wohl schon längst zu PostGIS gegriffen :sunglasses:

Ich würde auf keinen Fall davon ausgehen, dass die Wikipedia-Angaben richtig/vollständig sind. Auch eine Abfrage bei der DPAG liefert nicht alle PLZ einer Gemeinde.

kommen wir mal von der Theorie zur Praxis:


select -plz.osm_id, plz.note,-boundary.osm_id,boundary.name 
  from planet_osm_polygon plz,
       planet_osm_polygon boundary
 where boundary.boundary='administrative'
   and plz.boundary = 'postal_code'
   and length(boundary.tags->'de:amtlicher_gemeindeschluessel') >5
   and st_intersects (boundary.way,  plz.way)
 order by boundary.name, plz.note;

ergibt http://osm.wno-edv-service.de:82/images/osm/postcodes/plz_pro_gemeinde.txt

Gruss
walter

ps: um die Umlaute und andere Feinheiten kümmere ich mich später mal.

Gut, dann fangen wir mal bei den eigentlichen Daten an: :sunglasses:


    3346971 | 66265 Heusweiler                                                                     | 1187149 | Eppelborn
    1184805 | 66557 Illingen                                                                       | 1187149 | Eppelborn
    1184803 | 66571 Eppelborn                                                                      | 1187149 | Eppelborn
    3348207 | 66636 Tholey                                                                         | 1187149 | Eppelborn
    3348209 | 66646 Marpingen                                                                      | 1187149 | Eppelborn
    3348204 | 66822 Lebach                                                                         | 1187149 | Eppelborn

Dat kann so nicht stimmen… da dürften maximal 66571 und 66822 rauskommen (siehe vorheriger Post).

Hast du ein Beispiel hierzu?

Jo, ist logisch. Wieder mal das blöde st_intersects, was den Rand mit nimmt. Nun denn, dann buffern wir halt.
Die 2-3, die ich überprüft hatte, waren natürlich sauber :frowning:

Gruss
walter

23701 Süsel. Es gibt in Süsel auch Adressen in PLZ 23684. Das ist aber nur eins von zig oder hunderten Beispielen.

ST_Relate

ach du grüne neune, da muß ich mich mal reinknien.

Danke für den Tip
walter

uii, wenn ich eine Testauswertung mit Eppelborn und Umgebung füttere, kommt tatsächlich das Richtige raus:


select -b.osm_id border,b.name,-p.osm_id pcborder,p.note 
  from planet_osm_polygon b,
       planet_osm_polygon p
 where b.osm_id in (-1187149)
   and p.osm_id in (-3346971,-1184805,-1184803,-3348207,-3348209,-3348204)
   and b.way && p.way
   and ST_Relate(b.way,p.way,'T********')
 order by b.name,b.osm_id desc, p.note
;

 border  |   name    | pcborder |      note       
---------+-----------+----------+-----------------
 1187149 | Eppelborn |  1184803 | 66571 Eppelborn
 1187149 | Eppelborn |  3348204 | 66822 Lebach
(2 rows)