python下使用gdal空間插值

使用idw插值法對站點觀測數據進行面插值。
使用方法
1、gdal_grid.exe
在這裏插入圖片描述
2、gdal.grid()

opts = gdal.GridOptions(algorithm="invdistnn:power=2.0:smothing=0.0:radius=1.0:max_points=12:min_points=0:nodata=0.0",
							format="GTiff",outputType=gdal.GDT_Float32,zfield="WAVEHEIGHT")
	gdal.Grid(destName=output_file,srcDS=point_station_file,options=opts)

3、qgis中使用方式

從站點文本數據到插值結果完整代碼(github地址)

#!usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Author  : zhaoguanhua
@Email   : 
@Time    : 2020/3/6 14:11
@File    : Wave_Interpolation.py
@Software: PyCharm
"""

"""
基於站點數據,使用IDW插值生成海浪面數據,基於面數據生成浪高等值線數據。
"""
import os
import sys
import pandas as pd
import gdal
import ogr
import osr
import time

def read_excel(excel_file):
	"""
	讀取站點文本文件
	"""
	#sheet = pd.read_excel(excel_file,usecols=[2,12,13])
	sheet = pd.read_csv(excel_file)
	return sheet

def create_real_field(field_name,layer):
	field_geo = ogr.FieldDefn(field_name, ogr.OFTReal)
	field_geo.SetWidth(24)
	field_geo.SetPrecision(3)
	layer.CreateField(field_geo)  # 創建字段

def create_txt_field(field_name,layer):
	field_geo = ogr.FieldDefn(field_name, ogr.OFTString)
	field_geo.SetWidth(24)  # 設置長度
	layer.CreateField(field_geo)  # 創建字段

def write_point(station_data,point_station_file):
	"""
	站點數據寫成shapefile文件
	"""

	#gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","NO") #支持中文路徑
	gdal.SetConfigOption("SHAPE_ENCODING","GBK")          #屬性字段支持中文

	strDriverName = "ESRI Shapefile"
	oDriver = ogr.GetDriverByName(strDriverName)
	if oDriver ==None:
		print("{driver} 驅動不可用!".format(driver=strDriverName))
		os._exit(0)

	# 創建矢量數據源
	data_source = oDriver.CreateDataSource(point_station_file)

	#指定座標系
	srs = osr.SpatialReference()
	srs.ImportFromEPSG(4326)

	# 創建圖層
	wave_layer = data_source.CreateLayer("wave", srs, ogr.wkbPoint)

	#設置字段
	create_real_field("WAVEHEIGHT",wave_layer)
	create_txt_field("WAVEDFROM", wave_layer)
	create_real_field("WAVEPERIOD", wave_layer)
	create_real_field("LAT",wave_layer)
	create_real_field("LNG",wave_layer)
	create_txt_field("TIME", wave_layer)
	create_txt_field("SEANAME", wave_layer)
	create_real_field("RISK", wave_layer)
	create_txt_field("CELLSYSID", wave_layer)

	for index,row in station_data.iterrows():
		#print(index,row["WAVEHEIGHT"],row["LAT"],row["LNG"])

		if((row["LNG"]<100 or row["LNG"]>132)):
			continue
		wave_feature = ogr.Feature(wave_layer.GetLayerDefn())
		wave_feature.SetField("WAVEHEIGHT",row["WAVEHEIGHT"])
		wave_feature.SetField("WAVEDFROM", row["WAVEDFROM"])
		wave_feature.SetField("WAVEPERIOD", row["WAVEPERIOD"])
		wave_feature.SetField("LAT", row["LAT"])
		wave_feature.SetField("LNG", row["LNG"])
		wave_feature.SetField("TIME", row["TIME"])
		wave_feature.SetField("SEANAME", row["SEANAME"])
		wave_feature.SetField("RISK", row["RISK"])
		wave_feature.SetField("CELLSYSID", row["CELLSYSID"])

		wkt = "POINT(%f %f)"%(float(row['LNG']),float(row['LAT']))

		point = ogr.CreateGeometryFromWkt(wkt)
		wave_feature.SetGeometry(point)
		wave_layer.CreateFeature(wave_feature)

		feature=None

def idw(output_file,point_station_file):
	"""
	idw空間插值
	:param output_file:插值結果
	:param point_station_file: 矢量站點數據
	:return:
	"""
	#代碼調用
	opts = gdal.GridOptions(algorithm="invdistnn:power=2.0:smothing=0.0:radius=1.0:max_points=12:min_points=0:nodata=0.0",
							format="GTiff",outputType=gdal.GDT_Float32,zfield="WAVEHEIGHT")
	gdal.Grid(destName=output_file,srcDS=point_station_file,options=opts)
	
	#gdal_grid.exe調用
	# gdal_grid_tool = "gdal_grid.exe - l point_station -zfield WAVEHEIGHT" \
	# 				 "- a invdistnn: power = 2.0:smothing = 0.0:radius = 1.0:max_points = 12:min_points = 0:nodata = 0.0 " \
	# 				 "- ot Float64 - of GTiff {input} {output}".format(input=point_station_file,output=output_file)
	# 
	# os.system(gdal_grid_tool)

def main(text_file,tiff_file):

	dir_path,file_name = os.path.split(tiff_file)
	point_station_file = os.path.join(dir_path,"point_station.shp") #站點矢量文件

	station_data=read_excel(text_file)

	#文本文件轉矢量點文件
	write_point(station_data,point_station_file)

	#插值
	idw(tiff_file,point_station_file)

if __name__ == '__main__':
	wave_station = sys.argv[1]
	wave_interpolation = sys.argv[2]
	inperpolation_NAME = "WAVEHEIGHT"
	start_t = time.time()
	main(wave_station,wave_interpolation)
	end_t = time.time()
	print("總時間:{}s".format((end_t-start_t)))

生成的矢量站點結果

站點矢量數據
IDW插值結果
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章