NAS-ALKIS-Conversion / nutzung.py
shamim237's picture
Upload 11 files
baf9496 verified
import xml.etree.ElementTree as ET
import shapefile
import json
import re
import codecs
from shapely.geometry import Polygon, MultiPolygon
import sys
# Input XML file
input_xml = sys.argv[1]
# Input JSON file for bez_dict
bez_dict_file = sys.argv[2]
# Output shapefile
output_shapefile = sys.argv[3]
# Load bez_dict from JSON file
with codecs.open(bez_dict_file, 'r', encoding='utf-8') as f:
bez_dict = json.load(f)
# Create shapefile writer
w = shapefile.Writer(output_shapefile)
w.autoBalance = 1
# Define fields for shapefile
w.field('nutzart', 'C') # Nutzart as string
w.field('bez', 'C') # BEZ as string
w.field('name', 'C') # NAME as string
# Parse the XML file
tree = ET.parse(input_xml)
root = tree.getroot()
# List of tag names to process
tags_to_process = [
"AX_Gehoelz", "AX_Wohnbauflaeche", "AX_UnlandVegetationsloseFlaeche",
"AX_Strassenverkehr", "AX_StehendesGewaesser", "AX_SportFreizeitUndErholungsflaeche",
"AX_Platz", "AX_Landwirtschaft", "AX_IndustrieUndGewerbeflaeche",
"AX_Fliessgewaesser", "AX_FlaecheGemischterNutzung", "AX_Wald", "AX_Weg", "AX_Friedhof",
"AX_FlaecheBesondererFunktionalerPraegung", "AX_Bahnverkehr"
]
# Helper function to extract coordinates and create Polygon
def extract_polygon(coords_text):
coords = list(map(float, coords_text.split()))
return [(coords[i], coords[i+1]) for i in range(0, len(coords), 2)]
# Helper function to format nutzart
def format_nutzart(tag):
# Remove 'AX_' prefix and add spaces before capital letters
return ' '.join(re.findall('[A-Z][^A-Z]*', tag[3:]))
# Helper function to extract bez value
def extract_bez(elem):
funktion_elem = elem.find('.//{http://www.adv-online.de/namespaces/adv/gid/6.0}funktion')
vegetationsmerkmal_elem = elem.find('.//{http://www.adv-online.de/namespaces/adv/gid/6.0}vegetationsmerkmal')
if funktion_elem is not None:
return bez_dict.get(funktion_elem.text, "<null>")
elif vegetationsmerkmal_elem is not None:
return bez_dict.get(vegetationsmerkmal_elem.text, "<null>")
else:
return "<null>"
# Process the elements
for tag_name in tags_to_process:
for elem in root.findall(f".//{{http://www.adv-online.de/namespaces/adv/gid/6.0}}{tag_name}"):
# Format nutzart
nutzart = format_nutzart(tag_name)
# Extract bez
bez = extract_bez(elem)
# Extract name
name_elem = elem.find('.//{http://www.adv-online.de/namespaces/adv/gid/6.0}name')
name = name_elem.text if name_elem is not None else "<null>"
# Extract coordinates for polygon
coordinates = elem.findall('.//{http://www.opengis.net/gml/3.2}posList')
if coordinates:
polygon_coords = []
for coord_elem in coordinates:
polygon_coords.extend(extract_polygon(coord_elem.text))
# Create a Shapely polygon and fix invalid geometries
try:
poly = Polygon(polygon_coords)
if not poly.is_valid:
poly = poly.buffer(0)
if isinstance(poly, Polygon):
w.poly([list(poly.exterior.coords)])
elif isinstance(poly, MultiPolygon):
for p in poly.geoms:
w.poly([list(p.exterior.coords)])
# Add record to shapefile
w.record(nutzart, bez, name)
except Exception as e:
print(f"Error processing polygon: {e}")
# Save shapefile
w.close()
print("Shapefile created successfully.")
# Create .prj file
prj = open(output_shapefile.replace('.shp', '.prj'), "w")
epsg = 'PROJCS["ETRS89 / UTM zone 32N",GEOGCS["ETRS89",DATUM["European_Terrestrial_Reference_System_1989",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6258"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4258"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",9],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","25832"]]'
prj.write(epsg)
prj.close()
print("Shapefile and .prj file created successfully.")