Commit c500031c authored by Eric Duminil's avatar Eric Duminil
Browse files

Script to get coordinates by zipcode

parent 3e2ed659
...@@ -7,3 +7,4 @@ ...@@ -7,3 +7,4 @@
*.pdf *.pdf
cache cache
input input
plz/plz-5stellig.geojson
"""
For a given German Zipcode, returns the corresponding WKT Polygon or Multipolygon.
If pyperclip is installed, the WKT gets copied to the clipboard,
e.g. for RegionChooser or download_files_from_LGL_BW.py.
Also accepts multiple Zipcodes, or Zipcode prefix.
python get_coordinates_by_zipcode.py --help
usage: get_coordinates_by_zipcode.py [-h] PLZ [PLZ ...]
Get WKT geometry for desired PLZs
positional arguments:
PLZ desired PLZs
options:
-h, --help show this help message and exit
> python get_coordinates_by_zipcode.py 70174
> python get_coordinates_by_zipcode.py 70567 70569
> python get_coordinates_by_zipcode.py 70
"""
import argparse
import json
import re
from pathlib import Path
from shapely.geometry import shape
from shapely.ops import unary_union
INPUT_FOLDER = Path('plz')
PLZ_FILENAME = 'plz-5stellig.geojson'
PLZ_SHAPES = INPUT_FOLDER / PLZ_FILENAME
def download_if_needed():
if not PLZ_SHAPES.exists():
from tqdm import tqdm
import requests
URL = "https://downloads.suche-postleitzahl.org/v2/public/" + PLZ_FILENAME
response = requests.get(URL, stream=True)
INPUT_FOLDER.mkdir(exist_ok=True)
with open(PLZ_SHAPES, "wb") as handle:
for data in tqdm(response.iter_content(chunk_size=1024), unit='kB'):
handle.write(data)
def parse_data():
print("Parsing %s..." % PLZ_FILENAME)
download_if_needed()
try:
with open(PLZ_SHAPES) as f:
print(' Done')
return json.load(f)
except json.decoder.JSONDecodeError:
PLZ_SHAPES.unlink()
raise AttributeError(f"{PLZ_FILENAME} seems to be damaged. Removing it. Please try again!")
def get_plz(data, plz_patterns):
geometries = []
for plz_pattern in plz_patterns:
found = False
for plz_geojson in data['features']:
if re.match(plz_pattern, plz_geojson['properties']['plz']):
found = True
properties = plz_geojson['properties']
print('## %s' % properties['note'])
print('Population : %d' % properties['einwohner'])
print('Area : %.2f km²' % properties['qkm'])
# NOTE : Geometry can be either a polygon,
# a MultiPolygon : 98694 Ilmenau
# or a polygon with holes : 31860 Emmerthal
print('WKT Polygon : ')
geometries.append(shape(plz_geojson['geometry']))
if not found:
raise AttributeError(f"Sorry, no information could be found for PLZ={plz_pattern}")
merged = unary_union(geometries)
wkt_polygon = merged.simplify(0.0001).wkt
print(wkt_polygon)
try:
import pyperclip
pyperclip.copy(wkt_polygon)
print("WKT Polygon copied to clipboard.")
except ModuleNotFoundError:
pass
print()
print("Done!")
return wkt_polygon
def main(plzs):
data = parse_data()
get_plz(data, plzs)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Get WKT geometry for desired PLZs')
parser.add_argument('plzs', metavar='PLZ', type=str, nargs='+',
help='desired PLZs')
args = parser.parse_args()
main(args.plzs)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment