ArcGIS Python脚本之Arcpy数据访问模块
目录
目录
游标是包含表格或要素类中的一行或多行数据的内存对象。每一行都包含数据源中每个字段的属性和每个要素的几何特征。游标可用于搜索、添加、插入、更新和删除表和要素类中的数据。
ArcGIS 10.1引入了arcpy数据访问模块(arcpy.da),其中包括使用游标遍历每一行的方法。可以根据不同的需求创建不同类型的游标。例如,创建搜索游标(SearchCursor)用于从行中读取值,创建更新游标(UpdateCursor)用于更新行中的值或删除行,创建插入游标(InsertCursor)用于插入新的行等。
一、使用SearchCursor检索要素类中的要素
SearchCursor()函数返回一个SearchCursor对象,这个对象只能通过遍历行来返回只读目标,没有插入、删除或更新的功能。
可选的where子句用来限制返回的行。
示例:
import arcpy.da # 导入arcpy.da站点包
arcpy.env.workspace = "C:\ArcpyBook\Ch8" # 设置工作空间
with arcpy.da.SearchCursor("Schools.shp", ("Facility", "Name")) as cursor: # 使用with语句创建游标
for row in sorted(cursor): # 循环遍历SearchCursor中的行(sorted()排序)
print("School name: " + row[1])
与SearchCursor()函数一同使用的with语句用来创建、打开和关闭游标,因此,不需要再像使用ArcGIS 10.1之前的版本那样手动释放游标锁定。
为了提高游标性能,最好的做法是在游标中限制字段的个数,只返回完成任务所需的字段。
示例:
使用where子句来限制返回的行。
import arcpy.da # 导入arcpy.da站点包
arcpy.env.workspace = "C:\ArcpyBook\Ch8" # 设置工作空间
# 使用with语句创建游标, 使用where子句限制返回的行
with arcpy.da.SearchCursor("Schools.shp", ("Facility", "Name"), '"FACILITY" = \'HIGH SCHOOL\'') as cursor:
for row in sorted(cursor): # 循环遍历SearchCursor中的行(sorted()排序)
print("School name: " + row[1])
二、使用几何令牌改进游标性能
为了改进游标的性能,ArcGIS 10.1引入了geometry tokens(几何令牌),使用几何令牌可以只返回几何的一部分信息,而不是返回游标中的全部要素的几何信息。返回整个要素的几何信息会导致游标性能下降,因为需要返回大量数据,而只返回需要的特定的几何部分明显提高了游标的速度。
令牌是作为字段列表中的一个字段被传入游标的构造函数的,其格式为SHAPE@<Part of Feature to be Returned>。
几何令牌介绍:
示例:
import arcpy.da # 导入arcpy.da模块
import time
arcpy.env.workspace = "C:\ArcpyBook\Ch8" # 设置工作空间
start = time.clock() # 记录起始时间
""" 使用几何令牌指定返回每个要素的质心坐标和存储在PY_FULL_OW字段中的所有权信息"""
with arcpy.da.SearchCursor("coa_parcels.shp", ("PY_FULL_OW", "SHAPE@XY")) as cursor:
for row in cursor:
print("Parcel owner: {0} has a location of: {1}".format(row[0], row[1]))
elapsed = (time.clock() - start) # 总共耗费的时间
print("Execution time: " + str(elapsed))
三、使用InsertCursor插入行
InsertCursor()函数创建了InsertCursor对象,它可以以编程的方式将新记录添加到要素类和表中。
InsertCursor对象中的insertRow()方法用于添加新行,将列表或元组中的行作为参数传入insertRow()方法中。列表中的值必须与创建对象时定义的字段值相对应。
示例:
import arcpy # 导入arcpy站点包
arcpy.env.workspace = "C:\ArcpyBook\Ch8\WildfireData\WildlandFires.mdb"
""" 打开需要添加的文件 """
f = open("C:\ArcpyBook\Ch8\WildfireData\NorthAmericaWildfires_2007275.txt", "r")
lstFires = f.readlines() # 读取文件内容
try:
with arcpy.da.InsertCursor("FireIncidents", ("SHAPE@XY", "CONFIDENCEVALUE")) as cursor:
cntr = 1
for fire in lstFires:
if 'Latitude' in fire:
continue
vals = fire.split(",")
latitude = float(vals[0])
longitude = float(vals[1])
confid = int(vals[2])
rowValue = [(longitude, latitude), confid]
cursor.insertRow(rowValue) # 插入新记录
print("Record number " + str(cntr) + " written to feature class")
cntr = cntr + 1
except Exception as e:
print(e.message)
finally:
f.close()
四、使用UpdateCursor更新行
UpdateCursor()函数可用于更新或删除表或要素类中的行。返回的UpdateCursor游标将会锁定数据,如果在with语句中使用游标,则会自动释放数据锁定。
示例:
import arcpy # 导入arcpy站点包
""" 设置工作空间 """
arcpy.env.workspace = "C:\ArcpyBook\Ch8\WildfireData\WildlandFires.mdb"
try:
""" 添加新字段 """
arcpy.AddField_management("FireIncidents", "CONFID_RATING", "TEXT", "", "", "10")
print("CONFID_RATING field added to FireIncidents")
""" 取得UpdateCursor对象 """
with arcpy.da.UpdateCursor("FireIncidents", ("CONFIDENCEVALUE", "CONFID_RATING")) as cursor:
count = 1
for row in cursor:
if row[0] <= 40:
row[1] = 'POOR'
elif row[0] > 40 and row[0] <= 60:
row[1] = 'FAIR'
elif row[0] > 60 and row[0] <= 85:
row[1] = 'GOOD'
else:
row[1] = 'EXCELLENT'
cursor.updateRow(row) # 更新对应的数据
print("Record number " + str(count) + " updated")
count = count + 1
except Exception as e:
print(e.message)
五、使用UpdateCursor删除行
UpdateCursor除了可以编辑表或要素类的行外,还可以删除行。
是删除记录调用的是deleteRow()而不是updateRow()。
另外需要注意,当在编辑会话外删除行时,更改是永久性的。
示例:
import arcpy # 导入arcpy站点包
import os
""" 设置工作空间 """
arcpy.env.workspace = "C:\ArcpyBook\Ch8\WildfireData\WildlandFires.mdb"
try:
""" 取得UpdateCursor游标对象 """
with arcpy.da.UpdateCursor("FireIncidents", ("CONFID_RATING"), '[CONFID_RATING] = \'POOR\'') as cursor:
count = 1
for row in cursor:
cursor.deleteRow() # 删除对应行
print("Record number " + str(count) + " deleted")
count = count + 1
except Exception as e:
print(e.message)
六、在编辑会话中插入和更新行
在编辑会话外进行表或要素类的插入、更新或删除的操作是永久性的,不能撤销,而编辑会话则可以撤销任何不需要的更改。
数据访问模块中新的Editor类支持创建编辑会话和编辑操作功能。在编辑会话中,要素类或表的更改是临时性的,除非调用特定的方法才可进行永久更改,这与桌面ArcGIS中的”Edit“工具条的功能是相同的。
调用Editor.startEditing()启动编辑会话。在会话中使用Editor.startOperation()方法开始一个操作,在这个操作中可以对数据执行各种编辑操作。这些编辑可以被撤销、重做、回滚、中止等。完成这些操作后,先调用Editor.stopOperation()方法停止编辑操作,再调用Editor.stopEditing()方法停止编辑会话。会话结束时可以不保存,在这种情况下,更改将不会生效。
startEditing()方法有两个可选参数:
- with_undo —— 数据类型是布尔型,当设置为true时,将创建一个撤销/重做堆栈,默认值为ture。
- multiuser_mode ——
stopEditing()方法的参数为true或false,表示是否保存更改,默认值为true。
示例:
try:
edit = arcpy.da.Editor(r'C:\ArcpyBook\Ch8\WildfireData\WildlandFires.mdb')
edit.startEditing(True) # 启动编辑会话
""" 获取UpdateCursor游标对象 """
with arcpy.da.UpdateCursor("FireIncidents", ("CONFIDENCEVALUE", "CONFID_RATING")) as cursor:
count = 1
for row in cursor:
if row[0] > 40 and row[0] <= 60:
row[1] = 'GOOD'
elif row[0] > 60 and row[0] <= 85:
row[1] = 'BETTER'
else:
row[1] = 'BEST'
cursor.updateRow(row) # 更新行记录
print("Record number " + str(count) + " updated")
count = count + 1
edit.stopEditing(True) # 停止编辑会话
except Exception as e:
print(e.message)
七、读取要素类的几何信息
在Arcpy中,每个要素类都有相关的几何对象,如Polygon、Polyline、PointGeometry或MultiPoint等,都可以在游标中访问。这些几何对象存储在要素类属性表中的shape字段中,可以通过shape字段来读取每个要素的几何特征。
示例:
import arcpy # 导入arcpy站点包
""" 设置工作空间 """
infc = "C:\ArcpyBook\data\CityOfSanAntonio.gdb\SchoolDistricts"
""" 取得SearchCursor游标对象 """
for row in arcpy.da.SearchCursor(infc, ["OID@", "SHAPE@"]):
print("Feature {0}: ".format(row[0])) # 打印要素的标识码
partnum = 0
for part in row[1]: # 遍历要素的每一部分
print("Part {0}: ".format(partnum))
for pnt in part: # 遍历要素每一部分的每个顶点,并输出X和Y坐标
if pnt:
print("{0}, {1}".format(pnt.X, pnt.Y))
else:
print("Interior Ring:")
partnum += 1
八、使用Walk()遍历目录
Walk()函数是arcpy.da的一部分,通过自上而下或自下而上的方式遍历目录树,生成目录树中的文件名。每个目录或工作空间生成一个包含目录路径、目录名称和文件名的元组。
这个函数类似于Python的os.Walk()函数,但是它具有识别地理数据库结构的优点。os.Walk()函数是基于文件的,所以不能够提供有关地理数据库结构的信息,但是arcpy.da.Walk()可以。
示例:
使用os.walk()获取当前目录中的文件名列表:
import arcpy.da as da
import os # 导入os模块
print("os walk")
for dirpath, dirnames, filenames in os.walk(os.getcwd()):
for filename in filenames:
print(filename)
输出:
使用arcpy.da.Walk():
import arcpy.da as da
import os # 导入os模块
print("arcpy da walk")
""" 参数datatype用于指定返回列表的数据类型 """
for dirpath, dirnames, filenames in da.Walk(os.getcwd(), datatype="FeatureClass"):
for filename in filenames:
print(os.path.join(dirpath, filename))
输出:
转载自:https://blog.csdn.net/qq_35732147/article/details/86085878