Upgrading to 1.0 from a 0.x release

Before 1.0, a minor release can carry a breaking change. A rename takes effect in one release, with no deprecated alias and no runtime warning. This guide lists every breaking change on the way to 1.0, one row each, from what your code does now to what it does after.

This guide covers upgrades from 0.51.x to 1.0.0 (0.52.0, 0.53.0, 0.54.0, 0.55.1, 0.56.0, 0.57.0, 0.58.0, 0.59.0, 0.60.0, 0.61.0, 0.62.0, 0.62.2, 0.63.0, 0.64.0 and 1.0.0, not yet released). Breaking changes before 0.52.0 are in the package’s CHANGELOG.md. The list grows with each pre-1.0 minor until 1.0 ships. Until you upgrade, the documentation of your current release stays available.

How to use this guide

  • Find your current release, then apply every row with a later Since release, in order.
  • The compiler finds most rows for you, because a removed or renamed name is a type error. Rows marked behaviour compile unchanged but draw or answer differently, so check those by hand.
  • Upgrade the plugins with the SDK. Each one declares the first SDK release it needs, listed under Plugins.

Installing

SinceBeforeAfter
0.58.0the SDK parsed colours itselfculori v4 is a peer dependency: npm 7+ and Yarn install it, pnpm needs auto-install-peers=true or pnpm add culori
0.58.0maplibre-gl ^6.9.0, zod ^4.4.3maplibre-gl ^6.11.2, zod ^4.6.5

Core

SinceBeforeAfter
0.52.0asSoftWaypoint(position, radiusMeters)removed: every waypoint is a stop, and WaypointProps.radiusMeters is gone
0.55.1a reverse geocoding result’s properties.accessPointsproperties.entryPoints, an EntryPoint[] whose type is optional
0.58.0TomTomConfig.instance.put({ trackingId })removed, with the Tracking-ID header
0.58.0apiVersion on TomTomConfig or on a routing callremoved: each service calls the API version it pins
0.58.0TextWithPhonetics, with phonetic and phoneticLanguageCodeInstructionText, with text only
0.58.0POICategory V2 names: GAS_STATION, ELECTRIC_VEHICLE_STATION, HOTEL_MOTEL, SHOPPING_CENTER, SUPERMARKETS_HYPERMARKETS and 62 moretheir Places Search v3 names: FUEL_STATION, CHARGING_LOCATION, HOTEL_OR_MOTEL, MALL, SUPERMARKET, …
0.58.0COLLEGE_UNIVERSITY, LEISURE_SPORTS_CENTER, OPEN_PARKING_AREA, PERFORMING_ARTS_THEATER, ROAD_TRAFFIC_CONTROL_CENTERCOLLEGE_OR_UNIVERSITY, SPORTS_CENTER, OPEN_CAR_PARKING_AREA, THEATER, TRAFFIC_CONTROL_DEPARTMENT
0.58.0PUB_FOOD, POLYNESIAN_RESTAURANT, OTHER_WINTER_SPORT, SNOOKER_POOL_BILLIARDremoved: filtering on one already matched nothing
0.58.0TrafficIncidentTMC, TrafficIncidentTMCPoint, properties.tmc on an incidentremoved: Traffic Incident Details v2 carries no TMC data
0.58.0one AreaAnalyticsTimedEntry typeone entry type per granularity, AreaAnalyticsYearlyEntry to AreaAnalyticsHourlyEntry and AreaAnalyticsAverageEntry, with their time fields required
0.58.0AreaAnalyticsFeatureProperties.timezone always setoptional
0.59.0AreaAnalyticsFeatureProperties.name always setoptional, and absent from the SDK’s requests
0.59.0ChargingPoint.evseId always setoptional: some operators publish none
0.61.0View, viewsGeopoliticalView, geopoliticalViews (Geopolitical views)
0.62.2behaviour: the route progress helpers placed a point between two progress entries by vertex countby the line’s length. On a winding route, a distance or time between entries moves by up to a couple of kilometres or minutes
0.64.0bboxExpandedWithPosition, bboxExpandedWithBBox, bboxExpandedWithGeoJSON, toPointFeatureno longer exported: they were internal; bboxFromGeoJSON and bboxFromBBoxes build a bounding box
0.64.0mergeFromGlobal, TomTomHeaders, generateTomTomHeaders, bboxOnlyIfWithArea, getPositionStrict, toPointGeometry, poiCategoriesToID, poiCategoriesToIDs, poiIDsToCategories, getRoutePlanningLocationType, iconToTrafficIncidentCategory, trafficIncidentToIconCategory, MILE_IN_METERSnot in the published types: they are internal to the SDK’s packages; isBBoxWithArea tells a bounding box with area, getPosition reads a position
0.64.0RouteSummary and LegSummary with batteryConsumptionInkWh, batteryConsumptionInPCT, remainingChargeAtArrivalInkWh, remainingChargeAtArrivalInPCT, fuelConsumptionInLiters, and totalChargingTimeInSeconds on the route; ElectricSummary, CombustionSummary, SummaryWithConsumptionremoved: routes are planned without a vehicle consumption model
0.64.0LegSummary.chargingInformationAtEndOfLeg, ChargingStop, ChargingStopProps, ChargingConnectionInfo, ChargingPaymentOption, PaymentMethod, paymentMethods, PlugType, plugTypesremoved, with long-distance EV routing
0.64.0ChargingPark.availability, ChargingPoint.status, ChargingParkWithAvailability, EVChargingStationWithAvailabilityPlaceProps, ChargingStationsAvailability, ChargingPointAvailability, ConnectorAvailability, ChargingPointStatus, chargingPointStatus, ChargingStationsAccessType, chargingStationAccessTypesremoved, with real-time EV charging availability: chargingPark.connectors and chargingPark.chargingStations keep the static station data
0.64.0StaticChargingPoint, ChargingStation<P>ChargingPoint, which has no status, and ChargingStation, which takes no type parameter
0.64.0place.properties.dataSources.chargingAvailability, ChargingAvailabilityDataSourceremoved: nothing reads the id any more
0.64.0the reachable-range budgets remainingChargePCT, spentChargePCT, spentFuelLiters, in BudgetType, budgetTypes and budgetUnitsremoved: a budget is timeMinutes or distanceKM
1.0.0a Record<SectionType, …> over the section typesit needs a distinct entry too: calculateRoute fills sections.distinct when it returns two or more routes
1.0.0inputSectionTypes, inputSectionTypesWithGuidance, sectionTypes typed SectionType[]read-only lists of their exact types: copy one ([...sectionTypes]) where a mutable array is needed
1.0.0a Record<POICategory, …> over the POI categoriesit needs the ten _GENERIC codes in the row below too
1.0.0behaviour: a plain school’s poi.categories read SCHOOL, and likewise for THEATER, SPORTS_CENTER, MARINA, WEIGH_STATION, OPEN_CAR_PARKING_AREA, COLLEGE_OR_UNIVERSITY, CAR_WASH, AMUSEMENT_PARK and TRAFFIC_CONTROL_DEPARTMENTit reads the plain sub-category’s own code, such as SCHOOL_GENERIC, which a search can also ask for alone: match both where you matched the parent
1.0.0a route traffic section’s tec typed as always set, but undefined when the service sent no TEC codesoptional, and absent without codes: read section.tec?.causes

Services

Configuration and requests

