GDAL 矢量属性数据修改方式(python)

作者:Martian.Alien 时间:2021-01-30 20:53:28 

Case:需要给一个现有的shp数据创建一个字段,并将属性表中原有的一个文本类型的属性转换为整型后填入新创建的字段。

Problem:新字段创建成功,但是赋值操作无效,即无法成功给字段写入值。

solution:对字段进行赋值后需要,重新写入Feature,否则赋值无效,即layer0.SetFeature(feature)。

特别注意:在对数据进行读写操作,一定要以读写的方式打开,即Open(filePath,1),该方法的原型为Open(pszName,int bUpdate = false),并且具有返回值,参数说明如下:

名称说明
pszName需要打开文件或数据源的路径
bUpdate是否需要更新数据集,默认为只读,如果需要对数据进行读写操作,需要给此参数赋值1
返回值返回数据集的指针,如果为NULL,则表明打开数据集失败

以下将给出创建字段和获取字段值、子段赋值的实例。

1.为矢量数据创建字段


# 添加字段
defn = layer.GetLayerDefn()
fieldIndex=defn.GetFieldIndex('SSSS')
if fieldIndex<0:
 # 添加字段
 fieldDefn = ogr.FieldDefn('SSSS', ogr.OFTInteger)
 fieldDefn.SetPrecision(9)
 layer0.CreateField(fieldDefn,1);
fieldIndex2 = defn.GetFieldIndex('SSSS')
if fieldIndex2>0:
 print("字段创建成功:",fieldIndex)

2.获取字段值及字段赋值


feature = layer.GetNextFeature()
indexA = defn.GetFieldIndex('code')
indexB = defn.GetFieldIndex('SSSS')
oField = defn.GetFieldDefn(indexB)
fieldName = oField.GetNameRef()
while feature is not None:
 valueA= feature.GetFieldAsInteger(indexA)
 if valueA is None:
  feature.SetFieldNull(indexB)
  continue
 feature.SetField2(fieldName, valueA)
 layer0.SetFeature(feature)  
 feature = layer0.GetNextFeature()
#feature.Destroy()
ds.Destroy()

补充知识:Python批量修改shapefile属性表字段名(arcpy增删字段)

尝试了3种方法,时间紧迫屡败屡战,最后终于成功。

方法1和2是失败记录,希望有类似经历成功的同学分享下经验。

方法3是成功记录,修改 = 新增 + 计算 +删除相关字段,因为没有删除改名前字段需求,故删除部分没有另做。

方法1 —— 【将shapefile的dbf文件按csv文件读写】

——失败,dbf中有空值及编码问题

不同文件间通过改后缀简单粗暴改写,操作方法存在风险

过于依赖熟悉的领域,由于时间紧迫没有试用dbf第三方库 GDAL 矢量属性数据修改方式(python)


#-*- coding: utf-8 -*-

import os
import shutil
import csv

#批量修改shp中dbf文件中的字段名
#LANE_WIDTH改为LANEWIDTHL
#LANE_WID_1改为LANEWIDTHR
#ORIGIN_LIN改为ORG_LINKID

roadDir = r"D:\20Q1\00DATA\ModifyTitle\ROAD_TEST\\"
modifyRoadDir = r"D:\20Q1\00DATA\ModifyTitle\ModifiedLink\\"
csvDir = r"D:\20Q1\00DATA\ModifyTitle\ROAD_CSV\\"
fileList = os.listdir(roadDir)

num = 0
for file in fileList:
#新建修改后的城市文件夹
city = file.split("_")[0]

os.mkdir(csvDir + city)
os.mkdir(modifyRoadDir + city)
shutil.copy(roadDir + file + "/RD_LINK.dbf", csvDir + city + "/RD_LINK.csv")

print("正在生成{}新dbf文件......".format(city))
dbfData = []
#读取dbf数据为csv文件,读存内容部分
csvFile = open(csvDir + city + "/RD_LINK.csv",encoding='gbk',errors='ignore')
csvReader = csv.reader(csvFile)
for row in csvReader:
 titleLine = []
 if csvReader.line_num == 1:
  titleLine.append(row)
  continue #跳过第1行——列名
 dbfData.append(row)

#生成正确的字段名行
newTitleLine = []
modifyDic = {"LANE_WIDTH":"LANEWIDTHL","LANE_WID_1":"LANEWIDTHR","ORIGIN_LIN":"ORG_LINKID"}  
for fieldName in titleLine:
 if fieldName in modifyDic:
  newTitleLine.append(modifyDic[fieldName])
 else:
  newTitleLine.append(fieldName)

#写入新dbf文件
newDBF = open(modifyRoadDir + city + "/RD_LINK.dbf",'w')
csvWriter = csv.writer(newDBF)
csvWriter.writerow(newTitleLine)
for row in dbfData:
 csvWriter.writerow(row)
newDBF.close()
print("{}新dbf文件已生成!".format(city))

print("{}城市全部完成".format(num))

方法2——直接使用修改字段名函数——失败,arcpy模块没有AlterField_management方法

——失败,但发现直接探寻官方方法还是比网搜野路子要节约时间

GDAL 矢量属性数据修改方式(python)

使用Arcgis10.2 - Advanced浮动版,符合许可信息但Arcpy调用函数失败,存疑。附官网AlterField函数用法介绍:

https://pro.arcgis.com/zh-cn/pro-app/tool-reference/data-management/alter-field-properties.htm


#-*- coding: utf-8 -*-

import os
import arcpy

#批量修改shp中dbf文件中的字段名
#LANE_WIDTH改为LANEWIDTHL
#LANE_WID_1改为LANEWIDTHR
#ORIGIN_LIN改为ORG_LINKID

