基於ArcGIS的python編程 10、根據Excel表格批量生成點數據,批量裁剪

前面有一篇文章《基於ArcGIS的python編程 7.獲取面區域漁網網格的一組對角坐標》寫到獲取漁網網格的對角坐標就是應用百度地圖API的矩形查詢功能,爬取某區域的POI數據。經過這段時間的努力,終於把百度地圖上梅州市所有POI數據(程序順利跑完,可能會因為程序設計的問題,少部分POI可能會缺失)爬取下來並分類保存到Excel表格中,如圖1,Excel表格的格式如圖2。

圖1 Excel表格

圖2 Excel表格結構

這篇文章就是著重說明POI點的處理,不涉及爬取的過程;首先利用程序根據Excel表格批量生成點shp類型的數據;因為從網格坐標的獲取中可以知道,有些與梅州相交的網格是跨區域的如圖2,所以爬取的POI點不在梅州市範圍內,所以對點的shp數據進行批量裁剪,獲得只在梅州範圍內的POI。

圖3 網格

首先比較傳統的Excel表格生成shp數據在Arcmap里有現成的工具;點擊工具欄的添加數據圖標→選擇Excel表格如圖4→選擇選擇Excle表格下的sheet表→在圖層管理窗口選中剛剛添加的表格滑鼠右鍵→顯示XY數據→選中事件右鍵→數據→導出數據;剛剛開始我也是用這種方法的,如果是一兩個表,很快就可以完成,但是有很多個表的話,這樣重複的工作還是挺無聊的,然後就想偷懶一下,自己寫了一個簡單的批量生成點的程序。

圖4 導入Excel表格

根據Excel批量生成點數據

程序的大概思路如下:選擇一個或者多個表→根據表名,新建點要素類(CreateFeatureclass_management()函數)→讀取Excel表格的列名,作為點要素類的欄位名→根據列名給點要素添加欄位(AddField_management()函數)→利用插入游標插入點,遍歷Excel表格,寫入欄位信息。

完整代碼如下:

#coding=utf-8nimport arcpynimport xlrdnimport timennin_table=arcpy.GetParameterAsText(0) #輸入的表格,一個或者多個類型為任意值nsavepath=arcpy.GetParameterAsText(1) #保存的路徑,類型為文件夾(點數據名與表名一致nspatial=arcpy.GetParameterAsText(2) #參考坐標系,可以自己導入或者新建nntablename=[]ntablepaths=in_table.split(;) #獲得表路徑列表nfor path in tablepaths:n name=path.split()[-1].split(.)[0]n tablename.append(name) #通過簡單的字元串處理,獲得表名並放在表名列表中nnfor name in tablename:n #利用表名,根據CreateFeatureclass_management()函數新建一個點要素類n if arcpy.Exists(savepath + + name + .shp)==False:n arcpy.CreateFeatureclass_management(savepath,name,POINT,,,,spatial)n else:n passntry:n for table in tablepaths:n #根據表路徑,讀取表裡的內容n featurename=table.split()[-1].split(.)[0]n data=xlrd.open_workbook(table)n sh=data.sheets()[0]n ziduanNamelist=sh.row_values(0)#獲得列名,即點數據的欄位名n for ziduan in ziduanNamelist:n try:n #利用AddField_management()函數為剛剛創建的點要素添加欄位n arcpy.AddField_management(savepath++featurename+.shp,ziduan,TEXT)n except:n passn #time.sleep(0.5)#設置睡眠時間,因為我軟體的問題,太快了總是崩潰n rownum=sh.nrows #獲得表格的行數n #接下來讀取Excle表格的內容,利用插入游標給上面新建的點要素類插入數據(row)n Insercur = arcpy.InsertCursor(savepath + + featurename + .shp)n for r in range(1,rownum):n newpnt=arcpy.Point() #新建一個點n #獲得點的xy坐標並賦值給點的XY屬性,n # sh.cell(r,c).value,這裡的r,c索引要根據你自己表格的格式設置n newpnt.X=float(str(sh.cell(r,2).value))n newpnt.Y=float(str(sh.cell(r,1).value))nn pointGeo=arcpy.PointGeometry(newpnt)nn newrow = Insercur.newRow() #插入游標新建行rown newrow.shape=pointGeon for c in range(0,len(ziduanNamelist)):n #遍歷Excle表格,並把對應的內容賦值給點欄位n newrow.setValue(ziduanNamelist[c],sh.cell(r,c).value)n Insercur.insertRow(newrow) #插入rownexcept Exception as e:n #異常捕獲,用於調試n print e.messagen arcpy.AddError(e.message)n

腳本工具的製作這裡不再闡述,前面的文章《基於ArcGIS的python編程 5、利用Arcpy製作自定義腳本工具——點線拓撲》有說到,不太清楚的可以去回顧一下。

圖5 批量生成點數據工具參數屬性

圖6 點生成後的效果

批量裁剪,獲取梅州區域內的POI

傳統的思路就是一個點數據,一個面數據,利用裁剪工具一個一個的進行裁剪,也可以獲得區域內的POI;批量裁剪的思路參考一篇文章《Arcpy:柵格批量裁剪工具製作(01)》,內容大同小異,只是換了一個函數而已。

完整代碼如下:

# coding=UTF-8nimport arcpynnin_point = arcpy.GetParameterAsText(0) #點數據,一個或多個npoint_paths = in_point.split(;)nnin_feature = arcpy.GetParameterAsText(1) #裁剪要素(面區域)nfeature_paths = in_feature.split(;)nnout_file = arcpy.GetParameterAsText(2) #保存路徑,名字與裁剪前相同nnfor point_layer in point_paths:n name2 = point_layer.split()[-1].split(.)[0]n out_layer=out_file++name2n arcpy.Clip_analysis(point_layer, in_feature, out_layer)n

工具參數屬性如下:

圖7 批量裁剪工具參數屬性

圖8 裁剪後的POI數據

總結:

如果還想偷懶的話,可以把這兩個工具結合在一起,這裡不再闡述,有興趣的可以自己去弄一下。批量生成點數據的程序雖然可以成功跑完,可是感覺有點慢,雖然中間省了很多人工的步驟,不過感覺也沒比傳統的方法快多少,甚至更加慢了。不過這也不失為一種新的嘗試。至於優化,後面有時間再去完善一下,如果您有好的方法或者什麼建議,歡迎交流!

歡迎大家一起交流,一起學習,一起進步!


推薦閱讀:

回頭看一看我的2017年
arcgis api for js入門開發系列八聚合效果
我的屌絲giser成長記-研二篇

TAG:GIS软件工程师 | ArcGIS | GIS地理信息系统 |