本文主要是介绍[ArcPy] 将道路(shp)平均分配给志愿者 生成6*6格网 | 第六届全国大学生GIS技能大赛试题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
第六届全国大学生GIS应用技能大赛 下午题目
完整试题:http://www.higis.cn/753
文章目录
- 前言
- 题目
- 数据说明
- 分析
- 结果
- ArcPy实现
- 代码
- 制作ArcGIS自定义工具
- 生成的6*6格网
- 连接志愿者表
所有文件下载: http://download.csdn.net/download/summer_dew/10164828
前言
题目
创建一个6*6的格网,将商业圈道路数据随机分配到不同的志愿者进行管理
【方法一】用ArcGIS创建渔网-> 将志愿者的编号、道路ID进行连接
【缺点】没有体现随机分配
【方法二】用Arcpy创建每个志愿者的工作范围,并随机生成每个面的ID,达到随机分配的要求
数据说明
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,arcpyimport arcgisscripting,osimport 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: listdef getRandList(number):randList = []while len(randList) != number*number:n = random.randint(0, number*number-1) #产生随机数:0 <= n <= number-1if n in randList: #已经生成过了continueelse:randList.append(n)return randListif __name__ == '__main__':desc = arcpy.Describe(filein) #获取shp的信息# shp的范围XMin = desc.extent.XMinXMax = desc.extent.XMaxYMin = desc.extent.YMinYMax = desc.extent.YMaxstep_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.spatialReferencegp.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_xpoint.Y = YMin + j*step_yXYarray.add(point)# 左上角point.X = XMin + (i + 1) * step_xpoint.Y = YMin + j * step_yXYarray.add(point)# 右上角point.X = XMin + (i + 1) * step_xpoint.Y = YMin + (j + 1) * step_yXYarray.add(point)# 右下角point.X = XMin + i * step_xpoint.Y = YMin + (j+1) * step_yXYarray.add(point)# 左下角点point.X = XMin + i * step_xpoint.Y = YMin + j * step_yXYarray.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字段连接,可以得到分配的志愿者名字
这篇关于[ArcPy] 将道路(shp)平均分配给志愿者 生成6*6格网 | 第六届全国大学生GIS技能大赛试题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!