python学习笔记08:面向ArcGIS的python脚本编程

目录

1 引例

1.1 获取图层属性要素数目

1. 2 几点注意事项:

2 使用python进行地理处理

2.1 ArcPy包

2.1.1 import方式

2.1.2 from-import方式

2.1.3 from-import-as方式

2.2 使用地理工具

2.2.1 两种方式调用方式

2.2.2 参数属性分析--以裁切功能为例

2.2.3 GetParameterAsText()接受外部工具传参模式调用

2.2.4 导入自定义工具箱

2.2.5 获取工具语法

2.2.6 ArcPy函数

2.2.7 获取帮助

2.3 访问空间数据

2.3.1 检查数据的存在性--Exists

2.3.2 数据描述--Describe

2.3.3 列表函数

2.3.4 元组与字典

2.4 处理空间数据

2.4.1 游标

2.4.2 SQL的使用

2.4.3 处理表和字段名

2.5 处理文本文档

2.5.1 常用函数总结

2.5.2 经典文本读取方法总结

2.6 获取栅格信息

2.6.1 获取栅格数据:ListRasters()

2.6.2 栅格属性描述

2.6.3 处理栅格对象

2.6.4 Spatial Analyst模块

2.7 Numpy包

3 执行地理处理任务

3.1 制图脚本

3.1.1 典型流程

3.1.2 地图文档的属性和方法

3.1.3 图层

3.1.4 输出和打印地图

3.2 处理PDF文档

4 程序调试与错误处理

4.1 错误识别

4.2 程序调试

4.2.1 pythonWin调试

4.2.2 调试技巧

4.2.3 常见错误


本文为笔者学习赞德伯根《面向ArcGIS的Python脚本编程》的笔记总结

1 引例

1.1 获取图层属性要素数目

>>> arcpy.GetCount_management('road')

1. 2 几点注意事项:

  1. 加载已经写完的*.py文件,新建python窗口,右键单击Load(加载)已有脚本
  2. Python的官方网站包含大量的学习资源,适用于初学者的资源
  3. python官方命名规范《Style Guide for Python Code》,最好避免首字母使用下划线,因为它有特殊含义
  4. 列表使用方括号定义,元素以逗号隔开
  5. 方法的调用方式:<object>.<method>(<arguments>)
  6. 处理路径的三种方式:单斜杠(/)、两个反斜杠(\\)和路径前添加(r)
  7. 使用import导入外部模块
  8. 注释以#开头
  9. python每个对象包含三个特征:赋值标识(使用函数id(varName)查询)、类型(使用type(varName)查询
>>> name = 'road'
>>> id(name)
355610048
>>> type(name)
<type 'str'>
>>> print name
road

2 使用python进行地理处理

2.1 ArcPy包

2.1.1 import方式

它包含多个模块,其中两个专业模块,自动化制图模块(arcpy.mapping)和地图代数模块(arcpy.sa);模块在导入之后才能使用

import arcpy
import arcpy.mappping
import arcpy.sa

导入模块后,使用类型属性方式:arcpy.<class>.<property>

import arcpy
arcpy.env.workspace = "d:/Work/"

2.1.2 from-import方式

使用from-import语句,导入模块的一部分,此时可以省略类名:

from arcpy import env
env.workspace = "d:/Work/"

2.1.3 from-import-as方式

使用from-import-as语句增强导入代码可读性:

from arcpy import env as myEnv
myEnv.workspace = "d:/Work/"

2.2 使用地理工具

2.2.1 两种方式调用方式

  1. arcpy.<toolname_toolboxalias>(<parameters>)
  2. arcpy.<toolboxalias>.<toolname>(<parameters>)

两种方法都对,可以任意选择,但必须保证语法正确

import arcpy
arcpy.env.workspace = "d:/Work/"
#方式一
arcpy.Clip_analysis("in_features.shp", "clip_feature.shp", "out_feature_class.shp")
#方式二
arcpy.analysis.Clip("in_features.shp", "clip_feature.shp", "out_feature_class.shp")

2.2.2 参数属性分析--以裁切功能为例

裁切功能官方帮助:

Clip_analysis (in_features, clip_features, out_feature_class, {cluster_tolerance})

参数说明数据类型

in_features

要裁剪的要素。

Feature Layer

clip_features

用于裁剪输入要素的要素。

Feature Layer

out_feature_class

待创建的要素类。

Feature Class

cluster_tolerance

(可选)

所有要素坐标之间的最小距离以及坐标可以沿 X 和/或 Y 方向移动的距离。如果此值设置得较高,则数据的坐标精度将会较低;如果此值设置得较低,则数据的坐标精度将会较高。

Linear unit

每个参数都有四个属性:

  • 名称:工具参数的唯一标识
  • 类型:所需要的数据类型,如要素类、整型、字符串或栅格
  • 方向:输入参数还是输出参数
  • 必选:参数是必选参数还是可选参数,可选参数在官方文档中一般使用 {} 包着

地理信息处理工具语法基本模式:

  • 先必选参数,再可选参数;通常第一个为输入数据集,随后是输出数据集,接着是其他必选参数,最后是可选参数
  • 输入数据集以 in_ 前缀,输出数据集以 out_ 前缀
  • 如果一些参数可选参数不需要,可以跳过;跳过方式以下两种:1)设置为("")或("#"),2)明确参数名及其参数值

官方文档--缓冲区分析工具:

Buffer_analysis(in_features, out_feature_class, buffer_distance_or_field, {line_side}, {line_end_type}, {dissolve_option}, {dissolve_field;dissolve_field...})

#方式一:""
arcpy.Buffer_analysis("road","buffer","100 METERS","","","LIST","FID")
#方式二:"#"
arcpy.Buffer_analysis("road","buffer","100 METERS","#","#","LIST","FID")
#方式三:参数名及其赋值
arcpy.Buffer_analysis("road","buffer","100 METERS",dissolve_option = "LIST",dissolve_field = "FID")

2.2.3 GetParameterAsText()接受外部工具传参模式调用

增加代码的灵活性和可复用性

>>> import arcpy
>>> inFile = arcpy.GetParameterAsText(0)
>>> outFile = arcpy.GetParameterAsText(1)
>>> arcpy.Copy_management(inFile, outFile)

多数工具都只有一个输出,如果有多个输出,可以使用getOutput(index)得到指定索引的输出结果

>>> import arcpy
>>> arcpy.env.workspace = "d:/Work/"
>>> buffer = arcpy.Buffer_analysis("road","buffer","100 METERS","","","LIST","FID")
>>> count = arcpy.GetCount_management(buffer).getOutput(0)
>>> print count

2.2.4 导入自定义工具箱

ArcGIS的本地ToolBox文件路径:D:\Program Files (x86)\ArcGIS\Desktop10.1\ArcToolbox\Toolboxes(在你的安装目录里找)

自定义的*.tbx即使添加到ToolBox中,也必须使用ImportToolBox函数引入到开发环境中

>>> import arcpy
>>> arcpy.ImportToolBox("C:/mytool.tbx")
#也可以定义别名
>>> arcpy.ImportToolBox("C:/mytool.tbx", myTools)

使用方式如2.2.1部分相同

2.2.5 获取工具语法

使用Usage获得所有工具语法

>>> import arcpy
>>> tools = arcpy.ListTools("*_analysis")
>>> for tool in tools:
         print arcpy.Usage(tool)

help方法查看工具语法:

>>> print help(arcpy.Clip_analysis)

2.2.6 ArcPy函数

调用格式:arcpy.<functionname>.(<arguments>)

所有工具都是函数,但是函数并一定的是工具;工具函数与非工具函数的区别在于:

  • 帮助文档位置不同:ArcToolbox运行时得到工具帮助文档;非工具函数在ArcPy帮助文档中
  • 工具依赖许可,非工具函数不依赖ArcGIS许可
  • 工具处理得到地理信息可通过其他函数访问,非工具函数不生成地理处理信息
  • 工具函数调用需要工具箱别名和模块名,非工具函数直接调用
  • 工具函数返回结果对象,非工具函数不返回结果对象

2.2.7 获取帮助

在帮助文档中找到Geoprocessing > Python 和 Geoprocessing > ArcPy

每个工具都有帮助示例

地理处理工具的帮助文档位置Geoprocessing > Tool reference,可按照工具箱--工具集--工具方式访问

2.3 访问空间数据

2.3.1 检查数据的存在性--Exists

ArcPy中的两种路径类型:

  • 系统目录:Windows可识别的类型,例如:"C:\data"
  • 目录路径:仅ArcGIS可识别的路径类型,例如:"C:\data\study.gdb\final\street"

注:gdb表示文件地理数据库;mdb表示个人地理数据库;sde企业地理数据库

import arcpy
print arcpy.Exists("D:/data/country.shp")
#存在为true,不存在返回false

2.3.2 数据描述--Describe

Describe函数可识别多种数据集的类型,获取要素类型、数据集类型、空间参考信息、栅格波段、栅格数据集、属性表等

