2.3 ArcPy中的函数和类
2.3.1 基本概念
第1章已经介绍了Python中函数和类的基本概念,下面介绍模块(module)和包(package)的概念。
模块是一个Python文件,且模块以“.py”结尾,包含了Python对象定义和Python语句。模块可以让用户有逻辑地组织Python代码段。把相关的代码分配到一个模块里能让代码更好用、更易懂。模块能定义函数、类和变量,模块里也能包含可执行的代码。编程时需要使用import命令导入需要的模块。
简单来说,包就是文件夹,但该文件夹下必须存在__init__.py文件,该文件的内容可以为空。它是一个分层次的文件目录结构,定义了一个由模块、子包、及子包下的子包等组成的Python的应用集合。
Python中类和函数的区别主要在于,类可以有成员变量和各种方法,而函数没有。函数被调用运行时,返回或者不返回值都可以。类实例化为对象后,可以访问类中的方法和成员变量。模块如果没有把类声明为私有,其他模块就可以使用这个类,方法是使用import命令导入这个模块,然后用从模块中引用“类名”来调用。
ArcPy实际上是一个Python包,是ESRI公司在ArcGIS 10.0中推出的。安装ArcGIS桌面软件后,在安装目录下有一个ArcPy文件夹。
ArcPy包含有Python函数、类和模块。ArcGIS 10.6中的ArcPy有105个函数、39个类、5个模块(每个模块下又包含多个函数和类)。在不同版本的ArcGIS中,ArcPy的函数、类及模块变化不是很大。
从本质上来说,ArcPy实际上是对ArcObjects的相关组件类进行封装,使用户可以利用Python语言调用ArcObjects的相关组件类。因此,ArcPy必须在ArcGIS环境下使用,脱离ArcGIS环境无法使用ArcPy。用户往往还在计算机上安装了其他的Python编程环境,这时如果把其他的Python包放在ArcPy下面是可以使用的,但是如果把ArcPy的包复制到其他Python环境的包文件夹中,则无法使用。
2.3.2 常用函数
ArcPy提供了很多函数,用以完成简单的空间数据访问或处理,这里首先介绍常用的ArcPy函数,这些函数在编程中随时都可能被调用。
1.Describe函数
Describe函数定义为Describe(value),用以获取ArcPy中对象(如空间图层等)的基本属性,返回的Describe对象包含多个属性,如数据类型、字段、索引及许多其他属性。该对象的属性是动态的,这意味着所描述的数据类型如果不同,就会有不同的描述属性可供使用。
Describe属性被组织成一系列属性组。任何特定数据集都将至少获取其中一个组的属性。例如,如果要描述一个地学数据库要素类,可访问要素类、表和数据集属性组中的属性。所有数据,不管是哪种数据类型,总会获取通用Describe对象属性。
实际应用中常用该函数获取图层的基本属性,如图层的数据类型(Data Type,矢量还是栅格)、shape文件类型(Shape Type,点线面中的哪一类)和地学数据的空间参考(Spatial reference)等。下面给出一个例子,用以获取“中国政区.shp”文件的基本属性。
运行该段程序后,结果如下:
用户可以根据需要获取图层的其他属性,这些属性的获取可以为用户在后面的程序中判断如何处理空间数据提供依据。
2.Exists函数
Exists函数定义为Exists(dataset),该函数用于判断一个数据是否存在,可以用于测试矢量数据、表、数据集、shape文件、工作空间、图层、当前工作空间中的文件是否存在。该函数返回一个布尔变量,表示数据是否存在。这个函数非常重要,当处理产生新的文件或者用到某个数据时,最好首先判断一下该文件是否存在,可以根据判断结果进行下一步操作。下面给出一个删除文件前判断文件是否存在的例子。
3.列表函数
使用ArcPy编程的主要目的之一就是实现特定功能的自动化批处理工作,列表函数的主要功能就是列出特定信息的所用内容,可以方便地从头到尾遍历这些信息。列表函数可以为地学数据处理的批量工作提供极大的便利。
列表函数用于返回当前工作空间的数据列表及数据集中的字段、索引列表等。其中,数据列表可以指定数据类型及利用通配符参数(wild_card)对列表数据进行筛选条件的限定,字段列表可以指定字段类型。
常用的列表函数如表2.1所示。
表2.1 常用的列表函数
下面给出几个列表函数常用功能的例子,这几个例子在批量处理空间数据时具有重要的参考价值,很多复杂的批量处理程序都由下面的例子作为基础扩充而成。
1)列出所有工作空间
这段代码的作用是列出“e:/chinamap”目录下所有工作空间类型为“Folder”(文件夹)类型的工作空间,也就是找出该目录下的所有子目录。ArcPy支持的工作空间类型主要有Access、Coverage、FileGDB、Folder和SDE五种类型。
2)列出某工作空间中所有矢量数据文件名
这段代码的作用是列出“E:/chinamap/mapdata”目录下所有的矢量数据文件名。
3)列出某个shape文件所有属性字段
这段代码的作用是列出“公路.shp”文件的所有字段名称。
4)列出某个shape文件所有含有“p”字符的属性字段
这段代码的作用是列出“包头.shp”文件的字段名中第一个字符为“p”的字段名称。这个例子里面就用到了通配符,用户可以根据需要设置通配符,筛选出满足条件的数据。
4.临时图层生成函数
在处理地学数据时,会产生大量的中间文件,有些中间文件不需要保留,因此可以使用临时内存图层的方式创建,数据处理完毕后可以从内存清除。创建临时图层使用CreateScratchName()函数,它可以指定数据类型创建唯一的临时路径名称。如果未给定工作空间,则使用当前工作空间,函数格式如下:
该函数的参数意义说明如下:
prefix:添加到临时名称的前缀。
suffix:添加到临时名称的后缀。后缀可为空的双引号字符串。
data_type:用于创建临时名称的数据类型。有效数据类型有:Coverage、Dataset、FeatureClass、FeatureDataset、Folder、Geodataset、GeometricNetwork、ArcInfoTable、NetworkDataset、RasterBand、RasterCatalog、RasterDataset、Shapefile、Terrain和Workspace。
Workspace:用于确定待创建临时名称的工作空间。如果未指定,则使用当前工作空间。
下面给出一段代码,说明创建临时图层的用法。
2.3.3 常用类
ArcPy中的类在使用时需要进行实例化,通常需要构造类的对象来访问类的属性和方法。类在实例化时可以通过构造函数直接赋属性值,也可以先实例化,然后再进行赋值。下面给出一个实例化点对象和访问该对象属性的例子。
ArcPy提供了很多类用于处理各种空间数据,这里先介绍几种常用的类及其使用方法。
1.Extent类
Extent类是范围类,用于表示地图左下角和右上角坐标给定的一个矩形,主要通过使用X最小值、Y最小值、X最大值和Y最大值确定,其完整的定义如下:
由于范围实际上是一个矩形,属于几何对象,因此范围类也提供了多个方法对其进行各种空间关系的判断,判断的方法与几何对象空间关系判断的方法类似,读者可以参考第5章的相关内容。
2.工作环境类(Env类)
工作环境类Env类是ArcPy中最常用的类之一,可以控制地学数据处理工具运行的环境。工作环境类的属性非常多,超过50个。ArcPy中的工作环境以Env类属性的方式公开,可以通过ArcPy.Env.<环境名称>的方式来设置,在实际编程时,不同的空间数据处理使用的环境是不同的,需要根据需求来进行设置。表2.2给出了常用的工作环境属性。
表2.2 常用的工作环境属性
下面分别介绍表2.2中各个环境属性设置的方法。
1)cellSize(栅格单元尺寸)
cellSize是支持栅格单元尺寸环境设置的工具,可以设置输出栅格单元的大小或分辨率。默认输出分辨率由最粗的输入栅格数据集决定。一般在栅格数据分析时,会产生新的栅格数据,可以根据需要为新产生的栅格数据设置栅格单元尺寸,对应的ArcPy语句如下:
cellsize_option表示该参数是可选参数,能够设置为下面四种形式:
(1)MAXOF:输入最大值——所有输入数据集的最大像元大小。这是默认设置。
(2)MINOF:输入最小值——所有输入数据集的最小像元大小。
(3)number:直接使用指定的像元大小。
(4)layer_name:使用指定图层或栅格数据集的像元大小。
下面给出一个设置栅格单元尺寸的例子。
2)extent(范围)
范围环境设置让地学数据处理工具只处理设置范围内的要素或栅格。
范围环境设置实际上定义了地学数据处理工具要处理的要素或栅格。通过该项设置,可以让地学数据处理工具只处理大型数据集中的一部分,从而提高工具的运行效率。可将此项设置视为用于选择输入要素或栅格的一个矩形,任何穿过矩形的要素或栅格均将被处理。值得注意的是,矩形只用于选择要素,选择穿过矩形范围的要素参与地学数据处理,而非裁剪要素,因此输出数据集的范围通常会大于该设置项的范围。范围环境属性、穿过范围的要素和输出数据集的范围之间的关系如图2.9所示。
图2.9 范围环境属性、穿过范围的要素和输出数据集的范围之间的关系
范围环境设置的语句如下:
等号右边的extent也是一个可选参数,可以取以下内容为值。
(1)extent对象:用于定义范围的extent对象。
(2)MINOF:所有输入要素或栅格叠置的范围(彼此相交)。需要注意的是,有可能所有要素都不叠置,因此可能生成空范围(宽度和高度均为零),这种情况下不会处理任何要素或像元。
(3)MAXOF:所有输入数据的组合范围,将处理所有要素或像元。
(4)XMin、YMin、XMax、YMax:用于定义范围的以空格分隔的坐标,用于存储输入数据的坐标系。
(5)pathname:数据集的路径,将使用该参数所选数据集的范围。
下面给出一个用代码设置范围环境属性的例子。
3)mask(掩膜)
掩膜的功能与上述范围属性有些类似,设置“掩膜”环境属性后,运行过程中地学数据处理工具只考虑落入掩膜范围内的像元。使用掩膜的地学数据处理过程如图2.10所示。“掩膜”在GIS插值运算中使用特别多,一般采用某个研究区的边界(如行政边界、流域边界等)作为掩膜,可以保证插值产生的数据覆盖整个研究区。
图2.10 使用掩膜的地学数据处理过程
掩膜环境设置的语句如下:
mask_source定义掩膜的数据集,它可以是栅格数据,也可以是矢量要素数据集。如果数据集是栅格,含值的像元将构成掩膜,而掩膜中的所有NoData像元部分在输出中都将为NoData。
下面为设置掩膜的一个简单示例。
4)NoData(无值)
支持NoData环境设置的工具将仅处理图层中NoData有效的栅格。当输入的NoData值需要传递到输出结果栅格时,可使用此环境。可以通过该设置指定哪个值将用来指定为输出中的NoData值。
无值环境设置的语句如下:
参数“mapping_method”选择使用哪种NoData制图方法。
(1)None(无):不存在任何适当的NoData值规则。如果输入和输出具有相同的值范围,将传送NoData且不进行任何更改。但是,如果值范围有所改变,则输出中没有针对NoData的值。这是默认方法。
(2)Maximum(最大值):输出数据范围中的最大值可用作NoData值。
(3)Minimum(最小值):输出数据范围中的最小值可用作NoData值。
(4)Map values up(提升最低值):提升范围中的最低值,且最低值将变为NoData。如果数据无符号,零值会变为1,NoData值将为零,其余值保持不变。如果数据有符号,则会提升范围中的最低值,且最低值将变为NoData。例如,对于8位有符号的整数数据,-127会变为-126且NoData值将为-127。
(5)Map values down(降低最高值):NoData值是数据范围中的最大值,数据范围中的最高值会变为一个较小的值,而其余的值保持不变。例如,对于8位无符号的整数数据,NoData值原来为255,采用该参数后255会变为254,其余值保持不变。
(6)Promotion(提升):如果NoData值超出了输入的数据范围,则输出的像素深度可能会提升到下一个可用级别,而NoData会采用新数据范围内的最大值。例如,将值256作为8位无符号整数数据集的NoData时,由于256超过了8位无符号整数数据集所能表达的最大数(255),因此系统会自动将数据集提升到16位,并且NoData的值变为16位能表达的最大值(216-1)。
下面为设置无值属性的一个简单示例。
5)overwriteOutput(输出覆盖)
在地学数据处理过程中,经常会产生一些新的文件,这些文件有可能与已有的文件重名。如果程序没有对新文件进行判断,直接生成新文件,则程序会报错。如果不想对新文件进行判断,而让新文件直接覆盖已有的文件,则需要在环境属性里设置overwriteOutput属性。overwriteOutput是一个布尔型的属性,ArcPy默认overwriteOutput为False,不允许覆盖已有的文件,如果想要覆盖已有文件,则需将该属性改为True,代码如下:
6)workspace(当前工作空间)
“当前工作空间”环境设置是将指定的工作空间作为当前空间数据处理工具输入输出的默认位置,该功能的语法如下:
path是一个合法的数据处理空间,可以是文件目录、地学数据库和网络空间等。
下面为设置当前工作空间的一个简单示例。
3.空间参考类
空间参考是地理信息系统中的重要概念,所有的地学数据集(包括各种矢量数据和栅格数据)都应该具有一个空间参考,用于定义该数据集的坐标系。空间数据分析的前提是所有数据都统一到相同的空间参考下。如果空间参考不同,则需要进行各种空间参考的转换,而进行空间参考转换的前提是该数据集具有空间参考信息。ArcGIS通过投影文件(.prj)指定数据的空间参考信息。ArcPy提供了用以描述地学数据空间参考的SpatialReference类,利用该类可以方便地实现对各种空间参考的设置。
1)空间参考类的基本使用方式
空间参考类的实例化主要有四种方式。
(1)使用坐标系统的名称。
这种方式需要知道坐标系在ArcGIS软件中对应的名称,例子如下:
(2)使用投影文件(.prj)。
(3)使用坐标系统的编码(WKID)。
坐标系统的编码是一种简单的坐标系统表达方式。安装ArcGIS后,在安装目录Program Files\ArcGIS\Desktop10.X\Documentation下有两个PDF文件分别说明地理坐标和投影坐标的相关内容,里面介绍了不同坐标系对应的WKID码,这两个文件分别是geographic_coordinate_systems.pdf和projected_coordinate_systems.pdf。
由于投影坐标系使用的WKID数量较多,这里只介绍我国常用的几种地理坐标(Geographic Coordinate System)对应的WKID,分别如下:
4214 GCS_Beijing_1954
4326 GCS_WGS_1984
4490 GCS_China_Geodetic_Coordinate_System_2000
4555 GCS_New_Beijing
4610 GCS_Xian_1980
(4)使用坐标内容的文本字符串。
文本字符串实例化空间参考对象,实际上使用了投影文件中的文本内容。下面给出一个使用WGS84坐标系实例化空间参考对象的例子。
空间参考类虽然提供了多种属性和方法,但是实际应用中用到的属性很少,用到的方法主要有两个,分别是createFromFile(prj_file)和loadFromString(string),读者可以在帮助中查阅这两个方法的用法。
2)定义矢量数据投影
空间数据具有相同的空间参考信息是进行数据分析的前提。当矢量数据缺少空间参考信息时,首先要为该矢量数据定义空间参考信息,然后再通过投影转换的方式将不同的空间参考坐标转换到相同的空间参考坐标系下。
对shape文件来说,空间参考信息缺失意味着shape文件中缺少prj信息,因此要通过定义投影坐标的功能,为shape文件创建这个prj信息。创建语句定义如下:
其中,in_dataset为缺失空间参考的数据,coor_system为要创建的空间参考。
缺失空间参考的文件在ArcMap加载时会给出提示,本质上是该文件缺失对应的“.prj”文件,必须为该文件创建正确的坐标信息。下面给出一个利用已有shape文件的坐标信息为缺失空间参考的tmp.shp文件创建空间参考的例子。
运行完这段代码后,系统自动会在“E:\chinamap\mapdata\”目录下创建一个“tmp.prj”文件。
3)矢量数据投影转换
如果矢量数据的空间参考信息不一致,则需要通过投影转换的方式,将不同的坐标系统转换到相同的坐标系中。矢量数据投影转换方法定义如下:
投影转换实际上是利用投影转换公式对输入数据的坐标进行重新计算,产生一个新的文件,因此该函数需要有输入文件in_dataset和输出文件out_dataset,还要有投影转换的方法out_coor_system。如果两个坐标系的大地基准不同,还需要使用transform_method进行转换。因此,前面4个参数是进行投影转换最主要的参数,后面几个可以不用。
下面给出一个将“包头.shp”文件进行坐标系转换的例子,例子中使用了文本字符串和WKID实例化空间参考对象。
4)栅格数据投影转换
栅格数据的投影不一致时同样也要通过投影转换的方式将坐标系统一。但是,栅格数据的投影转换要比矢量数据的投影转换复杂。栅格数据的投影转换除了确定采用哪种投影方式转换,还需要考虑生成的新栅格文件与原栅格文件栅格单元尺寸是否一致。栅格投影允许设置投影后产生的新文件的栅格单元尺寸,当新尺寸和原栅格单元尺寸不一致时,还要进行重采样。栅格数据投影转换方法定义如下:
该函数的参数含义如下:
(1)in_raster:输入栅格数据集。
(2)out_raster:要创建的输出栅格数据集,可以为符合ArcGIS要求的bmp、gif、img、tif、jpg等格式。以地学数据库形式存储栅格数据集时,不需要定义扩展名。
(3)out_coor_system:输入栅格待投影到的目标坐标系。默认值将基于“输出坐标系”环境设置进行设定。
(4)resampling_type(可选):要使用的重采样算法。默认设置为NEAREST。
NEAREST:这是最快的重采样方法,因为此方法可将像素值的更改内容最小化。此方法适用于离散数据,如土地覆被。
BILINEAR:可采用平均化周围(距离权重)4个像素的值计算每个像素的值,适用于连续数据。
CUBIC:根据周围的16个像素拟合平滑曲线来计算每个像素的值。生成平滑影像,但可创建位于源数据中超出范围外的值,适用于连续数据。
MAJORITY:基于3×3窗口中出现频率最高的值来确定每个像素的值,适用于离散数据。
需要注意的是,NEAREST和MAJORITY适用于离散的分类数据,如土地利用分类。对连续数据(如高程表面)进行重采样时不能使用NEAREST或MAJORITY选项。BILINEAR选项和CUBIC选项主要适用于连续数据,不建议对离散数据(如分类数据)使用这两个选项,因为可能会改变像元值,从而使得某类里的一些数据发生变化,影响原始数据分类的结果表达。
(5)cell_size(可选):新栅格数据集的像元大小。默认像元大小为所选栅格数据集的像元大小。
(6)geographic_transform(可选):在两个地理坐标系或基准面之间实现转换的方法。当输入和输出坐标系的基准面相同时,地理(坐标)变换为可选参数。如果输入和输出基准面不同,则必须指定地理(坐标)变换。
(7)Registration_Point(可选):用于对齐像素的x坐标和y坐标(位于输出空间中)。
(8)in_coor_system(可选):输入栅格数据集的坐标系。
下面给出一个栅格数据转换坐标系的例子,这个例子定义了一个转换栅格数据的函数projectRaster,负责将source目录中WGS84坐标系的TIF格式栅格数据通过投影转换,转换到target目录下,转换的坐标为投影坐标WGS_1984_UTM_Zone_49N。