Skrip Python untuk mendapatkan perbedaan elevasi antara dua titik [ditutup]

10

Saya memiliki beberapa segmen aliran sepanjang 1000 Km. Saya perlu menemukan perbedaan ketinggian antara dua titik jarak 1 Km berturut-turut mulai dari hulu ke hilir. Bagaimana saya bisa mendapatkan perbedaan ketinggian dari DEM? Saya memiliki segmen aliran dalam format raster dan juga dalam format vektor. Akan lebih baik jika saya mendapat ide tentang skrip Python.

Ja Geo
sumber
mendapatkan peningkatan pada satu titik: gis.stackexchange.com/questions/29632/…
underdark

Jawaban:

24

Sebagai seorang ahli geologi, saya sering menggunakan teknik ini untuk membuat penampang geologis dengan Python murni. Saya menghadirkan solusi lengkap dalam Python: Menggunakan vektor dan layer raster dalam perspektif geologis, tanpa perangkat lunak GIS (dalam bahasa Prancis)

Saya menyajikan ringkasan dalam bahasa Inggris di sini:

  • untuk menunjukkan kepada Anda cara mengekstraksi nilai ketinggian DEM
  • bagaimana memperlakukan nilai-nilai ini

Jika Anda membuka DEM dengan modul GDAL / OGR Python:

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)

Akibatnya, Anda memiliki jumlah pita dan parameter geotransform. Jika Anda ingin mengekstrak nilai raster di bawah titik 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]]) 

Karena DEM, Anda mendapatkan nilai elevasi di bawah titik. Dengan 3 band raster dengan titik xy yang sama Anda mendapatkan 3 nilai (R, G, B). Jadi Anda bisa membuat fungsi yang memungkinkan untuk mendapatkan nilai dari beberapa raster di bawah titik 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

aplikasi

# 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  

Setelah itu, Anda memproses profil garis (yang mungkin memiliki segmen):

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

Untuk menghasilkan poin berjarak sama di telepon, Anda dapat menggunakan Shapely modul dengan interpolasi (lebih mudah daripada 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)

dan hasilnya (dengan juga nilai RGB dari peta geologis) dengan nilai x, y, z, jarak dari daftar Dalam 3D dengan matplotlib dan Visvis (nilai x, y, z)

masukkan deskripsi gambar di sini

Potongan melintang (x, ketinggian dari jarak saat ini (daftar dista)) dengan matplotlib : masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

gen
sumber
3
+1 untuk membuat solusi pythonic yang bagus dan untuk menggunakan matplotlib untuk membuat angka yang tampak hebat.
Fezter
Apakah ini tidak mungkin dengan arcpy?
Ja Geo
3
Saya tidak tahu, saya tidak menggunakan ArcPy
gen
Anda mengetik rasterx dua kali, seharusnya rasterx, rastery
Metiu