利用代码实现山脊线、山谷线的提取(arcpy版)

6 篇文章 1 订阅

山脊线和山谷线的实现代码其实大部分都是一样的,下面我会在适当的地方指出来,具体效果根据需要再改改吧

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)

dem
山谷线

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ggplot2是R语言中一个强大的可视化包,可以用于绘制各种图形,包括山脊图。 首先,我们需要准备一个数据集,其中包含各科成绩的信息。假设我们有一个数据框df,包含学生的姓名和各科成绩的列。我们可以使用如下代码创建数据集: ```R df <- data.frame( 姓名 = c("张三", "李四", "王五", "赵六", "钱七"), 数学 = c(80, 75, 90, 85, 95), 语文 = c(85, 90, 75, 80, 70), 英语 = c(90, 85, 95, 80, 75) ) ``` 接下来,我们使用ggplot2包来绘制山脊图,并显示中位数线。我们可以使用geom_density()函数来绘制山脊图,使用geom_vline()函数来添加中位数线。 ```R library(ggplot2) # 创建山脊图 ggplot(df, aes(x = 数学, fill = 姓名)) + geom_density(alpha = 0.6) + # 设置填充颜色的透明度 geom_vline(aes(xintercept = median(数学)), color = "red", linetype = "dashed", size = 1) + # 添加红色虚线中位数线 labs(title = "各科成绩的山脊图", x = "成绩", y = "密度") + # 设置标题和坐标轴标签 theme_minimal() # 设置为最小化主题 ``` 以上代码中,我们使用aes()函数指定x轴为数学成绩,fill参数用于根据姓名进行填充颜色,这样每个学生的山脊图就会有不同的颜色。使用alpha参数可以调整填充颜色的透明度。geom_vline()函数中,我们使用median()函数计算数学成绩的中位数,并使用color、linetype和size参数设置中位数线的样式。最后,使用labs()函数设置图形的标题和坐标轴标签,使用theme_minimal()函数设置最小化主题风格。 通过以上代码,我们就可以得到一幅显示各科成绩的山脊图,并且显示了数学成绩的中位数线

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如雾如电

随缘

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值