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)
Potongan melintang (x, ketinggian dari jarak saat ini (daftar dista)) dengan matplotlib :