roadDir = r"D:\20Q1\00DATA\ModifyTitle\ROAD_TEST\\"
fileList = os.listdir(roadDir)

num = 0
for file in fileList:
#截取城市名
city = file.split("_")[0]
print("正在修改{}的shp字段......".format(city))

#修改前后字段名对照字典
modifyDic = {"LANE_WIDTH":"LANEWIDTHL","LANE_WID_1":"LANEWIDTHR","ORIGIN_LIN":"ORG_LINKID"}

#读取shp数据
dbfFile = roadDir + file + "/RD_LINK.shp"
fieldList = arcpy.ListFields(dbfFile)
for field in fieldList: #遍历字段名
 if field.name.upper() in modifyDic: #找到待修改字段名
  arcpy.AlterField_management(dbfFile, field = field.name, new_field_name = modifyDic[field.name])

print("{}字段修改成功!".format(city))

print("{}城市全部完成".format(num))

方法3——添加改名后新字段(字段属性与前保持一致)、计算改名后字段值 = 改名前字段值,成功!


#-*- coding: utf-8 -*-

import os
import arcpy

#批量修改shp属性表中的字段名
#LANE_WIDTH改为LANEWIDTHL
#LANE_WID_1改为LANEWIDTHR
#ORIGIN_LIN改为ORG_LINKID

roadDir = r"D:\20Q1\00DATA\ModifyTitle\ROAD_TEST\\"
fileList = os.listdir(roadDir)

num = 0
for file in fileList:

city = file.split("_")[0] #截取城市名
print("正在添加和计算{}的shp正确字段......".format(city))

#修改前后字段名对照属性字典
modifyDic = {"LANE_WIDTH":["LANEWIDTHL","1"],#错误字段名:[正确字段名,长度]
    "LANE_WID_1":["LANEWIDTHR","1"],
    "ORIGIN_LIN":["ORG_LINKID","10"]}

#读取shp文件
shpFile = roadDir + file + "/RD_LINK.shp"

for wrongfieldName in modifyDic:
 correctfieldName = modifyDic[wrongfieldName][0]
 field_length = modifyDic[wrongfieldName][1]

# Process: 添加字段
 arcpy.AddField_management(shpFile, correctfieldName, "TEXT", "", "", field_length)
 # Process: 计算字段字段
 arcpy.CalculateField_management(shpFile, correctfieldName, "["+wrongfieldName+"]", "VB", "")

## # Process: 添加字段——LANEWIDTHL
## arcpy.AddField_management(shpFile, "LANEWIDTHL", "TEXT", "", "", "1")
## # Process: 计算字段字段——LANEWIDTHL
## arcpy.CalculateField_management(shpFile, "LANEWIDTHL", "["++]", "VB", "")
##
## # Process: 添加字段——LANEWIDTHR
## arcpy.AddField_management(shpFile, "LANEWIDTHR", "TEXT", "", "", "1")
## # Process: 计算字段字段——LANEWIDTHR
## arcpy.CalculateField_management(shpFile, "LANEWIDTHR", "[LANE_WID_1]", "VB", "")
##
## # Process: 添加字段——ORG_LINKID
## arcpy.AddField_management(shpFile, "ORG_LINKID", "TEXT", "", "", "10")
## # Process: 计算字段字段——ORG_LINKID
## arcpy.CalculateField_management(shpFile, "ORG_LINKID", "[ORIGIN_LIN]", "VB", "")
##
## # Process: 删除字段
## #arcpy.DeleteField_management(in_table, "LANE_WIDTH")

print("{}修改完成!请确认!".format(city))

num += 1
print("{}城市全部完成!".format(num))

来源:https://blog.csdn.net/feixiegis/article/details/80319568

标签:GDAL,矢量,属性,python
0
投稿

猜你喜欢

  • python Pygame的具体使用讲解

    2021-01-15 21:41:26
  • Python3以GitHub为例来实现模拟登录和爬取的实例讲解

    2022-01-17 14:52:02
  • MYSQL大量写入问题优化详解

    2024-01-24 04:26:56
  • 使用torchtext导入NLP数据集的操作

    2023-08-19 16:07:10
  • python写的一个文本编辑器

    2021-10-12 08:38:04
  • Python批量查询关键词微信指数实例方法

    2022-06-28 14:54:20
  • Python 'takes exactly 1 argument (2 given)' Python error

    2022-04-19 00:26:05
  • 从基础开始建立一个JS代码库第1/2页

    2024-04-16 10:40:59
  • 优化SQLServer数据库服务器内存配置的策略

    2009-05-13 10:25:00
  • pytorch 使用单个GPU与多个GPU进行训练与测试的方法

    2022-04-04 10:39:07
  • 修改mysql密码与忘记mysql密码的处理方法

    2024-01-23 21:53:48
  • 人工神经网络算法知识点总结

    2023-05-16 11:36:06
  • Mysql查询优化之IN子查询优化方法详解

    2024-01-16 11:38:07
  • 详解如何模拟实现node中的Events模块(通俗易懂版)

    2024-05-05 09:20:55
  • python3 对list中每个元素进行处理的方法

    2022-05-31 13:41:41
  • 边框样式的写法总结

    2009-01-18 13:00:00
  • Python网络编程之TCP与UDP协议套接字用法示例

    2023-12-07 06:34:45
  • 百万行WPF项目代码重构记录分析

    2023-12-30 23:00:28
  • 查看已安装tensorflow版本的方法示例

    2021-09-21 03:49:11
  • Python面向对象程序设计之继承、多态原理与用法详解

    2023-07-08 18:17:52
  • asp之家 网络编程 m.aspxhome.com