Là một nhà địa chất, tôi thường sử dụng kỹ thuật này để tạo mặt cắt địa chất trong Python thuần túy. Tôi đã trình bày một giải pháp hoàn chỉnh trong Python: Sử dụng các lớp vectơ và raster trong phối cảnh địa chất, không có phần mềm GIS (bằng tiếng Pháp)
Tôi trình bày ở đây một bản tóm tắt bằng tiếng Anh:
- để chỉ cho bạn cách trích xuất các giá trị độ cao của DEM
- làm thế nào để điều trị những giá trị này
Nếu bạn mở một DEM với mô-đun 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)
Kết quả là, bạn có số lượng băng tần và các tham số geotransform. Nếu bạn muốn trích xuất giá trị của raster theo điểm 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]])
Vì nó là DEM, bạn nhận được giá trị độ cao dưới điểm. Với 3 dải raster có cùng điểm xy, bạn nhận được 3 giá trị (R, G, B). Vì vậy, bạn có thể tạo một hàm cho phép nhận các giá trị của nhiều trình quét theo điểm 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
ứng dụng
# 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
Sau đó, bạn xử lý hồ sơ dòng (có thể có các phân đoạn):
# 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)
Để tạo các điểm tương đương trên dòng, bạn có thể sử dụng mô đun Shapely với phép nội suy (dễ hơn 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)
và kết quả (cũng với các giá trị RGB của bản đồ địa chất) với các giá trị x, y, z, khoảng cách của danh sách Trong 3D với matplotlib và Visvis (giá trị x, y, z)
Mặt cắt ngang (x, độ cao từ currentdistance (danh sách dista)) với matplotlib :