1.1 OSM历史数据获取
(1)OSM历史数据可在https://osm-internal.download.geofabrik.de/index.html获取,以美国数据为例,最小只能获取到某个州的整体数据,具体到某个市的数据可通过裁剪整个州的数据获取。
(2)以获取美国Portland市为例,按顺序点击红色框内超链接,到达Oregon州的OSM数据获取页面
(3)点击raw_directory_index就会出现下方的表格,按照需要的年份点击相应的超链接即可下载。(上方的oregon-internal.osh.pbf,包含所有年份的osm数据,需要登录osm账号之后进入internal server才可下载,且要使用osmium或其他插件/软件操作)
1.2 .osm.pbf转.shp
获取到 .osm.pbf文件后需要转换成.shp文件才方便通过ArcGIS等工具获取到其数据,数据转换可以在https://geoconverter.infs.ch/使用GeoConvert进行转换
1.3 指定城市的行政区划获取
以美国Oregon州的Portland市为例
(1)用ArcGIS打开转换后得到的shp文件夹内的multipolygons.shp文件
(2)打开属性表,在name那一列搜索Portland,找到type为boundary的面即为Portland市的行政区划
1.4 路网数据获取
osm内的lines.shp和multilinestring.shp内有osm路网数据,根据行政区划对这两个shp文件进行裁剪即可得到Portland市的路网数据。
osm道路类别及解释:https://wiki.openstreetmap.org/wiki/Zh-hans:Map_Features#Abutters
1.5 POI数据获取及处理
osm的poi数据存放在points.shp下,根据行政区划在ArcGIS使用空间关联工具,判断points是否在Portland市行政区划内(within)来获取Portland市内的points数据。根据https://wiki.openstreetmap.org/wiki/Zh-hans:Map_Features#Abutters,选择amenity(设施)、shop(商店)、historic(历史文物)、sport(运动)四大类poi进行提取。(别人好像只用amenity就够了)
由于points的类别信息都在"other_tags"字段下以一长串的字符串形式存在,使用python进行处理,其实就是取两指定字符串之间的字符串
import pandas as pd
import re
m = pd.read_csv("F:\\portland crime data\\portland_poi_way\\points\\portland_pois.csv")
m[['amenity', 'shop','historic', 'sport']] = ''
for i in range(m.shape[0]):
if '\"amenity\"=>' in m.loc[i, 'other_tags']:
m.loc[i, 'amenity'] = re.findall("\"amenity\"=>\"(.*?)\"",m.loc[i, 'other_tags'])[0]
if '\"shop\"=>' in m.loc[i, 'other_tags']:
if re.findall("\"shop\"=>\"(.*?)\"",m.loc[i, 'other_tags']):
m.loc[i, 'shop'] = re.findall("\"shop\"=>\"(.*?)\"",m.loc[i, 'other_tags'])[0]
else:
print(i)
if '\"historic\"=>' in m.loc[i, 'other_tags']:
m.loc[i, 'historic'] = re.findall("\"historic\"=>\"(.*?)\"",m.loc[i, 'other_tags'])[0]
if '\"sport\"=>' in m.loc[i, 'other_tags']:
m.loc[i, 'sport'] = re.findall("\"sport\"=>\"(.*?)\"",m.loc[i, 'other_tags'])[0]
if '\"military\"=>' in m.loc[i, 'other_tags']:
print(1)
m.loc[i, 'military'] = re.findall("\"military\"=>\"(.*?)\"",m.loc[i, 'other_tags'])[0]
if '\"natural\"=>' in m.loc[i, 'other_tags']:
m.loc[i, 'natural'] = re.findall("\"natural\"=>\"(.*?)\"",m.loc[i, 'other_tags'])[0]
以"amenity"=>“fast_food"为例,当这一串字符串出现在末尾时,可能会出现末尾的"丢失。使用re.findall(”“amenity”=>“(.*?)”“,m.loc[i, ‘other_tags’])是将"amenity”=>"和"之间的字符串以列表形式[‘fast_food’]返回,末尾缺失"时会返回空列表[],导致取值时报错,所以需要判断提取到的列表是否为空。(这里的数据只有shop有这个问题,所以只对shop进行了判断)
1.6 其他问题
(1)在使用ArcGIS的表至表将属性表直接转成csv文件可能会出现数据缺失、格式错误的问题,建议使用shapefile库将相应的属性表提取出来,用pandas库的DataFrame存储成csv文件。建议修改数据也用pandas进行操作,直接操作csv文件也会出现问题导致pandas读不回去了
(2)对于1.5中列表为空的情况,暂时的解决方法是在为空时print一下看看具体是哪行出问题,再进行具体赋值,暂时没想到什么好方法。