Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Eric Duminil
Get Baden-Württemberg CityGML Opendata
Commits
a117f3b8
Commit
a117f3b8
authored
Jun 29, 2026
by
Eric Duminil
Browse files
Formatting
parent
1a46804f
Changes
2
Show whitespace changes
Inline
Side-by-side
download_LoD2_from_LGL_BW.py
View file @
a117f3b8
...
@@ -20,29 +20,28 @@ Required:
...
@@ -20,29 +20,28 @@ Required:
Eric Duminil, 2025
Eric Duminil, 2025
"""
"""
import
argparse
import
argparse
from
pathlib
import
Path
import
logging
from
math
import
floor
import
subprocess
import
re
import
re
import
urllib.request
import
subprocess
import
time
import
time
import
urllib.request
import
zipfile
import
zipfile
import
logging
from
math
import
floor
from
pathlib
import
Path
from
pyproj
import
CRS
from
pyproj
import
Transformer
from
pyproj
import
CRS
,
Transformer
from
shapely
import
wkt
from
shapely
import
wkt
from
shapely.ops
import
transform
from
shapely.geometry
import
Point
from
shapely.geometry
import
Point
from
shapely.ops
import
transform
from
get_coordinates_by_zipcode
import
get_coordinates_by_zipcode
from
get_coordinates_by_zipcode
import
get_coordinates_by_zipcode
# Setup logging
# Setup logging
logging
.
basicConfig
(
logging
.
basicConfig
(
level
=
logging
.
INFO
,
level
=
logging
.
INFO
,
format
=
'
%(levelname)s - %(message)s
'
,
format
=
"
%(levelname)s - %(message)s
"
,
)
)
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
...
@@ -51,12 +50,10 @@ COORDINATES_REGEX = re.compile(r"(\-?\d+\.\d*) (\-?\d+\.\d*)")
...
@@ -51,12 +50,10 @@ COORDINATES_REGEX = re.compile(r"(\-?\d+\.\d*) (\-?\d+\.\d*)")
CITYGML_SERVER
=
"https://opengeodata.lgl-bw.de/data/lod2"
CITYGML_SERVER
=
"https://opengeodata.lgl-bw.de/data/lod2"
RASTER
=
2
# [km]
RASTER
=
2
# [km]
KILOMETER
=
1000
# [m]
KILOMETER
=
1000
# [m]
BUNDESLAND
=
'
bw
'
BUNDESLAND
=
"
bw
"
# UTM32N, used in BW. https://epsg.io/32632
# UTM32N, used in BW. https://epsg.io/32632
TO_LOCAL_CRS
=
Transformer
.
from_crs
(
CRS
.
from_epsg
(
4326
),
TO_LOCAL_CRS
=
Transformer
.
from_crs
(
CRS
.
from_epsg
(
4326
),
CRS
.
from_epsg
(
32632
),
always_xy
=
True
)
CRS
.
from_epsg
(
32632
),
always_xy
=
True
)
UTM
=
32
UTM
=
32
...
@@ -68,7 +65,7 @@ GML_GLOB = "LoD2_*/LoD2_*.gml"
...
@@ -68,7 +65,7 @@ GML_GLOB = "LoD2_*/LoD2_*.gml"
def
find_simstadt_folder
():
def
find_simstadt_folder
():
"""Find SimStadt installation on desktop"""
"""Find SimStadt installation on desktop"""
try
:
try
:
simstadt_folder
=
next
(
x
for
x
in
Path
.
home
().
glob
(
'
Desktop/SimStadt*_0.*/
'
)
if
x
.
is_dir
())
simstadt_folder
=
next
(
x
for
x
in
Path
.
home
().
glob
(
"
Desktop/SimStadt*_0.*/
"
)
if
x
.
is_dir
())
logger
.
info
(
"RegionChooser has been found in %s"
,
simstadt_folder
)
logger
.
info
(
"RegionChooser has been found in %s"
,
simstadt_folder
)
return
simstadt_folder
return
simstadt_folder
except
StopIteration
:
except
StopIteration
:
...
@@ -87,10 +84,10 @@ def coordinates_to_grid(longitude: float, latitude: float) -> tuple[int, int]:
...
@@ -87,10 +84,10 @@ def coordinates_to_grid(longitude: float, latitude: float) -> tuple[int, int]:
def
wkt_polygon_to_bounding_box
(
location_name
:
str
,
wkt_str
:
str
)
->
tuple
[
int
,
int
,
int
,
int
]:
def
wkt_polygon_to_bounding_box
(
location_name
:
str
,
wkt_str
:
str
)
->
tuple
[
int
,
int
,
int
,
int
]:
"""Returns (x, y) of lower-left and bottom-right tiles, containing a given region."""
"""Returns (x, y) of lower-left and bottom-right tiles, containing a given region."""
if
'
POLYGON
'
not
in
wkt_str
:
if
"
POLYGON
"
not
in
wkt_str
:
raise
ValueError
(
f
"wkt for
{
location_name
}
should be a WKT POLYGON or MULTIPOLYGON"
)
raise
ValueError
(
f
"wkt for
{
location_name
}
should be a WKT POLYGON or MULTIPOLYGON"
)
coordinates
=
re
.
findall
(
r
'
\-?\d+\.\d+
'
,
wkt_str
)
coordinates
=
re
.
findall
(
r
"
\-?\d+\.\d+
"
,
wkt_str
)
lons
=
[
float
(
lon
)
for
lon
in
coordinates
[::
2
]]
lons
=
[
float
(
lon
)
for
lon
in
coordinates
[::
2
]]
lats
=
[
float
(
lat
)
for
lat
in
coordinates
[
1
::
2
]]
lats
=
[
float
(
lat
)
for
lat
in
coordinates
[
1
::
2
]]
...
@@ -98,8 +95,7 @@ def wkt_polygon_to_bounding_box(location_name: str, wkt_str: str) -> tuple[int,
...
@@ -98,8 +95,7 @@ def wkt_polygon_to_bounding_box(location_name: str, wkt_str: str) -> tuple[int,
min_lon
,
max_lon
=
min
(
lons
),
max
(
lons
)
min_lon
,
max_lon
=
min
(
lons
),
max
(
lons
)
min_lat
,
max_lat
=
min
(
lats
),
max
(
lats
)
min_lat
,
max_lat
=
min
(
lats
),
max
(
lats
)
logger
.
info
(
"%s (%.3f°N %.3f°E -> %.3f°N %.3f°E)"
,
logger
.
info
(
"%s (%.3f°N %.3f°E -> %.3f°N %.3f°E)"
,
location_name
,
max_lat
,
min_lon
,
min_lat
,
max_lon
)
location_name
,
max_lat
,
min_lon
,
min_lat
,
max_lon
)
x1
,
y1
=
coordinates_to_grid
(
min_lon
,
min_lat
)
x1
,
y1
=
coordinates_to_grid
(
min_lon
,
min_lat
)
x2
,
y2
=
coordinates_to_grid
(
max_lon
,
max_lat
)
x2
,
y2
=
coordinates_to_grid
(
max_lon
,
max_lat
)
...
@@ -142,45 +138,47 @@ def download_whole_region(output_dir: Path, wkt_region: str, x1: int, x2: int, y
...
@@ -142,45 +138,47 @@ def download_whole_region(output_dir: Path, wkt_region: str, x1: int, x2: int, y
def
extract_region
(
output_dir
:
Path
,
location_name
:
str
,
wkt_str
:
str
,
simstadt_folder
:
Path
)
->
Path
|
None
:
def
extract_region
(
output_dir
:
Path
,
location_name
:
str
,
wkt_str
:
str
,
simstadt_folder
:
Path
)
->
Path
|
None
:
"""Uses RegionChooser to extract a given region from all the CityGML files found in subfolder."""
"""Uses RegionChooser to extract a given region from all the CityGML files found in subfolder."""
output_file
=
output_dir
/
(
location_name
+
'
.gml
'
)
output_file
=
output_dir
/
(
location_name
+
"
.gml
"
)
if
output_file
.
exists
():
if
output_file
.
exists
():
logger
.
info
(
" %s already exists. Not extracting."
,
output_file
)
logger
.
info
(
" %s already exists. Not extracting."
,
output_file
)
return
output_file
return
output_file
region_chooser_libs
=
simstadt_folder
/
'
lib/*
'
region_chooser_libs
=
simstadt_folder
/
"
lib/*
"
gml_inputs
=
list
(
output_dir
.
glob
(
GML_GLOB
))
gml_inputs
=
list
(
output_dir
.
glob
(
GML_GLOB
))
if
len
(
gml_inputs
)
==
0
:
if
len
(
gml_inputs
)
==
0
:
logger
.
error
(
logger
.
error
(
"Error: No CityGML found. At least part of the region should be in Baden-Württemberg!"
)
"Error: No CityGML found. At least part of the region should be in Baden-Württemberg!"
)
return
return
params_path
=
output_dir
/
'
params.txt
'
params_path
=
output_dir
/
"
params.txt
"
wkt_path
=
output_dir
/
'
region.wkt
'
wkt_path
=
output_dir
/
"
region.wkt
"
local_wkt
=
convert_wkt_to_local
(
wkt_str
)
local_wkt
=
convert_wkt_to_local
(
wkt_str
)
logger
.
info
(
" Extracting %s."
,
output_file
)
logger
.
info
(
" Extracting %s."
,
output_file
)
with
open
(
wkt_path
,
'w'
)
as
f
:
with
open
(
wkt_path
,
"w"
)
as
f
:
f
.
write
(
local_wkt
)
f
.
write
(
local_wkt
)
with
open
(
params_path
,
'w'
,
encoding
=
'
utf-8
'
)
as
f
:
with
open
(
params_path
,
"w"
,
encoding
=
"
utf-8
"
)
as
f
:
f
.
write
(
"
--input
\n
\"
"
)
f
.
write
(
'
--input
\n
"
'
)
f
.
write
(
','
.
join
(
f
'
{
gml
.
as_posix
()
}
'
for
gml
in
gml_inputs
))
f
.
write
(
","
.
join
(
f
"
{
gml
.
as_posix
()
}
"
for
gml
in
gml_inputs
))
f
.
write
(
"
\
"\n
"
)
f
.
write
(
'
"
\n
'
)
f
.
write
(
"--output
\n
"
)
f
.
write
(
"--output
\n
"
)
f
.
write
(
f
'"
{
output_file
.
as_posix
()
}
"
\n
'
)
f
.
write
(
f
'"
{
output_file
.
as_posix
()
}
"
\n
'
)
f
.
write
(
'
--local
\n
'
)
f
.
write
(
"
--local
\n
"
)
f
.
write
(
"--wkt
\n
"
)
f
.
write
(
"--wkt
\n
"
)
f
.
write
(
f
'"
{
wkt_path
.
as_posix
()
}
"
\n
'
)
f
.
write
(
f
'"
{
wkt_path
.
as_posix
()
}
"
\n
'
)
result
=
subprocess
.
run
(
result
=
subprocess
.
run
([
'java'
,
'-classpath'
,
f
'
{
region_chooser_libs
}
'
,
[
'eu.simstadt.regionchooser.RegionChooserCLI'
,
"java"
,
f
'@
{
params_path
}
'
"-classpath"
,
f
"
{
region_chooser_libs
}
"
,
"eu.simstadt.regionchooser.RegionChooserCLI"
,
f
"@
{
params_path
}
"
,
],
],
text
=
True
,
text
=
True
,
capture_output
=
True
,
capture_output
=
True
,
check
=
False
check
=
False
,
)
)
if
result
.
returncode
!=
0
:
if
result
.
returncode
!=
0
:
if
result
.
stderr
:
if
result
.
stderr
:
...
@@ -197,10 +195,10 @@ def get_wkt(wkt_or_zipcode: str) -> str:
...
@@ -197,10 +195,10 @@ def get_wkt(wkt_or_zipcode: str) -> str:
"70567"
"70567"
"70567,70569"
"70567,70569"
"""
"""
if
'
POLYGON
'
in
wkt_or_zipcode
:
if
"
POLYGON
"
in
wkt_or_zipcode
:
return
wkt_or_zipcode
return
wkt_or_zipcode
return
get_coordinates_by_zipcode
(
wkt_or_zipcode
.
split
(
','
))
return
get_coordinates_by_zipcode
(
wkt_or_zipcode
.
split
(
","
))
def
convert_coordinates
(
match
):
def
convert_coordinates
(
match
):
...
@@ -225,40 +223,56 @@ Examples:
...
@@ -225,40 +223,56 @@ Examples:
python download_LoD2_from_LGL_BW.py StuttgartCenter "POLYGON((9.175287 48.780916, 9.185501 48.777522, 9.181467 48.773704, 9.174429 48.768472, 9.168807 48.773902, 9.175287 48.780916))"
python download_LoD2_from_LGL_BW.py StuttgartCenter "POLYGON((9.175287 48.780916, 9.185501 48.777522, 9.181467 48.773704, 9.174429 48.768472, 9.168807 48.773902, 9.175287 48.780916))"
python download_LoD2_from_LGL_BW.py Freiburg "79098,79102" --output-folder="/path/to/FreiburgFolder"
python download_LoD2_from_LGL_BW.py Freiburg "79098,79102" --output-folder="/path/to/FreiburgFolder"
python download_LoD2_from_LGL_BW.py Möhringen "70567" --download-only
python download_LoD2_from_LGL_BW.py Möhringen "70567" --download-only
"""
"""
,
)
)
parser
.
add_argument
(
'name'
,
type
=
str
,
parser
.
add_argument
(
"name"
,
type
=
str
,
help
=
"Name of the region. Output files will use this name."
)
help
=
'Name of the region. Output files will use this name.'
)
parser
.
add_argument
(
'region'
,
type
=
str
,
parser
.
add_argument
(
help
=
'Desired region as as WKT POLYGON/MULTIPOLYGON string or zipcode(s) (comma-separated).'
)
"region"
,
type
=
str
,
help
=
"Desired region as as WKT POLYGON/MULTIPOLYGON string or zipcode(s) (comma-separated)."
)
parser
.
add_argument
(
'--download-only'
,
action
=
'store_true'
,
parser
.
add_argument
(
help
=
'Only download files without extracting the region (default: False).'
)
"--download-only"
,
action
=
"store_true"
,
help
=
"Only download files without extracting the region (default: False)."
,
)
parser
.
add_argument
(
'--simstadt-folder'
,
type
=
Path
,
default
=
None
,
parser
.
add_argument
(
help
=
'Path to SimStadt installation folder. By default, tries to find it on the Desktop.'
)
"--simstadt-folder"
,
type
=
Path
,
default
=
None
,
help
=
"Path to SimStadt installation folder. By default, tries to find it on the Desktop."
,
)
parser
.
add_argument
(
'--output-folder'
,
type
=
Path
,
default
=
None
,
parser
.
add_argument
(
help
=
'Folder in which the tiles should be downloaded and extracted. By default, use the folder of the current script / name.proj.'
)
"--output-folder"
,
type
=
Path
,
default
=
None
,
help
=
"Folder in which the tiles should be downloaded and extracted. By default, use the folder of the current script / name.proj."
,
)
return
parser
.
parse_args
()
return
parser
.
parse_args
()
def
main
(
location_name
:
str
,
wkt_or_zipcode
:
str
,
download_only
:
bool
=
False
,
def
main
(
simstadt_folder
:
Path
|
str
|
None
=
None
,
output_folder
:
Path
|
str
|
None
=
None
)
->
Path
|
None
:
location_name
:
str
,
wkt_or_zipcode
:
str
,
download_only
:
bool
=
False
,
simstadt_folder
:
Path
|
str
|
None
=
None
,
output_folder
:
Path
|
str
|
None
=
None
,
)
->
Path
|
None
:
"""Main function to process arguments and run the download/extraction"""
"""Main function to process arguments and run the download/extraction"""
# Validate location name
# Validate location name
if
' '
in
location_name
:
if
" "
in
location_name
:
logger
.
warning
(
"Location contains spaces, some workflows might fail."
)
logger
.
warning
(
"Location contains spaces, some workflows might fail."
)
if
output_folder
:
if
output_folder
:
output_folder
=
Path
(
output_folder
)
output_folder
=
Path
(
output_folder
)
else
:
else
:
# Create output directory
# Create output directory
output_folder
=
SCRIPT_DIR
/
(
location_name
+
'
.proj
'
)
output_folder
=
SCRIPT_DIR
/
(
location_name
+
"
.proj
"
)
output_folder
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
output_folder
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
...
@@ -279,8 +293,7 @@ def main(location_name: str, wkt_or_zipcode: str, download_only: bool = False,
...
@@ -279,8 +293,7 @@ def main(location_name: str, wkt_or_zipcode: str, download_only: bool = False,
if
simstadt_folder
:
if
simstadt_folder
:
simstadt_folder
=
Path
(
simstadt_folder
)
simstadt_folder
=
Path
(
simstadt_folder
)
else
:
else
:
logger
.
error
(
logger
.
error
(
"No SimStadt installation found! Please provide --simstadt-folder or use --download-only."
)
"No SimStadt installation found! Please provide --simstadt-folder or use --download-only."
)
return
return
gml_path
=
extract_region
(
output_folder
,
location_name
,
wkt_str
,
simstadt_folder
)
gml_path
=
extract_region
(
output_folder
,
location_name
,
wkt_str
,
simstadt_folder
)
...
@@ -291,6 +304,6 @@ def main(location_name: str, wkt_or_zipcode: str, download_only: bool = False,
...
@@ -291,6 +304,6 @@ def main(location_name: str, wkt_or_zipcode: str, download_only: bool = False,
return
gml_path
return
gml_path
if
__name__
==
'
__main__
'
:
if
__name__
==
"
__main__
"
:
args
=
parse_arguments
()
args
=
parse_arguments
()
main
(
args
.
name
,
args
.
region
,
args
.
download_only
,
args
.
simstadt_folder
,
args
.
output_folder
)
main
(
args
.
name
,
args
.
region
,
args
.
download_only
,
args
.
simstadt_folder
,
args
.
output_folder
)
get_coordinates_by_zipcode.py
View file @
a117f3b8
...
@@ -27,11 +27,12 @@ import argparse
...
@@ -27,11 +27,12 @@ import argparse
import
json
import
json
import
re
import
re
from
pathlib
import
Path
from
pathlib
import
Path
from
shapely.geometry
import
shape
from
shapely.geometry
import
shape
from
shapely.ops
import
unary_union
from
shapely.ops
import
unary_union
INPUT_FOLDER
=
Path
(
'
plz
'
)
INPUT_FOLDER
=
Path
(
"
plz
"
)
PLZ_FILENAME
:
str
=
'
plz-5stellig.geojson
'
PLZ_FILENAME
:
str
=
"
plz-5stellig.geojson
"
PLZ_SHAPE_FILE
=
INPUT_FOLDER
/
PLZ_FILENAME
PLZ_SHAPE_FILE
=
INPUT_FOLDER
/
PLZ_FILENAME
PRECISION
:
float
=
10
# [m]
PRECISION
:
float
=
10
# [m]
ONE_DEGREE
:
float
=
40e6
/
360
# [m]
ONE_DEGREE
:
float
=
40e6
/
360
# [m]
...
@@ -42,16 +43,17 @@ CACHED: bool = False
...
@@ -42,16 +43,17 @@ CACHED: bool = False
def
_download_plz_shapes_if_needed
()
->
None
:
def
_download_plz_shapes_if_needed
()
->
None
:
if
not
PLZ_SHAPE_FILE
.
exists
():
if
not
PLZ_SHAPE_FILE
.
exists
():
from
tqdm
import
tqdm
import
requests
import
requests
from
tqdm
import
tqdm
print
(
"Downloading %s..."
%
PLZ_FILENAME
)
print
(
"Downloading %s..."
%
PLZ_FILENAME
)
URL
=
"https://downloads.suche-postleitzahl.org/v2/public/"
+
PLZ_FILENAME
URL
=
"https://downloads.suche-postleitzahl.org/v2/public/"
+
PLZ_FILENAME
response
=
requests
.
get
(
URL
,
stream
=
True
)
response
=
requests
.
get
(
URL
,
stream
=
True
)
INPUT_FOLDER
.
mkdir
(
exist_ok
=
True
)
INPUT_FOLDER
.
mkdir
(
exist_ok
=
True
)
with
open
(
PLZ_SHAPE_FILE
,
"wb"
)
as
handle
:
with
open
(
PLZ_SHAPE_FILE
,
"wb"
)
as
handle
:
for
data
in
tqdm
(
response
.
iter_content
(
chunk_size
=
1024
),
unit
=
'
kB
'
):
for
data
in
tqdm
(
response
.
iter_content
(
chunk_size
=
1024
),
unit
=
"
kB
"
):
handle
.
write
(
data
)
handle
.
write
(
data
)
print
(
'
Done
'
)
print
(
"
Done
"
)
def
_get_plz_shapes
()
->
dict
:
def
_get_plz_shapes
()
->
dict
:
...
@@ -63,7 +65,7 @@ def _get_plz_shapes() -> dict:
...
@@ -63,7 +65,7 @@ def _get_plz_shapes() -> dict:
try
:
try
:
print
(
"Parsing %s..."
%
PLZ_FILENAME
)
print
(
"Parsing %s..."
%
PLZ_FILENAME
)
with
open
(
PLZ_SHAPE_FILE
)
as
f
:
with
open
(
PLZ_SHAPE_FILE
)
as
f
:
print
(
'
Done
'
)
print
(
"
Done
"
)
PLZ_SHAPES
=
json
.
load
(
f
)
PLZ_SHAPES
=
json
.
load
(
f
)
CACHED
=
True
CACHED
=
True
return
PLZ_SHAPES
return
PLZ_SHAPES
...
@@ -77,21 +79,21 @@ def get_coordinates_by_zipcode(plz_patterns: list[str], precision: float = PRECI
...
@@ -77,21 +79,21 @@ def get_coordinates_by_zipcode(plz_patterns: list[str], precision: float = PRECI
geometries
=
[]
geometries
=
[]
for
plz_pattern
in
plz_patterns
:
for
plz_pattern
in
plz_patterns
:
found
=
False
found
=
False
for
plz_geojson
in
plz_shapes
[
'
features
'
]:
for
plz_geojson
in
plz_shapes
[
"
features
"
]:
if
re
.
match
(
plz_pattern
,
plz_geojson
[
'
properties
'
][
'
plz
'
]):
if
re
.
match
(
plz_pattern
,
plz_geojson
[
"
properties
"
][
"
plz
"
]):
found
=
True
found
=
True
properties
=
plz_geojson
[
'
properties
'
]
properties
=
plz_geojson
[
"
properties
"
]
print
(
'
## %s
'
%
properties
[
'
note
'
])
print
(
"
## %s
"
%
properties
[
"
note
"
])
print
(
'
Population : %d
'
%
properties
[
'
einwohner
'
])
print
(
"
Population : %d
"
%
properties
[
"
einwohner
"
])
print
(
'
Area : %.2f km²
'
%
properties
[
'
qkm
'
])
print
(
"
Area : %.2f km²
"
%
properties
[
"
qkm
"
])
# NOTE : Geometry can be either a polygon,
# NOTE : Geometry can be either a polygon,
# a MultiPolygon : 98694 Ilmenau
# a MultiPolygon : 98694 Ilmenau
# or a polygon with holes : 31860 Emmerthal
# or a polygon with holes : 31860 Emmerthal
print
(
'
WKT Polygon :
'
)
print
(
"
WKT Polygon :
"
)
geometries
.
append
(
shape
(
plz_geojson
[
'
geometry
'
]))
geometries
.
append
(
shape
(
plz_geojson
[
"
geometry
"
]))
if
not
found
:
if
not
found
:
raise
AttributeError
(
f
"Sorry, no information could be found for PLZ=
{
plz_pattern
}
"
)
raise
AttributeError
(
f
"Sorry, no information could be found for PLZ=
{
plz_pattern
}
"
)
...
@@ -101,6 +103,7 @@ def get_coordinates_by_zipcode(plz_patterns: list[str], precision: float = PRECI
...
@@ -101,6 +103,7 @@ def get_coordinates_by_zipcode(plz_patterns: list[str], precision: float = PRECI
print
(
wkt_polygon
)
print
(
wkt_polygon
)
try
:
try
:
import
pyperclip
import
pyperclip
pyperclip
.
copy
(
wkt_polygon
)
pyperclip
.
copy
(
wkt_polygon
)
print
(
"WKT Polygon copied to clipboard."
)
print
(
"WKT Polygon copied to clipboard."
)
except
(
ModuleNotFoundError
,
RuntimeError
):
except
(
ModuleNotFoundError
,
RuntimeError
):
...
@@ -112,11 +115,9 @@ def get_coordinates_by_zipcode(plz_patterns: list[str], precision: float = PRECI
...
@@ -112,11 +115,9 @@ def get_coordinates_by_zipcode(plz_patterns: list[str], precision: float = PRECI
return
wkt_polygon
return
wkt_polygon
if
__name__
==
'__main__'
:
if
__name__
==
"__main__"
:
parser
=
argparse
.
ArgumentParser
(
description
=
'Get WKT geometry for desired PLZs'
)
parser
=
argparse
.
ArgumentParser
(
description
=
"Get WKT geometry for desired PLZs"
)
parser
.
add_argument
(
'plzs'
,
metavar
=
'PLZ'
,
type
=
str
,
nargs
=
'+'
,
parser
.
add_argument
(
"plzs"
,
metavar
=
"PLZ"
,
type
=
str
,
nargs
=
"+"
,
help
=
"desired PLZs"
)
help
=
'desired PLZs'
)
parser
.
add_argument
(
"-p"
,
"--precision"
,
default
=
PRECISION
,
type
=
int
,
help
=
"precision of returned polygon [m]"
)
parser
.
add_argument
(
'-p'
,
'--precision'
,
default
=
PRECISION
,
type
=
int
,
help
=
'precision of returned polygon [m]'
)
args
=
parser
.
parse_args
()
args
=
parser
.
parse_args
()
get_coordinates_by_zipcode
(
args
.
plzs
,
args
.
precision
)
get_coordinates_by_zipcode
(
args
.
plzs
,
args
.
precision
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment