AGS Python开发-ArcPy基础功能开发


1、数据列表与参数设置

1.1、数据列表与遍历

(1)返回数据列表的函数

ArcPy中提供了大量可以返回数据列表的函数,可以方便后续遍历数据。

函数名 说明
ListFields(dataset, wild_card, field_type) 返回数据集中的字段列表
ListIndexes(dataset, wild_card) 返回数据集中属性索引列表
ListDatasets(wild_card, feature_type) 返回工作空间中的数据集
ListFeatureClasses(wild_card, feature_type, feature_dataset) 返回工作空间中的要素类
ListFiles(wild_card) 返回工作空间中的文件
ListRasters(wild_card,raster_type) 返回工作空间中的栅格数据
ListTables(wild_card, table_type) 返回工作空间中的表
ListWorkspaces(wild_card, workspace_type) 返回工作空间列表
ListVersions(sde_workspace) 返回版本列表

参数说明:wild_card:字符串参数,用于过滤,支持通配符。

arcpy.env.workspace="c:/map.gdb"
fcs = arcpy.ListFeatureClasses("*","polygon")
fcCount = len(fcs)

(2)遍历数据列表
使用循环语句遍历。

dirPath = "D:/mapdata/test/worldshp"
arcpy.env.workspace=dirPath
ftClasses = arcpy.ListFeatureClasses()
for ftClass in ftClasses:
    print(ftClass)

(3)返回工具、工具箱和环境设置列表的函数
工具列表:arcpy.ListTools({wildcard})
环境设置列表:arcpy.ListEnvironments({wildcard})
工具箱列表:arcpy.ListToolboxes({wildcard})

(4)遍历子目录
ArcPy中遍历目录以及子目录,需要使用arcpy.da.Walk函数。Walk(top, topdown, onerror, followlinks, datatype, type)返回结果是一个元组(dirpath, dirnames,filenames)

workspace = "D:/mapdata/test/china/"
for dirpath,dirnames,filenames in arcpy.da.Walk(workspace,datatype="FeatureClass",type="Point"):
    print(dirpath,type(dirpath))
    print(dirnames)
    print(filenames)

1.2、多值参数设置

对于接收列表类型参数的地理处理工具,列表参数的设置有三种方式:列表、字符串、ValueTable。
(1)列表

fields=["AREA","PERIMETER","ORIG_FID"]
arcpy.DeleteField_management("citiesbuffer",fields)

(2)字符串
将多个值以逗号隔开。

strFlds="BUFF_DIST;ADCLASS"
arcpy.DeleteField_management("citiesbuffer",strFlds)

(3)ValueTable

vt = arcpy.ValueTable()
vt.addRow("PINYIN")
vt.addRow("ADCODE93")
arcpy.DeleteField_management("citiesbuffer",vt)

1.3、字段映射

在执行合并或追加等地理处理工具时,需要将输入源的字段映射到输出数据的字段上。对于这种字段映射关系的定义使用Fieldmappings和Fieldmap对象,Fieldmappings由Fieldmap组成,Fieldmap定义了多个输入字段与一个输出字段的映射关系。
(1)定义Fieldmap对象
方式1:创建空的Fieldmap对象

fldmap = arcpy.Fieldmap()

方式2:从Fieldmappings中创建

fc1 = "C:/data/CityData.gdb/Blocks1"
fieldmappings = arcpy.FieldMappings()
fieldmappings.addTable(fc1)
fldmap = fieldmappings.getFieldMap(fieldmappings.findFieldMapIndex("POP2000"))

(2)设置输入输出字段映射关系
如图层fc1的字段name,fc2的字段str,映射到输出图层的strname字段。

fldmap.addInputField(fc1, "name")
fldmap.addInputField(fc2, "str")
fldmap_outField = fldmap.outputField
fldmap_outField.name =  "strname"
fldmap.outputField = fldmap_outField

(3)定义输入图层与输出图层映射关系

fieldmappings = arcpy.FieldMappings()
fieldmappings.addTable(fc1)
fieldmappings.addTable(fc2)
fieldmappings.addFieldMap(fldmap)

(4)执行分析

vTab = arcpy.ValueTable()
vTab.addRow(fc1)
vTab.addRow(fc2)
outfc = "C:/data/CityData.gdb/AllBlocks"
arcpy.Merge_management(vTab, outfc, fieldmappings)

1.3、验证表和字段名称

在操作地理数据库中的要素类以及字段信息时,需要注意是否违反数据库的命名规范,如表名是否重复,是否包含非法字符等。ArcPy提供了如下函数供检验正确与否:
arcpy.ValidateTableName(name,{workspace}) #获取表名和工作空间路径并为该工作空间返回一个有效表名
arcpy.ValidateFieldName(name, {workspace}) #获取字符串(字段名)和工作空间路径,并基于输出地理数据库中的名称限制返回一个有效字段名

