搜罗全网!ArcGIS二次开发Python(arcpy)指南(三):三大文件对象操作


点击上方蓝字,关注我带你飞!前言:地图文档对象、数据框对象、还有最为重要的图层对象。每种对象都有着各自的属性和方法,都有着不同的妙用...

上一章非常详细介绍了 ArcPy 模块、Python 窗口、ArcGIS 程序之间进行文件存取、修改、保存的情况。这一章节就深入的具体的文件中,探究这些文件、数据框、图层对象有哪些实用的、好用的属性和方法。地图文档对象

地图文档对象提供了对 mxd 文件中的众多常用属性的访问,地图文档对象就是 mxd 文件对象。在第二章中我们就掌握了使用 MapDocument 创建地图文档对象,那么地图文档对象中有哪些方法和属性呢?由于地图文档对象的方法和属性非常多,也比较简单,详细说明请查阅官方文档 MapDocument (arcpy.mapping)。这里我通过 Python 输出了一部分属性, 代码(源代码可见文件 Chapter/code1.py)和结果如下:# -*- coding:utf-8 -*-from __future__ import unicode_literalsimport arcpyimport oscws = os.getcwd()arcpy.env.workspace = cwsarcpy.env.overwriteOutput = Truemxd = arcpy.mapping.MapDocument("../MXD/mxd1.mxd")print "activeDataFrame:{}".format(mxd.activeDataFrame)print "activeView:{}".format(mxd.activeView)print "author:{}".format(mxd.author)print "credits:{}".format(mxd.credits)print "dateExported:{}".format(mxd.dateExported)print "datePrinted:{}".format(mxd.datePrinted)print "dateSaved:{}".format(mxd.dateSaved)print "description:{}".format(mxd.description)print "filePath:{}".format(mxd.filePath)print "hyperlinkBase:{}".format(mxd.hyperlinkBase)print "pageSize:{}".format(mxd.pageSize)print "title:{}".format(mxd.title)print "tags:{}".format(mxd.tags)print "summary:{}".format(mxd.summary)运行结果:activeDataFrame:<geoprocessing Data Frame object object at 0x02BE2110>activeView:图层author:credits:dateExported:1899-12-30 00:00:00datePrinted:1899-12-30 00:00:00dateSaved:2021-05-14 15:41:45.000001description:filePath:../MXD/mxd1.mxdhyperlinkBase:pageSize:PageSize(width=20.997375328083994, height=29.692659385318777)title:tags:summary:1.保存地图文档对象还有几个重要方法如 save() 和 saveACopy() ,用于保存 mxd 文件。2.数据替换、修复ArcPy 对地图文档对象源文件的替换和修复提供了两个方法:一个是用于查找地图文档中所有图层(包括表)的工作空间路径并替换为新工作空间路径的 findAndReplaceWorkspacePaths() 方法。一个是为地图文档 (.mxd) 文件中所有的图层替换数据源的 replaceDataSource() 方法。其提供转换工作空间类型的能力(例如,用 SDE 数据源替换文件地理数据库数据源)。Note:图层对象中也有类似方法,注意区分。数据框对象

地图文档对象的下一层就是数据框对象(DataFrame对象),数据框对象提供对重要数据框属性的访问、修改。使用数据框对象不仅可以修改数据框的属性,用于设置地图范围,比例和旋转以及诸如空间参考之类的,还可以修改出图页面纸张的大小、布局甚至调整数据框的大小;同时在图层对象中也经常使用数据框对象来对文件进行限制。例如,ListLayers 方法提供了一个称为 data_frame 的可选参数,以便可以在单个数据框中而不是整个地图文档中搜索图层。同时数据框对象还用作可选参数,以区分打印或导出数据框与页面布局。因此,唯一地命名每个数据框很重要,这样可以轻松地引用特定的数据框。使用 ListDataFrames() 可以从地图文档对象中取得数据框对象,同样该操作读者应该在第二章就见过了,不清楚也没有关系,下面的示例代码也有。1.属性尺寸是数据框的重要数据,我们需要搞清楚大小位置和范围这两个基本概念。下图是截取 ArcMap 中的布局视图,可以明显看到有两个方框,最外面的方框表示我们的出图页面纸张,默认 A4 大小;左下角是出图页面纸张起始点 x =0,y = 0,默认单位 cm;里面的方框就是数据框,各种数据都依托这个数据框来显示,就像是一个窗口。大小位置表示的是数据框(内层的方框)在出图页面纸张(外部的方框)中的高、宽以及左下角起始点的位置,默认单位 cm。范围表示的是这个数据框(内层的方框)在参考系坐标中的具体位置,单位跟随使用的参考系坐标的单位。

