参考:
如何优雅的从OSM(OpenStreetMap)上获取一个城市的路网?
解决ArcGIS-OpenStreetMap Toolbox-Load OSM File错误
ArcGIS:按属性选择要素、按位置选择要素、空间和属性的组合查询;属性表中长度、面积等的量算
软件:
ArcMAp 10.8
ArcGIS Editor for OpenStreetMap 10.8
地图下载:
①从OSM上用区域选择的方式切片一个区域,进入官网后在右上角找到“导出”按钮,点击,然后通过设置区域拐点或者在地图上手动绘制的方式选中目标区域,然后点击左侧的蓝色按钮“导出”,保存数据。需要注意的是,这种方法只适用于小范围的数据。
②当需要下载整个城市数据时,通过Overpass API 来下载数据。
首先在OSM的官网搜索目标城市,得到城市ID。下图中括号里的912940就是北京的ID。
然后进入Overpass Turbo, 在第一个输入框里输入以下代码:
<osm-script timeout="1800" element-limit="100000000">
<union>
<area-query ref="3600912940"/>
<recurse type="node-relation" into="rels"/>
<recurse type="node-way"/>
<recurse type="way-relation"/>
</union>
<union>
<item/>
<recurse type="way-node"/>
</union>
<print mode="body"/>
</osm-script>
注意,在上述代码中, <area-query ref="3600912940"/>
中的数值表示了目标城市的id,计算规则为int(ID)+3600000000
,用数值相加的方式得到结果。方框右下角的Query按钮,保存结果。
另一种下载方法:
通过python使用Overpass API下载,
import requests
import re
import os
def get_osm_data(area_name, output_folder):
# 设置请求头
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
"Content-Type": "application/x-www-form-urlencoded"
}
# 构造 Overpass API 查询,查询行政区域的关系 ID
data = f'<osm-script><query type="relation"><has-kv k="boundary" v="administrative"/><has-kv k="name:zh" v="{area_name}"/></query><print/></osm-script>'
url = "http://www.overpass-api.de/api/interpreter"
response = requests.post(url, data=data.encode(), headers=headers)
# 利用正则表达式提取关系 ID
match = re.search('<relation id="(.*?)">', response.text)
if not match:
print("未找到相关行政区域数据。")
return
id = match.group(1)
id = str(3600000000 + int(id)) # 将 ID 转换为 10 位格式
# 构造查询,获取包含更详细信息的 OpenStreetMap 数据
data2 = f'<osm-script timeout="1800" element-limit="5000000000"><union><area-query ref="{id}"/><recurse type="node-relation" into="rels"/><recurse type="node-way"/><recurse type="way-relation"/></union><union><item/><recurse type="way-node"/></union><print mode="body"/></osm-script>'
response2 = requests.post(url, data=data2, headers=headers)
# 将结果保存到文件
output_file = os.path.join(output_folder, f"{area_name}.osm")
with open(output_file, "w", encoding="utf-8") as f:
f.write(response2.text)
print(f"OSM 数据已保存到 {output_file}")
# 指定行政区域名称和输出文件夹路径
area_name = "北京市"
output_folder = "osm_data "
# 调用函数获取并保存 OSM 数据
get_osm_data(area_name, output_folder)
有时候下载下来的数据使用ArcMap读取后只有路点没有路段和区域信息,打开下载的文件,若最后一行报错,则将element-limit的赋值改大再重新执行,比如element-limit="5000000000"。
ArcMap操作:
新建文件地理数据库
打开软件,选择“目录”,然后在右侧展开的目录中,点击“文件夹连接”,链接到自己的目标文件夹,然后在这个栏目的折叠内容中将出现刚才设置的文件夹。选中刚才设置的文件夹,点击鼠标右键,选择“新建”-“文件地理数据库”,根据需求命名,在这里我将其修改为Data.gdb。注意修改名称时需要保留后缀。
读取数据
点击ArcToolBox,选择OpenStreetMap ToolBox中的 Load OSM File,双击该选项,弹出一个新页面。在第一输入框里填入刚下下载的北京市的数据文件地址,第二个输入框填入刚才创建的数据库位置,可以通过操作“向上一级”按钮回到目录,再逐步选择文件夹进入创建好的数据库,在数据库内创建输出保存位置。点击确认,软件开始读取数据。
我在这个过程中出现了错误,参考以下方法进行了解决:
解决ArcGIS-OpenStreetMap Toolbox-Load OSM File错误
等待一段时间后,在左侧将展示出得到的数据结果,包括点、线、面三个属性:
处理数据
右键点击beijing_osm_ln,选择“打开属性表”,可以发现不同的路段具有不同的属性。
在软件上方工具栏的空白处点击鼠标右键,选择“编辑器',在编辑器工具栏点击“编辑器”,点击“开始编辑”,弹出来的选项中选择“beijing_osm_ln”,点击“确定”。
将整个区域缩放到合适的大小,通过拖拽鼠标选择所有的路线,点击“编辑器”-“合并”,合并要素默认为第一个,点击确定。
若内存不支持处理全部地图:
则根据需要删除部分数据。右键点击beijing_osm_ln,选择“打开属性表”,点击左上角的“表选项”,在下拉菜单中选择“按属性选择”。进行判断条件选择,先删除highway 属性为 'unclassified'的路段,先双击“highway”,单击“=”,单击“获取唯一值”,然后再生成的属性值中选择一个目标属性,在这里选择“unclassified”,得到属性表达公式highway = 'unclassified',然后点击应用。
此时highway属性为'unclassified'的都已经被选出来了,下图中蓝色部分。最下方显示当前在273768条数据中选中了12691条。点击顶部工具栏的×,删除这部分数据。然后总数据变为261077条。用同样的方法删除其他属性的路段,直至满足内存需求。
删除可参考字段含义:
tertiary(第三级道路):城市支路,
tertiary_link(第三级道路-连接):匝道,机场集散车行道路(数据量极少,多是未知道路)
residential(居住区道路):居住区车行道路,
unclassified(未分类道路):居住区车行道路,滨水车行道路,机场机动车通道
secondary(次要道路):城市次要车行道路,机场外围车行道路,
secondary_link(次要道路-连接):城市次要车行道路立交、匝道(数据量少,部分零散分布未知类别)
primary(主要道路):城市主要车行道路
primary_link(主要道路):城市主要车行道路立交,城市主要车行道路匝道(数据量少,部分零散分布未知类别)
motorway(高速公路):高速公路,过江隧道
motorway_link(高速公路-连接):高速公路立交,匝道
trunk(干道):高架快速路,机场进站快速路,过江隧道,桥上快速路
trunk_link(干道-连接):立交,匝道,桥上引道,机场进站快速路,国道改道
track(小路):郊区、乡村、工矿区、田间、林间小路
track_grade1(小路 级别1):郊区、乡村、工矿区、田间、林间小路
track_grade2(小路 级别2):郊区、乡村、工矿区、田间、林间小路
track_grade3(小路 级别3):郊区、乡村、工矿区、田间、林间小路
track_grade4(小路 级别4):郊区、乡村、工矿区、田间、林间小路
track_grade5(小路 级别5):郊区、乡村、工矿区、田间、林间小路
bridleway(马道):体育场馆内部专用道路(数据量极少,零星道路在公园、居住区内部)
living_street(生活街道):居住区车行道路,公园车行道路
path(小道):公园车行道路,居住区车行道路(分布零碎,量少)
service(服务性道路):居住区车行道路,火车站集散车行道,公园车行道路,公共建筑集散车行道,公交枢纽入口车行道路,停车场入口车行道路
footway(人行道):滨水绿道,公园步行道,广场步行道,大学步行道路,人行道,火车站人行集散道路
pedestrian(步行街道):步行街,广场步行道路,公园步行道路,居住区步行道路
steps(台阶踏步):人行过街天桥台阶,广场台阶、公共建筑入口台阶,登山台阶
cycleway(自行车道):滨水绿道,非机动车道,公园自行车道
unknown(未知道路):滨水车行道路,校园广场车行道路,乡道(数据量少,比较难判别道路类型)
在操作中记得及时保存编辑后的数据。删除一定数量的道路后,再将剩下的道路合并为一条,此时打开属性列表发现整个地图只有一条折线:
然后点击 编辑器--更多编辑工具--高级编辑,打开高级编辑工具栏。
先单击选中路段,然后再高级编辑工具栏中选中“打断相交线”,若不选中该按钮是灰色无法操作。这里的容差我设置为默认值。再打开属性列表可以发现,现在的道路包括多条路段。完成后,点击 编辑器-保存编辑内容-停止编辑。
在左侧图层中选中“beijing_osm_ln”,右击鼠标,选择 数据--导出数据,设置好数据保存位置,将数据转换为shp文件。根据需求决定是否将新生成的数据导入图层,在这里我选择了是。