from osgeo import ogr
from osgeo import gdalconst
import argparse
import os
def fillFiledNan(layer,fieldName,nanValue=None):
fids=[]
# 开启严格匹配
print("{}:正在处理".format(fieldName))
fieldIndex = ogr.Layer.FindFieldIndex(layer, fieldName, True)
if fieldIndex==-1:
print("要填充的字段不存在!")
exit(1)
nanValue=-9999
fieldType=None
ogr.Layer.SetAttributeFilter(layer,None)
while True:
feature=ogr.Layer.GetNextFeature(layer)
if not(fieldType):
fieldType=ogr.Feature.GetFieldType(feature,fieldIndex)
if fieldType==ogr.OFTInteger or fieldType==ogr.OFTInteger64 or fieldType==ogr.OFTReal:
nanValue=float(nanValue)
if not(feature):
break
fieldValue = ogr.Feature.GetField(feature, fieldIndex)
if fieldValue and fieldValue !=nanValue:
continue
fids.append(ogr.Feature.GetFID(feature))
distDict=dict()
ogr.Layer.SetAttributeFilter(layer,"{}<>{}".format(fieldName,nanValue))
for fid in fids:
feature=ogr.Layer.GetFeature(layer,fid)
featureGeometry=ogr.Feature.GetGeometryRef(feature)
featureID=fid
ogr.Layer.ResetReading(layer)
mindist=None
mindistFid=None
while True:
feature_=ogr.Layer.GetNextFeature(layer)
if not(feature_):
break
featureID_=ogr.Feature.GetFID(feature_)
distKey="{}_{}".format(featureID,featureID_) if featureID<featureID_ else "{}_{}".format(featureID_,featureID)
if not(distKey in distDict):
featureGeometry_=ogr.Feature.GetGeometryRef(feature_)
dist=ogr.Geometry.Distance(featureGeometry,featureGeometry_)
distDict[distKey]=dist
if (mindist and mindist >distDict[distKey]) or not(mindist):
mindist=distDict[distKey]
mindistFid=featureID_
if mindistFid:
mindistValue=ogr.Feature.GetField(ogr.Layer.GetFeature(layer,mindistFid),fieldIndex)
ogr.Feature.SetField(feature,fieldIndex,mindistValue)
# 更新图层数据
ogr.Layer.SetFeature(layer,feature)
return
if __name__=='__main__':
parser=argparse.ArgumentParser(description="矢量数据字段缺失值填充工具")
parser.add_argument("--inputFile",type=str,required=True,help='待处理的矢量数据')
parser.add_argument("--fieldNames",type=str,required=True,help="需要进行缺失值填充的字段:field1,field2,field3")
parser.add_argument("--nanValues",type=str,default='',help='字段缺失值:不传默认空为字段值为空的情况下缺失,传则要求参数数目与fieldNames参数数目一致或者只传一个,这种情况下待填充字段的缺失值都相同,用逗号隔开,其中字段值为空用.表示:v1,.,v2')
parser.add_argument("--outputFile",type=str,default='',help='输出文件,不传则默认直接在原文件的基础上修改')
args=parser.parse_args()
inputFile=args.inputFile
if not(os.path.exists(inputFile)):
print("输入文件:{} 不存在!".format(inputFile))
exit(1)
fieldNames=args.fieldNames
fieldNames=fieldNames.split(',')
if len(fieldNames)==0:
print("没有输入待填充字段!")
exit(1)
nanValues=args.nanValues
if nanValues:
nanValues=nanValues.split(',')
print(nanValues)
if len(nanValues)!=len(fieldNames) and len(nanValues)!=1 :
print("字段缺失值数目与待字段数目不一致!")
exit(1)
else:
nanValues=[]
outputFile=args.outputFile
if outputFile and os.path.exists(outputFile):
print("{}已经存在!".format(outputFile))
exit(1)
print(inputFile,fieldNames,nanValues,)
ogr.RegisterAll()
ds=ogr.Open(inputFile,gdalconst.GA_Update)
if not(ds):
print("数据集读取失败!")
exit(1)
if outputFile:
ds=ogr.Driver.CopyDataSource(ogr.DataSource.GetDriver(ds),ds,outputFile)
layer=ogr.DataSource.GetLayerByIndex(ds,0)
if not(layer):
print("数据集读取失败!")
exit(1)
for fieldName in fieldNames:
if len(nanValues)>1:
index=fieldNames.index(fieldName)
nanValue= nanValues[index]
fillFiledNan(layer,fieldName,nanValue)
elif len(nanValues)==1:
fillFiledNan(layer,fieldName,nanValues[0])
else:
fillFiledNan(layer,fieldName)
ogr.DataSource.Destroy(ds)
print('finished!')
gdal基于最近点对属性进行填充
最新推荐文章于 2023-04-22 13:32:54 发布