1.1 大小位置数据宽的大小位置支持修改,通过这4个数据框对象变量获取:高 elementHeight 、宽 elementWidth、x 轴起始坐标 elementPositionX 、y 轴起始坐标 elementPositionY。

在控制台中打印输出这4个属性值:print "elementHeight: {}".format(df.elementHeight)print "elementWidth: {}".format(df.elementWidth)print "elementPositionX: {}".format(df.elementPositionX)print "elementPositionY: {}".format(df.elementPositionY)属性输出如下:elementHeight: 27.1767elementWidth: 18.4814elementPositionX: 1.258elementPositionY: 1.258右键数据框点击打开属性,然后打开大小和位置选项卡,可以看到参数是一模一样的。

数据框对象通过修改上述四个属性值可以自定义布局界面出图范围的大小和位置,但是由于地图文档对象中的页面大小 pageSize 属性是只读,只能读取不能修改。纸张页面大小不能通过 ArcPy 修改,实际上数据框对象这4个属性没有太多的使用机会。1.2 范围打开 ArcMap ,随便添加一个数据,可以看到右下有这样的

数值,这个表示当前鼠标位置的 xy 坐标。既然有 xy 坐标就有坐标系,这个坐标系是投影坐标系也叫参考系(如果没有投影的数据显示的就是经纬度),参考系将地球绘制成一个平面,然后坐标与属性相连接,再配上不同的文件形式,形成了各种地理空间数据。可以把数据框理解为一个“窗户”,修改其范围可以使窗户变大看到更多的信息,也可以变小看的更细微,也可以移动。这个范围指的就是这个“窗户”在参考系中的坐标信息。可以通过数据框对象的 extent 来获得 Extent 对象,读取 Extent 对象可以获得当前的位置信息,也可以修改它来改变数据框框选的位置。使用 extent 修改范围的示例:newExtent = df.extentnewExtent.XMin, newExtent.YMin = -180.0, -90.0newExtent.XMax, newExtent.YMax = 180.0, 90.0df.extent = newExtent1.3 单位数据框中有两种单位,一个是地图单位,另一个是显示单位。地图单位与数据框的参考系单位一致;显示单位就是 ArcMap 右下角坐标的显示单位,这个可以自由设置。


使用数据框对象的 mapUnits 和 displayUnits 可以获得相关属性,不过注意 mapUnits 也就是地图单位是只读的。修改显示单位示例:df.displayUnits = "Meters" # 修改成米df.displayUnits = "Feet" # 修改成英尺注意显示单位英文开头大写;复数形式。1.4 比例尺讲了那么多坐标位置相关的信息,还有一个很重要的相关概念就是比例尺(英文 scale)。使用 scale 可以读取、修改比例尺大小,是一个简单但是很重要的属性。简单使用说明,控制比例尺为1:20000:df.scale = 20000Note:数据框又不是什么文件,只不过是 ArcGIS 软件中的一个抽象概念,怎么会有参考系呢?其实本身是没有,只有当你往新开启的 ArcMap 中添加数据后,这时数据框会复制图层数据的参考系。理解了这个问题可能你就能明白为什么有的时候添加数据后找不到了,因为和数据框参考系不匹配。2.方法数据框对象只有两个方法。panToExtent (extent):将数据框平移到新的范围并居中;参数 extent 表示新的范围对象。zoomToSelectedFeatures ():不需要传入任何参数;该方法可以使数据框的范围自动适配数据框中图层的范围,平移然后居中,如下图。配合 scale 效果更好。