SinceBeforeAfter
0.57.0the places services sent key= in the URLthey send TomTom-Api-Key and TomTom-Api-Version headers, which a proxy has to forward
0.58.0calculateReachableRange and trafficIncidentDetails sent GET URLsthey send the key, version and language as headers, and reachable ranges use POST
0.58.0customizeService, and a service function’s second argument overriding its request or response handlingremoved; calculateReachableRanges keeps its options argument
0.59.0customServiceBaseURL on a callremoved: every service builds its URL from the global commonBaseURL
0.59.0apiVersion passed per call or through TomTomConfig.putignored
0.64.0error instanceof SDKServiceError && error.status === 403, and the other status checkserror.code === 'API_KEY_REJECTED', one of the error codes every SDKError carries. status stays
0.64.0new SDKError(message, service, issues)new SDKError(message, service, { code, issues })
0.64.0ServiceTemplate, ParseResponseError, ParsedFetchResponse, RequestOptions, parseDefaultResponseError, buildResponseError, buildValidationErrorno longer exported: they were internal to the service call pipeline
0.64.0a commonBaseURL on http:, such as http://proxy.example.comserve it on https:. Otherwise, service calls reject and new TomTomMap throws with INSECURE_BASE_URL. Only loopback addresses keep http: (commonBaseURL)
1.0.0the error codes 'API_KEY_REJECTED', 'SERVICE_UNAVAILABLE', 'NETWORK_ERROR' and 'UNEXPECTED', on services and the map'INVALID_CREDENTIALS', 'LIVE_SERVICE_NOT_AVAILABLE', 'NETWORK_NOT_AVAILABLE' and 'INTERNAL', the names the TomTom Navigation SDK gives them
1.0.0error.code === 'API_KEY_REJECTED' for a 403'INSUFFICIENT_PERMISSIONS'. The key is valid but isn’t allowed to make the request, such as a call to a Private Preview API it has no access to. 'INVALID_CREDENTIALS' is a 401 only, on services and the map alike. behaviour
1.0.0a 403 rejected with the message 'Request failed with status code 403'it keeps the API’s message, and SDKServiceError.apiErrorCode holds the API’s own code. behaviour
1.0.0a list of the codes worth retrying, such as RATE_LIMITED and the 5xx oneerror.canRetry, on SDKError and TomTomMapError
1.0.0displayUnits on a service calla type error: no service reads it. Pass it to the formatters or the RoutingModule config
1.0.0behaviour: a retry on a service call was ignored for the global oneit overrides the global retry field by field for that call, and retry: undefined turns retrying off for it (Per-call overrides)
1.0.0SDKError.service typed string, and 'Reachable Range' for reachable rangesServiceName, the union of the services’ names, such as 'Geocode' and 'ReachableRange'. The error constructors take it too

Search and places

SinceBeforeAfter
0.52.0reverseGeocode with allowFreeformNewline, mapcodes, number, returnMatchType, returnRoadUse, returnSpeedLimit or roadUsesremoved, with the RoadUse type: reverse geocoding calls Orbis v2
0.52.0a reverse geocoding result’s bounding box, side of street, offset position, mapcodes, data sources, road class and use, speed limitnot returned
0.55.1{ position, radiusMeters } on a search{ geoBias: { position, radiusMeters } }
0.55.1{ boundingBox } on a search{ geoBias: { boundingBox } }
0.56.0explorationSearch, POPULATED_AREA_TAGS, RESERVED_AREA_TAGSno longer exported
0.57.0SearchSummary.totalResults and fuzzyLevel always numbersoptional
0.58.0search(), searchOne(), placeById()discoverPlaces(), discoverOnePlace(), getPlaceDetails()
0.58.0SearchResponse, PlaceByIdParams, PlaceByIdResponseDiscoverPlacesResponse, PlaceDetailsParams, PlaceDetailsResponse
0.58.0autocompleteSearch()getSearchSuggestions({ query, filters: { kinds: ['brand', 'category'] } }), or without kinds for brands, categories and places ranked together
0.58.0a pre-encoded query (encodeURIComponent) on geocode, discoverPlaces or getSearchSuggestionspass plain text. The SDK encodes it, and encoding it again resolves a different place
0.58.0reverseGeocode({ geographyType })reverseGeocode({ geographyTypes })
0.59.0poiCategories, poiBrands, indexes, geographyTypes, connectors, fuelTypes, minPowerKW, maxPowerKW, countries at the top level of a searchunder filters: { filters: { poiCategories: ['CAFE_PUB'] } }
0.59.0{ offset } for the next page, SearchSummary.offset{ cursor } set to the previous response’s properties.nextCursor, unchanged
0.59.0getPlaceWithEVAvailability and getPlacesWithEVAvailability resolved an aborted call as missing availabilitythey reject with SDKAbortError
0.61.0behaviour: getPOICategories and getPOICategoryCodes returned every category whose name contained a filterthey return each filter’s strongest matches: 'bar' gives Bar, not 15 categories
0.61.0{ view: 'IN' } on a search, suggestions, geocoding, reverse geocoding or place details call{ geopoliticalView: 'IN' }, or once for every call with TomTomConfig.instance.put({ geopoliticalView })
0.61.0alongRouteSearch({ route, maxDetourTimeSeconds, query, … })discoverPlaces({ route, maxDetourTimeSeconds, query, … }), resolving to a DiscoverPlacesResponse
0.61.0AlongRouteSearchResponse, FuzzySearchResponse, GeometrySearchResponse, GeometrySearchFeatureCollectionPropsDiscoverPlacesResponse, and SearchSummary for the collection properties
0.61.0the wire-format types of along-route, fuzzy and geometry search, such as FuzzySearchResponseAPI or GeometryAPIno longer exported, with no replacement
0.64.0getSearchSuggestions({ maxResults, origin })getSearchSuggestions({ limit, geoBias: { position } }), as the other searches name them
0.64.0the geometry data wire-format types GeometryDataResponseAPI, AdditionalDataAPIno longer exported, with no replacement
0.64.0evChargingStationsAvailability, getPlacesWithEVAvailability, getPlaceWithEVAvailability, hasChargingAvailability, ChargingStationsAvailabilityParams, PlacesWithEVAvailabilityOptionsremoved, with real-time EV charging availability: search results keep their static chargingPark
1.0.0behaviour: a poiCategoryQuery word that names a plain sub-category best, such as 'rto' or 'open car parking area', resolved to its parent’s code, which also searches the parent’s other sub-categoriesit resolves to the _GENERIC code, which searches that sub-category alone. Name the parent’s code to keep the wider search
1.0.0reverseGeocode resolved a Place, so place.properties.address compiled where nothing matchedReverseGeocodingResponse, a Place or the queried point without properties. Check if (place.properties) before you read it or pass it to PlacesModule.show (Reverse geocoding)
1.0.0geometryData typed every polygon’s properties as CommonPlaceProps, for Place[] input tooa Places collection types them as PlaceGeometryProps or null, and Place[] or geometry IDs as the service’s own PolygonFeatures
1.0.0behaviour: with a Places collection, a polygon that matched no place kept the service’s own propertiesit has null properties
1.0.0minFuzzyLevel and maxFuzzyLevel typed numberFuzzyLevel, the whole numbers 1 to 4: another number is a type error
1.0.0the wire-format types PoiCategoriesResponseAPI, PoiCategoryAPI, PlaceDetailsResponseAPI, PlaceDetailsResultAPIno longer exported, with no replacement

Routing and reachable ranges

SinceBeforeAfter
0.52.0VehicleDimensions with lengthMeters, widthMeters, heightMeters, axleWeightKGweightKG only
0.52.0VehicleRestrictions with loadTypes, adrCode, commercial; LoadType, loadTypesmaxSpeedKMH only
0.52.0guidance: { version }guidance: { type: 'coded' }
0.52.0a reachable range’s costModel.avoidAreas, avoid: ['alreadyUsedRoads'] or vehicle.state.headingrejected: that endpoint takes none of them
0.56.0chargingStopsStrategy on any vehicleneeds vehicle.preferences.chargingPreferences
0.56.0model.variantId on any vehicleelectric vehicles only, and on calculateRoute only with charging preferences
0.58.0guidance: { phonetics }, the Phonetics typeremoved
0.58.0the reachable-range budget remainingChargeCPTremainingChargePCT
0.58.0preferences on a generic or combustion vehicle, VehiclePreferenceselectric vehicles only, as ElectricVehiclePreferences
0.58.0calculateReachableRange dropped when: { option: 'arriveBy' } and a charge budget it could not convertit rejects them
0.62.0import { budgetTypes, type BudgetType, type ReachableRangeBudget } from '@tomtom-org/maps-sdk/services'from '@tomtom-org/maps-sdk/core', beside the new budgetUnits
0.64.0vehicle.engineType, vehicle.model.engine, vehicle.model.variantId, vehicle.state.currentChargePCT, currentChargeInkWh, currentFuelInLiters, vehicle.preferencesremoved: routes and reachable ranges are planned without a vehicle consumption model; vehicle takes model.dimensions.weightKG, state.heading and restrictions
0.64.0calculateRoute({ vehicle: { preferences: { chargingPreferences } }, chargingStopsStrategy }), chargingStopsStrategies, ChargingStopsStrategyremoved, with long-distance EV routing
0.64.0the vehicle types ElectricVehicleParams, CombustionVehicleParams, GenericVehicleParams, ElectricVehicleParamsWithChargingStops, VehicleEngineType, ElectricVehiclePreferences, ChargingPreferences, ChargingPreferencesKWH, ChargingPreferencesPCT, ElectricVehicleState, ElectricVehicleStateKWH, ElectricVehicleStatePCT, CombustionVehicleState, GenericVehicleState, PredefinedVehicleModel, ExplicitVehicleModel, VehicleEngineModel, ElectricEngineModel, CombustionEngineModel, ConsumptionModelBase, ElectricConsumptionModel, CombustionConsumptionModel, ConsumptionModelEfficiency, SpeedToConsumptionRate, ChargingModel, BatteryCurve, ChargingConnectorVehicleParameters, VehicleModel and VehicleState, with no engine variants
1.0.0InputSectionType was any SectionType, so sectionTypes: ['leg'] compiled and failed validationthe types a request can ask for; type your own lists InputSectionTypes, not SectionType[]
1.0.0InputSectionTypes was a mutable array, so push onto one compiledread-only: build the list whole, such as [...inputSectionTypes, 'lanes']
1.0.0behaviour: a lanes section’s properties held the API’s 'isManeuver''IS_MANEUVER', as LaneSectionProps documents
1.0.0behaviour: calculateReachableRanges skipped a range that failed with any service error but a 401, 403 or 429it skips a 4xx other than 401, 403, 404 and 429. Those, a 5xx and an error without a status reject the batch

