Как извлечь и визуализировать данные из файла OSM в Python
Я загрузил файл OpenStreetMap на свой рабочий стол и использовал свой OSM-файл в блокноте jupyter.
Мой код:
import xml.etree.cElementTree as ET
osm_file = "ahmedabad_india.osm"
for event, elem in ET.iterparse(osm_file, events=("start",)):
print(elem)
# prints the Element 'osm' at 0x03A7DC08>
#<Element 'bounds' at 0x03A7DDA0>
#<Element 'node' at 0x03A7DE90>
#<Element 'tag' at 0x03A7DF08> and so on ...
Я хотел бы увидеть содержимое всех tags
т.е. <'node', 'id', 'name', ...>
и так далее.
Я пытался с помощью elem
тег, но ничего не печатает.
Может ли кто-нибудь помочь мне выяснить, кто получить содержимое тегов, таких как узел, пути и т. Д.
2 ответа
Вы можете извлечь все данные из .osm
файл через PyOsmium (быстрая и гибкая библиотека C++ для работы с данными OpenStreetMap) и затем обрабатывает его с помощью Pandas:
Код:
import osmium as osm
import pandas as pd
class OSMHandler(osm.SimpleHandler):
def __init__(self):
osm.SimpleHandler.__init__(self)
self.osm_data = []
def tag_inventory(self, elem, elem_type):
for tag in elem.tags:
self.osm_data.append([elem_type,
elem.id,
elem.version,
elem.visible,
pd.Timestamp(elem.timestamp),
elem.uid,
elem.user,
elem.changeset,
len(elem.tags),
tag.k,
tag.v])
def node(self, n):
self.tag_inventory(n, "node")
def way(self, w):
self.tag_inventory(w, "way")
def relation(self, r):
self.tag_inventory(r, "relation")
osmhandler = OSMHandler()
# scan the input file and fills the handler list accordingly
osmhandler.apply_file("muenchen.osm")
# transform the list into a pandas DataFrame
data_colnames = ['type', 'id', 'version', 'visible', 'ts', 'uid',
'user', 'chgset', 'ntags', 'tagkey', 'tagvalue']
df_osm = pd.DataFrame(osmhandler.osm_data, columns=data_colnames)
df_osm = tag_genome.sort_values(by=['type', 'id', 'ts'])
Выход:
Вот полное объяснение загрузки функций из OSM и их визуализации на Python. Я не рекомендую писать Python для чтения файлов, потому что существует множество простых в использовании программ (например, GDAL), которые сделают это за вас.
Вам не нужно индивидуально обрабатывать узлы, пути и связи, чтобы использовать данные OpenStreetMap.
1. Выберите объект из OpenStreetMap.
Все функции помечены метаданными, такими как имя (
name=Starbucks
), тип здания () или часы работы (
opening_hours=Mo-Fr 08:00-12:00,13:00-17:30
) . Например, римский Колизей помечен так:
Чтобы загрузить подмножество функций OSM, сначала определите список ключей тегов и (необязательно) значений для фильтрации. Например, все рестораны с названиями будут отфильтрованы поamenity=restaurant
иname=*
.
Полезными ресурсами для изучения тегов, подходящих для вашего случая использования, являются веб-сайт OSM TagInfo и OSM Wiki.
В этом примере мы загрузим и визуализируемbuilding=university
.
2. Загрузите соответствующие функции
Существует три основных способа загрузки данных из OpenStreetMap, каждый из которых имеет свои плюсы и минусы.
а. Загрузка функций из OpenStreetMap с использованием API
Этот метод наименее ресурсоемкий (не требуется сервер), не требует установки GDAL и может быть реализован на всей планете. Требуется бесплатный ключ API для стороннего API извлечения OSM .
-
curl
/wget
до конечной точки и укажите функции для загрузки
curl --get 'https://osm.buntinglabs.com/v1/osm/extract' \
--data "tags=building=university" \
--data "api_key=YOUR_API_KEY" \
-o university_buildings.geojson
При этом загружаются все функции на планете, удовлетворяющие вашемуtags=
фильтровать как GeoJSON дляuniversity_buildings.geojson
.
Вам не нужно конвертировать файлы разных форматов. Если вам нужен небольшой отрывок, вы можете передатьbbox=
параметр и создайте ограничивающую рамку в bboxfinder .
б. Загрузите регион как и вручную извлеките его локально.
Этот метод можно выполнить на 100% локально, но для этого потребуется использовать небольшой регион (максимум ~10 районов) и .
Увеличьте масштаб и загрузите файл из OpenStreetMap Extract . Это будет большой файл, поскольку он в формате XML.
Файл фильтра для функций, которые вы хотите сохранить. См. ниже (c.), например, с
osmium
.Используйте ogr2ogr для преобразования в . Этот шаг сложен, поскольку GDAL хранит точки, линии и полигоны как отдельные полигоны. В этом уроке показано, как конвертировать
.osm
к , или см., например, ниже (c.).
в. Скачать планету как.osm.pbf
и извлечь на сервер
Этот метод ресурсоемок и требует более 100 ГБ дискового пространства, ~2 дня обработки и более 64 ГБ оперативной памяти. Однако он позволяет вам обыскивать всю планету. Требуется установить GDALустановка GDAL .
Торрент
planet.osm.pbf
или загрузите выдержку региона из Geofabrik Extracts.Отфильтруйте целевые функции, используя
osmium-tags-filter
:
osmium tags-filter -o university_buildings.osm.pbf planet.osm.pbf nwr/building=university
- Преобразуйте
university_buildings.osm.pbf
файл в.geojson
В зависимости от размера выходного файла он может быть слишком большим для GeoJSON (текстового), и вместо этого вам следует использовать GeoPackage (.gpkg
) или FlatGeobuf (.fgb
).
ogr2ogr -f GeoJSON output_points.json input.osm.pbf points
ogr2ogr -f GeoJSON output_lines.json input.osm.pbf lines
# ... continue for multilinestrings, multipolygons and other_relations
Тогда присоединяйтесь кoutput_points.json
,output_lines.json
и т. д. сogrmerge.py
.
3. Визуализация функций
После загрузки рекомендуется загрузить данные в geopandas — расширение pandas со встроенной пространственной поддержкой. Это самый простой способ визуализации пространственных данных в Python.
Мы загрузим данные вGeoDataFrame
а затем постройте его с помощью matplotlib :
import matplotlib.pyplot as plt
import geopandas as gpd
# Read our downloaded file from earlier
gdf = gpd.read_file('university_buildings.geojson', driver='GeoJSON')
# Plot and individually add each building name
ax = gdf.plot()
for x, y, label in zip(gdf.centroid.x, gdf.centroid.y, gdf.name):
ax.annotate(label, xy=(x, y), xytext=(3, 3), textcoords="offset points")
plt.show()
Это дает такой результат: