Use code to extract ridge and valley lines (arcpy version)

In fact, most of the implementation codes of the ridge line and the valley line are the same, I will point out the specific effect in the appropriate place below, and change the specific effect as needed.

import os
import gdal
import arcpy
from arcpy import env
import numpy as np

def read_img(filename):
	dataset=gdal.Open(filename)

	im_width = dataset.RasterXSize
	im_height = dataset.RasterYSize

	im_geotrans = dataset.GetGeoTransform()
	im_proj = dataset.GetProjection()
	im_data = dataset.ReadAsArray(0,0,im_width,im_height)

	del dataset 
	return im_proj,im_geotrans,im_width, im_height,im_data

def write_img(filename, im_proj, im_geotrans, im_data):
	if 'int8' in im_data.dtype.name:
		datatype = gdal.GDT_Byte
	elif 'int16' in im_data.dtype.name:
		datatype = gdal.GDT_UInt16
	else:
		datatype = gdal.GDT_Float32

	if len(im_data.shape) == 3:
		im_bands, im_height, im_width = im_data.shape
	else:
		im_bands, (im_height, im_width) = 1,im_data.shape 

	driver = gdal.GetDriverByName("GTiff")
	dataset = driver.Create(filename, im_width, im_height, im_bands, datatype)

	dataset.SetGeoTransform(im_geotrans)
	dataset.SetProjection(im_proj)

	if im_bands == 1:
		dataset.GetRasterBand(1).WriteArray(im_data)
	else:
		for i in range(im_bands):
			dataset.GetRasterBand(i+1).WriteArray(im_data[i])

	del dataset

def get_reverse(img_path,reverse_path):
	im_proj,im_geotrans,im_width, im_height,im_data = read_img(img_path)
	dem_reverse = im_data.max() - im_data
	dem_reverse = dem_reverse.astype(np.float32)
	write_img(reverse_path, im_proj, im_geotrans, dem_reverse)

def correct_slope_c(slope,slope_reverse,correct_slope_out):
	im_proj,im_geotrans,im_width, im_height,slope = read_img(slope)
	im_proj,im_geotrans,im_width, im_height,slope_reverse = read_img(slope_reverse)
	correct_slope = ((slope + slope_reverse) - abs(slope - slope_reverse)) / 2.0
	correct_slope = correct_slope.astype(np.float32)
	write_img(correct_slope_out, im_proj, im_geotrans, correct_slope)

def sg_extract(dem_ras, valley_out, temp_path):
	aspect_temp = os.path.join(temp_path, 'aspect.tif')
	arcpy.Aspect_3d(in_raster=dem_ras, out_raster=aspect_temp)
	slope_temp = os.path.join(temp_path, 'slope.tif')
	arcpy.Slope_3d(in_raster=aspect_temp,out_raster=slope_temp,output_measurement="DEGREE",z_factor="1")

	dem_reverse = os.path.join(temp_path, 'dem_reverse.tif')
	get_reverse(dem_ras, dem_reverse)
	aspect_reverse_temp = os.path.join(temp_path, 'aspect_reverse.tif')
	arcpy.Aspect_3d(in_raster=dem_reverse, out_raster=aspect_reverse_temp)
	slope_reverse_temp = os.path.join(temp_path, 'slope_reverse.tif')
	arcpy.Slope_3d(in_raster=aspect_reverse_temp,out_raster=slope_reverse_temp,output_measurement="DEGREE",z_factor="1")

	correct_slope_out = os.path.join(temp_path, 'correct_slope_temp.tif')
	correct_slope_data = correct_slope_c(slope_temp,slope_reverse_temp,correct_slope_out)

	dem_mean = os.path.join(temp_path, 'dem_mean.tif')
	arcpy.gp.FocalStatistics_sa(dem_ras, dem_mean, "Rectangle 25 25 CELL","MEAN","DATA")
	im_proj,im_geotrans,im_width, im_height,dem_data = read_img(dem_ras)
	im_proj,im_geotrans,im_width, im_height,dem_mean_data = read_img(dem_mean)
	dem_mean_c = dem_data - dem_mean_data

	#(公式("correct_data ">70)&("dem_mean_c ">0))和山谷线(公式("correct_data ">70)&("dem_mean_c "<0)
	#correct_data代表坡向变率,70是要自己设定的阈值,可以更改,dem_mean_c 是正负地形分布区域,是通过邻域分析的焦点统计得到的,具体可以自己去搜下arcgis怎么操作
	im_proj,im_geotrans,im_width, im_height, correct_data = read_img(correct_slope_out)
	correct_data[correct_data <= 60.0] = 0
	correct_data[correct_data > 60.0] = 1
	temp1 = os.path.join(temp_path, 'temp1.tif')
	write_img(temp1, im_proj, im_geotrans, correct_data)

	dem_mean_c[dem_mean_c >= 0] = 0
	dem_mean_c[dem_mean_c < 0] = 1
	temp2 = os.path.join(temp_path, 'temp2.tif')
	write_img(temp2, im_proj, im_geotrans, correct_data)

	arr = correct_data + dem_mean_c
	arr[arr < 2] = 0
	arr[arr >= 2] = 1
	write_img(valley_out, im_proj, im_geotrans, arr)


if __name__ == "__main__":
	dem_path = 'xxx/t_dem.tif'
	valley_out = 'xxx/t_dem_re.tif'
	temp_path = 'xxx/temp_dem/'

	arcpy.CheckOutExtension('Spatial')
	arcpy.env.overwriteOutput = True
	env.workspace = temp_path

	sg_extract(dem_path, valley_out, temp_path)

the
Valley line

Guess you like

Origin blog.csdn.net/qq_20373723/article/details/111239386