Traffic

SinceBeforeAfter
0.58.0trafficIncidentDetails({ trafficModelId })removed: v2 always serves the latest traffic state
0.58.0metricKeyToApiDataTypeno longer exported

Map

TomTomMap and styles

SinceBeforeAfter
0.53.0map.setStyle(style, { keepState: false })await map.setStyle(style, { resetState: true }); state is kept by default, as before
0.53.0setStyle returned nothingit returns a promise that settles once the modules are restored
0.53.0a StyleChangeHandler callback received { keepState }it receives { resetState }
0.53.0behaviour: overlays drew fixed colours on every styleon dark styles, geometry fills and labels, palettes, places connections, the area-analytics region boundary and the incident focus outline take dark-style colours. To keep a colour, set it
0.56.0a CustomStyle with both url and jsonexactly one of the two
0.58.0eventState held a user event type, such as hover or clickit also holds recently-hovered for hoverGracePeriodMS (400 ms). Exclude it from your own ['has', 'eventState'] expressions, or set hoverGracePeriodMS: 0
0.59.0{ version } on a standard style; DEFAULT_STYLE_VERSIONremoved: standard styles load the Orbis style version the SDK is verified against
0.59.0a Record<MapColorName, …> over nine coloursit needs an accent entry too
0.62.0map.getStyle()map.getStyleInput(), the StyleInput as given; map.mapLibreMap.getStyle() returns the style specification
0.62.0StyleModule, styleModulesStylePart, styleParts
0.62.0{ type: 'standard', include: ['hillshade'] }{ type: 'standard', include: ['terrain'] }
0.64.0TomTomMap({ mapLibre: { transformRequest } })a type error. The SDK sets transformRequest itself, so the value never took effect. Route requests through a proxy with commonBaseURL
1.0.0style: { type: 'custom', url } or { type: 'custom', json }; CustomStyle, CustomStyleSource, lightDarkThemeremoved: the map loads standard styles only. Start from the closest one and restyle it with the Styling Foundations module and map colours
1.0.0the standard style IDs standardLight, standardDark, drivingLight, drivingDark, satellitestreetLight, streetDark, streetLightDriving, streetDarkDriving, streetSatellite, each the Orbis style it loads in camelCase. monoLight and monoDark stay

Every module

SinceBeforeAfter
0.52.0PlacesModule.get(map), likewise for RoutingModule, GeometriesModule, CustomGeoJSONModule, TrafficIncidentOverlayModule, TrafficAreaAnalyticsModulePlacesModule.create(map); style-owned modules keep get() (Map modules)
0.52.0behaviour: each get() of a style-owned module built a new instanceit returns the map’s one instance
0.52.0module.events.<scope>.on('config-change' or 'shown-features', …)module.events.on(…). A named scope carries only user events
0.52.0module.events covered the main surfaceit covers every surface: places.events.places for pins typed as Place, geometries.events includes the labels
0.58.0FlowConfig, IncidentsConfig, TrafficIncidentOverlayConfig, TrafficAreaAnalyticsConfigTrafficFlowModuleConfig, TrafficIncidentsModuleConfig, TrafficIncidentOverlayModuleConfig, TrafficAreaAnalyticsModuleConfig
0.58.0the filter mode 'all_except''all-except', in the POI, traffic flow and traffic incident filters
0.61.0behaviour: isVisible() on POIsModule, BaseMapModule, TrafficFlowModule and TrafficIncidentsModule reported whether a layer drawsit returns the visible setting. Until something sets it, POIs and the base map report what the style draws, and the traffic modules false. Read a layer with map.mapLibreMap.getLayoutProperty(layerId, 'visibility')
0.61.0a subclass of AbstractDataOwnedMapModule with its own setVisibleit implements applyVisibility(config) instead, and the base class provides setVisible and isVisible; its config type takes visible?: boolean
0.62.0behaviour: a hovered or clicked route, geometry or incident details incident drew as any otherit stands out: a wider route outline, a denser geometry fill and wider border, the incident focus treatment. highlight.outlineWidthFactor: 1 on routes, highlight: { fillOpacityFactor: 1, lineWidthFactor: 1 } on geometries and focus: false on incident details keep the old look
0.62.0behaviour: an event state wrote properties.eventState into the feature objects you passed to showyour objects stay as given. Read states with getEventStates(), or from getShown(), which returns a new collection after each state change
0.62.0behaviour: a user click or hover left the state putEventState gave another featureit moves the state. A click takes click and contextmenu off the other features of its source, a hover takes hover, hover-move and long-hover
0.63.0mapDisplayPoiCategoryMappings, toBaseMapPOICategory, toBaseMapPOIGroup, baseMapPOICategoryValues, sharedInstanceIfCreated, SymbolLayerSpecWithoutSourceno longer exported: they were internal; MapStylePOICategory stays
0.64.0putEventState, cleanEventState, cleanEventStates on a data-owned module and its named scopes; PutEventStateOptions, CleanEventStateOptions, CleanEventStatesOptionssetEventState, clearEventState, clearEventStates; SetEventStateOptions, ClearEventStateOptions, ClearEventStatesOptions
0.64.0getShown() on POIsModule, TrafficFlowModule and TrafficIncidentsModulegetRenderedFeatures(): what the style’s tiles render in view; getShown() stays on the data-owned modules, the data show was given
0.64.0EventsProxy, sharedInstance, TomTomMapSource, InternalTomTomMapParams, poiLayerIDs, buildRoutingLayers, ROUTE_LINE_OUTLINE_COLORno longer exported: they were internal; ROUTE_LINE_OUTLINE_COLOR was '#105287'
0.64.0renderedRefId, findFeatureByRefId, filterLayersBySources, withEventState, combineEventScopes, scopedLayerSpecs, reservedScopeNames, assertNoReservedScopeNames, getIconIDForPlace, getPOIGroupForPlace, getPOILayerCategoryForPlace, STOP_DISPLAY_LABELno longer exported: they were internal; look a shown feature up by id in the module’s getShown()
1.0.0a KnobTarget of your own implementing _setKnobValue(id, value)_setKnobValues(values), the values by knob id applied in one change. A subclass of AbstractMapModule inherits it
1.0.0behaviour: an events.where() predicate took the first matching feature under the pointer, and a feature it rejected still took the pointer cursor and a hover or click highlightit decides on the top-most feature. A rejected one keeps the map cursor, takes no state, and no handler runs, even with a match beneath (Scoping events)

Knob catalogues

SinceBeforeAfter
0.61.0KnobKind with toggle, factor, number, color, enum, colorsit adds image, offset, enums and text: an exhaustive switch needs a case for each
0.61.0a KnobRange you declare as { min, max, step }it needs bounds: 'hard', 'hard-min' or 'soft', the ends validateKnobValue holds a value to
0.61.0a StylingKnob with range and options optional on every kindone member per kind: a factor or number knob carries its range, an enum knob its options, and no other kind either
0.61.0a module’s …KnobValueOf<id> took the expressions and objects the config also takes at that paththe plain value the knob holds
1.0.0PlacesKnob admitted the text kind, and TrafficFlowKnob, TrafficIncidentsKnob, TrafficIncidentDetailsKnob and TrafficAreaAnalyticsKnob the image kindthey list only the kinds their catalogues hold: drop a case 'text' or case 'image' from a switch over their kind

BaseMapModule

SinceBeforeAfter
0.52.0BaseMapModule.get(map, { layerGroupsFilter }), BaseMapModuleInitConfigname the groups per call: setVisible(visible, { layerGroups }), events.where({ layerGroups })
0.59.0layerGroupsVisibility: { mode: 'include', names: ['water', 'ferries'], visible: false }groups: { water: { visible: false }, ferries: { visible: false } }
0.59.0layerGroupsVisibility: { mode: 'exclude', names: ['land', 'roads'], visible: false }visible: false, groups: { land: {}, roads: {} }
0.59.0behaviour: applyConfig merged into the current configurationit replaces it; merge with updateConfig
0.59.0behaviour: resetConfig left hidden groups hiddenit puts every layer back as the style ships it
0.63.0setVisible(visible, { layerGroups: { mode: 'include', names } }), mode: 'exclude', also in isVisible and events.where{ layerGroups: { show: 'only', values } }, show: 'all-except': the ValuesFilter POIs and traffic filter by

POIsModule

SinceBeforeAfter
0.61.0POICategoryGroup was stringit is the union of the poiCategoryGroups names, such as 'FOOD_DRINKS_GROUP': a filterCategories value that names no group or category is a type error
0.62.0pois.filterCategories(filter)pois.updateConfig({ filters: { categories: filter } }), and updateConfig({ filters: undefined }) to show every POI
0.62.0pois.getShown().poipois.getShown().pois
0.64.0getStyleCategoriesno longer exported: it was internal; pois.updateConfig({ filters: { categories } }) filters the POIs by category or group

StylingModule

SinceBeforeAfter
0.56.0styling.set(id, value) accepted any knob value typea value of the wrong kind for that knob is a compile error
0.57.0the view.terrain and view.terrainExaggeration knobs, the terrain presetTerrainModule.get(map, { elevation: true, elevationExaggeration })
0.58.0styling.describe(), StylingCatalogue, StylingKnobDescriptor, StylingPresetDescriptor, KnobDescriptorthe static stylingKnobCatalogue and stylingPresetCatalogue, and styling.get(id) for the value in force
0.59.0the basemap.roadShields knobroads.shields
0.62.2behaviour: styling.layers queries also reached the layers modules add, such as route linesthey reach only the style’s own layers: restyle a module’s layers through its layers config
0.63.0StylingModule.get(map), StylingModuleConfig, StylingEventsStylingFoundationsModule.get(map), StylingFoundationsModuleConfig, StylingFoundationsEvents: it holds the foundations of the look, and every other part’s look is the module drawing it (Map styling)
0.63.0stylingKnobCatalogue, stylingKnobIds, StylingKnob, StylingKnobId, StylingKnobValueOf, StylingKnobValue, StylingKnobKind, StylingKnobRange, StylingKnobAppliesTo, stylingKnobKinds, stylingKnobAppliesTostylingFoundationsKnobCatalogue, stylingFoundationsKnobIds, StylingFoundationsKnob, StylingFoundationsKnobId, StylingFoundationsKnobValueOf, StylingFoundationsKnobValue, StylingFoundationsKnobKind, StylingFoundationsKnobRange, StylingFoundationsKnobAppliesTo, stylingFoundationsKnobKinds, stylingFoundationsKnobAppliesTo
0.63.0styling.set(id, value), styling.get(id), styling.reset(id)setKnob(styling, stylingFoundationsKnobCatalogue, id, value), getKnob(styling, stylingFoundationsKnobCatalogue, id), resetKnob(styling, stylingFoundationsKnobCatalogue, id), as on every module (Setting a knob by its id)
0.63.0styling.reset()styling.resetConfig()
0.63.0StylingSettingsStylingFoundationsModuleConfig, as every other module names its configuration
0.63.0the knobs basemap.<group>, buildings.footprints, buildings.3d and roads.shieldsthe Base Map Module’s groups: baseMap.setVisible(true, { layerGroups: { show: 'only', values: ['buildings3D'] } }), or setKnob(baseMap, baseMapKnobCatalogue, 'groups.buildings3D.visible', true); buildings2D and roadShields are the other two
0.63.0the knobs roads.exitNumbers, roads.arrows, roads.restricted, roads.underConstructionthe Base Map Module’s roads.exitNumbers.visible, roads.arrows.visible, roads.restricted.visible, roads.underConstruction.visible: BaseMapModule.get(map, { roads: { arrows: { visible: false } } })
0.63.0the knobs pois.sizeFactor, pois.minZoom, pois.zoomShiftthe POIs Module’s sizeFactor, minZoom, zoomShift: POIsModule.get(map, { sizeFactor: 1.2 })
0.63.0the knobs pois.labelColor, pois.labelOutlineColorPOIsModule’s label.color, label.haloColor: POIsModule.get(map, { label: { color, haloColor } })
0.63.0the knob pois.microMarkersPOIsModule’s microMarkers.visible
0.63.0the knobs traffic.flow.freeColor, slowColor, queueingColor, stationaryColor, closedColor and traffic.flow.widthFactorthe Traffic Flow Module’s colors.free, colors.slow, colors.queueing, colors.stationary, colors.closed and widthFactor: TrafficFlowModule.get(map, { colors: { slow: '#f59e0b' } })
0.63.0the knobs traffic.incidents.minorColor, moderateColor, majorColor, closedColor and traffic.incidents.widthFactorthe Traffic Incidents Module’s colors.minor, colors.moderate, colors.major, colors.closed and widthFactor, which route traffic sections and incident details follow
0.63.0the knobs hillshade.method, hillshade.lightDirection, hillshade.exaggeration, hillshade.maxZoom, hillshade.shadowColor, hillshade.highlightColor, hillshade.accentColorthe same ids on the Terrain Module: TerrainModule.get(map, { hillshade: { visible: true, exaggeration: 0.5 } })
0.63.0StylingColorKnobId, stylingColorKnobIdsStyleColorKnobId, styleColorKnobIds: the colour knobs of every module by their map-wide ids, such as 'colors.water', 'pois.label.color' and 'traffic.incidents.colors.major', which getStyleColor(map, id) reads (The knob catalogue)
0.63.0styling.applyPreset(id), styling.applyPreset(id, { merge: true })await applyMapPreset(map, id), { merge: true }: it sets the Styling Foundations, Base Map and POIs knobs each preset names, creating the modules the map lacks, and throws an Error for an unknown id (Presets)
0.63.0stylingPresetIds, stylingPresetCatalogue, StylingPresetId, StylingPresetmapPresetIds, mapPresetCatalogue, MapPresetId, MapPreset; MapPresetSettings gives each module’s values by its own catalogue ids
0.63.0behaviour: the data-viz preset hid road shields and 3D buildings, night-driving showed the shields and hid 3D buildings, and minimal hid both building groups and the shieldspresets leave whole groups as the style ships them; hide those with BaseMapModule
0.64.0the map colour labelOutline, its knob colors.labelOutlinelabelHalo, colors.labelHalo: the band around a label’s text is its halo, as in every module’s haloColor and haloWidth
1.0.0the knob ids view.sky, view.skyColor, view.horizonColor and view.spaceColor, also as colour ids in styleColorKnobIds, getStyleColor and Map Effects’ bloom.onlyview.sky.visible, view.sky.color, view.sky.horizonColor and view.space.color: the sky is a part with its own visible, and the space behind a globe another
1.0.0StylingFoundationsModuleConfig keyed by the knob id: StylingFoundationsModule.get(map, { 'labels.sizeFactor': 1.2 })each setting nested along its id, as on every module: { labels: { sizeFactor: 1.2 } }. setKnob, setKnobs and MapPresetSettings keep the ids
1.0.0behaviour: styling.updateConfig({ 'colors.water': … }) kept every other colour, and applyConfig and updateConfig checked each valueupdateConfig({ colors: { water } }) replaces the colours set before, and neither checks values at run time. For one setting or values held as data, use setKnob or setKnobs (Changing a setting)

TerrainModule

SinceBeforeAfter
0.57.0HillshadeModule.get(map, { visible: true })TerrainModule.get(map, { hillshade: true })
0.57.0hillshadeModule.setVisible(visible)terrain.setHillshadeVisible(visible)
0.61.0behaviour: isHillshadeVisible() reported whether a hillshade layer drawsit returns the hillshade setting, false until something sets it
0.61.0behaviour: isElevationEnabled() reported whether the map’s terrain is raisedit returns the elevation setting, and the map’s own terrain until something sets it. Read the map with map.mapLibreMap.getTerrain()
0.62.0terrain.setElevationExaggeration(2)terrain.updateConfig({ elevationExaggeration: 2 })
0.63.0TerrainModule.get(map, { hillshade: true, elevation: true, elevationExaggeration: 2 })TerrainModule.get(map, { hillshade: { visible: true }, elevation: { visible: true, exaggeration: 2 } })
0.63.0the knob ids hillshade, elevation, elevationExaggerationhillshade.visible, elevation.visible, elevation.exaggeration
0.63.0terrain.updateConfig({ elevationExaggeration: 2 })setKnob(terrain, terrainKnobCatalogue, 'elevation.exaggeration', 2): updateConfig({ elevation: { exaggeration: 2 } }) replaces the whole elevation object, dropping visible
0.63.0terrain.setElevationEnabled(visible), terrain.isElevationEnabled()terrain.setElevationVisible(visible), terrain.isElevationVisible()
1.0.0TerrainModule.get(map, { hillshade: { lightDirection, exaggeration, shadowColor, highlightColor, accentColor } })TerrainModule.get(map, { hillshade: { light: { direction }, intensity, colors: { shaded, lit, steep } } }): exaggeration is the raised surface’s vertical scale alone
1.0.0the knob ids hillshade.lightDirection, hillshade.exaggeration, hillshade.shadowColor, hillshade.highlightColor, hillshade.accentColor, also as terrain.-prefixed colour ids in styleColorKnobIds and getStyleColorhillshade.light.direction, hillshade.intensity, hillshade.colors.shaded, hillshade.colors.lit, hillshade.colors.steep

PlacesModule

SinceBeforeAfter
0.52.0the shown-features payload held the placesit is either { places } or { connections }, and showConnections emits it too
0.61.0PlacesModule.create(map, { theme: 'base-map' })PlacesModule.create(map, { markerType: 'base-map' })
0.61.0places.applyTheme('pin')places.applyMarkerType('pin')
0.61.0PlacesTheme, placesThemesPlacesMarkerType, placesMarkerTypes
0.61.0PlacesModule.create(map, { text: { title, color } })PlacesModule.create(map, { label: { title, color } })
0.61.0places.applyTextConfig({ color }), PlaceTextConfigplaces.applyLabelConfig({ color }), PlaceLabelConfig
0.61.0behaviour: the EV availability label defaulted to a threshold of 0, drawing every station green, while the pin used 0.3both default to 0.3: set evAvailability: { threshold: 0 } to keep the old label colour
0.62.0places.applyMarkerType(type), applyIconConfig(icon), applyLabelConfig(label), applyExtraFeatureProps(props)places.updateConfig({ markerType, icon, label, extraFeatureProps }), typed by your place shape with updateConfig<MyPlaceProps>(…)
0.62.0behaviour: on a dark map, connection labels and entry points had a near-black halo, and a color gave connection labels its darker shadethey take the dark grey halo of place labels, and a lighter shade of the colour; connections.textColor and connections.haloColor set either
0.62.2behaviour: a categoryIcons entry drew only the places of its own categoryit also draws the places of its map category that no entry names: RESTAURANT reaches an ITALIAN_RESTAURANT
0.63.0PlacesModule.create(map, { evAvailability: { enabled: true } }), the knob evAvailability.enabledPlacesModule.create(map, { evAvailability: { visible: true } }), evAvailability.visible
0.63.0connections: { label: (connection) => text, textColor, haloColor }, the knob ids connections.textColor, connections.haloColorconnections: { label: { title: (connection) => text, color, haloColor } }, connections.label.color, connections.label.haloColor: the label of places, waypoints and geometries
0.63.0cluster: { badge: { textColor, textSize } }, the knob ids cluster.badge.textColor, cluster.badge.textSizecluster: { badge: { label: { color, size } } }, cluster.badge.label.color, cluster.badge.label.size
0.64.0cluster.badge.strokeColor, cluster.badge.strokeWidth, and their knob idscluster.badge.outlineColor, cluster.badge.outlineWidth: the edge of a shape is its outline across the modules
0.64.0PlacesModule.create(map, { evAvailability }), EVAvailabilityConfig, the knobs evAvailability.visible, evAvailability.thresholdremoved, with real-time EV charging availability
0.64.0categoryIcons: [{ id, image, availabilityLevel }] on PlacesModule and POIsModule, AvailabilityLevelcategoryIcons: [{ id, image }]: one icon per category
1.0.0cluster: { source: { clusterRadius, clusterMaxZoom, clusterMinPoints, clusterProperties } }, the knob ids cluster.source.clusterRadius, cluster.source.clusterMaxZoom, cluster.source.clusterMinPointscluster: { source: { radius, maxZoom, minPoints, properties } }, cluster.source.radius, cluster.source.maxZoom, cluster.source.minPoints; PlacesClusterSourceConfig types them
1.0.0label: { offset }, the knob id label.offsetlabel: { distance }, label.distance: an offset is an [x, y] displacement on every module
1.0.0behaviour: under pin-clustered, a cluster reached the events.places handlers, typed Place but without a place’s properties, and took its hover and click statesit is inert there: no handler runs and it keeps the map cursor. Handle it on the module-wide events, with places.events.where((feature) => feature.properties.cluster === true) (Events)

RoutingModule

SinceBeforeAfter
0.52.0routing.events.user.on('click', …)routing.events.on('click', …)
0.52.0routing.events.module.on(…)routing.events.on(…)
0.52.0WAYPOINT_SOFT_IMAGE_ID, softWaypointIcon: a circle for a soft waypointremoved: every waypoint draws a numbered pin
0.54.0behaviour: the tollRoad section covered per-use tolls onlyit covers every stretch that costs money to drive
0.55.1layers.sections.incidentlayers.sections.traffic
0.55.1behaviour: sections.speedLimit drew a band, behind { visible: true }it posts speed-limit signs, by default
0.55.1sections.speedLimit color, opacity, width, style, pattern, iconremoved: it takes visible and sign
0.55.1a layers.sections.speedLimit override of routeSectionSpeedLimitLineof routeSectionSpeedLimitSign
0.55.1sections.country, the countrySections source, its events scope and getShown() entryremoved: border crossings are labelled with countryCrossings
0.59.0sections.<type>.sign.minzoom, countryCrossings.minzoomminZoom
0.60.0{ theme: { mainColor: '#f00', routeWidth: 'l', waypointSize: 's' } }{ color: '#f00', width: 'l', waypointSize: 's' }; RouteTheme is removed
0.60.0sections.<type>.icon.sizesections.<type>.icon.sizeFactor, clamped to 0.25–2
0.60.0getLayerToRenderLinesUnder() always returned a layer idit follows beforeLayerConfig, and returns undefined when the route lines are on top
0.61.0behaviour: icon.sizeFactor: 0.8 set the icon sizeit multiplies the size the section type draws: ferry, tollRoad, tunnel and vehicleRestricted keep their zoom ramp
0.61.0{ chargingStops: { text: { title } } }, ChargingStopTextConfig, the knob id chargingStops.text.visible{ chargingStops: { label: { title } } }, ChargingStopLabelConfig, chargingStops.label.visible
0.61.0behaviour: getConfig() filled in the global displayUnits when the module set noneit returns the configuration as given, and undefined after RoutingModule.create(map) or resetConfig(): read TomTomConfig.instance.get().displayUnits for the units in force
0.62.0behaviour: waypoint labels were black on a white halo on every mapthey follow the light/dark theme; waypoints: { label: { color: 'black', haloColor: '#ffffff' } } keeps the old look
0.62.2behaviour: a hovered or clicked waypoint drew as any otheronce a handler covers the waypoints, its pin grows 1.2 times with its stop mark; waypoints: { highlight: { sizeFactor: 1 } } keeps the old look
0.63.0RoutingModule.create(map, { waypointSize: 's', waypointSizeFactor: 1.5 }), the knob ids waypointSize, waypointSizeFactorRoutingModule.create(map, { waypoints: { size: 's', sizeFactor: 1.5 } }), waypoints.size, waypoints.sizeFactor
0.63.0countryCrossings: { textColor }, the knob id countryCrossings.textColorcountryCrossings: { label: { color } }, countryCrossings.label.color
0.63.0ROUTE_WIDTH_FACTOR_RANGE, ROUTE_WAYPOINT_SIZE_FACTOR_RANGE, ROUTE_WAYPOINT_HIGHLIGHT_SIZE_FACTOR_RANGE, SECTION_ICON_SIZE_FACTOR_RANGE, ROUTE_HIGHLIGHT_OUTLINE_WIDTH_FACTOR_RANGEthe knob’s range in routingKnobCatalogue: knobEntryOf(routingKnobCatalogue, 'widthFactor').range
0.63.0the undocumented route layer colours, widths and size helpers, such as ROUTE_LINE_FOREGROUND_COLOR or getWaypointIconSizeno longer exported; SELECTED_ROUTE_FILTER and DESELECTED_ROUTE_FILTER stay
0.64.0highlight: { outlineWidthFactor }, the knob highlight.outlineWidthFactorhighlight: { outline: { widthFactor } }, highlight.outline.widthFactor: each module’s highlight names the part it changes, then the property
0.64.0RoutingModule.create(map, { chargingStops }), ChargingStopsConfig, ChargingStopIconConfig, ChargingStopIconMapping, ChargingSpeedIconMapping, ChargingStopLabelConfig, the knobs chargingStops.visible, chargingStops.label.visible, layers.chargingStops, routing.events.chargingStops, getShown().chargingStopsremoved, with long-distance EV routing
1.0.0RoutingModule.create(map, { width: 'l', waypoints: { size: 's' } }), sections.<type>.width, the knob ids width, waypoints.size, sections.<type>.widthRoutingModule.create(map, { widthPreset: 'l', waypoints: { sizePreset: 's' } }), sections.<type>.widthPreset, and the knob ids follow: a preset is named *Preset, next to the *Factor that multiplies it
1.0.0behaviour: selectRoute kept the click state of the route lines and summary bubbles, so getEventStates().click named the route a click selectedit clears it. Read the selected route from routeState === 'selected' (Events)
1.0.0WaypointDisplayProps.id was a string, while a waypoint given a number id kept the number at runtimeit is a string or a number: the id you give, otherwise a generated string. Handlers and getEventStates() return it as given
1.0.0countryCrossings: { alignment }, CountryCrossingAlignment, the knob id countryCrossings.alignment, the bearing of a getShown().countryCrossings featureremoved: a crossing stays level with the screen
1.0.0behaviour: a crossing was a near-white or near-black plaque on the route line, drawn over whatever shared its placeit’s a bubble above the route in the selected summary bubble’s default colours, which follow the style and setMapColors(), and it hides where a waypoint pin, a summary bubble or a crossing close by covers it; countryCrossings: { color: '#1A2024', label: { color: '#F1F3F5' } } keeps the old colours on a light style