arcpy.env.workspace="D:/mapdata/test/worldshp"
ftClasses = arcpy.ListFeatureClasses()
for fc in ftClasses:
    outputFt = arcpy.ValidateTableName(fc)
    print(outputFt)

2、访问地理数据

2.1、检查数据是否存在

Exists(dataset)函数用于检查数据是否存在。
(1)检查GDB中的图层是否存在

arcpy.env.workspace = "d:/St_Johns/data.gdb"
fc = "roads"
if arcpy.Exists(fc):
    print(u"存在")

(2)检查SDE中的图层是否存在

arcpy.env.workspace = "Database Connections/Bluestar.sde"
fc = "ORASPATIAL.Rivers"
if arcpy.Exists(fc): 
    print(u"存在")

2.2、读取数据的属性信息

Describe函数用于读取数据的属性信息。

ftDesc = arcpy.Describe(ftClass)
print(ftDesc.shapeType)
print(ftDesc.spatialReference)

2.3、读取数据的字段信息

(1)从Describe()中获取

ftDesc = arcpy.Describe(ftClass)
fields = ftDesc.fields

(2)使用ListFields()获取

fields = arcpy.ListFields(ftClass)

2.4、空间参考

(1)读取空间参考

ftDesc = arcpy.Describe(ftClass)
sr = ftDesc.spatialReference

(2)创建空间参考
方式1(投影文件):sr = arcpy.SpatialReference("c:/prj/NAD 1983.prj")
方式2(坐标系名称):sr = arcpy.SpatialReference("GCS_China_Geodetic_Coordinate_System_2000")
方式3(wkid):sr = arcpy.SpatialReference(4490)

2.5、访问要素集和记录集

FeatureSet要素集对应要素类,RecordSet记录集对应表。两者操作方式一样。
(1)从要素类中读取数据集
方式1:

ft_set = arcpy.FeatureSet()
ft_set.load("c:/map/roads.shp")

方式2:

ft_set = arcpy.FeatureSet("c:/map/roads.shp")

(2)从Result对象中获取数据集

result = arcpy.BufferPoints_servertools(in_featureset, "5 feet")
out_featureset = result[0]

或者out_featureset = result.getOutput(0)
(3)保存要素集

out_featureset.save("c:/temp/base.gdb/towers_buffer")

3、游标

游标用于增、删、查、改地理数据。ArcPy中提供的游标有三种:查询游标、插入游标、更新游标。

游标对象 游标对象的方法 说明
arcpy.da.SearchCursor next 检索下一行
reset 将游标重置到起始位置
arcpy.da.InsertCursor insertRow 插入一行
arcpy.da.UpdateCursor updateRow 更新当前行
deleteRow 删除当前行
reset 将游标重置到起始位置
next 检索下一行

3.1、查询游标SearchCursor

(1)迭代游标
方式1:for语句(也可以使用while语句结合next()方法迭代)

cursor = arcpy.da.SearchCursor(fc, ['fieldA', 'fieldB'])
for row in cursor:
    print(row)
del row
del cursor

方式2:with语句

with arcpy.da.SearchCursor(fc, ['fieldA', 'fieldB']) as cursor:
    for row in cursor:
        print(row)

(2)游标重置
游标只支持向前导航,如果需要重新导航,需要调用reset方法重置。
(3)过滤查询
方式1:where条件查询。过滤条件建议写在三重引号中。

fc = "D:/St_Johns/data.gdb/roads"
cursor = arcpy.da.SearchCursor(fc, ("roadclass", "name"), """"roadclass" = 2""")
for row in cursor:
    print(row[1])
del row
del cursor

ArcGIS中对字段名的引用因数据源不同而不同,文件GDB和shape引用字段使用双引号,SDE不使用任何符号。为避免麻烦,使用AddFieldDelimiters函数处理。

fc = "D:/St_Johns/data.gdb/roads"
fieldname = "roadclass"
whereclause = """{} = 2""".format(arcpy.AddFieldDelimiters(fc, fieldname))
cursor = arcpy.da.SearchCursor(fc, ("roadclass", "name"), whereclause)
for row in cursor:
    # Print the name of the residential road
    print(row[1])
del row
del cursor

方式2:额外条件查询。额外条件包括:前缀条件(None、DISTINCT、TOP),后缀条件(None 、ORDER BY、GROUP BY)

cities = "D:/mapdata/test/worldshp/cities.shp"
flds = "CNTRY_NAME"
cursor = arcpy.da.SearchCursor(cities,flds,sql_clause=(None,"ORDER BY "+flds))
for row in cursor:
    print(row)
del row
del cursor

3.2、插入游标InsertCursor

(1)插入新数据

cursor = arcpy.da.InsertCursor("c:/base/data.gdb/roads_lut",  ["roadID", "distance"])
for i in range(0,25):
    cursor.insertRow([i, 100])
del cursor

3.3、更新游标UpdateCursor

更新游标支持数据更新和删除。
(1)更新数据

with arcpy.da.UpdateCursor("c:/base/data.gdb/roads", ["roadtype", "distance"]) as cursor:
    for row in cursor:
        row[1] = row[0] * 100
        #或者使用
        #row[1].setValue("distance", row[0].getValue("roadtype") * 100)
        cursor.updateRow(row)

(2)删除数据

with arcpy.da.UpdateCursor("c:/base/data.gdb/roads",  ["roadtype"]) as cursor:
    for row in cursor:
        if row[0] == 4:
            cursor.deleteRow()

3.4、Cursor对象与Row对象

查询游标、插入游标、更新游标返回的结果都是Cursor对象,它代表的是数据列表,由Row对象组成,Row对应是表中的一行记录。
(1)Cursor对象的方法

方法 说明
deleteRow(row) 删除表中的一行
insertRow(row) 向表插入一行
newRow() 创建空行
next() 检索下一行
reset() 重置索引到起始位置
updateRow(row) 更新一行
import datetime
import arcpy
 
cursor = arcpy.InsertCursor("c:/base/data.gdb/roads_maint")
for i in range(1000, 1025):
    row = cursor.newRow()
    row.setValue('rowid', i)
    row.setValue('distance', 100)
    row.setValue('CFCC', 'A10')
    row.setValue('LastInsp', datetime.datetime.now())
    cursor.insertRow(row)
del cursor, row

(2)Row对象的方法

方法 说明
getValue(field_name) 获取字段值
isNull(field_name) 字段值是否为空
setNull(field_name) 将字段值设置为空
setValue(field_name,value) 设置字段值

除了使用get方法读取字段值外,Row对象还支持直接访问字段名的方式获取值,如:row.NAME
(3)Cursor对象和Row对象使用注意事项
Cursor对象和Row对象使用完成,需要清除,如del row,cursor

3.5、游标与锁定

查询游标使用的是共享锁,插入游标和更新游标使用的是排它锁。使用排它锁时,会阻止其他应用程序访问数据集。游标释放方式:

  1. 在with语句中使用游标,会自动释放锁。
  2. 调用游标的reset()
  3. 游标调用完成
  4. del语句删除游标
cur = None
try:
    cur = arcpy.da.InsertCursor(outFC, ["SHAPE@XY"])
    xy = (5997594.4753, 2069901.75682)
    cursor.insertRow([xy])
except Exception as e:
   print(e)
finally:
    if cur:
        del cur

3.6、读写BLOB字段

在 Python 中,BLOB 字段可接受字符串 bytearray 和 memoryviews。当读取 BLOB 字段时,返回 memoryview 对象。
(1)写BLOB

data = open("c:/images/image1.png", "rb").read()
ic = arcpy.da.InsertCursor("c:/data/fgdb.gdb/fc", ['imageblob'])
ic.insertRow([data])

(2)读BLOB

sc = arcpy.da.SearchCursor("c:/data/fgdb.gdb/fc", ["imageblob"])
memview = sc.next()[0]
open("c:/images/image1_copy.png", "wb").write(memview.tobytes())

3.7、令牌

令牌是字段的一种快捷访问方式。常用令牌:
ObjectID字段的令牌:OID@
shape字段的令牌:SHAPE@
要素质心的令牌:SHAPE@XY
X、Y坐标的令牌:SHAPE@XSHAPE@Y
坐标JSON字符串的令牌:SHAPE@JSON
面积和长度的令牌:SHAPE@AREASHAPE@LENGTH
示例:

for row in arcpy.da.SearchCursor(infc, ["OID@", "SHAPE@"]):
     print("Feature {}:".format(row[0]))
    for pnt in row[1]:
        print("{}, {}".format(pnt.X, pnt.Y))

4、空间几何类型

ArcPy中提供的与几何类型相关的对象有:GeometryPointMultiPointPointGeometryPolylinePolygonExtent。其中PointExtent不算几何类型,它们无空间参考信息。

4.1、Point

Point是非几何对象,常配合游标使用。

point = arcpy.Point(5997577.46097, 2069905.81145)

4.2.、PointGeometry

point = arcpy.Point(25282, 43770)
ptGeometry = arcpy.PointGeometry(point)

