引言
最近在项目中需要使用地理空间信息来辅助进行聚类工作,除了常规的经纬度信息之外,还需要更重要的地理层级信息,如对于“都江堰”来进行查询,期望获得“都江堰,成都,中国”这样一个完整的地理层级关系。因此,在这两天笔者便研究了一下如何获得这样的信息。
使用geopy包来实现
工程中用的是Python2,而在python中也确实有现有的包可以实现这样的功能,比如一个常用的包是geopy
。
其使用方法如下:
# -*- coding: utf-8 -*-
from geopy.geocoders import Nominatim
geolocator = Nominatim()
location = geolocator.geocode("dujiangyan")
print (location.address)
程序输出:
都江堰市, 都江堰市 / Dujiangyan, 成都市 / Chengdu, 四川省, 中国
可以看到,确实输出了一串地理层级信息,而且其中也确实包含了我们想要的正确的结果,但是结构非常的不标准,这样的结构在之后的操作中,想要处理成方便程序使用的形式是有些困难的,因为有很多地名会输出各种意想不到的结果的形式。
还有一点问题是,这个包是通过在线查询来返回结果的,而每次返回所需的时间大约是数秒级别的,如果是单次的查询,那么这个时间是完全可以接受的,而若大批量的查询,特别是需要实时效果的话,这种方法就难以获得理想的效果了。
而在尝试过几个包之后,发现这个包的效果其实已经相对较好了。在以前曾经用过谷歌的地理信息查询服务,但是谷歌提供的接口目前开始收费了,所以笔者又把目光放向了开源的OpenStreetMap。
下载OpenStreetMap的地图包
OpenStreetMap是一款开源的,由网络大众共同打造的地图服务,而且是知名度最高、应用最为广泛的开源地图之一,在前一部分所介绍的geopy
包里的一部分返回数据就是通过这个开源地图得到的。而且,OpenStreetMap由于是开源地图,是提供地图的下载的。
要下载OSM上的地图,我们可以在这个网址直接下载:
http://download.geofabrik.de/index.html
进入页面之后,可以看到按大洲下载地图的链接,也可以从左边某个大洲点进去,下载某个国家的地图,如我们进入“Asia”,然后下载中国的地图。
可以看到,在下载中,有三个可选项,分别是.osm.pbf、.shp.zip、.osm.bz3,在这里,我们需要的是.osm文件中的信息,而第一项和第三项都是.osm文件的压缩形式,其中,.bz2是可以直接解压缩的,但是大小是.pbf的1.5到2倍左右。需要下载哪一项,大家可以自己斟酌。
如果下载的是.pbf文件,是需要一个专门的工具来将.pbf文件转换成.osm文件的,这个工具可以在这里下载:https://wiki.openstreetmap.org/wiki/Osmconvert
pbf文件转换
工具本身非常小,下载下来之后,放入存储下载数据的文件夹(即存储.pbf文件的文件夹,推荐所在分区留出较多空间,因为可能占用较多空间),然后打开之后是一个命令行操作的界面。这时,可以用如下的命令直接进行转换:
osmconvert syria-latest.osm.pbf --out-osm -o=syria-latest.osm_01.osm
当然,工具本身也比较方便,无需记忆命令,先按照提示键入a
,然后程序会询问要处理哪个文件,这时键入文件的全名,之后程序会询问需要对该文件进行什么操作,这时键入1
,选择要对文