Python-Skript zum Abrufen des Höhenunterschieds zwischen zwei Punkten [geschlossen]

10

Ich habe mehrere 1000 km lange Stromsegmente. Ich muss den Höhenunterschied zwischen zwei aufeinanderfolgenden Punkten mit einer Entfernung von 1 km von stromaufwärts nach stromabwärts ermitteln. Wie kann ich den Höhenunterschied von DEM ermitteln? Ich habe Stream-Segmente im Raster-Format und auch im Vektor-Format. Es wäre besser, wenn ich eine Idee zum Python-Skript hätte.

Ja Geo
quelle
Erhebung der Höhe an einem Punkt: gis.stackexchange.com/questions/29632/…
underdark

Antworten:

24

Als Geologe verwende ich diese Technik oft, um einen geologischen Querschnitt in reinem Python zu erstellen. Ich habe in Python eine Komplettlösung vorgestellt : Verwenden von Vektor- und Rasterebenen in einer geologischen Perspektive ohne GIS-Software (auf Französisch)

Ich präsentiere hier eine Zusammenfassung auf Englisch:

  • um Ihnen zu zeigen, wie Sie die Höhenwerte eines DEM extrahieren
  • wie man diese Werte behandelt

Wenn Sie ein DEM mit GDAL / OGR Python-Modul öffnen:

from osgeo import gdal
# raster dem10m
file = 'dem10m.asc'
layer = gdal.Open(file)
gt =layer.GetGeoTransform()
bands = layer.RasterCount
print bands
1
print gt
(263104.72544800001, 10.002079999999999, 0.0, 155223.647811, 0.0, -10.002079999999999)

Als Ergebnis haben Sie die Anzahl der Bänder und die Geotransformationsparameter. Wenn Sie den Wert des Rasters unter einem xy-Punkt extrahieren möchten:

x,y  = (263220.5,155110.6)
# transform to raster point coordinates
rasterx = int((x - gt[0]) / gt[1])
rastery = int((y - gt[3]) / gt[5])
# only one band here
print layer.GetRasterBand(1).ReadAsArray(rasterx,rastery, 1, 1)
array([[222]]) 

Da es sich um ein DEM handelt, erhalten Sie den Höhenwert unter dem Punkt. Mit 3 Rasterbändern mit demselben xy-Punkt erhalten Sie 3 Werte (R, G, B). Sie können also eine Funktion erstellen, mit der Sie die Werte mehrerer Raster unter einem xy-Punkt abrufen können:

def Val_raster(x,y,layer,bands,gt):
    col=[]
    px = int((x - gt[0]) / gt[1])
    py =int((y - gt[3]) / gt[5])
    for j in range(bands):
        band = layer.GetRasterBand(j+1)
        data = band.ReadAsArray(px,py, 1, 1)
        col.append(data[0][0])
  return col

Anwendung

# with a DEM (1 band)
px1 = int((x - gt1[0]) / gt1[1])
py1 = int((y - gt1[3]) / gt1[5])
print Val_raster(x,y,layer, band,gt)
[222] # elevation
# with a geological map (3 bands)
px2 = int((x - gt2[0]) / gt2[1])
py2 = int((y - gt2[3]) / gt2[5])
print Val_raster(x,y,couche2, bandes2,gt2)
[253, 215, 118] # RGB color  

Danach verarbeiten Sie das Linienprofil (das möglicherweise Segmente enthält):

# creation of an empty ogr linestring to handle all possible segments of a line with  Union (combining the segements)
profilogr = ogr.Geometry(ogr.wkbLineString)
# open the profile shapefile
source = ogr.Open('profilline.shp')
cshp = source.GetLayer()
# union the segments of the line
for element in cshp:
   geom =element.GetGeometryRef()
   profilogr = profilogr.Union(geom)

Um äquidistante Punkte auf der Linie zu generieren, können Sie das Shapely- Modul mit Interpolation verwenden (einfacher als ogr).

from shapely.wkb import loads
# transformation in Shapely geometry
profilshp = loads(profilogr.ExportToWkb())
# creation the equidistant points on the line with a step of 20m
lenght=profilshp.length
x = []
y = []
z = []
# distance of the topographic profile
dista = []
for currentdistance  in range(0,lenght,20):
     # creation of the point on the line
     point = profilshp.interpolate(currentdistance)
     xp,yp=point.x, point.y
     x.append(xp)
     y.append(yp)
     # extraction of the elevation value from the MNT
     z.append(Val_raster(xp,yp,layer, bands,gt)[0]
     dista.append(currentdistance)

und die Ergebnisse (mit auch den RGB-Werten einer geologischen Karte) mit den x-, y-, z- und Entfernungswerten der Listen in 3D mit matplotlib und Visvis (x-, y-, z-Werte)

Geben Sie hier die Bildbeschreibung ein

Querschnitte (x, Höhe vom Stromabstand (dista list)) mit matplotlib : Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Gen
quelle
3
+1 für die Erstellung einer großartigen Python-Lösung und für die Verwendung von Matplotlib zur Erstellung großartig aussehender Figuren.
Fezter
Ist das mit arcpy nicht möglich?
Ja Geo
3
Ich weiß nicht, ich benutze kein ArcPy
Gen
Sie haben zweimal Rasterx eingegeben, es sollte Rasterx sein, Rastery
Metiu