使用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)))
生成的矢量站點結果