使用 zoomToSelectedFeatures () 方法实现居中的效果,从左边到右边3.代码展示还有一些常规属性如 name 、description 等不常使用的就不说了,还有一个比较重要的空间参考属性 spatialReference 现在先不讲。展示代码见文件 Chapter/code2.py 。# -*- coding:utf-8 -*-from __future__ import unicode_literalsimport arcpyimport oscws = os.getcwd()arcpy.env.workspace = cwsarcpy.env.overwriteOutput = Truemxd = arcpy.mapping.MapDocument("../MXD/mxd1.mxd")# mxd = arcpy.mapping.MapDocument("CURRENT")df = arcpy.mapping.ListDataFrames(mxd)[0]df.displayUnits = "Meters"print "displayUnits: {}".format(df.displayUnits)print "mapUnits: {}".format(df.mapUnits)print "elementHeight: {}".format(df.elementHeight)print "elementWidth: {}".format(df.elementWidth)print "elementPositionX: {}".format(df.elementPositionX)print "elementPositionY: {}".format(df.elementPositionY)print "referenceScale: {}".format(df.referenceScale)print "type: {}".format(df.type)print "scale: {}".format(df.scale)print "extent: {}".format(df.extent)print "spatialReference: {}".format(df.spatialReference)print "description: {}".format(df.description)print "name: {}".format(df.name)print "credits: {}".format(df.credits)df.zoomToSelectedFeatures ()mxd.saveACopy("../MXD/mxd1 - copy.mxd", version="10.1")# ▶注释1◀# arcpy.RefreshTOC()# arcpy.RefreshActiveView()▶注释1◀:如果正通过 Python 窗口对这些图层文件进行修改并通过 CURRENT 引用地图文档,则可能无法立即查看 ArcMap 应用程序中的更改。要刷新地图文档,需要使用 RefreshActiveView 和 RefreshTOC 方法。输出结果:displayUnits: MetersmapUnits: FeetelementHeight: 27.1767elementWidth: 18.4814elementPositionX: 1.258elementPositionY: 1.258referenceScale: 1:0type: DATAFRAME_ELEMENTscale: 579856.429556extent: 738865.245049127 18801.3864922019 1241692.37188788 374164.788633054 NaN NaN NaN NaNspatialReference: <geoprocessing spatial reference object object at 0x064F7938>description:name: 图层credits:图层对象

图层对象提供了对 ArcMap 图层属性对话框中出现的众多常用图层属性的访问,同时也提供了用于保存图层文件的各种方法。地图文档中主要存在三大类图层:要素图层、图层组和栅格图层。通过 isFeatureLayer、isGroupLayer 和 isRasterLayer 属性,可以分辨出类型。前面说的不管是地图文档对象还是数据框对象,都是依附于 mxd 文件,而图层对象不仅仅只能依附于 mxd 文件之上,也能单独在脚本中创建使用。创建于 mxd 文件中,使用 ListLayers 方法:mxd = arcpy.mapping.MapDocument("../MXD/mxd1.mxd")df = arcpy.mapping.ListDataFrames(mxd)[0]lyr = arcpy.mapping.ListLayers(mxd, data_frame=df)[0]传入了 data_frame 参数,限定返回的图层对象。独立创建,使用 Layer 类:lyr2 = arcpy.mapping.Layer("../SHP/Boroughs.shp")1.图层选择、应用ArcGIS 提供了两种选择图层中要素的方法。分别是按位置选择图层和按属性选择图层,对应 ArcPy 中的 SelectLayerByLocation_management 和 SelectLayerByAttribute_management 两种方法。按位置选择图层根据与另一个图层中的要素的空间关系来选择本图层中的要素;按属性选择图层基于属性查询在图层或表视图中添加、更新或移除选择内容。特别注意:输入必须是要素图层;不允许是要素类。可以使用图层对象的 getSelectionSet 和 setSelectionSet 方法来保存和应用被选中的图层要素:getSelectionSet 方法返回一个由选中图层要素 ID 组成的列表;setSelectionSet (method, oidList) 需要传入两个参数,一个是选择方法,一个是要素 ID 列表。以下示例展示这几种方法的使用,源代码可见于文件 Chapter3/code3.py。# -*- coding:utf-8 -*-from __future__ import unicode_literalsimport arcpyimport oscws = os.getcwd()arcpy.env.workspace = cwsarcpy.env.overwriteOutput = Truelyr = arcpy.mapping.Layer("../SHP/Boroughs.shp")print "Before:{}".format(lyr.getSelectionSet()) # ▶注释1◀arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", "")lyr_id = lyr.getSelectionSet()print "After Selected:{}".format(lyr_id) # ▶注释2◀new_id = lyr_id[:3]print "New ID:{}".format(new_id)lyr.setSelectionSet("NEW", new_id) # ▶注释3◀arcpy.CopyFeatures_management(lyr, "newID_lyr.shp") # ▶注释4◀输出结果Before:NoneAfter Selected:[0L, 1L, 2L, 3L, 4L]New ID:[0L, 1L, 2L]示例中使用的样本 shp 文件共有五个要素。

Boroughs.shp 图层中有五个要素▶注释1◀:getSelectionSet 方法返回当前图层中被选中的要素。由于尚未选中任何要素,返回为空。▶注释2◀:使用了 SelectLayerByAttribute_management 方法将全部要素选中,第一个参数为输入图层;第二个参数为选择类型:可以是重新选择(NEW_SELECTION):取消之前的选择项,重新进行选择;添加选择(ADD_TO_SELECTION):在之前选择的基础上,增加新的选中项;移除选择(REMOVE_FROM_SELECTION):在之前选择的基础上,移除选中项;交集选择(SUBSET_SELECTION):只保留之前选中项和当前选中项的交集部分;反转选择(SWITCH_SELECTION):取相反,使用该类型时,不输入第三个参数;清楚选择(CLEAR_SELECTION):清空选择,使用该类型时,不输入第三个参数。第三个参数传入属性查询语句。在该示例中,传入空查询语句表示全选。所以输出 getSelectionSet 方法返回的列表为:[0L, 1L, 2L, 3L, 4L]。▶注释3◀&▶注释4◀:取列表的前三位,然后使用 setSelectionSet 方法根据新生成的 ID 列表选取图层要素,然后导出为 shp 文件。

newID_lyr.shp 图层中有3个要素扩展:图层中选中要素的 ID 保存下来进行二次利用可以有效的和 ArcPy 中的数据遍历游标结合使用。筛选出存在选中要素的图层:lyr_lis = arcpy.mapping.ListLayers(mxd)sel_lyrs = [lyr.name for lyr in lyr_lis if lyr.getSelectionSet()]print sel_lyrs...2.标注、图层查询语句根据需求,制图时可能会对标注设置查询语句;同样对图层也可能设置查询语句。查询语句不同于上面的选择,设置查询语句后,在不用导出 shp 文件的情况下图层就能显示满足查询语句的要素,隐藏不满足的要素。2.1 图层查询语句该功能对应 mxd 文件中图层属性中的定义查询选项卡;ArcPy 中对应的就是 definitionQuery 属性了。设置定义查询语句:BoroName = 'Bronx';使用 Python 窗口运行。mxd = arcpy.mapping.MapDocument("CURRENT")df = arcpy.mapping.ListDataFrames(mxd)[0]lyr = arcpy.mapping.ListLayers(mxd, data_frame=df)[0]express = "BoroName = 'Bronx'"lyr.definitionQuery = expressarcpy.RefreshTOC()arcpy.RefreshActiveView()2.2 标注查询语句使用 labelClasses 获取标注对象;使用该对象显示标注、设置标注的示例代码如下,源代码见于文件 Chapter3/code4.py。# -*- coding:utf-8 -*-from __future__ import unicode_literalsimport arcpyimport oscws = os.getcwd()arcpy.env.workspace = cwsarcpy.env.overwriteOutput = Truemxd = arcpy.mapping.MapDocument("CURRENT")df = arcpy.mapping.ListDataFrames(mxd)[0]lyr = arcpy.mapping.ListLayers(mxd, data_frame=df)[0]# 设置定义查询语句 ▶注释1◀# lyr.visible = True# express = "BoroName = 'Bronx'"# lyr.definitionQuery = express# 设置标注查询语句lyr.showLabels = Trueif lyr.supports("LABELCLASSES"): for lblClass in lyr.labelClasses: lblClass.expression = "[BoroName]" # ▶注释2◀ lblClass.SQLQuery = "Shape_Length >= 700000" # ▶注释3◀ lblClass.showClassLabels = True print lblClass.classNamearcpy.RefreshTOC()arcpy.RefreshActiveView()▶注释1◀:对图层使用定义查询语句。▶注释2◀:设置图层的单个标注类表达式。这可以简单到只有一个字段,也可以使用 VBScript、JScript 或 Python 表达式来进行更高级的表达。该示例中仅显示字段 BoroName 的值。▶注释3◀:设置标注查询语句,限制标注的显示。该示例中仅显示周长大于700000的要素。Note:Chapter3/code4.py 中示例源代码需要在Python 窗口中运行。3.居中(图层对象)以一个特定图层为标准,将其设置居中(通常用来出图),需要将图层对象的 getExtent() 方法的值传给数据框对象的 extent 属性;如果是希望图层中被选中的要素居中的话,就使用 getSelectedExtent() 方法。居中是自动化制图相关操作中的常用设置。Python 窗口下运行的简单示例代码如下:mxd = arcpy.mapping.MapDocument("CURRENT")df = arcpy.mapping.ListDataFrames(mxd)[0]lyr = arcpy.mapping.ListLayers(mxd, data_frame=df)[0]# df.extent = .getSelectedExtent()df.extent = .getExtent()arcpy.RefreshTOC()arcpy.RefreshActiveView()4.数据替换、修复ArcPy 对图层对象源文件的替换和修复提供了两个方法:一个是用于查找图层的工作空间路径并替换为新工作空间路径的 findAndReplaceWorkspacePath() 方法。一个是为地图文档 (.mxd) 或图层 (.lyr) 文件中的图层替换数据源的 replaceDataSource() 方法。其提供转换工作空间类型的能力(例如,用 SDE 数据源替换文件地理数据库数据源)。Note:地图文档对象中也有类似方法,注意区分。5.类型、支持检查有三大类型图层:要素图层、图层组和栅格图层,但并非全部,还有其他特殊图层。所以自动化过程中需要分辨和判断当前的图层类型和支持的相关属性。使用 isFeatureLayer 等属性可以判断图层类型from __future__ import unicode_literalsimport arcpyimport oscws = os.getcwd()arcpy.env.workspace = cwsarcpy.env.overwriteOutput = Truelyr = arcpy.mapping.Layer("../SHP/Boroughs.shp")print lyr.isFeatureLayerprint lyr.isGroupLayerprint lyr.isRasterLayerprint lyr.isServiceLayerprint lyr.isNetworkAnalystLayerprint lyr.isRasterizingLayer使用 support 方法可以检查当前图层对象是否支持的该属性,返回 True或者 False。目前 support 方法支持17种图层对象属性的检查:BRIGHTNESS、CONTRAST、DATASETNAME、DATASOURCE、DEFINITIONQUERY、LONGNAME、LABELCLASSES、DESCRIPTION、NAME、SERVICEPROPERTIES、SHOWLABELS、SYMBOLOGY、SYMBOLOGYTYPE、TIME、TRANSPARENCY、VISIBLE、WORKSPACEPATH。mxd = arcpy.mapping.MapDocument("../MXD/mxd1.mxd")df = arcpy.mapping.ListDataFrames(mxd)[0]lyr = arcpy.mapping.ListLayers(mxd, data_frame=df)[0]print lyr.supports("BRIGHTNESS") # False6.其他除了上面介绍的一些实用属性和方法外,图层对象还有一些基础属性,比如 name、description、credits...还需注意属性 longName 和 name 的区别,longName 用于表达图层组中图层的名称(形式如“组名称/图层名称”)。maxScale、minScale 用于设置或获取图层的最大、最小比例阈值。该属性对应图层属性中常规选项卡中的比例范围。该功能相当于网络地图中的显示缩放级别,这里很少会使用到。

save() 和 saveACopy() 方法用于将图层对象保存为 .lyr 文件。结束语

该章节内容到这里就结束啦,可以收藏下来哦,如果以后有遇到相关问题,可以再来细细的查阅。使用版本:Windows 10PyCharm 2020.3.3ArcGIS 10.3Python 2.7.8源代码、教学文档离线小册子下载: