在操作屬性表中,無論是使用搜索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