Move Azure Maps basemap support to map-layers-formats#9300
Conversation
There was a problem hiding this comment.
Pull request overview
Adds first-class Azure Maps support as a basemap provider alongside Bing and MapBox. Provider name "AzureMapsProvider" is added to BackgroundMapProviderName, BaseMapLayerSettings.fromProvider materializes Azure Street/Aerial/Hybrid base layers, and a new @beta AzureMaps helper centralizes Hybrid road-label composition. DisplayStyleState's backgroundMapBase setter and changeBackgroundMapProvider are refactored so Azure helper-layer normalization is owned in one seam. Adds Azure source validation (subscription-key required), maps 401/403 runtime tile failures to RequireAuth, preserves provider metadata on MapLayerSource, and adds tests, docs, and changelog entries.
Changes:
- Add
AzureMapsProvideras a first-class background map provider incore-common, with provider-backed Azure base-layer creation - Add
AzureMapshelper plusDisplayStyleStateplumbing incore-frontend, including provider-seeded Azure sources and Azure format validation/auth handling - Add learning docs, NextVersion changelog, API reports, and switch display-test-app to the shared provider path
Reviewed changes
Copilot reviewed 34 out of 35 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
core/common/src/BackgroundMapProvider.ts |
Adds "AzureMapsProvider" to provider name union and fromJSON switch |
core/common/src/BackgroundMapSettings.ts |
Doc-comment update for new provider name |
core/common/src/MapLayerSettings.ts |
Azure branch in BaseMapLayerSettings.fromProvider |
core/common/src/test/BackgroundMapSettings.test.ts |
Azure provider round-trip tests |
core/common/src/test/MapLayerSettings.test.ts |
Azure base-layer materialization tests |
core/frontend/src/DisplayStyleState.ts |
Centralized Azure helper-layer normalization in backgroundMapBase setter and changeBackgroundMapProvider |
core/frontend/src/core-frontend.ts |
Public export of AzureMaps helper |
core/frontend/src/tile/internal.ts |
Internal re-export of AzureMaps |
core/frontend/src/tile/map/AzureMaps.ts |
New @beta helper for Azure base/helper-layer composition |
core/frontend/src/tile/map/MapLayerSources.ts |
Adds Azure seeded sources, persists provider metadata, makes public-source loading best-effort |
core/frontend/src/tile/map/MapLayerImageryFormats.ts |
Re-enables AzureMapsMapLayerFormat and adds URL + access-key validation |
core/frontend/src/tile/map/MapLayerImageryProvider.ts |
Generalizes 401/403 → RequireAuth in shared base class |
core/frontend/src/internal/tile/map/ImageryProviders/AzureMapsLayerImageryProvider.ts |
Enforces subscription-key and throws auth error on missing creds |
core/frontend/src/public/assets/MapLayerSources.json |
Trailing-newline cleanup; Azure entries removed (none added) |
core/frontend/src/test/DisplayStyleState.test.ts |
Provider-switching, helper-layer materialization/cleanup tests |
core/frontend/src/test/example-code/MapImagery.test.ts |
Test-backed publish-extract snippets for the learning doc |
core/frontend/src/test/tile/map/MapLayerImageryFormats.test.ts |
Azure validation and runtime auth tests |
core/frontend/src/test/tile/map/MapLayerSources.test.ts |
Provider-metadata round-trip tests |
core/frontend-devtools/src/tools/MapLayerTool.ts |
Async refactor; better error reporting and source-not-found message |
core/frontend-devtools/public/locales/en/FrontendDevTools.json |
New MapLayerSourceNotFound localization key |
test-apps/display-test-app/src/common/DtaConfiguration.ts |
Adds azureMapsKey config |
test-apps/display-test-app/src/frontend/App.ts |
Wires AzureMaps startup credential |
test-apps/display-test-app/src/frontend/ViewAttributes.ts |
Switches to provider API and AzureMaps.getBackgroundMapType |
example-code/snippets/src/frontend/MapImagery.ts |
Placeholder pointing at relocated examples |
docs/learning/frontend/MapImagery.md |
New "Map imagery and basemap providers" learning doc |
docs/learning/frontend/index.md, docs/learning/display/index.md |
Index links to the new doc |
docs/changehistory/NextVersion.md |
Release notes for the Azure provider surface |
docs/azure-maps-basemap-implementation-spec.md |
Internal-style implementation spec added under public docs |
common/api/core-common.api.md, common/api/core-frontend.api.md, common/api/summary/core-frontend.exports.csv |
API report updates |
common/changes/@itwin/* |
Lockstep none-type change files |
Comments suppressed due to low confidence (1)
core/frontend/src/tile/map/MapLayerSources.ts:254
- The
// eslint-disable-next-line @typescript-eslint/no-non-null-assertioncomments here suppress a non-null check on aMapLayerSource.fromBackgroundMapProps(...)result that is only guaranteed to be non-null because the URL/name strings are hardcoded insideBaseMapLayerSettings.fromProvider. If a future change toBaseMapLayerSettings.fromProviderever returns a settings object that failsMapLayerSource.fromJSON(e.g., due to validation tightening), this seeding code will pushundefinedintomapLayerSourcesand downstreamaddSource(source)calls will dereference it. Consider returning early whenfromBackgroundMapPropsreturnsundefined(the same pattern used elsewhere) rather than using!, so the failure mode is a missing seed rather than a runtime crash.
private static getAzureMapsLayerSource(): MapLayerSource[] {
// Azure Hybrid is intentionally not exposed as a public source entry because it is
// composed behavior (imagery base + internal labels helper layer), not a single source.
return [
MapLayerSources.fromBackgroundMapPropsOrThrow({ providerName: "AzureMapsProvider", providerData: { mapType: BackgroundMapType.Street } }),
MapLayerSources.fromBackgroundMapPropsOrThrow({ providerName: "AzureMapsProvider", providerData: { mapType: BackgroundMapType.Aerial } }),
Rewrite Azure Maps basemap support to be extension-owned in @itwin/map-layers-formats, add display-test-app Azure settings-panel integration, and remove the prior core-owned Azure basemap/provider surface.
bcc1dc0 to
64730a3
Compare
Why
Azure Maps basemap support needs to exist without turning Azure into a first-class
@itwin/core-frontendbackground-map provider. The core frontend package should keep owning generic display-style, startup, and map-layer APIs, while Azure-specific URL construction, Hybrid composition, validation, and auth behavior live with the optional vendor integration package that already owns similar provider-specific logic.That split only helps if applications still have a clear end-to-end path. This branch keeps the generic Azure key slot in
IModelApp.startup({ mapLayerOptions }), moves Azure-specific basemap behavior into@itwin/map-layers-formats, gives display-test-app a concrete way to exercise that flow, and documents how core startup and extension-owned helpers interleave.What
extensions/map-layers-formats/src/AzureMaps/AzureMaps.ts(beta helper API)extensions/map-layers-formats/src/AzureMaps/AzureMapsImageryFormat.ts,AzureMapsImageryProvider.ts, andsrc/internal/AzureMapsUtils.ts(runtime Azure integration)extensions/map-layers-formats/src/mapLayersFormats.ts,src/map-layers-formats.ts,common/api/map-layers-formats.api.md, andcommon/api/summary/map-layers-formats.exports.csv(registration and public surface)MapLayersFormats.initialize()and import through the package’s public API surface.test-apps/display-test-app/src/common/DtaConfiguration.ts,src/frontend/App.ts, andsrc/frontend/ViewAttributes.ts(display-test-app wiring)docs/learning/frontend/MapLayersAndBasemaps.md,docs/learning/frontend/index.md,docs/learning/display/index.md,extensions/map-layers-formats/README.md,example-code/snippets/src/frontend/AzureMaps.ts, anddocs/changehistory/NextVersion.md(docs, snippets, release notes)extensions/map-layers-formats/src/test/AzureMaps/AzureMaps.test.ts(regression coverage)Change file:
common/changes/@itwin/map-layers-formats/nam-azure-maps-extension-basemaps_2026-05-15-15-30.json.Tests
New and updated test coverage
AzureMaps.test.ts—creates Street, Aerial, and Hybrid basemap settingsAzureMaps.test.ts—creates and cleans up the Hybrid road-labels helper layerAzureMaps.test.ts—preserves existing base-layer display state when applying an Azure basemapapplyBackgroundMap()from resetting generic base-layer display state like visibility and transparency when switching to Azure.AzureMaps.test.ts—does not remove manually attached equivalent Azure road-label layersAzureMaps.test.ts—requires the subscription-key credential name during validation and tile loadingAzureMaps.test.ts—maps Azure 401/403 tile responses to RequireAuthValidation
masterwithorigin/masterbefore refreshing the branch diff for this PR description.cd extensions/map-layers-formats && rushx buildcd extensions/map-layers-formats && rushx test --grep AzureMapsNambot 🤖