使用arcpy对两个要素进行更新操作

本文详细介绍如何在GIS环境中使用Python脚本进行要素更新、插入及处理空值的技巧,解决常见bug并提供绕行方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求1:

想在两个要素之间做更新,目标要素需要更新源要素的内容过来,包括几何和属性信息,他们的字段基本一致。

数据:

案例数据:

链接:https://pan.baidu.com/s/1xAcOTuLXvtdPiiSFGPDWdQ 
提取码:lh2i 

 脚本:

import arcpy

arcpy.env.workspace = r"E:\testing\Beijing4490_v10_0.gdb"
edit = arcpy.da.Editor(r"E:\testing\Beijing4490_v10_0.gdb")

# Edit session is started without an undo/redo stack for versioned data
#  (for second argument, use False for unversioned data)
edit.startEditing(False, True)
edit.startOperation()
#da.SearchCursor字段不能使用*,必须指定Shape@,之前可以使用ListFields列出所有字段,使用*会导致后面的shape无法赋值
cursor = arcpy.da.SearchCursor("source",["SHAPE@","name"],where_clause="OBJECTID = 4")

for row in cursor:

    shape = row[0]
    # index = cursor.fields.index("GBCODE")
    name = row[1]
    print name

# Insert a row into the table.
cursor1 = arcpy.da.UpdateCursor("destination",["SHAPE@","name"],where_clause="OBJECTID = 4")
for row1 in cursor1:
    row1[0]=shape
    row1[1]=name
    cursor1.updateRow(row1)

print("success")

# Stop the edit operation.
edit.stopOperation()

# Stop the edit session and save the changes
edit.stopEditing(True)
del cursor1
del cursor

效果图:

destination图层的OBJECTID为4要素的几何形状和属性信息(NAME99字段)被更新。

 

 需求2:将source图层的图形和属性插入给destination图层

由于da.InsertCursor无法修改参与了几何网络的要素类,是一个已知bug,只能使用arcpy.InsertCursor

import  arcpy

arcpy.env.workspace = r"E:\testing\Beijing4490_v10_0.gdb"
edit = arcpy.da.Editor(r"E:\testing\Beijing4490_v10_0.gdb")

edit.startEditing(False, True)
edit.startOperation()
cursor = arcpy.da.SearchCursor("destination",["SHAPE@","ADCODE99"],where_clause="OBJECTID = 12")

for row in cursor:

    shape = row[0]
    # index = cursor.fields.index("ADCODE99")
    length = row[1]

cursor1 = arcpy.InsertCursor("source")
row1 = cursor1.newRow()
row1.setValue("Shape", shape)
row1.setValue("ADCODE99", length)
cursor1.insertRow(row1)

print("success")

# Stop the edit operation.
edit.stopOperation()

# Stop the edit session and save the changes
edit.stopEditing(True)
del cursor1
del cursor

 需求3:将空值赋值给有默认值的要素。

测试环境:

       ①要素类在要素数据集中

       ②该要素类参与了几何网络

       ③该要素类所在的要素数据集注册了版本

       ④所用数据库为企业级地理数据库Oracle

       ⑤其他条件:属性域,允许为空,有默认值

遇到的问题:更新一个应用了属性域有默认值(默认值不为空)但可为空的字段时发现了一个问题,当源要素该字段为空,目标要素该字段不为空,通过da.UpdateCursor无法将源要素该字段空值赋给目标要素,最终得到的结果是默认值而非空值。

经过研究,发现使用arcpy.da下没有方法能够将空值(数值型/字符串型等)传递给另一个字段。
这被认定是一个bug,见链接:https://support.esri.com/zh-cn/bugs/nimbus/QlVHLTAwMDA5MTMxNA==
这个bug目前正在新的产品计划之中,如果修复的话,也会在上述链接中进行状态更新。

绕行方案是使用之前老的update cursor,里面有setNull()方法,可以将数值型等字段的属性值设置为null。

import arcpy

arcpy.env.workspace = r"C:\Users\admin\AppData\Roaming\ESRI\Desktop10.7\ArcCatalog\ORCLUSER1.sde"
edit = arcpy.da.Editor( r"C:\Users\admin\AppData\Roaming\ESRI\Desktop10.7\ArcCatalog\ORCLUSER1.sde")

# Edit session is started without an undo/redo stack for versioned data
#  (for second argument, use False for unversioned data)
edit.startEditing(False, True)
edit.startOperation()

cursor = arcpy.SearchCursor("source2","OBJECTID = 4","",["SHAPE@","test"])

for row in cursor:
    shape = row[0]
    # index = cursor.fields.index("GBCODE")
    test = row[1]
    print test

# Insert a row into the table.
cursor1 = arcpy.UpdateCursor("destination2","OBJECTID = 4","",["SHAPE@","test"])
for row1 in cursor1:
    row1[0]=shape
    if test is None:
        row1[1].setNull(test)
        print row1[1]
    else:
        row1[1] = test

    cursor1.updateRow(row1)

print("success")

# Stop the edit operation.
edit.stopOperation()

# Stop the edit session and save the changes
edit.stopEditing(True)
del cursor1
del cursor

参考资料:

 https://gis.stackexchange.com/questions/183932/insert-or-update-cursor-setting-value-to-none-not-honored-when-field-has-a-def

https://blog.youkuaiyun.com/baoqian1993/article/details/71157714 创建几何网络

https://www.cnblogs.com/aoldman/archive/2013/05/02/3054729.html

https://blog.youkuaiyun.com/sophiasy/article/details/38088429

https://blog.youkuaiyun.com/kone0611/article/details/50259599

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值