全球路网数据的获取(OSM)

2021-03-12  本文已影响0人  沉迷科研的憨憨

提到路网数据,我猜大家第一时间想到的就是OSM(OpenStreetMap)数据。过去做区域尺度下的研究时,很多时候拿到手上的数据都是别人收集和处理好的,只知道数据来自于OSM平台,但对于OSM数据如何获取与处理过程却并不清楚。
我目前所做的研究工作需要利用到全球400余个特定城市路网数据,但手上仅有中国区域城市路网数据。这几天一直都在琢磨怎么去获取得到我想要的路网数据,在过程中遇到了很多坑,所以做个小小的总结,供大家参考~
(对于急需全球路网数据的同学,直接跳过前两部分的废话~)

1. OSM全球路网数据

首先我再交代一下需要获取的目标数据:全球400余个特定城市路网数据。
我最开始想到的方法是,直接从OSM平台获取全球路网数据,然后借助ArcGIS利用城市行政边界对数据进行裁剪,最终得到需要的城市路网数据。这个方法虽然比较古板,但是思路非常清晰,对于技术要求不高。


OSM数据下载地址

在下载页面,我们可以看到有两种下载数据文件格式类型:.osm.pdf和.osm.bz2,这两种数据文件都是osm压缩文件。我们从OSM获取的数据都是OSM格式的数据,在处理osm文件类型数据时,我们会用到ArcGIS软件(需安装OSM插件)或GDAL。
这里有几个坑:(1)用ArcGIS是无法处理这两类osm压缩文件的,需要转成osm.xml格式才能加载进去,而仅有.osm.bz2能够解压(7Zip)出osm.xml文件,所以说如果你想要用ArcGIS来处理osm数据,请下载.osm.bz2格式的数据,别搞错了各位;(2)那如何处理.osm.pdf呢,这里需要用到GDAL工具,进入数据文件夹,输入以下命令之一

# 从压缩文件export.osm.pdf中直接导出shp文件
ogr2ogr -f "ESRI Shapefile" map.shp export.osm.pdf

# 从压缩文件export.osm.pdf中先导出gpkg文件
ogr2ogr -f GPKG map.gpkg export.osm.pdf
# 再从gpkg数据中导出shp
ogr2ogr -f "ESRI Shapefile" output_folder map.gpkg

即可将数据转换为shp数据或GPKG文件(建议转GPKG文件),看上去是不是很简单。但是问题又来了,你下载的原始.osm.pdf文件往往几个G,电脑在处理时会很吃力很慢(我用实验室的高性能工作站也是这种局面),而且意外的错误比较多。如何去解决只能自行Google,我已经放弃了这种做法。

在补充一点,如何使用gdal导出osm文件中的shp数据,代码如下:

ogr2ogr -f "ESRI Shapefile" map.shp export.osm.pdf
ogr2ogr -f GPKG map.gpkg export.osm

2. 借助overpass-api获取区域路网

OSM提供了一个通过编码检索数据的API接口,这一部分内容就需要有一定的网络爬虫基础。简单来说,找到接口API的URL 也就是这个 https://overpass-api.de/api/interpreter,然后将查询信息封装进一个post请求,将Request发送给API接口,API接口会返回给你最终的查询结果Response。最后你将Response解析成你想要的shp数据。
在利用爬虫检索路网数据时,需要分成两部操作:(1)通过城市名查询该城市的OSM-ID;(2)再通过OSM-ID查询该城市的路网信息,将其解析为osm文件。
以下是代码的关键部分,整个流程看上去是非常清晰的:

def req_id(city_name):
    # 构造PostXml
    xmlData = '<osm-script output=\"json\"><query type=\"relation\">' \
              '<has-kv k=\"boundary\" v=\"administrative\"/>' \
              '<has-kv k=\"name:en\" v=\"city_name\"/>' \
              '</query><print/></osm-script>'
    xmlData = xmlData.replace('city_name', city_name)

    # 请求URL 返回JSON数据
    api_url = 'http://overpass-api.de/api/interpreter'
    try:
        res = requests.get(url=api_url, data=xmlData, headers={'Content-Type': 'application/xml'})
        if res.status_code == 200:
            return res.json()
    except Exception as e:
        print('Error: ', e)
        return None
def req_osm_file(city_id):
    # 构造PostXml
    xmlData = r'<osm-script timeout="18000"><union><area-query ref="city_id"/>' \
              r'<recurse type="node-relation" into="rels"/><recurse type="node-way"/>' \
              r'<recurse type="way-relation"/></union><union><item/><recurse type="way-node"/>' \
              r'</union><print mode="body"/></osm-script>'

    xmlData = xmlData.replace('city_id', city_id)

    # 请求URL 返回JSON数据
    api_url = 'http://overpass-api.de/api/interpreter'
    try:
        res = requests.get(url=api_url, data=xmlData, headers={'Content-Type': 'application/xml'})
        if res.status_code == 200:
            return res.text
    except Exception as e:
        print('Error: ', e)
        return None

但是但是!!当你访问一定次数之后,迎接你的就是429状态码(访问太频繁,直接就拒绝你的请求),技术小白的我也不知道接下来怎么处理,还是果断放弃了这个获取途径。

3. 全球道路数据库

做到后面,我已经对OSM极度厌恶,哎~ 可能还是自己太菜了,是我不配......
后来,我想了想看看找找有没有别的数据源,总不能在一条树上吊s吧。
最终,我发现了GRIP全球道路数据库!!


GRIP全球道路数据库数据下载网站

该数据库是整合了目前所有公开的地理参考道路数据集(包括OpenStreetMap),并且集中协调了道路的属性信息。相比OSM数据,该数据在应用分析时非常方法,下载之后可直接在ArcGIS中打开。并且类别信息也进行了简化,被划分为5种类别:高速公里、主要道路、次要道路、第三级道路与当地道路。总之,强烈推荐!!
参考文献:Paper by Meijer et al (2018)
数据地址:GRIP全球道路数据库

上一篇下一篇

猜你喜欢

热点阅读