# Vollständiges Python-Skript zur Wanderweg-Analyse der regionalen Pärke der Schweiz
# Für jeden Park wird die Berechnung in einer Schleife durchgeführt und in einer eindeutigen GDB gespeichert.
# Dominik Erni
# PWRG2
# Module Import
import arcpy
import os
import geopandas as gpd
import osmnx as ox
arcpy.env.overwriteOutput = True
# Perimeter
perimeters = [
("a", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\a"),
("b", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\b"),
("c", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\c"),
("d", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\d"),
("e", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\e"),
("f", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\f"),
("g", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\g"),
("h", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\h"),
("i", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\i"),
("j", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\j"),
("k", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\k"),
("l", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\l"),
("m", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\m"),
("n", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\n"),
("o", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\o"),
("p", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\p"),
("q", r"C:\Users\domin\Documents\Projekt_PWRG2\data\Perimeter\Perimeter.gdb\q")
]
# Hilfsfunktionen
def get_poi_type(row):
'''OSM-Typen filtern für Handhabung in Feature Class'''
if row.get("amenity") in ["restaurant", "drinking_water", "bbq"]:
return row["amenity"]
if row.get("natural") == "peak":
return "peak"
if row.get("tourism") == "viewpoint":
return "viewpoint"
return "other"
def get_unique_values(fc, field):
'''Auflistung von Werten innerhalb Attributfeld.'''
values = set()
with arcpy.da.SearchCursor(fc, [field]) as cursor:
for row in cursor:
if row[0] is not None:
values.add(row[0])
return sorted(values)
# Hauptfunktion Analyse
def run_analysis(perimeter_name, perimeter_fc):
# Perimeter abrufen # ---------------------------------------------
OutDir = r"C:\Users\domin\Documents\Projekt_PWRG2\output\Perimeter"
perimeter_shp = r"perimeter.shp"
print("Ausgewählter Perimeter: {0}.".format(perimeter_name)) # klassische print-Variante Python 3 gem. Literatur Tateosian, 2015. Neu: f-string.
# fcs in shape konventieren
arcpy.FeatureClassToFeatureClass_conversion(perimeter_fc, OutDir, perimeter_shp)
# OSM Abfrage POI # ---------------------------------------------
# Perimeter/Area für OSM lesen in geopandas (CH1903+)
perimeter = r"C:\Users\domin\Documents\Projekt_PWRG2\output\Perimeter\perimeter.shp"
area = gpd.read_file(perimeter)
area = area.to_crs(epsg=2056)
# Für OSM-Abfrage WGS84
area_wgs84 = area.to_crs(epsg=4326)
polygon = area_wgs84.geometry.iloc[0]
# OSM-Tags definieren
tags = {
"amenity": [
"restaurant",
"drinking_water",
"bbq"
],
"natural": [
"peak"
],
"tourism": [
"viewpoint"
]
}
# OSM-Abfrage
pois = ox.features_from_polygon(polygon, tags)
# Reprojektion zurück nach CH1903+
pois = pois.to_crs(epsg=2056)
pois_points = pois[pois.geometry.type == "Point"]
pois_points["poi_type"] = pois_points.apply(get_poi_type, 1) # Anwendung Funktion "get_poi_type"
# File GDB erstellen
out_folder = r"C:\Users\domin\Documents\Projekt_PWRG2\data\OSM"
gdb_name = "osm_pois.gdb"
out_fc_name = "pois_osm"
gdb_path = os.path.join(out_folder, gdb_name)
if not arcpy.Exists(gdb_path):
arcpy.CreateFileGDB_management(out_folder, gdb_name)
# In GDB schreiben
pois_points.to_file(
gdb_path,
driver="OpenFileGDB",
layer=out_fc_name
)
# Clip Grundlagedaten mit Perimeter # ---------------------------------------------
# Teil Vektordaten (für Feature Classes in allen Unterordner)
# Ausnahme Ordner Perimeter und Order OSM
rootDir = r"C:\Users\domin\Documents\Projekt_PWRG2\data"
outDir = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch"
exclude_dirs = ["perimeter", "osm"]
# Scratch-GDB erstellen
scratch_gdb = os.path.join(outDir, "scratch.gdb")
# scratch.gdb erstellen (falls nicht vorhanden)
if not arcpy.Exists(scratch_gdb):
arcpy.management.CreateFileGDB(scratch_gdb)
for root, dirs, files in os.walk(rootDir):
dirs[:] = [d for d in dirs if d.lower() not in exclude_dirs]
for d in dirs:
if d.lower().endswith(".gdb"):
gdb_path = os.path.join(root, d)
arcpy.env.workspace = gdb_path
fcs = arcpy.ListFeatureClasses()
for fc in fcs:
outfile = os.path.join(scratch_gdb, f"{fc}_clip")
arcpy.analysis.Clip(in_features=fc,
clip_features=perimeter_fc,
out_feature_class=outfile)
# Grundlagedaten mit Perimeter clippen
# Teil Rasterdaten
rootDir = r"C:\Users\domin\Documents\Projekt_PWRG2\data"
outDir = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch"
exclude_dirs = {"perimeter", "osm"}
for root, dirs, files in os.walk(rootDir):
dirs[:] = [d for d in dirs if d.lower() not in exclude_dirs]
for d in dirs:
gdb_path = os.path.join(root, d)
arcpy.env.workspace = gdb_path
rasters = arcpy.ListRasters("*", "TIF")
for ras in rasters:
base = os.path.splitext(ras)[0] # Unterschied zu Vektordateien: Hier müssen die Endungen .tif etc entfernt werden.
out_name = arcpy.ValidateTableName(f"{base}_clip", scratch_gdb) # Namens-Validierung hier auch ergänzt, weil Raster-Daten.
outfile = os.path.join(scratch_gdb, out_name)
arcpy.management.Clip(
in_raster=ras,
rectangle="#",
out_raster=outfile,
in_template_dataset=perimeter_fc,
nodata_value="-9999",
clipping_geometry="ClippingGeometry"
)
# Nachbearbeitung nach Clip # ---------------------------------------------
# Landcover Bezeichnungen hinzufügen
clipped_fc = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch.gdb\TLMRegio_LandCover_clip"
new_field = "LANDCOVER_LABEL"
# Prüfen, ob Feld bereits existiert
field_names = [f.name for f in arcpy.ListFields(clipped_fc)]
if new_field not in field_names:
arcpy.management.AddField(clipped_fc, new_field, "TEXT", field_length=50)
mapping = {
0: "Wald",
1: "Fels",
2: "Geroell",
3: "Gletscher",
4: "See",
5: "Siedl",
6: "Stadtzentr",
7: "Stausee",
8: "Obstanlage",
9: "Reben",
10: "Sumpf",
11: "Kulturland"
}
with arcpy.da.UpdateCursor(clipped_fc, ["OBJVAL", "LANDCOVER_LABEL"]) as cursor:
for val, label in cursor:
cursor.updateRow((val, mapping.get(val, "Unbekannt")))
# POIs kategorisieren für Analyse
in_pois = r"C:\Users\domin\Documents\Projekt_PWRG2\data\OSM\osm_pois.gdb\pois_osm"
out_gdb = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch.gdb"
# Restaurants
arcpy.conversion.FeatureClassToFeatureClass(
in_features=in_pois,
out_path=out_gdb,
out_name="poi_restaurant",
where_clause="poi_type = 'restaurant'"
)
# Gipfel und Aussichtspunkte
arcpy.conversion.FeatureClassToFeatureClass(
in_features=in_pois,
out_path=out_gdb,
out_name="poi_view",
where_clause="poi_type IN ('peak', 'viewpoint')"
)
# Grillplätze und Trinkwasserstellen
arcpy.conversion.FeatureClassToFeatureClass(
in_features=in_pois,
out_path=out_gdb,
out_name="poi_infrastructure",
where_clause="poi_type IN ('bbq', 'drinking_water')"
)
# Biotopinventare zusammenfassen
scratch_gdb = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch.gdb"
biotope_fcs = [
os.path.join(scratch_gdb, "hochmoor_clip"),
os.path.join(scratch_gdb, "flachmoor_clip"),
os.path.join(scratch_gdb, "tww_clip"),
os.path.join(scratch_gdb, "Auengebiete_clip"),
os.path.join(scratch_gdb, "amphibLaichgebiet_clip"),
]
out_biotope = os.path.join(scratch_gdb, "Biotopinventare")
# Merge
arcpy.management.Merge(biotope_fcs, out_biotope)
out_biotope_dissolve = os.path.join(scratch_gdb, "Biotopinventare_Dissolved")
# Dissolve
arcpy.management.Dissolve(
in_features=out_biotope,
out_feature_class=out_biotope_dissolve,
dissolve_field=None
)
if arcpy.Exists(out_biotope):
arcpy.management.Delete(out_biotope)
# Segmentierung Wanderwegenetz # ---------------------------------------------
input_fc = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch.gdb\main_tlm_strassen_strasse_clip"
root = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch"
analysis_gdb_name = "scratch_analysis.gdb"
analysis_gdb = os.path.join(root, analysis_gdb_name)
segment_length = 100 # Meter
# scratch_analysis.gdb erstellen (falls nicht vorhanden)
if not arcpy.Exists(analysis_gdb):
arcpy.management.CreateFileGDB(
out_folder_path=root,
out_name=analysis_gdb_name
)
# Dissolve
dissolved_fc = os.path.join(analysis_gdb, "wanderwege_dissolved")
arcpy.management.Dissolve(
in_features=input_fc,
out_feature_class=dissolved_fc,
dissolve_field=None
)
# Punkte entlang der Linien erzeugen
points_fc = os.path.join(analysis_gdb, "split_points")
arcpy.management.GeneratePointsAlongLines(
Input_Features=dissolved_fc,
Output_Feature_Class=points_fc,
Point_Placement="DISTANCE",
Distance=f"{segment_length} Meters"
)
# Linien an diesen Punkten splitten
out_name = f"wanderwege_seg"
out_fc = os.path.join(analysis_gdb, out_name)
if arcpy.Exists(out_fc):
arcpy.Delete_management(out_fc)
arcpy.management.SplitLineAtPoint(
in_features=dissolved_fc,
point_features=points_fc,
out_feature_class=out_fc,
search_radius="1 Meters"
)
# Segmentlängen berechnen
arcpy.management.AddGeometryAttributes(
out_fc,
"LENGTH"
)
# Eindeutige Segment-ID generieren für spätere Geoverarbeitungen
if "SEG_ID" not in [f.name for f in arcpy.ListFields(out_fc)]:
arcpy.AddField_management(out_fc, "SEG_ID", "LONG")
with arcpy.da.UpdateCursor(
out_fc,
["OBJECTID", "SEG_ID"]
) as cur:
for oid, _ in cur:
cur.updateRow((oid, oid))
# Cleanup
arcpy.management.Delete(points_fc)
arcpy.management.Delete(dissolved_fc)
# Analyse Vektordaten # ---------------------------------------------
# Punktdaten
segments_fc = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch_analysis.gdb\wanderwege_seg"
gdb_path = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch.gdb"
poi_sets = {
"OeV": os.path.join(gdb_path, "Betriebspunkt_OeV_clip"),
"REST": os.path.join(gdb_path, "poi_restaurant"),
"VIEW": os.path.join(gdb_path, "poi_view"),
"INFRA": os.path.join(gdb_path, "poi_infrastructure")
}
for key, points_fc in poi_sets.items():
# Near
arcpy.analysis.Near(
in_features=segments_fc,
near_features=points_fc,
)
near_field = f"NEAR_{key}"
# Near-Distanz-Feld anlegen
if near_field not in [f.name for f in arcpy.ListFields(segments_fc)]:
arcpy.management.AddField(
segments_fc,
near_field,
"DOUBLE"
)
# NEAR_DIST in eigenes Feld kopieren
with arcpy.da.UpdateCursor(
segments_fc,
["NEAR_DIST", near_field]
) as cursor:
for near_dist, stored_dist in cursor:
cursor.updateRow((near_dist, near_dist))
# Polygondaten
segments_fc = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch_analysis.gdb\wanderwege_seg"
landcover_fc = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch.gdb\TLMRegio_LandCover_clip"
scratch_gdb = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch_analysis.gdb"
# Gesamtlänge Wanderwegnetz (Referenz)
length_field = "LENGTH"
total_length = 0.0
with arcpy.da.SearchCursor(segments_fc, [length_field]) as cursor:
total_length = sum(row[0] for row in cursor)
print(f"Gesamtlänge Wanderwege für Perimeter {perimeter_name}: {total_length:.1f} m")
# Ergebnistabelle erstellen
result_table = os.path.join(scratch_gdb, "PolygonRatios")
if arcpy.Exists(result_table):
arcpy.management.Delete(result_table)
arcpy.management.CreateTable(scratch_gdb, "PolygonRatios")
arcpy.management.AddField(result_table, "Layer", "TEXT", 50)
arcpy.management.AddField(result_table, "Category", "TEXT", 80)
arcpy.management.AddField(result_table, "SumLength", "DOUBLE")
arcpy.management.AddField(result_table, "Ratio", "DOUBLE")
# Landcover
landcover_field = "LANDCOVER_LABEL"
landcover_values = get_unique_values(landcover_fc, landcover_field)
for label in landcover_values:
where = f"{landcover_field} = '{label}'"
landcover_lyr = "landcover_lyr"
arcpy.management.MakeFeatureLayer(landcover_fc, landcover_lyr, where)
out_fc = os.path.join(scratch_gdb, f"lc_{label}")
if arcpy.Exists(out_fc):
arcpy.management.Delete(out_fc)
arcpy.analysis.Intersect([segments_fc, landcover_lyr], out_fc)
# Länge berechnen
arcpy.management.AddGeometryAttributes(out_fc, "LENGTH")
sum_len = 0.0
with arcpy.da.SearchCursor(out_fc, ["LENGTH"]) as cursor:
sum_len = sum(row[0] for row in cursor)
ratio = sum_len / total_length if total_length > 0 else 0
with arcpy.da.InsertCursor(
result_table,
["Layer", "Category", "SumLength", "Ratio"]
) as ic:
ic.insertRow(["Landcover", label, sum_len, ratio])
# Cleanup
arcpy.management.Delete(out_fc)
# Biotopinventare
biotope_fc = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch.gdb\Biotopinventare_Dissolved"
out_fc = os.path.join(scratch_gdb, "biotope_intersect")
# Intersect Wanderwegsegmente × Biotope
arcpy.analysis.Intersect(
[segments_fc, biotope_fc],
out_fc
)
# Länge berechnen
arcpy.management.AddGeometryAttributes(
out_fc,
"LENGTH",
Length_Unit="METERS"
)
# Länge summieren
sum_len = 0.0
with arcpy.da.SearchCursor(out_fc, ["LENGTH"]) as cursor:
sum_len = sum(row[0] for row in cursor)
# Ratio berechnen
ratio = sum_len / total_length if total_length > 0 else 0
# In Ergebnistabelle schreiben
with arcpy.da.InsertCursor(
result_table,
["Layer", "Category", "SumLength", "Ratio"]
) as ic:
ic.insertRow(["Biotopinventare", "ALL", sum_len, ratio])
# Cleanup
arcpy.management.Delete(out_fc)
# Analyse Rasterdaten # ---------------------------------------------
# Höhenintervalle
scratch_gdb = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch_analysis.gdb"
segments_fc = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch_analysis.gdb\wanderwege_seg"
dhm25_raster = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch.gdb\dhm25_2056_clip"
result_table_hoehen = os.path.join(scratch_gdb, "Hoehenanalyse")
# Gesamtlänge Wanderwegnetz (Referenz)
length_field = "LENGTH"
total_length = 0.0
with arcpy.da.SearchCursor(segments_fc, [length_field]) as cursor:
total_length = sum(row[0] for row in cursor)
# Höhenwert (Raster) auf Segmente übertragen
arcpy.ddd.AddSurfaceInformation(
in_feature_class=segments_fc,
in_surface=dhm25_raster,
out_property="Z_MEAN",
method="BILINEAR"
)
fields = [f.name for f in arcpy.ListFields(segments_fc)]
if "HOEHE_MEAN" in fields:
arcpy.management.DeleteField(segments_fc, "HOEHE_MEAN")
arcpy.management.AlterField(
segments_fc,
"Z_MEAN",
new_field_name="HOEHE_MEAN",
new_field_alias="HOEHE_MEAN"
)
# Feld für Höhenklasse
if "HOEHE_KL" not in [f.name for f in arcpy.ListFields(segments_fc)]:
arcpy.AddField_management(segments_fc, "HOEHE_KL", "SHORT")
with arcpy.da.UpdateCursor(
segments_fc,
["HOEHE_MEAN", "HOEHE_KL"]
) as cursor:
for z, kl in cursor:
if z is None:
kl = -1
elif z <= 500:
kl = 1
elif 500 < z <= 1000:
kl = 2
elif 1000 < z <= 1500:
kl = 3
elif 1500 < z <= 2000:
kl = 4
elif 2000 < z <= 2500:
kl = 5
else:
kl = 6 # >2500
cursor.updateRow((z, kl))
# Segmentlängen pro Höhenklasse summieren
hoehen_sum = {
1: 0.0,
2: 0.0,
3: 0.0,
4: 0.0,
5: 0.0,
6: 0.0
}
with arcpy.da.SearchCursor(
segments_fc,
["HOEHE_KL", "LENGTH"]
) as cursor:
for kl, length in cursor:
if kl in hoehen_sum:
hoehen_sum[kl] += length
# Ergebnistabelle erzeugen
if arcpy.Exists(result_table_hoehen):
arcpy.Delete_management(result_table_hoehen)
arcpy.CreateTable_management(scratch_gdb, "Hoehenanalyse")
arcpy.AddField_management(result_table_hoehen, "Hoehenklasse", "SHORT")
arcpy.AddField_management(result_table_hoehen, "h_min", "SHORT")
arcpy.AddField_management(result_table_hoehen, "h_max", "SHORT")
arcpy.AddField_management(result_table_hoehen, "SumLength", "DOUBLE")
arcpy.AddField_management(result_table_hoehen, "Ratio", "DOUBLE")
# Ergebnisse in Tabelle schreiben
hoehen_klassen = {
1: (0, 500),
2: (500, 1000),
3: (1000, 1500),
4: (1500, 2000),
5: (2000, 2500),
6: (2500, 9999)
}
with arcpy.da.InsertCursor(
result_table_hoehen,
["Hoehenklasse", "h_min", "h_max", "SumLength", "Ratio"]
) as ic:
for kl, (h_min, h_max) in hoehen_klassen.items():
length = hoehen_sum.get(kl, 0.0)
ratio = length / total_length if total_length > 0 else 0
ic.insertRow([kl, h_min, h_max, length, ratio])
# Lärm
scratch_gdb = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch_analysis.gdb"
segments_fc = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch_analysis.gdb\wanderwege_seg"
laerm_raster = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch.gdb\laerm_strassenlaerm_tag_2056_clip"
result_table_laerm = os.path.join(scratch_gdb, "Laermanalyse")
midpoints_fc = os.path.join(scratch_gdb, "seg_midpoints")
midpoints_fc_db = os.path.join(scratch_gdb, "seg_midpoints_db")
for fc in [midpoints_fc, midpoints_fc_db]:
if arcpy.Exists(fc):
arcpy.management.Delete(fc)
fields = [f.name for f in arcpy.ListFields(segments_fc)]
if "RASTERVALU" in fields:
arcpy.management.DeleteField(segments_fc, "RASTERVALU")
arcpy.management.FeatureToPoint(
in_features=segments_fc,
out_feature_class=midpoints_fc,
point_location="INSIDE"
)
arcpy.sa.ExtractValuesToPoints(
in_point_features=midpoints_fc,
in_raster=laerm_raster,
out_point_features=midpoints_fc_db,
interpolate_values="NONE"
)
arcpy.management.JoinField(
in_data=segments_fc,
in_field="SEG_ID",
join_table=midpoints_fc_db,
join_field="SEG_ID",
fields=["RASTERVALU"]
)
fields = [f.name for f in arcpy.ListFields(segments_fc)]
if "LAERM_MEAN" in fields:
arcpy.management.DeleteField(segments_fc, "LAERM_MEAN")
arcpy.management.AlterField(
segments_fc,
"RASTERVALU",
new_field_name="LAERM_MEAN",
new_field_alias="LAERM_MEAN"
)
# Feld für Lärmklasse
if "LAERM_KL" not in [f.name for f in arcpy.ListFields(segments_fc)]:
arcpy.AddField_management(segments_fc, "LAERM_KL", "SHORT")
with arcpy.da.UpdateCursor(
segments_fc,
["LAERM_MEAN", "LAERM_KL"]
) as cursor:
for z, kl in cursor:
if z is None:
kl = -1
elif 40 <= z < 50:
kl = 1 # 40–50 dB
elif 50 <= z < 60:
kl = 2 # 50–60 dB
elif z >= 60:
kl = 3 # >60 dB
else:
kl = 0 # <40 dB
cursor.updateRow((z, kl))
# Segmentlängen pro Lärmklasse summieren
laerm_sum = {
1: 0.0, # 40–50 db
2: 0.0, # 50–60 db
3: 0.0 # >60 db
}
with arcpy.da.SearchCursor(
segments_fc,
["LAERM_KL", "LENGTH"]
) as cursor:
for kl, length in cursor:
if kl in laerm_sum:
laerm_sum[kl] += length
# Ergebnistabelle erzeugen
if arcpy.Exists(result_table_laerm):
arcpy.Delete_management(result_table_laerm)
arcpy.CreateTable_management(scratch_gdb, "Laermanalyse")
arcpy.AddField_management(result_table_laerm, "Laermklasse", "SHORT")
arcpy.AddField_management(result_table_laerm, "db_min", "SHORT")
arcpy.AddField_management(result_table_laerm, "db_max", "SHORT")
arcpy.AddField_management(result_table_laerm, "SumLenght", "DOUBLE")
arcpy.AddField_management(result_table_laerm, "Ratio", "DOUBLE")
# Ergebnisse in Tabelle schreiben
laerm_klassen = {
1: (40, 50),
2: (50, 60),
3: (60, 999)
}
with arcpy.da.InsertCursor(
result_table_laerm,
["Laermklasse", "db_min", "db_max", "SumLenght", "Ratio"]
) as ic:
for kl, (db_min, db_max) in laerm_klassen.items():
length = laerm_sum.get(kl, 0.0)
ratio = length / total_length if total_length > 0 else 0
ic.insertRow([kl, db_min, db_max, length, ratio])
# Cleanup
arcpy.management.Delete(midpoints_fc)
arcpy.management.Delete(midpoints_fc_db)
# Analyseabschluss # ---------------------------------------------
# Name der Output-GDB
output_gdb_name = f"{perimeter_name}.gdb"
output_folder = r"C:\Users\domin\Documents\Projekt_PWRG2\output\Py"
output_gdb = os.path.join(output_folder, output_gdb_name)
# Pfade zu den Scratch-GDBs
scratch_analysis_gdb = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch_analysis.gdb"
scratch_gdb = r"C:\Users\domin\Documents\Projekt_PWRG2\scratch\scratch.gdb"
# Output-Ordner erstellen, falls er nicht existiert
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# Kopiere scratch_analysis.gdb nach Output
if arcpy.Exists(output_gdb):
arcpy.Delete_management(output_gdb)
arcpy.Copy_management(scratch_analysis_gdb, output_gdb)
print(f"GDB-Kopie erstellt: {output_gdb}")
# Feature Class → Table (keine Geometrie)
table_bez = "wanderwege_seg_tbl"
out_name = table_bez
out_path = output_gdb
arcpy.conversion.TableToTable(
in_rows=segments_fc,
out_path=out_path,
out_name=out_name
)
# Perimeter umbenennen
input_shp = r"C:\Users\domin\Documents\Projekt_PWRG2\output\Perimeter\perimeter.shp"
output_folder = r"C:\Users\domin\Documents\Projekt_PWRG2\output\Perimeter"
# Shapefile-Name aus GDB-Name ableiten
output_name = os.path.splitext(output_gdb_name)[0]
output_shp = os.path.join(output_folder, f"{output_name}.shp")
# Ausgabe-Ordner erstellen, falls er nicht existiert
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# Shapefile kopieren
if arcpy.Exists(input_shp):
arcpy.CopyFeatures_management(input_shp, output_shp)
# Altes Shapefile löschen
if arcpy.Exists(input_shp):
arcpy.Delete_management(input_shp)
# Ausführung Hauptfunktion mit LOOP durch Perimeterliste
for perimeter_name, perimeter_fc in perimeters:
run_analysis(perimeter_name, perimeter_fc)