1. Why this page matters¶
Remote sensing imagery often needs context. A satellite image may show pixels, but your project may need buildings, roads, land-use polygons, administrative boundaries, reference samples or validation data to make the analysis meaningful.
In the previous page, you searched for raster imagery. This page focuses on vector and contextual data that can support the same project.
The next page explains how to document and cite both raster and vector sources.
2. Core idea¶
Vector data can support an SDS320 project in several roles:
| Role | Example |
|---|---|
| Study area definition | boundary polygon, city extent, protected area |
| Context | roads, rivers, land use, buildings |
| Training data | building footprints, road lines, labelled polygons |
| Validation data | independent reference points or polygons |
| Interpretation | administrative units, population context, infrastructure |
| Visualisation | map overlays, labels, location context |
The same vector dataset can be helpful for one project and misleading for another. You need to check completeness, date, geometry quality and licence.
3. Workflow¶
Step 1: Identify the role of vector data¶
Consider what you need the vector data for before downloading it.
Examples:
I need building footprints as context for interpreting model outputs.I need administrative boundaries to summarise predicted change by district.I need road data to compare detected linear features with mapped roads.This avoids collecting vector layers that do not support the analysis.
Step 2: Choose a vector source¶
Possible sources include:
| Source | Possible use |
|---|---|
| Overture Maps | Buildings, places, transportation, divisions and base features. |
| OpenStreetMap | Roads, buildings, amenities, land use and other volunteered map features. |
| National or regional open data portals | Official boundaries, cadastral layers, land-use data or infrastructure. |
| WRI / Global Nature Watch data platforms | Environmental monitoring and forest-related context data. |
| Project-specific datasets | Field data, labelled samples, provided training data or institutional data. |
Step 3: Access Overture Maps data¶
The GeoAI source material shows Overture Maps as a source for building footprints and other vector data. Overture data can be useful for buildings, places, transportation and other contextual features.
The geoai package offers two ways to access Overture data. Both rely on the overturemaps package, which is installed automatically as a dependency of geoai in the SDS320 environment. Both can take a few minutes to run depending on the size of your bounding box and your network speed.
Option A: Download to a file¶
download_overture_buildings() uses the Overture Maps CLI to download building footprints for a bounding box and save them to disk:
import os
import geoai
bbox = (8.53, 47.37, 8.54, 47.38) # example WGS84 bbox near Zurich
output_path = "buildings.geojson"
geoai.download_overture_buildings(
bbox=bbox,
output=output_path,
overture_type="building",
)
full_path = os.path.abspath(output_path)
file_size_mb = os.path.getsize(full_path) / (1024 * 1024)
print(f"Buildings saved to {full_path}")
print(f"File size: {file_size_mb:.2f} MB")The saved file size depends on the bounding box size and building density: a small test area like the one above is typically well under a megabyte, while a city-scale query can reach tens or hundreds of megabytes. Check the file size before scaling up your bounding box.
Option B: Load directly as a GeoDataFrame¶
For more flexibility, get_overture_data() returns the data directly as a GeoDataFrame, which is convenient for immediate inspection and filtering. It also supports other feature types beyond buildings, such as places, roads, land cover and water:
import geoai
bbox = (8.53, 47.37, 8.54, 47.38) # example WGS84 bbox near Zurich
buildings = geoai.get_overture_data(
overture_type="building",
bbox=bbox,
output="buildings.parquet",
)
print(f"Downloaded {len(buildings)} buildings")
buildings.head()Step 4: Access OSM-style data¶
While Overture Maps is increasingly popular for building footprints, OpenStreetMap (OSM) remains a valuable source for roads, points of interest, land-use polygons and many other features maintained by a global community of volunteers. In GeoAI projects, OSM data is commonly used to generate training labels for tasks such as road extraction, building detection and land-use classification.
The quackosm library uses DuckDB to extract OSM data efficiently from PBF files, and leafmap.osm provides convenient wrapper functions around it. You can query by bounding box, by place name or by a custom geometry.
To query by bounding box, use quackosm_gdf_from_bbox() with an OSM tag filter:
import leafmap.osm as osm
bbox = (8.53, 47.37, 8.54, 47.38) # example WGS84 bbox near Zurich
buildings_osm = osm.quackosm_gdf_from_bbox(bbox, tags={"building": True})
print(f"Downloaded {len(buildings_osm)} buildings")
buildings_osm.head()To query by place name, use quackosm_gdf_from_place():
roads = osm.quackosm_gdf_from_place("Basel, Switzerland", tags={"highway": True})
print(f"Downloaded {len(roads)} road segments")
roads.head()For more precise control over the query area, pass a Shapely geometry to quackosm_gdf_from_geometry():
from shapely.geometry import Polygon
polygon = Polygon([
(8.53, 47.37),
(8.54, 47.37),
(8.54, 47.38),
(8.53, 47.38),
])
natural = osm.quackosm_gdf_from_geometry(polygon, tags={"natural": True})
print(f"Downloaded {len(natural)} natural features")
natural.head()The quackosm functions accept any valid OSM tag for filtering. Common tags for GeoAI work include building, landuse, natural, waterway, highway and amenity.
Step 5: Access Swiss geodata¶
If your project area is in Switzerland, the federal geoportal map.geo.admin.ch is backed by a set of free public REST APIs from swisstopo. Most endpoints need no API key, which makes them convenient for use, but swisstopo does enforce rate limits on high-frequency requests.
The relevant services are:
| Service | Base URL | Purpose |
|---|---|---|
| Core REST API | api3.geo.admin.ch | Geocoding, the “identify” endpoint (query features at a point), feature search, height/elevation lookup. |
| STAC catalog | data.geo.admin.ch | Downloadable datasets such as orthophotos, elevation models and 3D building data. |
| WMTS tile service | wmts.geo.admin.ch | Map tiles and imagery, and the basis for shareable map.geo.admin.ch links. |
Because most of these endpoints are plain REST services, you can query them directly with requests, without a dedicated Python wrapper. The following example uses the “identify” endpoint with an envelope (bounding box) geometry to download the Suitability of roofs for the use of solar energy dataset, published by the Swiss Federal Office of Energy (SFOE), for a small residential quarter in Zurich, and loads the result directly into a GeoDataFrame:
import requests
import geopandas as gpd
from shapely.geometry import shape
identify_url = "https://api3.geo.admin.ch/rest/services/api/MapServer/identify"
bbox = "8.5470,47.3950,8.5490,47.3970" # small quarter in Zurich, WGS84
response = requests.get(
identify_url,
params={
"geometry": bbox,
"geometryType": "esriGeometryEnvelope",
"geometryFormat": "geojson",
"sr": 4326,
"layers": "all:ch.bfe.solarenergie-eignung-daecher",
"tolerance": 0,
"mapExtent": "8.50,47.35,8.60,47.45",
"imageDisplay": "800,600,96",
"returnGeometry": "true",
},
)
response.raise_for_status()
results = response.json()["results"]
roofs = gpd.GeoDataFrame(
[r["properties"] for r in results],
geometry=[shape(r["geometry"]) for r in results],
crs="EPSG:4326",
)
print(f"Downloaded {len(roofs)} roof facets")
roofs[["klasse_text", "flaeche", "stromertrag"]].head()Each roof facet carries a suitability class (klasse_text, ranging from low to top suitability), its area in square metres (flaeche) and an estimated annual electricity yield in kWh (stromertrag). This dataset is only offered as a single whole-of-Switzerland download through the STAC catalog, so for a small project area, querying by bounding box like this is more practical than downloading the full national file.
You can also query features at a specific point using the “identify” endpoint. This is useful for contextual lookups, for example checking whether a location sits on a mapped hiking trail:
identify_url = "https://api3.geo.admin.ch/rest/services/api/MapServer/identify"
response = requests.get(
identify_url,
params={
"geometry": "8.5480,47.3980",
"geometryType": "esriGeometryPoint",
"sr": 4326,
"layers": "all:ch.swisstopo.swisstlm3d-wanderwege",
"tolerance": 200,
"mapExtent": "8.50,47.35,8.60,47.45",
"imageDisplay": "800,600,96",
},
)
response.raise_for_status()
results = response.json()["results"]
print(f"Found {len(results)} nearby trail segments")
if results:
print(results[0]["attributes"])A third pattern is feature search: querying a layer’s attributes by name instead of by location. The following example searches the swisstopo district-boundary layer for districts named “Bern”:
find_url = "https://api3.geo.admin.ch/rest/services/api/MapServer/find"
response = requests.get(
find_url,
params={
"layer": "ch.swisstopo.swissboundaries3d-bezirk-flaeche.fill",
"searchText": "Bern",
"searchField": "name",
"returnGeometry": "false",
},
)
response.raise_for_status()
for feature in response.json()["results"]:
print(feature["attributes"]["name"], feature["attributes"]["flaeche"], "ha")Project check: direct API access is convenient for small, targeted lookups, such as a single quarter or a handful of points. For bulk downloads over a larger area, prefer the STAC catalog or an official bulk-download tool instead of looping over the REST API.
Step 6: Access global datasets¶
Alongside the specific sources above, a growing number of platforms curate global environmental and urban monitoring datasets, each with its own interactive map viewer. These are worth browsing manually first, since not every platform offers a convenient API, and a manual download through the browser is sometimes the most practical route into a project.
| Platform | What it offers | Explore |
|---|---|---|
| World Resources Institute (WRI) Data Explorer | A long-established, broad catalogue of curated environmental and socioeconomic datasets covering forests, water, cities, climate and land use. | wri.org/data |
| Global Nature Watch | A newer WRI platform for near-real-time, satellite-based monitoring of forest and land-cover change worldwide. | globalnaturewatch |
| Fields of the World (FTW) | A benchmark and interactive inference app for machine-learning-derived agricultural field boundaries, useful as training data or comparison in cropland-mapping projects. | fieldsofthe.world |
| Global Building Atlas (GBA) | AI-generated global building footprints and height data, viewable through a Google Earth Engine app. | sat |
A few more platforms worth knowing about:
ESA WorldCover, a global 10 m land-cover map with its own interactive viewer: esa-worldcover.org
The Awesome GEE Community Datasets catalogue, the same
sat-ioproject behind the Global Building Atlas, which hosts dozens of similar community-built Earth Engine apps for global monitoring themes: samapriya.github .io /awesome -gee -community -datasets
Step 7: Check vector data quality¶
After loading vector data, inspect it before using it.
print("Rows:", len(buildings))
print("CRS:", buildings.crs)
print("Geometry types:", buildings.geom_type.value_counts())
print("Bounds:", buildings.total_bounds)Also map a small sample with your imagery or basemap. Check whether the data align spatially and whether obvious features are missing.
Step 8: Save vector data¶
For project work, prefer robust and reproducible formats.
Common choices include:
| Format | Use |
|---|---|
| GeoPackage | Good general-purpose local vector format. |
| GeoParquet | Efficient for larger vector datasets and modern cloud workflows. |
| GeoJSON | Easy to inspect and share for small datasets. |
| Shapefile | Still common, but has quite some practical limitations. |
Record which format you used and why.
4. Python reactivation¶
Vector data workflows often use familiar GeoPandas operations:
# Inspect columns
buildings.columns
# Select useful columns
selected = buildings[["geometry"]].copy()
# Check approximate feature count
len(selected)If you calculate areas, make sure the data are in a projected CRS with metre-based units.
# Example only: use a suitable CRS for your own study area
buildings_projected = buildings.to_crs("EPSG:2056")
buildings_projected["area_m2"] = buildings_projected.area5. Common pitfalls¶
| Pitfall | How to avoid it |
|---|---|
| Treating vector data as complete truth | Check completeness and source limitations. |
| Ignoring CRS | Confirm that vector and raster data align before analysis. |
| Using huge vector datasets too early | Start with a small bounding box. |
| Using building footprints as labels without checking quality | Inspect alignment with imagery. |
| Forgetting licence and attribution | Record provider and reuse conditions. |
| Saving only processed data | Preserve notes about original source and access route. |
6. Mini task¶
Find one vector or contextual dataset for your project.
Write:
Dataset:
Provider:
Feature type:
Role in project:
Access method:
CRS:
Format:
Quality concern:
Licence or attribution note:
Decision:Sample solution
Dataset: Overture Maps buildings
Provider: Overture Maps
Feature type: building footprints
Role in project: context layer and possible validation support
Access method: bbox query through Overture tools or GeoAI helper function
CRS: check after download
Format: GeoParquet
Quality concern: completeness and alignment may vary by location
Licence or attribution note: check Overture documentation before publication
Decision: test small AOI and overlay on imagery7. Key takeaways¶
Vector data can define study areas, provide context, support labels or help evaluate outputs.
Choose vector data based on its role in your project.
Inspect completeness, CRS, geometry type and spatial alignment.
Start with a small area before downloading large vector datasets.
Document provider, access method, licence and limitations.