OSM的道路圖
Table of contents
背景
- How to download OSM data in specified region with specific tag (I.E. highway)( 2020 Nov ‘15, 04:45)這個網頁討論的主題是如何從OpenStreetMap(OSM)下載指定區域的數據並過濾特定標籤(例如“highway”標籤)。討論中的建議方案包括:
- 使用Overpass-Turbo:這是一個線上工具,可以用來查詢和下載特定區域和標籤的OSM數據。
- 使用 Geofabrik 或 BBBike :這些網站提供預先打包的shapefile,但無法選擇特定標籤。
- 手動創建shapefile:下載OSM數據並使用工具如 osm2pgsql 和 pgsql2shp 來創建shapefile,或者直接使用 ogr2ogr 來轉換。
overpass-turbo
切割站台
#網址規則
https://overpass-turbo.eu/?Q=
/* This has been generated by the overpass-turbo wizard. The original search was:
“type=route & route=bus” */
/[out:json][timeout:25];
// gather results
(
// query part for: “type=route and route=bus”
way[highway]();
);
// print results
out body;
>;
out skel qt;
&C=51.18533;3.56321;16
url="https://overpass-api.de/api/interpreter?data=%2F%2F%20%40name%20songshanAirport%0A%0A%2F*%0AThis%20has%20been%20generated%20by%20the%20overpass-turbo%20wizard.%0AThe%20original%20search%20was%3A%0A%E2%80%9Ctype%3Droute%20%26%20route%3Dbus%E2%80%9D%0A*%2F%0A%5Bout%3Ajson%5D%5Btimeout%3A25%5D%3B%0A%2F%2F%20gather%20results%0A%28%0A%20%20%2F%2F%20query%20part%20for%3A%20%E2%80%9Ctype%3Droute%20and%20route%3Dbus%E2%80%9D%0A%20%20way%5Bhighway%5D%2825.06289035627052%2C121.54017305374147%2C25.07091380670631%2C121.56654024124147%29%3B%0A%29%3B%0A%2F%2F%20print%20results%0Aout%20body%3B%0A%3E%3B%0Aout%20skel%20qt%3B"
source
- source code
- main author:
- Martin Raifer(tyr_asd)
- HeiGIT: Heidelberg, DE
json format
import json
import xml.etree.ElementTree as ET
# 載入 Overpass API 的 JSON 數據
with open('overpass_output.json') as f:
data = json.load(f)
# 創建 OSM 根元素
osm = ET.Element('osm', version='0.6')
# 將 JSON 數據轉換為 OSM XML
for element in data['elements']:
if element['type'] == 'node':
node = ET.SubElement(osm, 'node', id=str(element['id']), lat=str(element['lat']), lon=str(element['lon']))
elif element['type'] == 'way':
way = ET.SubElement(osm, 'way', id=str(element['id']))
for nd in element['nodes']:
ET.SubElement(way, 'nd', ref=str(nd))
elif element['type'] == 'relation':
relation = ET.SubElement(osm, 'relation', id=str(element['id']))
for member in element['members']:
ET.SubElement(relation, 'member', type=member['type'], ref=str(member['ref']), role=member.get('role', ''))
# 將 OSM XML 寫入檔案
tree = ET.ElementTree(osm)
tree.write('output.osm', encoding='utf-8', xml_declaration=True)
- Overpass API切割結果似乎沒有relations
In [14]: set([ element['type'] for element in data['elements']])
Out[14]: {'node', 'way'}
Geofabrik
下載台灣地區的 OpenStreetMap 資料
此伺服器上提供的 OpenStreetMap 資料檔案不包含OSM 物件的使用者名稱、使用者 ID 和變更集 ID,因為這些欄位被假定包含有關 OpenStreetMap 貢獻者的個人信息,因此受歐盟資料保護法規的約束。 包含完整元資料的摘錄僅供 OpenStreetMap 貢獻者使用。
常用格式
- taiwan-latest.osm.pbf,適用於 Osmium、Osmosis、imposm、osm2pgsql、mkgmap 等。文件的最後修改時間為 1 天前,包含截至 該時間 的所有 OSM 資料。檔案大小:275 MB; MD5 總和:17bf64369467e02da9a4753fe6335414。
- taiwan-latest-free.shp.zip,解壓縮後會產生許多與 ESRI 相容的形狀檔。(格式說明PDF)該文件最後修改時間為23小時前。檔案大小:203 MB; MD5 總和:723227f0761ef8b02e950e055798a007。
其他格式和輔助文件
- taiwan-latest.osm.bz2,解壓縮後產生OSM XML;用於無法處理 .pbf 格式的程式。已棄用。該文件的最後修改時間是 100 天前。檔案大小:351 MB; MD5 總和:f511eee6b138a9a45f88d4ddd55e28cb。
- taiwan-internal.osh.pbf 歷史文件包含個人數據,僅在內部伺服器上可用。請參閱上面的通知以了解更多資訊。
- 描述該區域範圍的.poly 檔案。
- 符合Shortbread 架構的實驗性向量切片包,可與 MapLibre 和其他支援 MVT 的軟體一起使用
- .osc.gz 檔案包含該區域中的所有更改,適用於 Osmosis 更新等
- 該地區的 Taginfo 統計信息
- 原始目錄索引可讓您查看和下載舊文件
次區域
沒有為此區域定義子區域。
file_stats
(py39) 21:15@kuang:~/MyPrograms/CADN-A
$ python osm_file_stats.py taiwan-latest.osm
Nodes: 21,366,772
Ways: 1,533,433
Relations: 37,756
Cutter
- 使用 osmium模組
serial
parallel
(py39) 20:12@kuang:~/MyPrograms/CADN-A
$ cat cut_osmMult2.py
import osmium
import multiprocessing
class BoundingBoxHandler(osmium.SimpleHandler):
def __init__(self, min_lat, min_lon, max_lat, max_lon, output_file):
super().__init__()
self.min_lat = min_lat
self.min_lon = min_lon
self.max_lat = max_lat
self.max_lon = max_lon
self.writer = osmium.SimpleWriter(output_file)
def node(self, n):
if self.min_lat <= n.location.lat <= self.max_lat and self.min_lon <= n.location.lon <= self.max_lon:
self.writer.add_node(n)
def way(self, w):
if any(self.min_lat <= n.lat <= self.max_lat and self.min_lon <= n.lon <= self.max_lon for n in w.nodes):
self.writer.add_way(w)
def relation(self, r):
if any(self.min_lat <= n.lat <= self.max_lat and self.min_lon <= n.lon <= self.max_lon for n in r.nodes):
self.writer.add_relation(r)
def close(self):
self.writer.close()
def process_bbox(min_lat, min_lon, max_lat, max_lon, input_file, output_file):
handler = BoundingBoxHandler(min_lat, min_lon, max_lat, max_lon, output_file)
handler.apply_file(input_file)
handler.close()
def divide_bbox(min_lat, min_lon, max_lat, max_lon, num_parts):
lat_step = (max_lat - min_lat) / num_parts
lon_step = (max_lon - min_lon) / num_parts
bboxes = []
for i in range(num_parts):
for j in range(num_parts):
bboxes.append((min_lat + i * lat_step, min_lon + j * lon_step,
min_lat + (i + 1) * lat_step, min_lon + (j + 1) * lon_step))
return bboxes
if __name__ == '__main__':
# 設定經緯度範圍
min_lat = 25.0562234
min_lon = 121.5332504
max_lat = 25.0792724
max_lon = 121.5712818
# 分割經緯度範圍
num_parts = 3 # 這裡設置為3x3的區塊
bboxes = divide_bbox(min_lat, min_lon, max_lat, max_lon, num_parts)
# 使用多進程處理每個區塊
processes = []
for i, bbox in enumerate(bboxes):
p = multiprocessing.Process(target=process_bbox, args=(bbox[0], bbox[1], bbox[2], bbox[3], 'input.osm', f'output_{i}.osm'))
processes.append(p)
p.start()
for p in processes:
p.join()
使用 osmconvert
- install:
sudo apt install osmctools
first cut
ln -s taiwan-latest.osm input.osm left=121.5332504 right=121.5712818 top=25.0792724 bottom=25.0562234 osmconvert input.osm -b=${left},${bottom},${right},${top} --complete-ways -o=output.osm
further cutting
mv output.osm output48.osm ln -sf output48.osm input.osm echo ${left},${bottom},${right},${top} left=121.5432504 right=121.5612818 top=25.07 bottom=25.0662234 osmconvert input.osm -b=${left},${bottom},${right},${top} --complete-ways -o=output.osm
- view by aspose
convert to KML and view
fail using ogr2ogr
ogr2ogr -f "KML" output.kml input.osm
- try python
- s
BBBike
Onlne Viewers
aspose.app
- upload and save as png
- limitations
- size: 32MB
- time interval between uploadings: 2min
- output_0.osm(3X3的西南角)
MyGeodata.Cloud
- upload .osm data and
- conversion to pdf: 5mb/month
- viewing on map and save png
- Songshan Airport from taiwan-latest.osm