GeometriesModule

SinceBeforeAfter
0.59.0{ theme: 'inverted' }, GeometryTheme, geometryThemes{ fillStyle: 'inverted' }, GeometryFillStyle, geometryFillStyles
0.59.0a feature’s properties.themeproperties.fillStyle
0.59.0themedGeometryConfigfillStyledGeometryConfig, which takes an options object from 0.61.0
0.59.0textConfig: { textField }, GeometryTextConfiglabel: { text }, GeometryLabel; applyTextConfig({ text }). All three are renamed again in 0.61.0
0.59.0lineLabelConfig: { textSize, textColor, textHaloColor, textHaloWidth, textOpacity, textOffset }, GeometryLineLabelConfiglineLabel: { size, color, haloColor, haloWidth, opacity, offset }, GeometryLineLabel, which is GeometryLineLabelConfig again from 0.61.0
0.59.0fill.color as a legacy MapLibre function object ({ stops })a colour or a MapLibre expression
0.60.0fill: { beforeLayerConfig }, line: { beforeLayerConfig }, GeometryBeforeLayerTargetsbeforeLayerConfig: { fill, line } on the module, all covering the part it leaves out
0.60.0behaviour: applyConfig without a target for a part left it where it wasit puts that part back in its default place; moveBeforeLayer still leaves it
0.61.0fill: { color: 'warm' }, a palette namefill: { palette: 'warm' }
0.61.0geometries.applyTextConfig({ text })geometries.applyLabelConfig({ text })
0.61.0GeometryLabel, GeometryLineLabelGeometryLabelConfig, GeometryLineLabelConfig
0.61.0fillStyledGeometryConfig('retro', 'top')fillStyledGeometryConfig({ palette: 'retro', beforeLayerConfig: 'top' })
0.61.0reachableRangeGeometryConfig('cold', 'inverted', 'top', fn)reachableRangeGeometryConfig({ palette: 'cold', fillStyle: 'inverted', beforeLayerConfig: 'top', title: fn })
0.61.0prepareReachableRangesForDisplay(result, 'inverted', fn), ReachableRangeLabelFnprepareReachableRangesForDisplay(result, { fillStyle: 'inverted', title: fn }), ReachableRangeTitleFn
0.62.0geometries.applyLabelConfig({ text })geometries.updateConfig({ label: { text } })
0.62.0geometries.moveBeforeLayer(target), leaving a part the record names no target for where it wasgeometries.updateConfig({ beforeLayerConfig: target }), which puts that part back in its default place
0.62.0fill: { palette: 'warm' }, a palette name; colorPalettes, colorPaletteIDs, ColorPaletteOptionsfill: { palette: ['#793F0D', '#AC703D', …] }, a list of your own CSS colours, such as the ones the map-theme plugin’s deriveMapColors returns
0.62.0the fill.palette knob of geometriesKnobCatalogue, of kind enumof kind colors
0.62.0behaviour: a palette name adapted its colours to dark map stylesthe colours you give are drawn as given
0.62.0behaviour: fillStyledGeometryConfig() without a palette coloured the features with fadedRainbowthey draw in one colour, the map’s accent or the default
0.62.0GeometriesModule.create(map, reachableRangeGeometryConfig(options)), ReachableRangeGeometryConfigOptionsReachableRangesModule.create(map, options), ReachableRangesModuleConfig; without a palette, its bands ramp from the map’s accent toward its land colour
0.62.0prepareReachableRangesForDisplay, buildReachableRangeFeatures, ReachableRangesDisplayOptionsReachableRangesModule.show(result), which prepares the ranges itself
0.62.2line: { layer }, drawn under the curated line fieldsdeprecated: layers.line, which wins over them
0.63.0line: { layer: { paint, layout } }removed: layers: { line: { paint, layout } }, which wins over the curated line fields; set a line-width there and it is drawn as given in every state
0.63.0label: { text }, lineLabel: { text }label: { title }, lineLabel: { title }: the field that names a label’s content on every module
0.63.0ReachableRangesModule.create(map, { title: fn })ReachableRangesModule.create(map, { label: { title: fn } }); ReachableRangesModuleSerializableConfig leaves out label.title
0.63.0ReachableRangesModule.create(map, { palette }), the knob id paletteReachableRangesModule.create(map, { fill: { palette } }), fill.palette, as GeometriesModule takes it
0.64.0highlight: { fillOpacityFactor, lineWidthFactor }, the knobs highlight.fillOpacityFactor, highlight.lineWidthFactor, also on ReachableRangesModulehighlight: { fill: { opacityFactor }, line: { widthFactor } }, highlight.fill.opacityFactor, highlight.line.widthFactor
0.64.0ReachableRangesModule’s label, its knobs label.*, ReachableRangeLabelConfiglineLabel, lineLabel.*, ReachableRangeLineLabelConfig: the labels run along the borders, as GeometriesModule’s lineLabel
1.0.0GeometriesModule.create(map, { fillStyle: 'inverted' }), the knob id fillStyle, also on ReachableRangesModuleGeometriesModule.create(map, { fill: { style: 'inverted' } }), fill.style; a feature’s properties.fillStyle stays. updateConfig({ fill }) replaces the whole fill: spread the current one to keep its style

TrafficFlowModule

SinceBeforeAfter
0.62.0trafficFlow.filter(filters), trafficFlow.filter()trafficFlow.updateConfig({ filters }), updateConfig({ filters: undefined })
0.63.0filters: { any: [{ roadCategories }] }, the knob ids filters.any.0.*filters: { roadCategories }, filters.*: the fields of filters are one filter, and any adds the further ones a road may match instead; TrafficFlowFilters is FiltersWithAlternatives<TrafficFlowFilter>
0.63.0showRoadClosures, the knob id filters.any.0.showRoadClosuresroadClosures, filters.roadClosures
1.0.0TrafficFlowModuleFeature typed its geometry LineString, while a section a tile draws in several parts came as a MultiLineStringa LineString or a MultiLineString: check geometry.type before you read its coordinates

TrafficIncidentsModule

SinceBeforeAfter
0.59.0icons: { filters }, or a second argument to filter(lines, icons)the root filters, for lines and icons alike; icons takes { visible } only
0.59.0IncidentsCommonConfigremoved: IncidentIconsConfig is { visible }
0.61.0behaviour: isVisible() was true while icons: { visible: true } drew the icons of hidden incidentsit is false whenever the incidents are set hidden: anyIconLayersVisible() reads the icons, and isIconsVisible() from 0.62.0
0.62.0incidents.anyIconLayersVisible(), whether an icon layer drawsincidents.isIconsVisible(), the icons.visible setting, or isVisible() while it is unset. Read a layer with map.mapLibreMap.getLayoutProperty(layerId, 'visibility')
0.62.0incidents.filter(filters), incidents.filter()incidents.updateConfig({ filters }), updateConfig({ filters: undefined })
0.63.0filters: { any: [{ magnitudes }] }, the knob ids filters.any.0.*filters: { magnitudes }, filters.*: the fields of filters are one filter, and any adds the further ones an incident may match instead; TrafficIncidentsFilters is FiltersWithAlternatives<TrafficIncidentsFilter>
1.0.0filters: { delays: { mustHaveDelay, minDelayMinutes } }, the knob ids filters.delays.mustHaveDelay, filters.delays.minDelayMinutesfilters: { delays: { required, minMinutes } }, filters.delays.required, filters.delays.minMinutes
1.0.0TrafficIncidentsModuleFeature’s roadSubcategory was required, and undefined off street and service roadsit is optional, and absent there, as on TrafficFlowModuleFeature

TrafficIncidentDetailsModule

SinceBeforeAfter
0.59.0focus: { widthScale: 1.6 }focus: { widthFactor: 1.6 }, clamped to 1–1.8
0.59.0behaviour: isVisible() reported whether anything was drawnit reports the visible setting; overlay.getShown().incidents.features.length > 0 says whether anything is drawn
0.62.0overlay.moveBeforeLayer(target)overlay.updateConfig({ beforeLayerConfig: target })
0.62.0TrafficIncidentOverlayModule, TrafficIncidentOverlayModuleConfig, trafficIncidentOverlayKnobCatalogue, trafficIncidentOverlayKnobIds, TrafficIncidentOverlayKnob, TrafficIncidentOverlayKnobId, TrafficIncidentOverlayKnobValueOfTrafficIncidentDetailsModule, TrafficIncidentDetailsModuleConfig, trafficIncidentDetailsKnobCatalogue, trafficIncidentDetailsKnobIds, TrafficIncidentDetailsKnob, TrafficIncidentDetailsKnobId, TrafficIncidentDetailsKnobValueOf
0.62.0sources and layers suffixed traffic-incident-overlay-Ntraffic-incident-details-N
0.63.0INCIDENT_FOCUS_WIDTH_FACTOR_RANGEknobEntryOf(trafficIncidentDetailsKnobCatalogue, 'highlight.widthFactor').range
0.63.0focus: { outlineColor, widthFactor } or focus: false, IncidentFocusStyle, the knob ids focus.outlineColor and focus.widthFactorhighlight: { outlineColor, widthFactor } or highlight: false, IncidentHighlightConfig, highlight.outlineColor and highlight.widthFactor: the look of a focused, hovered or clicked incident, not the setFocus subset itself
0.63.0layers.focusHalo, the layer id suffix -focus-halolayers.highlightHalo, -highlight-halo
0.64.0highlight: { outlineColor, widthFactor }, the knobs highlight.outlineColor, highlight.widthFactorhighlight: { outline: { color }, line: { widthFactor } }, highlight.outline.color, highlight.line.widthFactor

TrafficAreaAnalyticsModule

SinceBeforeAfter
0.59.0behaviour: applyConfig merged into the current configurationit replaces it: merge with updateConfig, change one metric with setColor, setHeight or filter given that metric
0.59.0behaviour: isVisible() reported whether anything was drawnit reports the visible setting; read the heatmap, hexgrid and square collections of getShown() for what is drawn
0.60.0beforeLayerConfig: { heatmap, hexgrid: { flat2D, extrusion3D }, square: { flat2D, extrusion3D } }keyed by display mode, 'hexgrid-2d', 'hexgrid-3d', 'square-2d', 'square-3d' and heatmap, plus all for the rest
0.62.0analytics.setMode(mode), analytics.setMetric(metric), analytics.modeanalytics.updateConfig({ displayMode: mode }), updateConfig({ activeMetric: metric }), analytics.getConfig()?.displayMode
0.62.0behaviour: a style change emitted shown-featuresit no longer does, as on the other modules
0.62.0analytics.filter(filters, metrics), analytics.clearFilter(metrics)analytics.setFilters(filters, metrics), setFilters(undefined, metrics)
0.62.0analytics.moveBeforeLayer(target), leaving a display mode the record names no target for where it wasanalytics.updateConfig({ beforeLayerConfig: target }), which puts that mode back in its default place
0.62.0AreaAnalyticsColorThemeAreaAnalyticsPalette; areaAnalyticsPalettes lists its names
0.62.0metricConfig.<metric>.color: 'heat'metricConfig.<metric>.palette: 'heat'; a custom { valueType, stops } moves to colorStops
0.62.0analytics.setColor('heat', metrics)analytics.setPalette('heat', metrics); use setColorStops(colorStops, metrics) for custom stops, and pass undefined to clear either
0.62.0resolveColorStops('heat')resolveColorStops(metric, { palette: 'heat' }), which returns a { valueType, stops } config
0.62.0getConfig().metricConfig.speed.color held the stops setColor('heat') expanded togetConfig().metricConfig.speed.palette holds 'heat'; read the stops with resolveColorStops
0.62.0behaviour: a networkLength palette spanned the fixed 0–5,000 m rangeit spans the loaded range; set colorStops with valueType: 'relativeToPredefinedRangePCT' to keep the fixed range
0.62.0a raw height’s scaleFactormetersPerUnit, the metres of height per unit of the metric
0.62.0the knob ids metricConfig.<metric>.color and metricConfig.<metric>.height.scaleFactormetricConfig.<metric>.palette and metricConfig.<metric>.height.metersPerUnit
0.62.2behaviour: a metric filter with both min and max kept the cells within eitherit keeps the cells within both
0.63.0metricConfig, its knob ids metricConfig.<metric>.*metrics, metrics.<metric>.*, as routing’s sections.<type>
0.63.0colorStops: { valueType: 'relativeToPredefinedRangePCT' }, 'relativeToActualRangePCT', AreaAnalyticsValueTypecolorStops: { scaleMode: 'predefinedRange' }, 'currentRange', AreaAnalyticsScaleMode: the vocabulary of the height’s scaleMode
0.63.0regionPolygon: { fillOpacity, outlineOpacity, outlineWidth, inverted: true }regionPolygon: { fill: { opacity }, line: { opacity, width }, fillStyle: 'inverted' }, as GeometriesModule names them; the knob ids follow
1.0.0height: { maxHeightMeters, minHeightMeters }, setHeight({ maxHeightMeters }), the knob ids metrics.<metric>.height.maxHeightMeters, metrics.<metric>.height.minHeightMetersheight: { maxMeters, minMeters }, setHeight({ maxMeters }), metrics.<metric>.height.maxMeters, metrics.<metric>.height.minMeters
1.0.0regionPolygon: { fillStyle: 'inverted' }, the knob id regionPolygon.fillStyleregionPolygon: { fill: { style: 'inverted' } }, regionPolygon.fill.style, as GeometriesModule takes it

CustomGeoJSONModule

SinceBeforeAfter
0.52.0shown-features subscribed per source scopecustomModule.events.on('shown-features', ({ sourceName, data }) => …) on the module
0.52.0a source named on, off or wherenot allowed: rename the source
0.61.0behaviour: show() drew the layers of a module hidden with setVisible(false) or visible: falsethey stay hidden, and the data draws on setVisible(true): call it where show() used to reveal them
0.64.0beforeID on a layer, a raw MapLibre layer idbeforeLayerConfig: 'top', a style layer such as 'lowestLabel', or { layerID } for a layer outside the style; beforeLayerConfig on the module places the layers that set none

Plugins

Each plugin declares the first SDK release it needs, up to <1.0.0, plus the 1.0.0 release candidates:

First SDK release neededPlugin releases
0.61.0Map Effects 0.1.2, Viewport Places 0.5.1, Map Theme 0.2.2, Flyover 0.0.2
0.62.0Agent Toolkit 0.11.0, Landmarks 3D 0.0.8
0.63.0Agent Toolkit 0.12.0, Map Effects 0.2.0, Map Theme 0.2.3, and the next release of every other plugin
0.64.0Agent Toolkit 0.13.0, Map Effects 0.2.1, Map Theme 0.3.0, Flyover 0.0.3, and the next release of every other plugin
1.0.0-rc.0Agent Toolkit 0.14.0
1.0.0-rc.2Agent Toolkit 0.15.1, Map Effects 0.3.0, Landmarks 3D 0.1.0

