Skip to content

Add Overture data source support#541

Merged
bdon merged 63 commits intoprotomaps:mainfrom
migurski:migurski/add-overture-basemap-source
Mar 2, 2026
Merged

Add Overture data source support#541
bdon merged 63 commits intoprotomaps:mainfrom
migurski:migurski/add-overture-basemap-source

Conversation

@migurski
Copy link
Collaborator

@migurski migurski commented Jan 3, 2026

Add basemap support for Overture Maps input data as alternative to OSM extracts. Port kind=/kind_detail=/min_zoom= mappings with no changes to MapLibre styles.

Layers

All Protomaps layers except for Boundaries and Transit have some coverage in this PR.

POIs

  • Overture theme=places basic_category mapped to Protomaps kind, with limited exceptions
  • No OSM-style polygon area grading is available for POI importance
  • Future work:
    • Can we use QRank to find high-priority POIs?
    • Try filtering by Overture confidence scores to eliminate bad POIs

Roads

  • Rendering includes theme=transportation type=segment subtype=road, subtype=rail, and subtype=water
  • Overture class and subclass mapped to Protomaps kind, kind_detail, and internal highway
  • Uses linear referencing from Overture array properties like road_flags to split linestrings on bridge, tunnel, and level flags to match rendering of OSM basemap
  • No features for airport runways are available

Places

  • Rendering includes high-zoom places like cities and neighborhoods from theme=places
  • Future work:
    • Include low-zoom places like states and countries

Buildings

  • Rendering includes both theme=buildings type=building and type=building_part to match Protomaps visual style

Landuse

  • Rendering includes theme=base type=land_use to match Protomaps visual style

Earth, Water, and Land Cover

  • Rendering uses theme=base type=land, type=water, type=land_cover to match Protomaps visual style
  • Future work:
    • Reduce excessive labels displayed for water bodies
    • Fix visual appearance of grainy land cover at low zooms

Testing

Extract Overture data with e.g. DuckDB:

COPY (
    SELECT *
    FROM read_parquet(
        's3://overturemaps-us-west-2/release/2025-12-17.0/**/*.parquet',
        hive_partitioning=1, filename=1, union_by_name=1
    )
    WHERE theme IN ('transportation', 'places', 'base', 'buildings', 'divisions')
      AND bbox.xmin <= -121
      AND bbox.xmax >= -123
      AND bbox.ymin <= 38
      AND bbox.ymax >= 37
) TO 'data/sources/bay-area.parquet' (FORMAT PARQUET);

Generate PMTiles from Overture data:

java -jar target/protomaps-basemap-HEAD-with-deps.jar \
    --overture=data/sources/bay-area.parquet --download --force

Run the app/ map frontend or one of the HTML examples to preview.

Screenshots

Taken from interactive preview at mike.teczno.com; compare with OSM data at maps.protomaps.com.

Screenshot 2026-01-03 at 3 24 25 PM

Screenshot 2026-01-03 at 3 24 48 PM

Screenshot 2026-01-03 at 3 25 06 PM

Screenshot 2026-01-03 at 3 25 25 PM

Screenshot 2026-01-03 at 3 25 56 PM

Screenshot 2026-01-03 at 3 26 18 PM

Flavor Compatibility

The changes in this PR map Overture properties to existing Protomaps conventions with no changes to styles, so all five of the included flavors are compatible: black, grayscale, white, light, and dark.

Screenshot 2026-01-03 at 3 38 32 PM Screenshot 2026-01-03 at 3 38 46 PM Screenshot 2026-01-03 at 3 38 03 PM Screenshot 2026-01-03 at 3 39 58 PM Screenshot 2026-01-03 at 3 39 01 PM

@migurski migurski force-pushed the migurski/add-overture-basemap-source branch from a905299 to 03a5d92 Compare January 5, 2026 19:09
@danabauer
Copy link

This is awesome, @migurski. /cc @jonahadkins

migurski and others added 28 commits January 12, 2026 08:52
…and line splitting

- Updated 6 existing tests to include access_restrictions and road_flags data
- Added 6 new splitting tests for partial bridge/tunnel/oneway/level application
- Tests use simple geometries (0,0)-(1,0) for easy verification
- All 12 tests failing as expected (property extraction and splitting not yet implemented)
- References real Overture feature IDs and OSM way IDs in comments
…way/level properties

Major Changes:
- Created com.protomaps.basemap.geometry.Linear utility class for line splitting operations
- Rewrote Roads.processOverture() to handle fractional 'between' ranges from Overture data
- Implemented collectSplitPoints() to gather all split positions from road_flags, access_restrictions, and level_rules
- Implemented extractSegmentProperties() to determine which properties apply to each split segment
- Added emitRoadFeature() to create features with custom split geometries

Results:
- 15/21 tests now passing (6 original property extraction tests now pass)
- 6 splitting tests create correct features with correct attributes and geometries
- Only remaining issue: cosmetic Norm{} wrapper in test assertions (geometries are actually correct)

Implementation handles:
- Partial bridges via road_flags with 'is_bridge' flag
- Partial tunnels via road_flags with 'is_tunnel' flag
- Partial oneway restrictions via access_restrictions with heading='backward'
- Partial level changes via level_rules
- Overlapping property ranges (e.g., bridge + oneway on same segment)
- Multiple split points creating 2-5 output features per input feature
…urved roads

