**
基于arcpy的矢量文件坐标系获取与更改、渔网创建、按位置选择导出和字段赋值
**
前言
主要内容:基于arcpy①获取矢量文件坐标系、改变矢量文件坐标系;②基于矢量文件创建渔网单元格;③按位置选择导出指定位置矢量或按位置选择给指定位置矢量文件字段赋值。一、获取矢量文件坐标系
主要使用arcpy.Describe,具体如下:
shp_file_abspath = r''
_des = arcpy.Describe(_shapefile) #获取矢量文件对象属性
_coord_sys = _des.spatialReference #获取矢量文件坐标系
_coord_sys_name = _coord_sys.name #获取矢量文件坐标系名字
print(_coord_sys_name) #打印矢量文件坐标系名字
结果显示为:CGCS2000_3_Degree_GK_Zone_38
二、copy一个矢量文件,并改变坐标系
使用场景:假设shp_1矢量文件坐标系是wgs84,我想把它坐标系变为投影的CGCS2000_3_Degree_GK_Zone_38坐标系,如果直接定义投影总是出现问题,经过尝试使用可通过如下方法实现。
使用arcpy.CopyFeatures_management拷贝为一个新的矢量文件可以实现,相当于在arcgis中定义数据框坐标系为目标坐标系,后拷贝导出新文件,具体如下:
shp_1_abspath = r'' #需要更改坐标系的矢量文件,假设其现在的坐标系是wgs84
shp_object_corrdinate = r'' #目标坐标系矢量文件,假设目标坐标系为投影坐标系的CGCS2000_3_Degree_GK_Zone_38
shp_2_abs_path = r'' #copy出的新的矢量文件,其坐标系为CGCS2000_3_Degree_GK_Zone_38
# 获取目标坐标系文件
object_corrdinate_system = arcpy.Describe(shp_object_corrdinate).spatialReference
# 下面这句个人理解相当于定于arcgis数据框坐标系更改为目标坐标系,不知道是否恰当
env.outputCoordinateSystem = object_corrdinate_system
# 拷贝文件
arcpy.CopyFeatures_management(shp_1_abspath, shp_2_abs_path)
这样导出后的新文件shp_2_abs_path的坐标系就变成了CGCS2000_3_Degree_GK_Zone_38
三、根据一个矢量边界范围创建渔网单元格
看如下代码:
input_extent_shapefile = r'' # 需要制作渔网单元格的边界范围矢量文件
# 特别需要注意的是input_extent_shapefile文件一定要是投影坐标系,不然会报错或者渔网创建失败
output_fishnet_shapefile = r'' # 渔网单元格输出绝对路径
grid_unit = 100 # 渔网单元格边长,单位:米
four_point_list=arcpy.Describe(input_extent_shapefile)
arcpy.CreateFishnet_management(output_fishnet_shapefile, str(four_point_list.extent.XMin) + " " + str(four_point_list.extent.YMin),str(four_point_list.extent.XMin) + " " + str(four_point_list.extent.YMin+10), str(grid_unit), str(grid_unit), "0", "0", str(four_point_list.extent.XMax) + " " + str(four_point_list.extent.YMax), 'NO_LABELS', "#", 'POLYGON')
四、导出边界范围内的所有渔网单元格
使用场景:上述创建的渔网单元格总体范围是一个矩形,有一些是在边界范围之外的(见下图所示),我们可以通过arcpy.SelectLayerByLocation_management导出在边界范围之内我们需要的渔网单元格,具体做法如下。
上图为创建好的渔网单元格,黑色线框为范围边界矢量文件,红色为渔网单元格,显然有许多渔网单元格在范围之外,不是我们需要的!!
fishnet = r'' # 创建好的渔网单元格绝对路径
boundary = r'' # 边界范围矢量文件绝对路径
arcpy.MakeFeatureLayer_management(fishnet, 'target_lyr')
arcpy.SelectLayerByLocation_management('target_lyr', 'COMPLETELY_WITHIN', boundary) #COMPLETELY_WITHIN表示完全在边界范围之内
matchcount = int(arcpy.GetCount_management('target_lyr')[0]) # 统计下边界范围之内渔网单元格个数
if matchcount == 0:
print('目标位置内没有带操作的矢量图斑.....')
else:
arcpy.CopyFeatures_management('target_lyr', output_shapefile) # 拷贝边界范围内的渔网单元格并导出
五、根据两个矢量文件空间位置对其中一个矢量文件字段赋值
使用场景:这个名字不好起,我用文字更详细的描述下
假设有两个矢量文件,文件1为shp_1和文件2为shp_2,这两个矢量文件在空间上有交叉、重叠,且这两个矢量文件均有多个要素(或者叫图斑),我想将文件1与文件2相交的位置对应的文件1的图斑的某个字段全部赋值为特定值,具体如下操作:
shp1 = r'' # 需要字段赋值的矢量文件,赋值的字段名字为mark,将该字段赋值为999
shp2 = r'' # 进行位置判断的矢量文件
arcpy.MakeFeatureLayer_management(shp1, 'target_lyr')
arcpy.SelectLayerByLocation_management('target_lyr', 'INTERSECT', shp2) #INTERSECT表示相交
matchcount = int(arcpy.GetCount_management('target_lyr')[0])
if matchcount == 0:
print('目标位置内没有带操作的矢量图斑.....')
else:
cursor = arcpy.UpdateCursor('target_lyr')
for row in cursor:
row.setValue("mark", 999)
cursor.updateRow(row)
总结
本文基于arcpy相关模块,对矢量文件进行一些常规基本操作,对于批量处理具有重要作用,供大家参考。欢迎各位点赞关注。多谢!
上述应用均基于我个人工作需求,如果其他不同需要欢迎留言打扰。