目录
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脚本编程》的笔记总结
>>> arcpy.GetCount_management('road')
>>> name = 'road'
>>> id(name)
355610048
>>> type(name)
>>> print name
road
它包含多个模块,其中两个专业模块,自动化制图模块(arcpy.mapping)和地图代数模块(arcpy.sa);模块在导入之后才能使用
import arcpy
import arcpy.mappping
import arcpy.sa
导入模块后,使用类型属性方式:arcpy.
import arcpy
arcpy.env.workspace = "d:/Work/"
使用from-import语句,导入模块的一部分,此时可以省略类名:
from arcpy import env
env.workspace = "d:/Work/"
使用from-import-as语句增强导入代码可读性:
from arcpy import env as myEnv
myEnv.workspace = "d:/Work/"
两种方法都对,可以任意选择,但必须保证语法正确
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")
裁切功能官方帮助:
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 |
每个参数都有四个属性:
地理信息处理工具语法基本模式:
官方文档--缓冲区分析工具:
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")
增加代码的灵活性和可复用性
>>> 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
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部分相同
使用Usage获得所有工具语法
>>> import arcpy
>>> tools = arcpy.ListTools("*_analysis")
>>> for tool in tools:
print arcpy.Usage(tool)
help方法查看工具语法:
>>> print help(arcpy.Clip_analysis)
调用格式:arcpy.
所有工具都是函数,但是函数并一定的是工具;工具函数与非工具函数的区别在于:
在帮助文档中找到Geoprocessing > Python 和 Geoprocessing > ArcPy
每个工具都有帮助示例
地理处理工具的帮助文档位置Geoprocessing > Tool reference,可按照工具箱--工具集--工具方式访问
ArcPy中的两种路径类型:
注:gdb表示文件地理数据库;mdb表示个人地理数据库;sde企业地理数据库
import arcpy
print arcpy.Exists("D:/data/country.shp")
#存在为true,不存在返回false
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,去除了文件的后缀,只保留了文件名称本体
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编码,在处理多语言时比较安全
元组的基本概念
字典的基本概念:
install = arcpy.GetInstallInfo()
for key in install:
... print "{0},{1}".format(key, install[key])
使用游标来遍历属性表中的每一条属性记录,或者添加新的记录
定义在ArcPy.da模块,主要包含三种功能:
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)
ArcGIS中的SQL表达式的帮助信息:Building a query expression
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)
存在性判断及处理方式:
解析属性表和字段名:
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:"替换为""
(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"):
<处理函数>
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
三种栅格元素类型:
栅格属性:
代码示例:
>>> 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
使用地图代数方式创建,多波段栅格数据保存变成了单波段的坡度图:
>>> ouRaster = arcpy.sa.Slope("China.png")
>>> ouRaster.save("mch.tif")
使用栅格创建,【保存正常】:
>>> ouRaster1 = arcpy.Raster("China.png")
>>> ouRaster1.save("ra.tif")
坡度提取代码及结果展示
>>> 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")
栅格数据转化为Numpy数据的数据的脚本,然后使用SciPy包调用专门的函数处理成ArcGIS可识别的格式
两个函数分别是:NumPyArrayToRaster和RasterToNumPyArray
arcpy.mapping
典型的流程包括:打开地图文档,修改数据框属性,加载图层、编辑页面中的元素、将地图文档导出为PDF
mapdoc = arcpy.mapping.MapDocument(r"E:\ArcGISlearn\data.mxd")
#如果是在ArcGIS环境下打开了*.mxd文件,可使用CURRENT关键字;使用该关键字时,需在创建脚本时候选“Always run in foreground”
mapdoc = arcpy.mapping.MapDocument("CURRENT")
关键属性和方法:
一个结构化的示例代码:
获取文件路径、设置制图文档的标题、设置数据框
>>> mapdoc = arcpy.mapping.MapDocument("CURRENT")
>>> listdf = arcpy.mapping.ListDataFrames(mapdoc)
>>> for fd in listdf:
print fd.name
fd.scale = 24000
>>> del mapdoc
DataFrame对象地图范围、比例尺、旋转、空间参考;panToExtend保持比例尺不变的情况下,居中显示
两种方式:
从磁盘获取*.lyr文件,并获取他们的名字的例子:
注解:例子中*.lyr中包含了多个图层,故可将其作为ListLayers的参数
重要的属性和方法:
>>> 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")
输出
打印
合并pdf文档:
打印地图文档的所有页面
分析错误、添加print语句输出、选择性注释代码、调试器