- Add comprehensive unit tests for line splitting with curves
- Rewrite Linear.splitAtFractions() to preserve all vertices between split points
- Add coordinate transformation from lat/lon to world coordinates before emitting
- All 9 new Linear tests pass, roads render correctly with curves preserved

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
migurski and others added 2 commits February 16, 2026 13:38
When using --overture with a Parquet file, the basemap now reads the
bounding box from the GeoParquet metadata and uses it to set the bounds
in the output PMTiles archive. This enables "fit bounds" functionality
on maps.protomaps.com to zoom to the precise area covered by the data.

The bounds are only applied when no --bounds argument is provided,
allowing users to still override with manual bounds if needed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@migurski
Copy link
Collaborator Author

It would be useful if planetiler.addParquetSource read the bounds of the Parquet file (is this standardized in GeoParquet?) and then passed it through to the bounds header of the tile archive output. This way "fit bounds" on maps.protomaps.com would zoom to the precise area.

I’ll research what’s needed for this in the current PR.

The adjustment for this was small, implemented in 160a21c. The input Parquet files don’t consistently have bounding boxes defined when they're generated by DuckDB, so in my tests the output bounds are accurately set to match the whole-earth bbox of the input data. A way around this might be to read the actual envelope from Parquet row groups?

I resolved the merge conflicts.

Refactors bounds reading logic into a separate testable method and adds comprehensive test coverage including valid bounds extraction, missing file handling, and invalid file handling. Includes test GeoParquet file with Alcatraz Island buildings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@migurski migurski requested a review from bdon February 24, 2026 18:25
@wipfli
Copy link
Collaborator

wipfli commented Feb 27, 2026

Doing some testing in Zürich I saw some differences between the OpenStreetMap version and the Overture version. Let me list them below.

@wipfli
Copy link
Collaborator

wipfli commented Feb 27, 2026

River names show along polygon outline.

In the OpenStreetMap version the Limmat river label is in the center of the river. This label in the center is missing in the Overture version, but there is a line label for Limmat along the polygon outline of the river.

OpenStreetMap: https://maps.protomaps.com/#flavorName=light&lang=en&map=17.4/47.381202/8.541093&tiles=https://oliverwipfli.ch/data/osm.pmtiles
Overture: https://maps.protomaps.com/#map=17.4/47.381202/8.541093&theme=light&lang=en&tiles=https://oliverwipfli.ch/data/bay-area.pmtiles&flavorName=light

image

@wipfli
Copy link
Collaborator

wipfli commented Feb 27, 2026

Bridge polygons are missing in the Overture version.

To make bridges look a little bit better we added polygons for bridges in the OpenStreetMap version. Those are not present in the Overture version.

OpenStreetMap: https://maps.protomaps.com/#flavorName=light&lang=en&map=17.4/47.381202/8.541093&tiles=https://oliverwipfli.ch/data/osm.pmtiles
Overture: https://maps.protomaps.com/#map=17.4/47.381202/8.541093&theme=light&lang=en&tiles=https://oliverwipfli.ch/data/bay-area.pmtiles&flavorName=light

image

@wipfli
Copy link
Collaborator

wipfli commented Feb 27, 2026

Different use of neighborhood/quarter labels.

In OpenStreetMap we use all-caps labels for neighborhoods. For example "ENGE" in for Zürich Enge. In the Overture version however we use all-caps labels for squares, for example "Tessinerplatz".

OpenStreetMap:

https://maps.protomaps.com/#flavorName=light&lang=en&map=13.78/47.36248/8.54037&tiles=https://oliverwipfli.ch/data/osm.pmtiles

Overture: https://maps.protomaps.com/#map=13.78/47.36248/8.54037&theme=light&lang=en&tiles=https://oliverwipfli.ch/data/bay-area.pmtiles&flavorName=light

image

Copy link
Collaborator

@wipfli wipfli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to use string constants with a short prefix instead of variables.

So instead of

const String KIND = "protomaps:kind";
use(KIND, "highway")

Do something like

use("pm:kind", "highway")

@wipfli
Copy link
Collaborator

wipfli commented Feb 27, 2026

@bdon Mike said you did a planet run, can you share a link to the PMTiles file? I found it very useful to inspect visually on maps.protomaps.com what the differences are...

@bdon
Copy link
Member

bdon commented Feb 27, 2026

@migurski
Copy link
Collaborator Author

migurski commented Mar 1, 2026

I would prefer to use string constants with a short prefix instead of variables.

I replaced them throughout the PR.

- Replaced string constants with literals
- Removed old comments
@migurski migurski requested a review from wipfli March 1, 2026 05:17
@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 1, 2026

@wipfli
Copy link
Collaborator

wipfli commented Mar 2, 2026

This looks good to me. I did make some visual checks if Switzerland's OpenStreetMap map still looks the same after this pr and I could not find any differences, so that is a good sign!

var buildings = new Buildings();
registerHandler(buildings);
registerSourceHandler("osm", buildings::processOsm);
registerSourceHandler("pm:overture", buildings::processOverture);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please use "overture" instead of "pm:overture" to align it with the "osm" source...

@bdon bdon merged commit 11da474 into protomaps:main Mar 2, 2026
6 checks passed
bdon added a commit that referenced this pull request Mar 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants