在Arcmap中使用Python.docx
《在Arcmap中使用Python.docx》由会员分享,可在线阅读,更多相关《在Arcmap中使用Python.docx(8页珍藏版)》请在冰豆网上搜索。
在Arcmap中使用Python
ArcGIS中的Python简介:
ArcGIS8.X之前不能使用脚本语言,只能通过VB,C++的应用程序接口访问。
ArcGIS9.0/9.1版本开始引入Python,通过PythonCOM接口调用gp(GeoProcessing对象),这种方式类似于调用其它程序的脚本,必须通过导入Win32com包实现(单独安装),同时必须启动ArcMap等程序之后才能进行操作。
如下:
importwin32com.client#9.1以前老版本的访问方式
gp=win32com.client.dispatch("esriGeoProcessing.GPDispatch.1")
ArcGIS9.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对象了。
如下:
importarcgisscripting#9.2以后新版本的调用方式
gp=arcgisscripting.create()
注意:
9.1和9.2在python代码上的区别仅此两行而已!
!
但9.3之后增加了许多列表函数,需要改写程序。
importarcgisscripting#9.3以后版本的调用方式
gp=arcgisscripting.create(9.3)#在9.3中使用create不添加版本号以9.2兼容方式运行
importarcpy#10.0以后的版本
在ArcGIS的9.3版本中,gp对象增加了许多列表对象如:
ListFields,ListFeatureClasses等,这样使得操作更加方便,避免频繁地遍历。
ArcGIS9.3版本脚本在F1帮助中键入“Geoprocessorobject”,或打开“Geoprocessing->Auto..script->Scriptingobject->Geoprocessingobject”。
1、典型的Python导入模块介绍
importsys#导入标准模块用于获取用户数的参数,如sys.argv[1]
importos#导入标准模块用于获取工作路径,如os.path
importarcgisscripting#导入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()
……
delrow,rows#必须释放资源
脚本访问:
1、创建gp对象后,可以先通过describe方法确定数据的描述信息,不同的数据类型描述信息是不同的。
如shape文件的描述信息有:
ShapeType(点,线,面等类型),FeatureType(注记、复杂边)等描述信息。
importarcgisscripting
gp=arcgisscripting.create(9.3)
srcName=r"d:
\000.shp"
desc=gp.Describe(srcName)
ifdesc.ShapeType=="Polyline":
pass
如果数据类型为shape文件或table表,则可以不读取shp文件,直接通过描述信息访问字段Fields、索引Index信息。
……
desc=gp.Describe(srcName)
flds=desc.Fields
forfldinflds:
print(fld.Name)
注:
当然,字段、索引信息也可不通过desc,而通过ListFields,ListIndexes函数来访问
flds=gp.ListFields(srcName)
forfldinflds:
print(fld.Name)
通过描述信息,也可直接访问坐标系(空间参考)信息。
……
desc=gp.Describe(srcName)
sr=desc.SpatialReference
printsr.Name,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):
printrow.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):
ifrow.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")访问
printfea.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(ipnt=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(iarr=fea.GetPart(i)#线面对象必须通过GetPart(i)遍历多个部分
j,pnt=0,arr.Next()
while(pnt):
print(pnt.x,pnt.y)
pnt=arr.Next()
j+=1
if(notpnt):
#面:
如果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")
forliinptLst:
#通过坐标创建点、点数组对象
pnt.x,pnt.y=li[0],li[1]
arr.add(pnt)
row=rows.NewRow()#设置记录的shape值并插入要素集
row.Shape=arr
rows.InsertRow(row)
arr.RemoveAll()
delrows,row,arr#必须释放资源
6、创建临时几何对象
上面是直接创建要素,也可以通过点/点列表创建临时几何对象
临时几何对象可以跟单个要素一样进行length,area,centroid等计算
……ptLst=[[],[],...]……
arr=gp.CreateObject("Array")
pnt=gp.CreateObject("Point")#通过坐标创建点、点数组对象
forliinptLst:
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=...工作路径时,必须使用路径全名。
ifgp.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):
printfd.Name;fd=fds.Next()
fds=desc.Fields#9.3版本可直接通过forin实现
forfdinfds:
printfd.Name
5、列操作(字段编辑)
字段Field/col一般通过Next方式遍历。
cols=gp.ListFields(shpPathName)#获取字段集
col=cols.Next()#遍历所有字段
whilecol:
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中选择“Addresultofgeoprocessingoperationstothedisplay”即可。
7、如何读写点对象
whilerow:
#遍历所有要素
fea=row.GetValue("Shape")#获取要素的几何属性
pnt=fea.GetPart()#点对象只有1个对象,GetPart相当于取该点
printpnt.x,pnt.y#获取点对象的属性
row=rows.Next()#Next下一个要素
8、如何读写线对象
线对象可能包括几个线段(part),每个线段中可能包含多个点(point),
whilerow:
#遍历所有要素
fea=row.GetValue("Shape")#获取要素的几何属性
foriinrange(fea.PartCount):
part=fea.GetPart(i)
pnt=part.Next()
whilepnt:
printpnt.x,pnt.y
pnt=part.Next()
row=rows.Next()#Next下一个要素