Spaces:
Sleeping
Sleeping
File size: 5,306 Bytes
baf9496 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
import xml.etree.ElementTree as ET
import shapefile
import sys
# Input XML file
input_xml = sys.argv[1]
# Output shapefile
output_shapefile = sys.argv[2]
# Create shapefile writer
w = shapefile.Writer(output_shapefile)
w.autoBalance = 1
# Define fields for shapefile
w.field('gebnutzbez', 'C') # Gebaeude Nutzung Bezeichnung
w.field('funktion', 'C') # Funktion value (mapped to text)
w.field('fktkurz', 'C') # Kurz Funktion (<null>)
w.field('name', 'C') # Name value
w.field('anzahlgs', 'C') # Anzahl der Oberirdischen Geschosse
w.field('lagebeztxt', 'C') # Lagebezeichnung text
# Parse the XML file
tree = ET.parse(input_xml)
root = tree.getroot()
# Namespace map
ns = {'gml': 'http://www.opengis.net/gml/3.2',
'adv': 'http://www.adv-online.de/namespaces/adv/gid/6.0'}
# Building function mapping
funktion_mapping = {
'1000': 'Wohngebäude',
'2000': 'Gebäude für Wirtschaft oder Gewerbe',
'3000': 'Gebäude für öffentliche Zwecke',
'3020': 'Gebäude für Bildung und Forschung',
'2463': 'Garage',
'1610': 'Überdachung',
'2523': 'Umformer',
'1620': 'Treppe',
'9999': 'Sonstiges',
'1700': 'Mauer',
'3041': 'Kirche',
'3065': 'Kinderkrippe, Kindergarten, Kindertagesstätte',
'3043': 'Kapelle',
'3072': 'Feuerwehr'
}
# Helper function to extract polygon coordinates
def extract_polygon(coords_text):
try:
coords = list(map(float, coords_text.split()))
return [(coords[i], coords[i+1]) for i in range(0, len(coords), 2)]
except Exception as e:
print(f"Error parsing coordinates: {e}")
return None
# Cache frequently accessed elements
lagebezeichnung_cache = {}
for lage_elem in root.findall('.//adv:AX_LagebezeichnungMitHausnummer', ns):
gml_id = lage_elem.attrib.get('{http://www.opengis.net/gml/3.2}id')
if gml_id:
unverschluesselt_elem = lage_elem.find('.//adv:lagebezeichnung/adv:AX_Lagebezeichnung/adv:unverschluesselt', ns)
hausnummer_elem = lage_elem.find('.//adv:hausnummer', ns)
unverschluesselt = unverschluesselt_elem.text if unverschluesselt_elem is not None else ''
hausnummer = hausnummer_elem.text if hausnummer_elem is not None else ''
lagebezeichnung_cache[gml_id] = f"{unverschluesselt} {hausnummer}".strip()
# Process AX_Gebaeude and AX_SonstigesBauwerkOderSonstigeEinrichtung
for gebaeude in root.findall('.//adv:AX_Gebaeude', ns) + root.findall('.//adv:AX_SonstigesBauwerkOderSonstigeEinrichtung', ns):
# Create 'gebnutzbez' value
gebnutzbez = 'Gebaeude' if gebaeude.tag == '{http://www.adv-online.de/namespaces/adv/gid/6.0}AX_Gebaeude' else 'Sonstiges Bauwerk Oder Sonstige Einrichtung'
# Extract and map 'funktion' value
funktion_elem = gebaeude.find('.//adv:gebaeudefunktion', ns)
if funktion_elem is None:
funktion_elem = gebaeude.find('.//adv:bauwerksfunktion', ns)
funktion = funktion_mapping.get(funktion_elem.text, 'Unbekannt') if funktion_elem is not None and funktion_elem.text else '<null>'
# Set 'fktkurz' to '<null>'
fktkurz = '<null>'
# Extract 'name' value
name_elem = gebaeude.find('.//adv:name', ns)
name = name_elem.text if name_elem is not None else '<null>'
# Extract 'anzahlDerOberirdischenGeschosse' value
anzahlgs_elem = gebaeude.find('.//adv:anzahlDerOberirdischenGeschosse', ns)
anzahlgs = anzahlgs_elem.text if anzahlgs_elem is not None else '<null>'
# Extract 'lagebeztxt' based on the 'zeigtAuf' reference
zeigtauf_elem = gebaeude.find('.//adv:zeigtAuf', ns)
lagebeztxt = '<null>'
if zeigtauf_elem is not None:
xlink_href = zeigtauf_elem.attrib.get('{http://www.w3.org/1999/xlink}href')
if xlink_href:
gml_id = xlink_href.split(':')[-1]
lagebeztxt = lagebezeichnung_cache.get(gml_id, '<null>')
# Extract coordinates for the polygon
pos_list = gebaeude.findall('.//gml:posList', ns)
polygon_coords = []
if pos_list:
for pos in pos_list:
coords = extract_polygon(pos.text)
if coords:
polygon_coords.extend(coords)
if polygon_coords:
# Add polygon and record to shapefile
w.poly([polygon_coords])
w.record(gebnutzbez, funktion, fktkurz, name, anzahlgs, lagebeztxt)
# Save shapefile
w.close()
# Define spatial reference (projection file)
with open(output_shapefile.replace('.shp', '.prj'), 'w') as prj_file:
prj_file.write('PROJCS["ETRS89 / UTM zone 32N",'
'GEOGCS["ETRS89",'
'DATUM["European_Terrestrial_Reference_System_1989",'
'SPHEROID["GRS 1980",6378137,298.257222101]],'
'PRIMEM["Greenwich",0],'
'UNIT["degree",0.0174532925199433]],'
'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]]') |