rd = arcpy.Describe(r"E:\ArcGISlearn\全部章节源码\第六章\data\road.shp")
print rd.ShapeType
#输出结果:Polyline
print rd.datasetType
#FeatureClass
print rd.SpatialReference.name
#Unknown
print rd.path
#E:\ArcGISlearn\全部章节源码\第六章\data
print rd.CatalogPath
#E:\ArcGISlearn\全部章节源码\第六章\data\road.shp
print rd.name
#road.shp
print rd.file
#road.shp
print rd.baseName
#road,去除了文件的后缀,只保留了文件名称本体

2.3.3 列表函数

print arcpy.ListFeatureClasses()

/*
[u'Sheet1_XYToLine', u'Point_PointsToLine1', u'Sheet1_XYToLine2', u'E34t_PointsToLine', u'Point_PointsToLine', u'Point_PointsToLine2', u'Point_PointsToLine3', u'Point_PointsToLine4', u'\u7f13\u51b2_\u9910\u996e_point', u'\u7f13\u51b2_\u9910\u996e_point_2']
*/

fl = arcpy.ListFields(r"E:\ArcGISlearn\全部章节源码\第六章\data\road.shp")
for f in fl:
...     print f.name
...     
/*
FID
Shape
Id
*/

#格式化字符串输出
for f in fl:
...     print "{0} is a type of {1}".format(f.name, f.type)
...     
/*
FID is a type of OID
Shape is a type of Geometry
Id is a type of Integer
*/

#列表函数的使用
len(fl)
#3

u表示Unicode编码,在处理多语言时比较安全

2.3.4 元组与字典

元组的基本概念

  • 逗号分割
  • 元组中的元素不允许修改
  • 元组切片操作可以得到新的元组
  • 记数 count 和索引 index 可用于元组

字典的基本概念:

  • 使用{ }括起来,元素间使用逗号隔开,每个元素由键值对以冒号连接
  • 每个键值对必须是完整的,顺序随意
  • 使用 [ ] 赋值语句添加新元素:di["key"]="value"
  • 修改元素的值:di["key"]="newValue"
  • 删除元素:del di[key]
  • 以列表形式返回字典中的键值对信息,di.items()
install = arcpy.GetInstallInfo()
for key in install:
...     print "{0},{1}".format(key, install[key])

2.4 处理空间数据

2.4.1 游标

使用游标来遍历属性表中的每一条属性记录,或者添加新的记录

定义在ArcPy.da模块,主要包含三种功能:

  • 搜索游标【SearchCursor】,用来检索行记录
  • 插入游标【InsertCursor】,向表或要素类中添加行
  • 删除游标【UpdateCursor】,从表或要素类中删除行
arcpy.da.SearchCursor(r"E:\ArcGISlearn\全部章节源码\第六章\data\road - 副本.shp", "FID")
arcpy.da.UpdateCursor(r"E:\ArcGISlearn\全部章节源码\第六章\data\road - 副本.shp", "FID")
arcpy.da.InsertCursor(r"E:\ArcGISlearn\全部章节源码\第六章\data\road - 副本.shp", "FID")

游标只能向前,使用next执行n次,抵达属性表的结尾部分,如果继续再向前调用next,会报StopIteration异常

创建游标后还得删除游标,否则会报错:

search = arcpy.da.SearchCursor(r"E:\ArcGISlearn\全部章节源码\第六章\data\road - 副本.shp", "FID")
for row in search:
...     print "{0}".format(row)
del search
del row

但是使用with语句后,可以不使用del语句:

with arcpy.da.SearchCursor(r"E:\ArcGISlearn\全部章节源码\第六章\data\road - 副本.shp", "FID") as myCursor:
...     for row in myCursor:
...         print "{0}".format(row)

2.4.2 SQL的使用

ArcGIS中的SQL表达式的帮助信息:Building a query expression

2.4.3 处理表和字段名

arcpy.ValidateTableName:确定表名在给定的工作空间是否有效

print arcpy.ValidateTableName("road -副本.shp")
#road__副本_shp

要素拷贝案例:

arcpy.ValidateFieldName:判断给定的名字是否是一个有效的字段名称

print arcpy.ValidateFieldName("FID")
#FID

