OpenStreetMap#

Cet ensemble de données est externe à la plateforme Digital Earth Africa.

Aperçu#

OpenStreetMap <https://www.openstreetmap.org/> est une base de données géographique gratuite et ouverte, fournissant des informations sur la localisation des routes, des bâtiments et des points de repère. Elle est construite, maintenue et soutenue par une communauté géospatiale mondiale.

Les données OpenStreetMap sont sous licence Open Data Commons Open Database License (ODbL) par la Fondation OpenStreetMap (OSMF). Il est libre de copier, distribuer, transmettre et adapter les données, en mentionnant OpenStreetMap et ses contributeurs. Les informations complètes sur la licence et les directives d’attribution sont disponibles sur la page OpenStreetMap’s Copyright and License page.

Description#

Ce bloc-notes montrera comment accéder aux données OpenStreetMap à l’aide du package Python `osmnx <https://osmnx.readthedocs.io/en/stable/osmnx.html>`__.

Commencer#

Pour exécuter cette analyse, exécutez toutes les cellules du bloc-notes, en commençant par la cellule « Charger les packages ».

Charger des paquets#

Importez les packages Python utilisés pour l’analyse.

[1]:
try:
    import duckdb
except ImportError:
    !pip install duckdb
    import duckdb

from shapely import from_wkb
import geopandas as gpd

Nous utiliserons le package duckdb pour accéder aux données OpenStreetMap et les visualiser avec geopandas. Nous devons d’abord nous connecter à DuckDB et définir certains paramètres.

[2]:
# Connect to DuckDB and load spatial/http modules
con = duckdb.connect()
con.execute("INSTALL spatial; LOAD spatial;")
con.execute("INSTALL httpfs; LOAD httpfs;")

con.execute("SET s3_region='us-west-2';")
con.execute("SET s3_access_key_id='';")
con.execute("SET s3_secret_access_key='';")

# Fetch latest release string automatically
latest_release = con.execute(
    "SELECT latest FROM 'https://stac.overturemaps.org/catalog.json'"
).fetchone()[0]

Paramètres d’analyse#

Cette section définit les paramètres d’analyse, notamment :

  • central_lat, central_lon, buffer : latitude/longitude centrales et taille de la fenêtre d’analyse pour la zone d’intérêt

L’emplacement par défaut est à Johannesburg, en Afrique du Sud.

[3]:
# Set the central latitude and longitude.
central_lat = -26.2041
central_lon = 28.0473

# Set the buffer to load around the central coordinates.
buffer = 0.05

# Compute the bounding box for the study area.
xmin, xmax = central_lon - buffer, central_lon + buffer
ymin, ymax = central_lat - buffer, central_lat + buffer

bbox = (xmin, ymin, xmax, ymax)

Récupérer les géométries des bâtiments à partir d’OpenStreetMap#

Différents types de géométries peuvent être interrogés en modifiant la classe dans la requête et l’URL. Dans ce cas, nous sélectionnons toutes les empreintes au sol des bâtiments dans la zone.

À l’aide de l’emplacement et des balises, les géométries seront récupérées à partir d’OpenStreetMap et les résultats seront renvoyés sous forme de GeoDataFrame Geopandas.

[4]:
# Query OpenStreetMap vector data hosted on AWS S3
query = f"""
SELECT
    id,
    names.primary AS name,
    class AS building_type,
    height,
    geometry
FROM read_parquet('s3://overturemaps-us-west-2/release/{latest_release}/theme=buildings/type=building/*')
WHERE bbox.xmin >= {xmin} AND bbox.xmax <= {xmax}
  AND bbox.ymin >= {ymin} AND bbox.ymax <= {ymax}
"""

df = con.execute(query).fetchdf()

# Convert WKB bytes to Shapely geometry objects
df['geometry'] = df['geometry'].apply(lambda g: from_wkb(bytes(g)) if g else None)

# Build GeoDataFrame
geometries = gpd.GeoDataFrame(df, geometry='geometry', crs="EPSG:4326")

Ensuite, nous vérifions les premières lignes des géométries que nous avons chargées pour les empreintes au sol des bâtiments.

