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

作者: 辛立 | 来源:发表于2017-06-18 21:43 被阅读263次

    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

    相关文章

      网友评论

        本文标题:AGS Python开发-ArcPy基础功能开发

        本文链接:https://www.haomeiwen.com/subject/unniqxtx.html