AddField_management(in_table, field_name, field_type, {field_precision}, {field_scale}, {field_length}, {field_alias}, {field_is_nullable}, {field_is_required}, {field_domain}

添加字段的代码案例:

fc = r"E:\ArcGISlearn\全部章节源码\第六章\data\road - 副本.shp"
arcpy.AddField_management(fc,"Def", "TEXT", "", "",255)
fl = arcpy.ListFields(fc)
for f in fl:
...     print "{0}".format(f.name)

存在性判断及处理方式:

  • 对于字段,使用ListFields方法获取所有字段,判断字段是否存在
  • 对于表,可以使用CreateUniqueName函数,创建唯一的名称

解析属性表和字段名:

  • ParseTableName返回一个逗号隔开,包含数据库名、所有者名和表名的字符串的列表
  • ParseFieldName返回一个逗号隔开,包含数据库名、所有者名、表名和字段名的字符串的列表

2.5 处理文本文档

2.5.1 常用函数总结

  • open(path, mode),其中mode可表示为r、w、+、a、b
  • write("要写入的内容")
  • read()默认读取全部内容,也可以指定要读取的字符的个数;返回单一字符串,包含换行符\n
  • seek()设置文件当前读取的位置
  • readline()读取一行文本,返回字符串包含换行符\n
  • readlines()读取所有行文本,以列表形式返回
  • writelines()写入多行数据
  • write()写入单行数据
  • close()关闭文件

pathName = r"E:\ArcGISlearn\geoInfo.txt"
f = open(pathName, "r")
lines = f.readlines()
fw = open("E:/ou.txt", "w")
for l in lines:
    tmp = l.split(" ")
    fw.write("{0} {1} {2}".format(tmp[1], tmp[3],tmp[5])
f.close()
fw.close()

原作者的实现思路是:将"ID:"、"Lat:"和"Lon:"替换为""

2.5.2 经典文本读取方法总结

(1)使用read函数读取文本所有字符

#方式一:
f = open("my.txt")
ch = f.read(1)
while ch:
    <处理函数>
    ch = f.read(1)
f.close()

#方式二
f = open("my.txt")
ch = f.read(1)
while True:
    ch = f.read(1)
    if ch not Char: break
    <处理函数>
f.close()

(2)按行读取模式

#方式一:
f = open("my.txt")
ch = f.read(1)
for line in f:
    <处理函数>
f.close()

#方式二
f = open("my.txt")
ch = f.read(1)
for line in f.readlines():
    if not line: break
    <处理函数>
f.close()

对于大文件使用readlines比较消耗内存,使用fileinput模块创建文件内容对象

#方式一:
import fileinput
for line in fileinput.input("my.txt"):
    <处理函数>

2.6 获取栅格信息

2.6.1 获取栅格数据:ListRasters()

ListRasters({wild_card}, {raster_type})
第一个参数:通过名称限制要返回的结果;第二个参数:指定数据类型,如*.tif,*.img

示例代码:

>>> from arcpy import env
>>> env.workspace=r"E:\ArcGISlearn\全部章节源码\第十章\data"
>>> rl = arcpy.ListRasters()
>>> for r in rl:
...     print r

2.6.2 栅格属性描述

三种栅格元素类型:

  • 栅格数据集:包含多种数据格式,可由单波段或多波段构成
  • 栅格波段:栅格数据集中的某个图层,即某个光谱范围内的值
  • 栅格目录:以表格形式存储的栅格数据集的集合,用于表示一组具有相邻、重叠或部分重叠关系的栅格数据集

栅格属性:

代码示例:

>>> from arcpy import env
>>> env.workspace=r"E:\ArcGISlearn\全部章节源码\第十章\data"
>>> raster = "ASTGTM_N32E118K.img"
>>> des = arcpy.Describe(raster)
>>> print des.datatype
#RasterLayer
>>> print des.bandcount
#1
>>> print des.compressionType
#RLE
>>> print des.format
#IMAGINE Image
>>> print des.sensorType
#
>>> print des.permanent
#True
>>> print des.height
#3741
>>> print des.width
#3185
>>> print des.IsInteger
#True
>>> print des.meanCellHeight
#30.0
>>> print des.meanCellWidth
#30.0
>>> print des.noDataValue
#32767
>>> print des.pixelType
#S16
>>> print des.pixeltype
#S16
>>> print des.primaryField
#1
>>> print des.tableType
#Index

获取栅格投影信息:

>>> spaRef = des.spatialReference
>>> print spaRef.name
#WGS_1984_UTM_Zone_50N
>>> print spaRef.linearUnitName
#Meter

对于多波段栅格处理:

>>> env.workspace = r"E:\Amiee\ArcGISlearn"
>>> raster = "China.png"
>>> des1 = arcpy.Describe(raster)
>>> print des1.bandcount
#4
>>> rband1 = "China.png/Band_2"
>>> desb2 = arcpy.Describe(rband1)
>>> print desb2.width
#1086

2.6.3 处理栅格对象

  1. 创建栅格对象Raster,两种方式:
    1. 已有栅格文件创建
    2. 地图代数语句创建栅格对象
  2. 保存到本地磁盘save

使用地图代数方式创建,多波段栅格数据保存变成了单波段的坡度图

>>> ouRaster = arcpy.sa.Slope("China.png")
>>> ouRaster.save("mch.tif")

使用栅格创建,【保存正常】:

>>> ouRaster1 = arcpy.Raster("China.png")
>>> ouRaster1.save("ra.tif")

2.6.4 Spatial Analyst模块

坡度提取代码及结果展示

>>> env.workspace = r"E:\ArcGISlearn\全部章节源码\第十章"
>>> inr = arcpy.Raster("ASTGTM_N32E118K.img")
>>> ou = arcpy.sa.Slope(inr)

 

使用地图代数将英尺转化为米

#方式二
ou1 = inr * 0.3048
#方式二
ou = arcpy.sa.Times(inr, "0.3048")

2.7 Numpy包

栅格数据转化为Numpy数据的数据的脚本,然后使用SciPy包调用专门的函数处理成ArcGIS可识别的格式

两个函数分别是:NumPyArrayToRaster和RasterToNumPyArray

3 执行地理处理任务

3.1 制图脚本

3.1.1 典型流程

arcpy.mapping

典型的流程包括:打开地图文档,修改数据框属性,加载图层、编辑页面中的元素、将地图文档导出为PDF

mapdoc = arcpy.mapping.MapDocument(r"E:\ArcGISlearn\data.mxd")
#如果是在ArcGIS环境下打开了*.mxd文件,可使用CURRENT关键字;使用该关键字时,需在创建脚本时候选“Always run in foreground”
mapdoc = arcpy.mapping.MapDocument("CURRENT")

关键属性和方法:

  • save()和saveACopy()分别为保存到当前文档或新文档,后者类似于另存为
  • RsrefreshActiveView()和RsfreshTOC()可用于刷新

一个结构化的示例代码:

3.1.2 地图文档的属性和方法

获取文件路径、设置制图文档的标题、设置数据框

>>> mapdoc = arcpy.mapping.MapDocument("CURRENT")
>>> listdf = arcpy.mapping.ListDataFrames(mapdoc)
>>> for fd in listdf:
    print fd.name
    fd.scale = 24000
>>> del mapdoc

DataFrame对象地图范围、比例尺、旋转、空间参考;panToExtend保持比例尺不变的情况下,居中显示

3.1.3 图层

两种方式:

  1. Layer函数:
  2. ListLayers函数

       

从磁盘获取*.lyr文件,并获取他们的名字的例子:

注解:例子中*.lyr中包含了多个图层,故可将其作为ListLayers的参数

重要的属性和方法

  1. ly.name 图层名称
  2. ly.showLabels 显示当前地图文档中所有图层的标注
  3. ly.dataSource获取图层的完整路径名称
  4. ly.datasetName获取图层的名称
  5. ly.support判断图层是否支持某一属性
>>> from arcpy import env
>>> env.workspace = r"E:\Amiee\ArcGISlearn\全部章节源码\十六章"
>>> mapd = arcpy.mapping.MapDocument("CURRENT")
>>> lry = arcpy.mapping.Layer(mapd)
>>> for ly in lyr:
...     print ly.dataSource
...     print ly.datasetName
...     print ly.supports("LONGNAME")

3.1.4 输出和打印地图

输出

打印

3.2 处理PDF文档

合并pdf文档:

打印地图文档的所有页面

4 程序调试与错误处理

4.1 错误识别

  • 错误类型:拼写错误、标点错误、缩进错误
  • for语句末尾的冒号:
  • pythonWin中可以使用Check进行语法检查,
  • 没有语法错误的提示
  • 显示行号:View>Options>Editer
  • 缩进不一致:
  • 空格检查:
  • View>Whitespace显示脚本中的缩进字符
  • 不建议从其他文件复制代码
  • 虽然提示的某一行,但实际错误可能是在上一行

4.2 程序调试

分析错误、添加print语句输出、选择性注释代码、调试器

4.2.1 pythonWin调试

4.2.2 调试技巧

  • 处理大文件时,尝试在一个性质相同且数据量较小的文件上运行代码
  • 通过print语句或断点监视变量值的变化
  • 在可能重复运行的地方设置断点
  • 文件锁定,防止文件被覆盖

4.2.3 常见错误

 

  • 5
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小薛引路

喜欢的读者,可以打赏鼓励一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值