Script Python pour obtenir la différence d'altitude entre deux points [fermé]


10

J'ai plusieurs segments de cours d'eau de 1000 km de long. J'ai besoin de trouver la différence d'altitude entre deux points de distance consécutifs de 1 km à partir de l'amont vers l'aval. Comment puis-je obtenir la différence d'altitude à partir de DEM? J'ai des segments de flux au format raster et également au format vectoriel. Ce serait mieux si j'avais une idée du script Python.


obtenir l'élévation à un point: gis.stackexchange.com/questions/29632/…
— underdark

Réponses:


24

En tant que géologue, j'utilise souvent cette technique pour réaliser des coupes géologiques en Python pur. J'ai présenté une solution complète en Python: en utilisant le vecteur et les couches raster dans un point de vue géologique, sans logiciel SIG (en français)

Je présente ici un résumé en anglais:

  • pour vous montrer comment extraire les valeurs d'élévation d'un DEM
  • comment traiter ces valeurs

Si vous ouvrez un DEM avec le module Python GDAL / OGR:

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)

Par conséquent, vous avez le nombre de bandes et les paramètres de géotransformation. Si vous souhaitez extraire la valeur du raster sous un point xy:

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]]) 

Comme il s'agit d'un DEM, vous obtenez la valeur d'élévation sous le point. Avec 3 bandes raster avec le même point xy, vous obtenez 3 valeurs (R, G, B). Vous pouvez donc créer une fonction qui permet d'obtenir les valeurs de plusieurs rasters sous un point xy:

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

application

# 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  

Après cela, vous traitez le profil de ligne (qui peut avoir des segments):

# 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)

Pour générer des points équidistants sur la ligne, vous pouvez utiliser le module Shapely avec interpolation (plus facile que l'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)

et les résultats (avec aussi les valeurs RVB d'une carte géologique) avec les valeurs x, y, z, distance des listes En 3D avec matplotlib et Visvis ( valeurs x, y, z)

entrez la description de l'image ici

Coupes (x, élévation de la distance actuelle (liste dista )) avec matplotlib : entrez la description de l'image ici

entrez la description de l'image ici


3
+1 pour créer une excellente solution pythonique et pour utiliser matplotlib pour créer de superbes figures.
— Fezter

N'est-ce pas possible avec arcpy?
— Ja Geo

3
Je ne sais pas, je n'utilise pas ArcPy
— gène

Vous avez tapé rasterx deux fois, cela devrait être rasterx, rastery
— Metiu
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.