The Since column below is the plugin’s own version.

Agent Toolkit

SinceBeforeAfter
0.6.1FeatureFlags.experimentalSearch; summarizePlace(place, flags), summarizePlaces(places, flags)removed; summarizePlace(place), summarizePlaces(places)
0.7.0the toggleTilesBaseMapLayerGroups toolsetMapStyling with the basemap.<group>, buildings.footprints and buildings.3d knobs
0.7.0BaseMapState.getHillshadeModuleremoved, with HillshadeModule
0.8.0the describeMapStyling toolremoved: setMapStyling’s schema names every knob with its range or values
0.8.0'all_except' in toggleTilesPOIs and recallState'all-except'
0.9.0theme on findReachableAreas, processData, updatePlacesDisplay, locatePlace, discoverPlaces geometries; _shownThemefillStyle; _shownFillStyle
0.10.0updateRoutesDisplay({ mainColor }), RoutingState.mainColor, RoutingState.setMainColorupdateRoutesDisplay({ color }), RoutingState.color, RoutingState.setColor
0.11.0behaviour: getCurrentLocation sent the model the exact position, the device’s accuracy and the timestamp of a fresh high-accuracy fixit sends the position rounded to 3 decimals (about 100 m), accuracy of at least 111 m and no timestamp: tools: { getCurrentLocation: createGetCurrentLocationTool({ fullPrecision: true }) } keeps the exact one (Tools)
0.11.0RangeState.getEntryGeometriesModule(id) drew the entry’s reachable rangesRangeState.getEntryRangesModule(id) returns its ReachableRangesModule; getEntryGeometriesModule returns a plain GeometriesModule for polygons in a style of your own
0.11.0updateTrafficAreaAnalyticsDisplay({ colorTheme: 'heat' })updateTrafficAreaAnalyticsDisplay({ palette: 'heat' })
0.11.0updateTrafficAreaAnalyticsDisplay({ heightScale: 200 }){ maxHeightMeters: 200 } for predefinedRange or currentRange; { metersPerUnit: 200 } selects raw
0.11.0behaviour: place boundaries and custom geometries drew one rainbow colour eachthey draw in the map’s accent; outlined ones keep a neutral grey border
0.12.0setMapStyling with the basemap.<group>, buildings.footprints, buildings.3d and roads.shields knobstoggleTilesBaseMapLayerGroups({ visible, layerGroups }), which also reports the groups hidden afterwards
0.12.0setMapStyling with pois.labelColor, traffic.flow.slowColor, roads.arrows and the other knobs that left StylingModulethe map-wide ids of the module owning each: pois.label.color, traffic.flow.colors.slow, roads.arrows.visible, terrain.hillshade.exaggeration; preset applies a map preset, and reset: true resets the look knobs of every module the map has
0.12.0BaseMapState.getStylingModule()BaseMapState.getStylingFoundationsModule()
0.14.0setMapStyling with view.sky, view.skyColor, view.horizonColor, view.spaceColorview.sky.visible, view.sky.color, view.sky.horizonColor, view.space.color, the SDK’s ids
0.14.0toggleTilesBaseMapLayerGroups({ visible, layerGroups })setMapStyling with visible and groups.<group>.visible; settings lists every knob set, in place of the hidden groups
0.14.0toggleTilesPOIssetMapStyling with pois.visible and pois.filters.categories.show / .values
0.14.0toggleTilesTrafficFlow, toggleTilesTrafficIncidentssetMapStyling with traffic.flow.visible, traffic.incidents.visible and their filters.* knobs
0.14.0behaviour: setMapStyling({ reset: true }) reset the look knobs onlyit resets every knob, what the map shows included
0.14.0setPaintProperties({ changes: [{ layerId, propertyName, value }] }), setLayoutProperties (same shape)setLayerProperties({ changes: [{ layerId, paint?, layout? }] }), each a record of property name to value
0.14.0updateRoutesDisplay({ color }), RoutingState.color, RoutingState.setColor(color)setMapStyling({ set: { 'routes.color': color } }), RoutingState.knobs.values.color, RoutingState.knobs.set('color', color)
0.14.0updateTrafficAreaAnalyticsDisplay({ mode, metric, palette, scaleMode, maxHeightMeters, metersPerUnit, filter })setMapStyling with traffic.areaAnalytics.displayMode, .activeMetric and .metrics.<metric>.palette, .height.scaleMode, .height.maxMeters, .height.metersPerUnit, .filters.min / .max
0.14.0CustomGeometriesEntry._shownFillStyleremoved: the entry’s module holds its fill style
0.16.0PlacesEntry.geometries, and the boundaries PlacesState fetches, shows and returns, typed PolygonFeature<CommonPlaceProps>PolygonFeature: a fetched boundary carries the Geometry Data service’s own properties, not its place’s

Landmarks 3D

SinceBeforeAfter
0.1.0displayMode: 'dark', setDisplayMode('dark')updateConfig({ color: 'hsl(210, 9%, 17%)' }), or setKnob(landmarks, landmarks3DKnobCatalogue, 'color', …)
0.1.0displayMode: 'light', setDisplayMode('light')updateConfig({ color: 'hsl(38, 6%, 90%)' })
0.1.0displayMode: 'inherited', setDisplayMode('inherited')resetConfig(): each knob left unset follows the base map’s 3D buildings
0.1.0getDisplayMode(), Landmarks3DDisplayModeremoved: getConfig() for the knobs set, getKnob(landmarks, landmarks3DKnobCatalogue, id) for the value in force
0.1.0await landmarks.setVisible(visible)landmarks.setVisible(visible) returns void, and stores visible in the configuration
0.1.0behaviour: new Landmarks3D(map) showed the base map’s 3D - Building layer on every style load, over a hidden buildings3D groupit leaves the layer as it is. For the 3D city around the landmarks, BaseMapModule.get(map, { groups: { buildings3D: { visible: true } } })

Map Effects

SinceBeforeAfter
0.1.0effects.describe(), MapEffectsCatalogue, MapEffectsKnobDescriptorthe static effectKnobCatalogue, and getKnob(effects, effectKnobCatalogue, id) for the value in force
0.2.0effects.set(settings)effects.updateConfig(settings), or setKnob(effects, effectKnobCatalogue, id, value) for one knob
0.2.0effects.get(id), effects.reset(id)getKnob(effects, effectKnobCatalogue, id), resetKnob(effects, effectKnobCatalogue, id)
0.2.0effects.reset()effects.resetConfig()
0.2.0bloom.only naming 'traffic.incidents.majorColor', 'pois.labelColor'the map-wide ids 'traffic.incidents.colors.major', 'pois.label.color' (Bloom)
0.2.0StylingColorKnobGroupStyleColorKnobGroup
0.3.0MapEffectsSettings keyed by the knob id: new MapEffects(map, { 'bloom.intensity': 0.5 })MapEffectsConfig, each knob nested along its id: { bloom: { intensity: 0.5 } }. setKnob, setKnobs and getKnob keep the ids
0.3.0behaviour: the constructor, applyConfig and updateConfig threw RangeError for a value out of rangethey check nothing at run time, as on a map module. Pass values from outside your code to setKnobs(effects, effectKnobCatalogue, values), which checks them
0.3.0behaviour: effects.updateConfig({ 'bloom.threshold': 0.3 }) kept the bloom’s other knobsupdateConfig({ bloom: { threshold: 0.3 } }) replaces the whole bloom. setKnob(effects, effectKnobCatalogue, 'bloom.threshold', 0.3) keeps them

Map Theme

SinceBeforeAfter
0.2.0deriveMapColors, deriveMapColorsFromCss and deriveMapColorsFromImage returned nine coloursthey also return accent, which setMapColors rejects before SDK 0.59.0, so upgrade both together
0.3.0deriveMapColors, deriveMapColorsFromCss and deriveMapColorsFromImage returned labelOutlinethey return labelHalo, the name SDK 0.64.0 takes

Viewport Places

SinceBeforeAfter
0.3.0searchOptions: { geoBias }removed: each module searches the current viewport
0.4.0remove(id) logged an unknown idit throws, as update does
0.5.0searchOptions: { poiCategories }searchOptions: { filters: { poiCategories } }; no cursor