4.3、Polyline

array = arcpy.Array([arcpy.Point(5997611.48964, 2069897.7022),arcpy.Point(5997577.46097, 2069905.81145)])
polyline = arcpy.Polyline(array)

4.4、Polygon

array = arcpy.Array([arcpy.Point(1, 2),arcpy.Point(2, 4), arcpy.Point(3, 7)])
polygon = arcpy.Polygon(array)

array中的坐标不需要闭合。

4.5、Extent

记录矩形范围的最大最小XY等信息。

xmin = 12
xmax = 24
ymin = 8
ymax = 30
extent = arcpy.Extent(xmin,ymin,xmax,ymax)

4.6、与游标结合使用

fc = "c:/data/gdb.gdb/roads"
cursor = arcpy.da.InsertCursor(fc, ["SHAPE@"])
array = arcpy.Array([arcpy.Point(5997611.48964, 2069897.7022), arcpy.Point(5997577.46097, 2069905.81145)])
polyline = arcpy.Polyline(array)
cursor.insertRow([polyline])

4.7、与地理处理工具结合使用

(1)作为输入几何参数
自定义构建几何对象,作为地理处理工具的参数。

coordinates = [ [2365000, 7355000],[2365000, 7455000], [2465000, 7455000], [2465000, 7355000]]
array = arcpy.Array([arcpy.Point(x, y) for x, y in coordinates])
boundary = arcpy.Polygon(array, arcpy.SpatialReference(2953))
result = arcpy.Clip_analysis('c:/data/rivers.shp', boundary, 'c:/data/rivers_clipped.shp')

(2)作为输出几何对象
将地理处理工具的输出设置为空几何对象,可以用来输出几何对象列表。

geometries = arcpy.CopyFeatures_management('c:/temp/outlines.shp', arcpy.Geometry())
length = sum([g.length for g in geometries])
print('Total length: {}'.format(length))

4.8、拓扑和几何操作

每个几何对象中都提供了拓扑和几何相关的操作,如:buffer(distance)clip(envelope)crosses(second_geometry)intersect(other, dimension)等等。

5、arcpy.mapping地图制图模块

地图制图模块提供了管理mxd文档和图层,图层渲染、地图打印输出、地图服务发布等功能。
(1)访问地图文档
方式1:访问当前地图文档

mxd = arcpy.mapping.MapDocument("CURRENT")

方式2:访问指定路径的地图文档

mxd = arcpy.mapping.MapDocument("C:/Project/Watersheds.mxd")

(2)列表函数
ListDataFrames:返回文档中的图层框DataFrame对象列表
ListLayers:返回地图图层Layer对象列表,Layer对应的是lyr文件。
ListLayoutEelements:返回布局元素列表
ListTableViews:返回独立表TableView对象列表
ListStyleItems:返回符号SytleItem对象列表

mxd = arcpy.mapping.MapDocument("CURRENT")
riverLyr = arcpy.mapping.ListLayers(mxd, "Rivers")[0]
titleTxt = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "title")[0]

(3)数据源修复

mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd")
mxd.findAndReplaceWorkspacePaths(r"C:\Project\Data", r"C:\Project\Data2")
mxd.saveACopy(r"C:\Project\Project2.mxd")
del mxd

(4)图层显示信息设置
如:打开标注和设置透明度。

mxd = arcpy.mapping.MapDocument(r"c:\mapdata\chinamap\china.mxd")
dataFrame = arcpy.mapping.ListDataFrames(mxd, u"图层")[0]
 
layer = arcpy.mapping.ListLayers(mxd, "", dataFrame)[0]
layer.showLabels = True
layer.labelClasses[0].expression = '[CITY NAME] +"-"+[CNTRY NAME]'
layer.transparency = 50
mxd.save()
del mxd

(5)地图文档输出

arcpy.mapping.ExportToPDF(mxd, r"C:\Project\map.pdf")

详情参考:http://desktop.arcgis.com/zh-cn/arcmap/latest/analyze/arcpy-mapping/exportreport.htm

6、SDE中执行SQL操作

arcpy.ArcSDESQLExecute对象提供了直接使用SQL语句操作地理数据库的方法。支持的SQL语句包括:SELECT、INSERT、UPDATE、DELETE。
使用SQL操作SDE的注意事项如下:

  1. 版本化的数据只能通过版本化视图来使用SQL。非版本化的数据无此限制。
  2. 使用数据库原生空间类型构建的地理数据库,可以使用数据库本身的空间SQL语句。

详情参考:http://desktop.arcgis.com/zh-cn/arcmap/latest/analyze/python/executing-sql-using-an-egdb-connection.htm

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容