[ArcPy] 將道路(shp)平均分配給志願者 生成6*6格網 | 第六屆全國大學生GIS技能大賽試題
阿新 • • 發佈:2019-02-13
所有檔案下載:http://download.csdn.net/download/summer_dew/10164828
前言
題目
建立一個6*6的格網,將商業圈道路資料隨機分配到不同的志願者進行管理
資料說明
road.shp 商業圈道路資料
volunteer.xls 志願者統計表
分析
問題實際上,就是把道路資料平均分成36塊,然後每一塊分配一個志願者
- 怎麼把道路資料平均分36塊:得到道路資料的範圍,按範圍平均分
- 怎麼把志願者分配到每塊中:生成一個6*6的隨機矩陣,值在0-35之內,並值不能重複。然後將volunteer表格按id連線到裡面
結果
ArcPy實現
程式碼
# -*- coding:utf-8 -*- # Author: PasserQi # Time:2017/12/18 # Func:將shp檔案分成6*6份,每份賦予分配0-35中不同的值,輸出形式為面狀shp # Desc:若要建立ArcGIS自定義工具,該檔案不能出現中文 import sys,arcpy import arcgisscripting,os import random # 製作ArcGIS自定義工具箱時,得到初始引數 # filein = sys.argv[1] # fileout = sys.argv[2] # rowNum = int(sys.argv[3]) # 測試資料 filein = r'E:\user\Desktop\RandShp\Data\road.shp' fileout = r'E:\user\Desktop\RandShp\rand_polygon.shp' number = 6 # @function:產生number*number個不重複的隨機數,數值範圍在0 <= n <= number-1 # @param: number # @return: list def getRandList(number): randList = [] while len(randList) != number*number: n = random.randint(0, number*number-1) #產生隨機數:0 <= n <= number-1 if n in randList: #已經生成過了 continue else: randList.append(n) return randList if __name__ == '__main__': desc = arcpy.Describe(filein) #獲取shp的資訊 # shp的範圍 XMin = desc.extent.XMin XMax = desc.extent.XMax YMin = desc.extent.YMin YMax = desc.extent.YMax step_x = (XMax - XMin) / number # x的步長 step_y = (YMax - YMin) / number # y的步長 #得到number*number個不重複的隨機數 randList = getRandList(number) # ------------------------------------ # 儲存成shp檔案 gp = arcgisscripting.create() # 建立shp檔案 outWorkspace = os.path.split(fileout)[0] outName = os.path.split(fileout)[-1] spat_ref = desc.spatialReference gp.CreateFeatureClass_management(outWorkspace, outName, "POLYGON", "", "", "", spat_ref) # 新增欄位 gp.AddField_management(fileout, "number", "LONG") # 獲取fileout檔案的遊標,插入資料 cur = gp.InsertCursor(fileout) # 新的一行 newRow = cur.newRow() # 插入資料 for i in range(0,number): for j in range(0,number): XYarray = gp.CreateObject("array") point = gp.CreateObject("point") # 左下角點 point.X = XMin + i*step_x point.Y = YMin + j*step_y XYarray.add(point) # 左上角 point.X = XMin + (i + 1) * step_x point.Y = YMin + j * step_y XYarray.add(point) # 右上角 point.X = XMin + (i + 1) * step_x point.Y = YMin + (j + 1) * step_y XYarray.add(point) # 右下角 point.X = XMin + i * step_x point.Y = YMin + (j+1) * step_y XYarray.add(point) # 左下角點 point.X = XMin + i * step_x point.Y = YMin + j * step_y XYarray.add(point) newRow.setValue("Shape",XYarray) #實體的形狀,面狀一定要閉合的點 newRow.setValue("number",randList[i*6+j] ) #插入隨機分配的值 cur.InsertRow(newRow) #新的一行 del cur,newRow
製作ArcGIS自定義工具
注意:若要將py檔案製作成ArcGIS自定義工具,py檔案中不能出現中文字元,否則會有異常錯誤。這裡先將中文字元全部刪除,再建立
為road.shp生成6*6的格網
生成的6*6格網
按road.shp範圍生成了一個6*6的格網rand_polygon.shp,每個格網都有一個number屬性,標識該格分配的志願者id
連線志願者表
將voluteer.xls中的id與rand_polygon.shp的number欄位連線,可以得到分配的志願者名字