本文是街景影像分析入门的第一篇文章。
在这边文章中,我将教会你如何处理路网数据、生成采样点、访问百度地图API获取街景影像。
这里使用从OSM获取的路网生成采样点,如何获取可以自行查询学习一下, 资料很多。从OSM获取的路网可能充满匝道、双线道路。如果直接使用这样的道路获取街景,可能获取大量的重复影像。为此,需要尽可能简化路网。
后续步骤的工具要求数据带有投影坐标,而OSM的WGS1984是地理坐标系。使用【投影】工具将路网投影至某种投影坐标系。我一般投影至Web Mercator坐标系。
从OSM获取的路网包括了步道、自行车道等在街景影像获取中无用的道路。使用ArcGIS的按属性筛选功能,根据fclass删去不需要的类别即可。我个人一般保留以下类别的道路。
使用ArcGIS工具【拆分多部件要素】即可
启动编辑器,唤出【高级编辑】。
选中研究区的所有道路,打断相交线,保存。
设置好道路文件路径后,使用以下代码,可以对道路进行简化。
import arcpy
input_road = r"./yt2022.gdb/ytroad"#输入
merged_road = r"./yt2022.gdb/roadMerge"#中间数据,处理后可删
thinned_road = r"./yt2022.gdb/roadThin"#中间数据,处理后可删
output_road = r"./yt2022.gdb/roadSimple"#简化后的道路
# 合并双线道路
arcpy.MergeDividedRoads_cartography(input_road, "level", "30 meters", merged_road)
# 删除复杂短街道
arcpy.AddField_management(merged_road, "visibility", "SHORT")
arcpy.CalculateField_management(merged_road, "visibility", 0)
arcpy.AddField_management(merged_road, "level", "SHORT")
arcpy.CalculateField_management(merged_road, "level", 1)
arcpy.ThinRoadNetwork_cartography(merged_road, "50 meters", "visibility", "level")
arcpy.SelectLayerByAttribute_management(merged_road, "NEW_SELECTION", '"visibility" = 0')
arcpy.CopyFeatures_management(merged_road, thinned_road)
# 删除悬挂街道
arcpy.TrimLine_edit(thinned_road, "50 meters", "DELETE_SHORT")
# 重新转回WGS84坐标
arcpy.Project_management(thinned_road, output_road, arcpy.SpatialReference(4326))
使用以下代码,导出采样点。请注意,以下代码只适用于ArcGIS Pro配套的Python3。使用ArcMap配套的Python2可能需要自己做一些调整。
import arcpy
#输出的采样点csv文件
outputPointFile = r""
#上一步处理好的道路
input_road = r""
#三个中间数据
densified_road = r""
out_road = r""
out_points = r""
#复制文件,确保输入数据不免,以免出问题后无法重新处理
arcpy.CopyFeatures_management(input_road, densified_road)
sr = arcpy.Describe(densified_road).SpatialReference
arcpy.Densify_edit(densified_road, "DISTANCE", "40 Meters")
arcpy.SplitLine_management(densified_road, out_road)
#创建点要素,字段分别为路段的ID、X、Y
arcpy.CreateFeatureclass_management(arcpy.env.workspace, out_points, 'POINT', spatial_reference=sr)
arcpy.AddField_management(out_points, "roadFID", "DOUBLE", 9)
arcpy.AddField_management(out_points, "pointX", "DOUBLE", 9)
arcpy.AddField_management(out_points, "pointY", "DOUBLE", 9)
cursor_point = arcpy.da.InsertCursor(out_points, ['SHAPE@',"pointX","pointY","roadFID"])
# 需要读取的属性
fields_array = ["SHAPE@","OBJECTID"]
for row in arcpy.da.SearchCursor(out_road, fields_array):
line_geo = row[0] # 线要素
seg_id = row[1]
# 第一个点和最后一个点
fp = line_geo.firstPoint
lp = line_geo.lastPoint
cursor_point.insertRow([fp,float(fp.X),float(fp.Y),seg_id])
cursor_point.insertRow([lp,float(lp.X),float(lp.Y),seg_id])
arcpy.AddXY_management(out_points)
# 根据位置去除相同点,
fields = ["Shape"]
arcpy.DeleteIdentical_management(out_points, fields)
f = open(outputPointFile,'w')
f.write("ID,pointX,pointY,direction\n")
for row in arcpy.da.SearchCursor(out_points, ["OBJECTID","POINT_X","POINT_Y"]):
f.write("{0},{1},{2}\n".format(row[0],row[1],row[2]))
f.close()