[5]:
# Display the first five building records.
geometries.head()
[5]:
id name building_type height geometry
0 aafca274-d2c3-4f1c-874a-848ef1f33244 None None NaN POLYGON ((27.99768 -26.24087, 27.99771 -26.240...
1 9be17437-90a4-4129-ad05-63e335844c8c None None NaN POLYGON ((27.99768 -26.24169, 27.99757 -26.241...
2 50ea7281-0f41-4d0f-b5a0-671d60606f0a None None NaN POLYGON ((27.99765 -26.24198, 27.99764 -26.242...
3 7ea6bfe2-e9af-40a2-bd8a-9659c37df5b1 None None NaN POLYGON ((27.99744 -26.24225, 27.99737 -26.242...
4 912e634e-4e71-4a05-8549-70b926d45ff3 None None NaN POLYGON ((27.99764 -26.24231, 27.99752 -26.242...
[6]:
#fill building_type = None
geometries['building_type_filled'] = geometries['building_type'].fillna('unspecified')

#visualize the geometries retrieved
geometries.plot(figsize=(10,12), cmap='tab20', column='building_type_filled', legend=True, legend_kwds={'bbox_to_anchor':(1.25,1)});
../../../_images/sandbox_notebooks_Datasets_OpenStreetMap_14_0.png

Récupérer les géométries routières à partir d’OpenStreetMap#

Les réseaux routiers peuvent être récupérés à l’aide de la balise « highway ». Une liste de valeurs de balise peut être utilisée pour sélectionner des types spécifiques de géométries.

Les valeurs de balise pour « highway » et leurs descriptions peuvent être trouvées sur https://wiki.openstreetmap.org/wiki/OpenStreetMap_Carto/Lines

[7]:
# Query OpenStreetMap vector data hosted on AWS S3
query = f"""
SELECT
    id,
    names.primary AS name,
    class AS highway,
    geometry
FROM read_parquet('s3://overturemaps-us-west-2/release/{latest_release}/theme=transportation/type=segment/*')
WHERE bbox.xmin >= {xmin} AND bbox.xmax <= {xmax}
  AND bbox.ymin >= {ymin} AND bbox.ymax <= {ymax}
"""

df = con.execute(query).fetchdf()

# Convert WKB bytes to Shapely geometry objects
df['geometry'] = df['geometry'].apply(lambda g: from_wkb(bytes(g)) if g else None)

# Build GeoDataFrame
geometries = gpd.GeoDataFrame(df, geometry='geometry', crs="EPSG:4326")
[8]:
#print the first few rows
geometries.head()
[8]:
id name highway geometry
0 98bb3b8c-5d1c-4462-90a3-164af738c8d5 None service LINESTRING (28.0072 -26.25237, 28.00731 -26.25...
1 3661d160-4fe4-4590-b95b-6076fd2e4d5a None service LINESTRING (28.0076 -26.25192, 28.0076 -26.252...
2 8b4b56ef-9d38-4233-baa6-a5942aeecb5d Caro Street residential LINESTRING (28.00719 -26.25194, 28.0076 -26.25...
3 00aaa097-4405-405c-b716-de45b439a6a4 Tilrae Drive residential LINESTRING (28.00643 -26.25196, 28.00689 -26.2...
4 b244db64-ae95-49f2-ac0c-2f87d013e12b Limerick Road residential LINESTRING (28.00635 -26.25015, 28.00639 -26.2...
[9]:
#visualize the geometries retrieved

highway_types = geometries['highway'].dropna().unique().tolist()

geometries.dropna(subset=['highway']).plot(figsize=(10, 12), cmap='tab10', column='highway', categorical=True, categories=highway_types, legend=True);
../../../_images/sandbox_notebooks_Datasets_OpenStreetMap_18_0.png

Informations Complémentaires#

Licence : Le code de ce carnet est sous licence Apache, version 2.0 <https://www.apache.org/licenses/LICENSE-2.0>. Les données de Digital Earth Africa sont sous licence Creative Commons par attribution 4.0 <https://creativecommons.org/licenses/by/4.0/>.

Ce notebook accède aux données OpenStreetMap, par conséquent, lors du partage des résultats d’analyse, l’attribution doit suivre les directives de la page « Copyright et licence d’OpenStreetMap » <https://www.openstreetmap.org/copyright>.

Contact : Si vous avez besoin d’aide, veuillez poster une question sur le canal Slack Open Data Cube <http://slack.opendatacube.org/>`__ ou sur le GIS Stack Exchange en utilisant la balise open-data-cube (vous pouvez consulter les questions posées précédemment ici). Si vous souhaitez signaler un problème avec ce bloc-notes, vous pouvez en déposer un sur Github.

Version de Datacube compatible :

[10]:
import datacube
print(datacube.__version__)
1.9.13

Dernier test :

[11]:
from datetime import datetime
datetime.today().strftime('%Y-%m-%d')
[11]:
'2026-07-23'