文档库 最新最全的文档下载
当前位置:文档库 › 在Arcmap中使用Python

在Arcmap中使用Python

在Arcmap中使用Python
在Arcmap中使用Python

ArcGIS中的Python简介:

ArcGIS 8.X之前不能使用脚本语言,只能通过VB, C++的应用程序接口访问。ArcGIS 9.0/9.1

版本开始引入Python,通过PythonCOM接口调用gp(GeoProcessing对象),这种方式类似于调用其它程序的脚本,必须通过导入Win32com包实现(单独安装),同时必须启动ArcMap等程序之后才能进行操作。如下:

import win32com.client # 9.1以前老版本的访问方式

gp = win32com.client.dispatch("esriGeoProcessing.GPDispatch.1")

ArcGIS 9.2版本之后就抛弃了PythonCOM方式,采用C/C++扩展了一个一个Python对象(GP),该对象位于..\ArcGIS\BIN\arcgisscripting.dll,该对象直接引用了Python24.dll(位于

C:\WINDOWS\system32),从名称可以看出全部使用小写名称也是C的风格。使用GP对象可以在不启动ArcGIS方式下直接处理数据,性能更加稳定。要在Python中直接使用gp对象,需要在PYTHONPATH 变量中增加..\ArcGIS\BIN\目录,这样在Python脚本中就可以直接导入arcgisscripting对象了。如下:

import arcgisscripting # 9.2以后新版本的调用方式

gp = arcgisscripting.create()

注意:9.1和9.2在python代码上的区别仅此两行而已!!但9.3之后增加了许多列表函数,需要改写程序。

import arcgisscripting # 9.3以后版本的调用方式

gp = arcgisscripting.create(9.3) # 在9.3中使用create不添加版本号以9.2兼容方式运行

import arcpy # 10.0以后的版本

在ArcGIS的9.3版本中,gp对象增加了许多列表对象如:ListFields, ListFeatureClasses等,

这样使得操作更加方便,避免频繁地遍历。

ArcGIS 9.3版本脚本在F1帮助中键入“Geoprocessor object”,或打开“Geoprocessing -> Auto.. script -> Scripting object ->Geoprocessing object”。

1、典型的Python导入模块介绍

import sys # 导入标准模块用于获取用户数的参数,如sys.argv[1] import os # 导入标准模块用于获取工作路径,如os.path

import arcgisscripting # 导入ArcGIS模块用于数据操作,如gp

2、关于记录指针cursor和文件锁lock

文件锁防止多个进程同时修改文件,文件锁有两种:共享锁shared和独占锁exclusive。共享锁用于同时浏览,如同时在ArcMap和ArcCat中打开并浏览同一个shp文件。独占锁用于文件编辑,如在ArcMap中编辑,此时文件以独占方式使用,此时不能再被其它程序编辑。

因此,使用InsertCursor或UpdateCursor编辑文件后,必须释放资源,否则文件不能被再次编辑。在python中释放资源必须显式调用del,在vbs中必须显式调用set...Nothing。如下:rows = gp.InsertCursor("d:\\000.shp") # 插入模式访问

row = rows.NewRow()

……

del row, rows # 必须释放资源

脚本访问:

1、创建gp对象后,可以先通过describe方法确定数据的描述信息,不同的数据类型描述信息是不同

的。

如shape文件的描述信息有:ShapeType(点,线,面等类型),FeatureType(注记、复杂边)

等描述信息。

import arcgisscripting

gp = arcgisscripting.create(9.3)

srcName = r"d:\000.shp"

desc = gp.Describe(srcName)

if desc.ShapeType=="Polyline": pass

如果数据类型为shape文件或table表,则可以不读取shp文件,直接通过描述信息访问字段Fields、索引Index信息。

……

desc = gp.Describe(srcName)

flds = desc.Fields

for fld in flds:

print(https://www.wendangku.net/doc/d55557133.html,)

注:当然,字段、索引信息也可不通过desc,而通过ListFields, ListIndexes函数来访问

flds = gp.ListFields(srcName)

for fld in flds:

print(https://www.wendangku.net/doc/d55557133.html,)

通过描述信息,也可直接访问坐标系(空间参考)信息。

……

desc = gp.Describe(srcName)

sr = desc.SpatialReference

print https://www.wendangku.net/doc/d55557133.html,, srType

2、创建gp对象之后,即可进行数据读写,数据读写必须通过Cursor对象实现。

Cursor访问有三种模式:Insert(增加要素),Update(编辑或删除要素),Search(要素检索)。

rows = gp.InsertCursor(srcName) # 插入模式访问

row = rows.NewRow()

rows = gp.UpdateCursor(srcName) # 更新模式访问

row = rows.Next()

通过检索模式访问,可以通过SQL遍历满足条件的记录

rows = gp.SearchCursor(srcName, "ID = 0") # 检索模式访问

rows = gp.SearchCursor(srcName, "TH = 'H50G'") # 检索模式访问

row = rows.Next()

while(row):

print row.FID # 直接用字段名称

row = rows.Next()

3、在设置访问模式之后,就可以对要素的插入、更新、删除等操作

插入操作:

rows = gp.InsertCursor(srcName) # 插入不需要进行Next()操作row = rows.NewRow()

row.RowID = 1

row.Distance = 100

rows.InsertRow(row)

更新操作:

rows = gp.UpdateCursor(srcName)

row = rows.Next()

while(row):

row.Distance = row.RowID * 25

rows.UpdateRow(row)

row = rows.Next()

删除操作:

rows = gp.UpdateCursor(srcName)

row = rows.Next()

while(row):

if row.Distance == 10:

rows.DeleteRow(row)

row = rows.Next()

4、设置访问模式后,可以访问单个要素的属性,如length, area, centroid等

rows = gp.UpdateCursor(srcName)

row = rows.Next()

while(row):

fea = row.Shape # 也可以通过fea = row.GetValue("Shape") 访问

print fea.Area # 获取其他字段数值也是利用该函数,如row.GetValue("图号") row = rows.Next()

5、读写具体的点、线、面对象

读取单点对象:

……

while(row):

fea = row.Shape

pnt = fea.GetPart() # 单点的GetPart() 获取一个点,相当于GetPart(0)

print(pnt.x, pnt.y)

row = rows.Next()

读取多点对象:

……

while(row):

fea = row.Shape

i, pn = 0, fea.PartCount # 获取组成的个数

while(i

pnt = fea.GetPart(i) # 多点必须通过GetPart(i)遍历所有部分

print(pnt.x, pnt.y)

i += 1

row = rows.Next()

读取线、面对象:

……

while(row):

fea = row.Shape

i, pn = 0, fea.PartCount # 获取组成个数

print("本要素有%d个部分"%pn)

while(i

arr = fea.GetPart(i) # 线面对象必须通过GetPart(i)遍历多个部分

j, pnt = 0, arr.Next()

while(pnt):

print(pnt.x, pnt.y)

pnt = arr.Next()

j += 1

if(not pnt): # 面:如果part第一次结束后第二个part有值,表示有内部环

pnt = arr.Next()

if(pnt): print("内部环")

i += 1

print(" 第%d个部分有%d个节点"%(i, j))

row = rows.Next()

根据坐标列表写入线文件:

……ptLst = [[],[],...] ……

gp.CreateFeatureClass(os.path.dirname(srcName), os.path.basename(srcName), "polyline", "")

rows = gp.InsertCursor(srcName) # 设置插入访问模式

arr = gp.CreateObject("Array")

pnt = gp.CreateObject("Point")

for li in ptLst: # 通过坐标创建点、点数组对象

pnt.x, pnt.y = li[0], li[1]

arr.add(pnt)

row = rows.NewRow() # 设置记录的shape值并插入要素集

row.Shape = arr

rows.InsertRow(row)

arr.RemoveAll()

del rows, row, arr # 必须释放资源

6、创建临时几何对象

上面是直接创建要素,也可以通过点/点列表创建临时几何对象

临时几何对象可以跟单个要素一样进行length, area, centroid等计算

……ptLst = [[],[],...] ……

arr = gp.CreateObject("Array")

pnt = gp.CreateObject("Point") # 通过坐标创建点、点数组对象

for li in ptLst:

pnt.x, pnt.y = li[0], li[1]

arr.add(pnt)

geoPt = gp.CreateObject("Geometry", "Point", pnt)

geoLn = gp.CreateObject("Geometry", "Polyline", arr)

geoPg = gp.CreateObejct("Geometry", "Polygon", arr)

3、判断shape文件的类型

shape文件的类型有:Point, Polyline, Polygon, Multipoint, MultiPatch等5种。通过

gp.Describe方法访问,没有设置gp.workspace=...工作路径时,必须使用路径全名。

if gp.describe("d:\\000.shp").ShapeType == "Polyline": #判断shp文件类型

4、获取shp文件范围信息

desc = gp.decribe("d:\\000.shp")

注意:不同的数据类型,describe返回的数值类型不同,如shpe文件的描述包括:ShapeType, FeatureType等。

ext = desc.extent.split() # 9.2版本返回字符串,需用split()分开

wid = desc.extent.width # 9.3版本返回列表,同时可以访问xymin,xymax,width, height, lowerleft, upperright等众多属性

获取shp文件的所有字段名称

fds = desc.Fields # 9.2版本必须通过Next方式实现

fd = fds.Next()

while(fd): print https://www.wendangku.net/doc/d55557133.html,; fd=fds.Next()

fds = desc.Fields # 9.3版本可直接通过for in实现

for fd in fds: print https://www.wendangku.net/doc/d55557133.html,

5、列操作(字段编辑)

字段Field/col一般通过Next方式遍历。

cols = gp.ListFields(shpPathName) # 获取字段集

col = cols.Next() # 遍历所有字段

while col: col = col.Next()

gp.AddField(shpPathName, "X坐标", "double") # 增加字段

gp.DeleteField(shpPathName, "X坐标") # 删除字段

Expr = "float(!Shape.area!)/1e6" # 计算面积平方公里

gp.CalculateField_management(shpPathName, "Area", Expr, "PYTHON")

Expr = '"%.2f"%float(!Shape.Centroid!.split(" ")[0])' # 计算X坐标

gp.CalculateField_management(shpPathName, "X坐标", Expr, "PYTHON")

注意:

1、VB中字段采用[ ],而Python中则采用! !方式。

2、Python中常用操作几何对象的方式有:!Shape.Centroid!取面心点;!Shape.Length!取长度,!Shape.Area!取面积。

3、Python中取X,Y坐标比较特殊!!

6、如何让自定义处理完毕后加载到当前工程

在 Tool > Options >GeoProcessing中选择“Add result of geoprocessing operations to the display”即可。

7、如何读写点对象

while row: # 遍历所有要素

fea = row.GetValue("Shape") # 获取要素的几何属性

pnt = fea.GetPart() # 点对象只有1个对象,GetPart相当于取该点

print pnt.x, pnt.y # 获取点对象的属性

row = rows.Next() # Next 下一个要素

8、如何读写线对象

线对象可能包括几个线段(part),每个线段中可能包含多个点(point),

while row: # 遍历所有要素

fea = row.GetValue("Shape") # 获取要素的几何属性

for i in range(fea.PartCount):

part = fea.GetPart(i)

pnt = part.Next()

while pnt:

print pnt.x, pnt.y

pnt = part.Next()

row = rows.Next() # Next 下一个要素

相关文档