Geoanalyse mit python

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Zandernico12
User
Beiträge: 2
Registriert: Donnerstag 10. Juli 2025, 14:31

Moin, ich bin nicht sehr erfahren mit der Programmierung mit Python. Ich möchte gerne mit Python eine Windenergiepotenzialanalyse in Deutschland machen. Als Datenbasis gilt das DLM250 und Shapefiles vom Bundesamt für Naturschutz. Ich möchte gerne einen Code haben der Ausschlusskriterien definiert und wo ich verschiedene Abstandswerte eintragen kann. Dann sollen die Unterkategorien zum Beispiel(Wohngebäude, Campingplätze, Gewerbegebiete) zu einer Kategorie (Siedlungsstruktur) zusammengefasst werden. Das gleiche soll dann für Wälder, Infrastruktur und Schutzgebiete geschehen. Danach sollen die Ausschlussflächen errechnet werden, sowie die verfügbare Fläche für Windenergie und die Gesamtfläche.

Im Nachgang würde ich gerne in die verfügbaren Flächen so viele Windenergieanlagen mit einem bestimmten Abstand, den ich noch festlegen kann platzieren. Die Anzahl der installierbaren Anlagen soll ebenfalls ausgegeben werden.

Ich habe jetzt Tage lang versucht einen code zu schreiben der funktioniert. Leider hat es nie so richtig geklappt und chatgpt hilft mir auch nicht weiter. Vielleicht hat hier ja jemand Erfahrung und kann mir helfen. Würde mich sehr freuen. :D
Zandernico12
User
Beiträge: 2
Registriert: Donnerstag 10. Juli 2025, 14:31

import geopandas as gpd
from shapely.ops import unary_union
import matplotlib.pyplot as plt


#Abstände Siedlungsstrukturen
abstand_Wohngebäude= 2000
abstand_KurKlinikgebiete= 0
abstand_Camping= 0
abstand_Gewerbe_Industriegebiete= 1000
abstand_SportFreizeit= 400
abstand_Friedhöfe= 400
abstand_SonstigeGebäude= 400

#abstände Schutzgebiete

abstand_Biosphaerenreservate= 1000
abstand_FFH_Gebiete= 0
abstand_Nationale_Naturmomente= 1000
abstand_Nationalparke= 1000
abstand_Naturschutzgebiete= 1000
abstand_SPA_Gebiete= 2000


#Abstände Gewässer
abstand_Fließgewässer= 50
abstand_Kanäle= 50
abstand_Bundeswasserstraßen= 50
abstand_stehendeGewässer= 50
abstand_SonstigeGewässer= 50

#Abstände Infrastruktur
abstand_Luftverkehr= 0
abstand_Bundesautobahnen= 40
abstand_Bundesstraßen= 40
abstand_Landstraßen= 20
abstand_Kreisstraßen= 15
abstand_Bahnlinien= 150
abstand_Seilbahn= 0
abstand_Hochspannungsleitung= 100

#Abstand Waldgebiete
abstand_wald = 0


# Daten einlesen Deutschland

import geopandas as gpd

gebiet = gpd.read_file("data/geb01_f.shp")
deutschland = gebiet[gebiet["OBJART"] == 75004]


#Daten einlesen Siedlungsstrukturen

Wohngebäude = gpd.read_file("data/sie05_p.shp")
Wohngebäude = Wohngebäude[Wohngebäude["OBJART"] == "31001"]
buffer_Wohngebäude = Wohngebäude.buffer(abstand_Wohngebäude)

KurKlinikgebiete = gpd.read_file("data/sie02_f.shp")
KurKlinikgebiete = KurKlinikgebiete[KurKlinikgebiete["OBJART"] == "41007"]
buffer_KurKlinikgebiete = KurKlinikgebiete.buffer(abstand_KurKlinikgebiete)

Camping = gpd.read_file("data/sie02_f.shp")
Camping = Camping[Camping["OBJART"] == "41008"]
buffer_Camping = Camping.buffer(abstand_Camping)

Gewerbe_Industriegebiete = gpd.read_file("data/sie02_f.shp")
Gewerbe_Industriegebiete = Gewerbe_Industriegebiete[Gewerbe_Industriegebiete["OBJART"] == "41002"]
buffer_Gewerbe_Industriegebiete = Gewerbe_Industriegebiete.buffer(abstand_Gewerbe_Industriegebiete)


SportFreizeit = gpd.read_file("data/sie02_f.shp")
SportFreizeit = SportFreizeit[SportFreizeit["OBJART"] == "41008"]
buffer_SportFreizeit = SportFreizeit.buffer(abstand_SportFreizeit)

Friedhöfe = gpd.read_file("data/sie02_f.shp")
Friedhöfe = Friedhöfe[Friedhöfe["OBJART"] == "41009"]
buffer_Friedhöfe = Friedhöfe.buffer(abstand_Friedhöfe)

SonstigeGebäude = gpd.read_file("data/sie02_f.shp")
SonstigeGebäude = SonstigeGebäude[SonstigeGebäude["OBJART"] == "41008"]
buffer_SonstigeGebäude = SonstigeGebäude.buffer(abstand_SonstigeGebäude)




# Daten einlesen "Gewässer"

Fließgewässer = gpd.read_file("data/gew01_f.shp")
Fließgewässer = Fließgewässer[Fließgewässer["OBJART"] == "44001"]
buffer_Fließgewässer = Fließgewässer.buffer(abstand_Fließgewässer)

Kanäle = gpd.read_file("data/gew01_f.shp")
Kanäle = Kanäle[Kanäle["OBJART"] == "44001"]
buffer_Kanäle = Kanäle.buffer(abstand_Kanäle)

Bundeswasserstraßen = gpd.read_file("data/gew01_f.shp")
Bundeswasserstraßen = Bundeswasserstraßen[Bundeswasserstraßen["OBJART"] == "44001"]
buffer_Bundeswasserstraßen = Bundeswasserstraßen.buffer(abstand_Bundeswasserstraßen)

stehendeGewässer = gpd.read_file("data/gew01_f.shp")
stehendeGewässer = stehendeGewässer[stehendeGewässer["OBJART"] == "44006"]
buffer_stehendeGewässer = stehendeGewässer.buffer(abstand_stehendeGewässer)

SonstigeGewässer = gpd.read_file("data/gew01_f.shp")
SonstigeGewässer = SonstigeGewässer[SonstigeGewässer["OBJART"] == "44007"]
buffer_SonstigeGewässer = SonstigeGewässer.buffer(abstand_SonstigeGewässer)


# Daten einlesen "Wald"

wald = gpd.read_file("data/veg02_f.shp")
wald = wald[wald["OBJART"] == "43002"]
buffer_wald = wald.buffer(abstand_wald)

# Daten einlesen "Infrastruktur"

Luftverkehr = gpd.read_file("data/ver04_f.shp")
Luftverkehr = Luftverkehr[Luftverkehr["OBJART"] == "42015"]
buffer_Luftverkehr = Luftverkehr.buffer(abstand_Luftverkehr)

Bundesautobahnen = gpd.read_file("data/ver01_l.shp")
Bundesautobahnen = Bundesautobahnen[Bundesautobahnen["OBJART"] == "42003"]
buffer_Bundesautobahnen = Bundesautobahnen.buffer(abstand_Bundesautobahnen)

Bundesstraßen = gpd.read_file("data/ver01_l.shp")
Bundesstraßen = Bundesstraßen[Bundesstraßen["OBJART"] == "42003"]
buffer_Bundesstraßen = Bundesstraßen.buffer(abstand_Bundesstraßen)

Landstraßen = gpd.read_file("data/ver02_l.shp")
Landstraßen = Landstraßen[Landstraßen["OBJART"] == "42003"] # objart noch für kreis- und landstraßen einfügen
buffer_Landstraßen = Landstraßen.buffer(abstand_Landstraßen)

Kreisstraßen = gpd.read_file("data/ver02_l.shp")
Kreisstraßen = Kreisstraßen[Kreisstraßen["OBJART"] == "42003"]
buffer_Kreisstraßen = Kreisstraßen.buffer(abstand_Kreisstraßen)

Bahnlinien = gpd.read_file("data/ver03_l.shp")
Bahnlinien = Bahnlinien[Bahnlinien["OBJART"] == "42014"]
buffer_Bahnlinien = Bahnlinien.buffer(abstand_Bahnlinien)

Seilbahn = gpd.read_file("data/ver01_l.shp")
Seilbahn = Seilbahn[Seilbahn["OBJART"] == "42003"]
buffer_Seilbahn = Seilbahn.buffer(abstand_Seilbahn)


Hochspannungsleitung = gpd.read_file("data/sie03_l.shp")
Hochspannungsleitung = Hochspannungsleitung[Hochspannungsleitung["OBJART"] == "51005"]
buffer_Hochspannungsleitung = Hochspannungsleitung.buffer(abstand_Hochspannungsleitung)


# Daten einlesen "Schutzgebiete"

Biospaerenreservate = gpd.read_file("data/Biosphaerenreservate.shp")
buffer_Biospaerenreservate = Biospaerenreservate.buffer(abstand_Biosphaerenreservate)

FFH_Gebiete = gpd.read_file("data/FFH_Gebiete.shp")
buffer_FFH_Gebiete = FFH_Gebiete.buffer(abstand_FFH_Gebiete)


Nationalparke = gpd.read_file("data/Nationalparke.shp")
buffer_Nationalparke = Nationalparke.buffer(abstand_Nationalparke)


SPA_Gebiete = gpd.read_file("data/SPA_Gebiete.shp")
buffer_SPA_Gebiete = SPA_Gebiete.buffer(abstand_SPA_Gebiete)


Naturschutzgebiete = gpd.read_file("data/Naturschutzgebiete.shp")
buffer_Naturschutzgebiete = Naturschutzgebiete.buffer(abstand_Naturschutzgebiete)

Nationale_Naturmomente = gpd.read_file("data/Nationale_Naturmomente.shp")
buffer_Nationale_Naturmomente = Nationale_Naturmomente.buffer(abstand_Nationale_Naturmomente)


# CRS annehmen von erster Quelle
crs = Wohngebäude.crs


# Ausschlusskriterien zu einem Hauptpunkt zusammenfassen

# Siedlungsstruktur
siedlungsstruktur = gpd.GeoSeries(unary_union([
*buffer_Wohngebäude,
*buffer_KurKlinikgebiete,
*buffer_SonstigeGebäude,
*buffer_Camping,
*buffer_Gewerbe_Industriegebiete,
*buffer_SportFreizeit,
*buffer_Friedhöfe,
]), crs=crs)

# Infrastruktur

infrastruktur = gpd.GeoSeries(unary_union([
*buffer_Luftverkehr,
*buffer_Hochspannungsleitung,
*buffer_Bundesautobahnen,
*buffer_Landstraßen,
*buffer_Kreisstraßen,
*buffer_Bahnlinien,
*buffer_Seilbahn,
*buffer_Bundesstraßen,

]), crs=crs)


#Schutzgebiete

schutzgebiete = gpd.GeoSeries(unary_union([
*buffer_Biospaerenreservate,
*buffer_FFH_Gebiete,
*buffer_Nationalparke,
*buffer_SPA_Gebiete,
*buffer_Naturschutzgebiete,
*buffer_Nationale_Naturmomente,

]), crs=crs)




# Gewässer

gewässer = gpd.GeoSeries(unary_union([
*buffer_stehendeGewässer,
*buffer_Fließgewässer,
*buffer_Kanäle,
*buffer_Bundeswasserstraßen,
*buffer_SonstigeGewässer,
]), crs=crs)


#Wald

wald = gpd.GeoSeries(unary_union([
*buffer_wald,

]), crs=crs)



# Einheitliches Koordinatensystem
crs = gebiet.crs
siedlungen = siedlungsstruktur.to_crs(crs)
gewaesser = gewässer.to_crs(crs)
wald = wald.to_crs(crs)
infrastruktur = infrastruktur.to_crs(crs)
schutzgebiete = schutzgebiete.to_crs(crs)



from geopandas import GeoDataFrame

# -----------------------------
# 1. Ausschlussflächen vereinigen
# -----------------------------

# Alle Gruppen in einer Liste zusammenführen
alle_buffer = [
*siedlungen.geometry,
*gewaesser.geometry,
*infrastruktur.geometry,
*wald.geometry,
*schutzgebiete.geometry
]

# Geometrien vereinigen
ausschlussflaeche_geom = unary_union(alle_buffer)
ausschlussflaeche = GeoDataFrame(geometry=[ausschlussflaeche_geom], crs=crs)

# -----------------------------
# 2. Verfügbare Fläche berechnen
# -----------------------------
verfuegbare_flaeche = gpd.overlay(deutschland, ausschlussflaeche, how='difference')

# -----------------------------
# 3. Flächenstatistik in km² berechnen
# -----------------------------
planungsgebiet_fl = deutschland.geometry.area.sum() / 1e6
ausschluss_fl = ausschlussflaeche.geometry.area.sum() / 1e6
verfuegbar_fl = verfuegbare_flaeche.geometry.area.sum() / 1e6

print("\n📊 Flächenübersicht [km²]")
print(f"Gesamtfläche : {planungsgebiet_fl:.2f}")
print(f"Ausschlussfläche : {ausschluss_fl:.2f}")
print(f"Verfügbare Fläche : {verfuegbar_fl:.2f}")


Das ist der code den ich bisher habe zur Berechnung der Flächen. Dieser funktioniert aber irgendwie nicht
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

Eine Aussage wie "funktioniert irgendwie nicht" ist wenig hilfreich. Beschreibe bitte genau, was passiert, was Du erwartest und welchen Fehler es gibt.
Programmieren ist nicht nur, irgendwelchen Code aneinander zu kopieren, sondern die Strukturen ermitteln und Funktionen zu schreiben, die eine bestimmte Aufgabe lösen. Diese Funktionen kann man dann testen, und erst, wenn diese funktionieren, kümmert man sich um das nächste Teilproblem.

Bei Dir tritt z.B. die selbe Anfrage 27mal im Code auf:

Code: Alles auswählen

Wohngebäude = gpd.read_file("data/sie05_p.shp")
Wohngebäude = Wohngebäude[Wohngebäude["OBJART"] == "31001"]
buffer_Wohngebäude = Wohngebäude.buffer(abstand_Wohngebäude)
Das wäre ein Fall für eine einfache Funktion, die eine Shape-Datei liest, sie nach Objektart und Abstand filtert:

Code: Alles auswählen

def read_shapes(filename, object_type=None, distance=None):
	shapes = gpd.read_file(filename)
	if object_type is not None:
        shapes = shapes[shape['OBJART'] == object_type]
    if distance is not None:
        shapes = shapes.buffer(distance)
Dann kann man auch eine einfache Datenstruktur definieren und alles mit wenigen Zeilen Code lesen:

Code: Alles auswählen

GEO_DATA = {
    "Siedlungsstrukturen": [
        ("data/sie05_p.shp", "31001", 2000), # Wohngebäude
        ("data/sie02_f.shp", "41007", 0), # KurKlinikgebiete
        ("data/sie02_f.shp", "31001", 0), # Camping
        ...
    ],
    "Gewässer": [
        ("data/gew01_f.shp", "44001", 50), # Fließgewässer
        ... 
    ],
    "Schutzgebiete": [
        ("data/Biosphaerenreservate.shp", None, 1000),  # Biospaerenreservate
        ("data/FFH_Gebiete.shp", None, 0),  # FFH_Gebiete
        ("data/Nationalparke.shp", None, 1000),  # Nationalparke
        ...
    ],
    ...
}

geo_data_shapes = {}
for name, files in geo_data.items():
    geo_data_shapes[name] = [
        read_shapes(filename, object_type, distance)
        for (filename, object_type, distance) in files
    ]

structures = {}
for name, shapes in geo_data_shapes:
    structures[name] = gpd.GeoSeries(unary_union(chain.from_iterable(shape)), crs=crs)
juergenkulow
User
Beiträge: 8
Registriert: Freitag 6. Juni 2025, 08:09

Nach Installation von:

Code: Alles auswählen

pip install geopandas
# https://pypi.org/project/geopandas/
bekomme ich folgende Fehlermeldung:

Code: Alles auswählen

kulow@kulow-G73Jw:~$ python3 /tmp/a.py

A module that was compiled using NumPy 1.x cannot be run in
NumPy 2.2.6 as it may crash. To support both 1.x and 2.x
versions of NumPy, modules must be compiled with NumPy 2.0.
Some module may need to rebuild instead e.g. with 'pybind11>=2.12'.

If you are a user of the module, the easiest solution will be to
downgrade to 'numpy<2' or try to upgrade the affected module.
We expect that some modules will need time to support NumPy 2.

Traceback (most recent call last):  File "/tmp/a.py", line 3, in <module>
    import matplotlib.pyplot as plt
  File "/usr/lib/python3/dist-packages/matplotlib/__init__.py", line 109, in <module>
  ...
Wenn ich #import matplotlib.pyplot as plt auskommentiere bekomme ich folgende Fehlermeldung

Code: Alles auswählen

kulow@kulow-G73Jw:~$ python3 /tmp/a.py
Traceback (most recent call last):
  File "/tmp/a.py", line 51, in <module>
    gebiet = gpd.read_file("data/geb01_f.shp")
Wo finde ich die Datei: data/geb01_f.shp ?

Bitte benutze für Deinen Code die <> CodeTages.
Danke
Bitte stelle Deine Fragen, denn den Erkenntnisapparat einschalten entscheidet über das einzig bekannte Leben im Universum.

Jürgen Kulow Wersten :D_üsseldorf NRW D Europa Erde Sonnensystem Lokale_Flocke Lokale_Blase Orion-Arm
Milchstraße Lokale_Gruppe Virgo-Superhaufen Laniakea Sichtbares_Universum
Benutzeravatar
__blackjack__
User
Beiträge: 14027
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Die beiden Schleifen aus dem Quelltext von Sirius3 könnte man auch als „dict comprehension“ schreiben:

Code: Alles auswählen

    geo_data_shapes = {
        name: [
            read_shapes(filename, object_type, distance)
            for filename, object_type, distance in files
        ]
        for name, files in geo_data.items()
    }

    structures = {
        name: gpd.GeoSeries(unary_union(chain.from_iterable(shapes)), crs=crs)
        for name, shapes in geo_data_shapes
    }
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Antworten