在操作属性表中,无论是使用搜索SearchCursor,还是UpdateCursor,抑或其他的Cursor,都或多或少的用到令牌(形如用SHAPE@来做标记),比如下面的代码。令牌在我看来是对操作属性类和表的一种返回标记,你比如说返回记录的几何信息,xy座标信息,质心等。而esri公司之所以提出了令牌是为改善操作属性表性能,让查询更加优化,速度得以提高。
按照相关的资料,我们可以知道。在操作属性表中无非有下面几类令牌。
那么今天我们要来学习一下这些令牌对点、线、面要素类操作,返回的数据情况。
- 点(Point)
首先我们做了一份如下图的测试数据,创建了三个点,使用的座标系是WGS84的。
然后我们使用pycharm来编写对点要素类数据类型的测试代码。注意了,这里我们把所有的令牌都将上去,用于测试点要素类型数据。
#encoding:utf-8
import arcpy
ts_point=r"C:\Users\qin\Desktop\test\shp_pt\ts_pt.shp"
with arcpy.da.SearchCursor(ts_point,["Flag","FID","SHAPE@XY","SHAPE@X","SHAPE@TRUECENTROID"
,"SHAPE@Y","SHAPE@Z","SHAPE@M","SHAPE@","SHAPE@AREA","SHAPE@LENGTH"
,"OID@"]) as searchCursor:
for row in searchCursor:
print "Flag value is {0}".format(row[0])
print "FID value is {0}".format(row[1])
x, y = row[2]
print "SHAPE@XY value X is {0} Y is {1}".format(x,y)
x1, y1 = row[2]
print "SHAPE@TRUECENTROID value X is {0} Y is {1}".format(x1, y1)
print "SHAPE@Y value is {0}".format(row[4])
print "SHAPE@Z value is {0}".format(row[5])
print "SHAPE@M value is {0}".format(row[6])
ts=row[7]
print "type of SHAPE@ is {0}".format(row[7])
print "SHAPE@AREA value is {0}".format(row[8])
print "SHAPE@LENGTH value is {0}".format(row[9])
print "OID@ value is {0}".format(row[10])
print "finished"
错误一
好了,现在我们来运行一下编写好的程序。首先出现了下面的错误。显然我们的点数据是没有Z值的,以至于报了下面的错误。
现在将令牌"SHAPE@Z"给删除掉。继续运行代码。
错误二
现在造成的这个错误是由于令牌"SHAPE@M"引起的。你会很奇怪,Z值和M值是什么,拿来干嘛的,又是怎么产生的,等等一系列的疑问。在这里,我们就不去寻根问底了。总之没有这个值。
现在我们将上面的令牌去掉,重新运行程序。似乎这次程序可以跑起来了,我们打断点来看一下运行的结果。从下图中,我们可以看得出,当遍历要素类,每一条记录row是一个元组数据(tuple),经过点没有长度、面积,但是这里还是给我们返回了0值。
那么我们来看一下06这个PointGeometry数据。从下面的数据中可以看得出firstPoint、lastPoint是相等的。可以取上面的值用于表示座标点。
- 线(Polyline)
我们在这里也准备了一份数据,如下图所示。为两条线,有一个Flag属性。
同样来测试一下令牌在线的情况,写了下面的代码。
import arcpy
ts_polyline=r"C:\Users\qin\Desktop\test\shp_pt\ts_polyline.shp"
with arcpy.da.SearchCursor(ts_polyline, ["Flag", "FID", "SHAPE@XY", "SHAPE@X", "SHAPE@TRUECENTROID"
, "SHAPE@Y", "SHAPE@Z", "SHAPE@M", "SHAPE@", "SHAPE@AREA", "SHAPE@LENGTH"
, "OID@"]) as searchCursor:
for row in searchCursor:
print "Flag value is {0}".format(row[0])
print "FID value is {0}".format(row[1])
x, y = row[2]
print "SHAPE@XY value X is {0} Y is {1}".format(x, y)
x1, y1 = row[2]
print "SHAPE@TRUECENTROID value X is {0} Y is {1}".format(x1, y1)
print "SHAPE@Y value is {0}".format(row[4])
print "SHAPE@Z value is {0}".format(row[5])
print "SHAPE@M value is {0}".format(row[6])
ts = row[7]
print "type of SHAPE@ is {0}".format(row[7])
print "SHAPE@AREA value is {0}".format(row[8])
print "SHAPE@LENGTH value is {0}".format(row[9])
print "OID@ value is {0}".format(row[10])
print "finished"
同样会出现下面的错误:
错误一:
没有z值。
错误二:
没有M值
将上面两个令牌去掉,代码可以跑起来了。我们来看一下遍历记录的信息。除了06这个属性为polyline和点不一样,另外我们的长度也是有了值。
我们来看一下06的值,如下图所示。这里很重的信息是partCount,pointCount两个属性,这里告诉我们这是由一个part组成,有四个点,而其他的起始点、最后点信息在我们一些工具开发中也会用到的。
我可用使用下面的代码来遍历一下顶点。
for part in row[6]:
tt=part
for index in range(0, part.count-1):
tPoint=part.getObject(index)
print "index of {0} the X is {1} the Y is {2}".format(index,tPoint.X,tPoint.Y)
print "very good"
好了,最后我们来看一下,在polyline类型的数据中,能够运行起来的令牌,以及完整的代码。
with arcpy.da.SearchCursor(ts_polyline, ["Flag", "FID", "SHAPE@XY", "SHAPE@X", "SHAPE@TRUECENTROID"
, "SHAPE@Y", "SHAPE@", "SHAPE@AREA", "SHAPE@LENGTH"
, "OID@"]) as searchCursor:
for row in searchCursor:
print "Flag value is {0}".format(row[0])
print "FID value is {0}".format(row[1])
x, y = row[2]
print "SHAPE@XY value X is {0} Y is {1}".format(x, y)
print "SHAPE@X value is {0}".format(row[3])
x1, y1 = row[4]
print "SHAPE@TRUECENTROID value X is {0} Y is {1}".format(x1, y1)
print "SHAPE@Y value is {0}".format(row[5])
for part in row[6]:
tt=part
for index in range(0, part.count-1):
tPoint=part.getObject(index)
print "index of {0} the X is {1} the Y is {2}".format(index,tPoint.X,tPoint.Y)
print "very good"
print "type of SHAPE@ is {0}".format(row[6])
print "SHAPE@AREA value is {0}".format(row[7])
print "SHAPE@LENGTH value is {0}".format(row[8])
print "OID@ value is {0}".format(row[9])
print "finished"
最后我们来看一下polygon。相信这种数据类型,对于我们在生产一线的小伙伴是经常打交道的。我们同样制作了一份数据,如下图所示。
由于从点(Point)和线(Polyline)中,我们知道都没有去创建m和z值,所以我们这里将这两个令牌给去掉。同样使用下面的代码来测试。
with arcpy.da.SearchCursor(ts_polygon, ["Flag", "FID", "SHAPE@XY", "SHAPE@X", "SHAPE@TRUECENTROID"
, "SHAPE@Y", "SHAPE@", "SHAPE@AREA", "SHAPE@LENGTH"
, "OID@"]) as searchCursor:
for row in searchCursor:
print "Flag value is {0}".format(row[0])
print "FID value is {0}".format(row[1])
x, y = row[2]
print "SHAPE@XY value X is {0} Y is {1}".format(x, y)
print "SHAPE@X value is {0}".format(row[3])
x1, y1 = row[4]
print "SHAPE@TRUECENTROID value X is {0} Y is {1}".format(x1, y1)
print "SHAPE@Y value is {0}".format(row[5])
for part in row[6]:
tt=part
for index in range(0, part.count-1):
tPoint=part.getObject(index)
print "index of {0} the X is {1} the Y is {2}".format(index,tPoint.X,tPoint.Y)
print "very good"
print "type of SHAPE@ is {0}".format(row[6])
print "SHAPE@AREA value is {0}".format(row[7])
print "SHAPE@LENGTH value is {0}".format(row[8])
print "OID@ value is {0}".format(row[9])
print "finished"
用debug来看一下运行的结果。我们可以看到和线(polyline)数据相比,polyline将有了面积
也是由part组成。
总结
至此,令牌在点,线,面中相关内容就介绍完了,当然如果想接触更多的内容,可以去接触一下多点、多线等相关的知识。而在这里我会知道,在点中SHAPE@AREA、SHAPE@LENGTH为零,而polyline的SHAPE@AREA是有值的,对于polygon而言,这两个都是有值的。同时大家也学会了如何去遍历顶点。
更多内容,请微信扫二维码关注公众号,或者加入arcpy开发qq学习群:487352121