maplibre_gl_platform_interface
A common platform interface for the maplibre_gl plugin. This package is only intended to be used by the maplibre_gl package.
0.27.0
84K downloads/mo
#1194 most downloaded on pub.dev
maplibre/flutter-maplibre-gl
What this package is like to depend on
Last release 4 days ago
19 Aug 2026
Release timing varies
gaps range from 2 weeks to 9 months
Nearly every release is documented
notes for 14 of 15 stable releases
Nothing withdrawn
no release was ever pulled
3 years old
15 releases · first in 2023
8 releases in the last 12 months
see the full history below
Release timeline
15 releases · Jun 2023 to Aug 2026Releases
latest 15-
0.27.019 Aug 2026Release notes
Open source →Release 0.27.0
The plugin has a documentation site now, at maplibre.org/flutter-maplibre-gl: a guide for every part of the API, each with a live map you can pan and click.
This release regenerates the whole style property surface from the current MapLibre style spec, closes long-standing gaps between the three platforms, and cuts start-up time and the cost of large data updates. Upgrading costs little: the only compile-time change is
SourceProperties.copyWithmoving to named parameters, plus one small change for Android apps and one or two for web apps, all below.Actions needed
- Android: a map now survives its activity being destroyed and recreated, but your style content does not come back with it. Add sources, layers and images inside
onStyleLoadedCallback, which fires again after every recreation, rather than inonMapCreatedorinitState. See the migration guide (#805). - Web: the plugin now loads MapLibre GL JS itself. Delete the
maplibre-gl.jsscript tag and themaplibre-gl.csslink tag fromweb/index.html: if they stay, your pinned copy silently overrides the version the plugin is tested against. See the migration guide (#928). - Web: MapLibre GL JS 6 requires WebGL2 and no longer falls back to WebGL1, so a browser without it (Safari and iOS before 15) shows no map. Point
MapLibreMap.webLibrarySourceat a version 5 build to keep those browsers working. Version 6 also slices vector tiles instead of overscaling them, soqueryRenderedFeaturescan return a different set of features. See the migration guide (#943). SourceProperties.copyWithtakes named parameters instead of a dozen required positional ones, soprops.copyWith(cluster: true)works and future spec additions stop breaking every caller. Calls that passed values positionally need the parameter names added (#957).Expressions.xornever meant xor:^is the style spec's exponentiation operator, so the expression raised the first input to the power of the second. It is nowExpressions.power, andExpressions.moduloreplaces the misspelledExpressions.precent. The old names still work as deprecated aliases, so nothing stops compiling, but any style built withxorwas doing something else (#957).- Android, iOS: the two offline download errors that carried a vendor name are renamed,
mapboxTileCountLimitExceededtotileCountLimitExceededandmapboxInvalidRegionDefinitiontoinvalidRegionDefinition. When they fire does not change, but acatchmatching either oldPlatformExceptioncode needs the new one (#956).
Added
- Android, iOS, Web:
addColorReliefLayer()colours the terrain by elevation from a raster DEM source, the hypsometric tint of a physical map. The colour ramp is acolorReliefColorexpression overExpressions.elevation, andcolorReliefOpacitysets how strongly it covers what is below. See the color relief guide (#958). - Android, iOS, Web:
addBackgroundLayer()paints the whole map withbackgroundColoror tiles it withbackgroundPattern, the one layer type with no source. PassbelowLayerIdto place it under the layers it backs. Most published styles already carry a layer calledbackground, so reusing that id fails withlayerAlreadyExists. Changing its properties after adding it can stop it drawing while the style's own background layer is still there (maplibre-native#4502). See the background layer guide (#959). - Web:
setProjection()switches between themercator,globeandvertical-perspectiveprojections, or interpolates between them by zoom.setTerrain()raises the map by the elevation of a raster DEM source, withnullto flatten it again, andsetSky()draws the sky and the atmosphere above the horizon. All three throw anUnsupportedErroron Android and iOS, where MapLibre Native implements none of them yet. See the globe, terrain and sky guide (#960). - Android, iOS, Web: the style property surface is regenerated from the current MapLibre style spec instead of a four-year-old copy. New layer properties:
textVariableAnchorOffseton symbols,hillshadeMethodandhillshadeIlluminationAltitudefor multidirectional hillshading. New expressions:Expressions.distance,within,indexOf,sliceandelevation(#957). MapLibreMap.preWarm()starts the map engine during app start-up, for apps whose first screen is a map. Saves roughly 170 to 480 ms on Android, 45 to 165 ms on iOS and 10 to 50 ms on web (#867).- Android: feature state (
setFeatureState,getFeatureState,removeFeatureState) works on Android as well as web, so single features can be restyled without re-feeding the source. iOS throws; its SDK does not expose the API yet.promoteIdstays web-only, so Android features need a top-levelidin the GeoJSON. See the feature state guide (#889). - Android, iOS: offline regions can move between devices.
exportOfflineDatabase()writes a shareable copy,mergeOfflineRegions()imports one (now on iOS too), andgetOfflineDatabasePath()locates the store. See the offline regions guide (#886). - Android, iOS, Web: the location puck can be driven from your own position updates instead of the device GPS, with no location permission needed:
locationSource: ManualLocationSource()pluscontroller.updateManualLocation(). See the user location guide (#840). - Android, iOS, Web:
getClusterExpansionZoom()gives the zoom at which a cluster splits, so a cluster tap can zoom to exactly that instead of guessing withzoom + 2.getClusterLeaves()andgetClusterChildren()read the points behind a cluster. All three take the cluster feature'scluster_id. See the cluster guide (#896). getLayerProperties()andgetSourceProperties()read a layer's or source's properties by id, in the same shape on every platform, ornullif the id is unknown. On iOS only what came with the style is readable, so a layer or source you added at runtime answersnullthere while Android and web answer normally (#513, #985).- Android, iOS, Web:
setLight()sets the style's light source, which shades extruded geometries:anchor,position,colorandintensity. Android and iOS take constant values, web also accepts expressions; Android answersINVALID_ARGUMENTfor a value it cannot take. See the globe, terrain and sky guide (#960). setPadding()keeps map content centred while a bottom sheet or side panel covers part of the map, instead of passing padding to every camera call (#258).pauseMap()andresumeMap()stop and restart rendering for a map that is alive but off screen, such as one on an inactive tab. No-op on web (#805).- Android, iOS:
setTrackingCameraOptions()pitches the camera without giving up the active tracking mode, for a navigation-style view that stays tilted while it keeps following the user. On web it throws anUnsupportedError. See the user location guide (#888). - Web:
setGlobalStateProperty()sets a value in the style's global state, which theExpressions.globalStateexpression reads, so one switch restyles any number of layers at once. Android and iOS throw anUnsupportedError. See the expressions guide (#960). - Web:
MapLibreMap.webLibrarySourcechooses where MapLibre GL JS comes from: the build the plugin is tested against, a self-hosted copy, or one the page loads itself.MapLibreMap.ensureWebLibraryLoaded()completes once MapLibre GL JS is loaded, for calling into it directly, for exampleaddProtocol(#928). - Android, iOS, Web:
fillExtrusionRoundedCornerDistancerounds the corners of extruded shapes. Its generated dartdoc still readsnot on js, because the pinned style spec records MapLibre GL JS support for it as an open issue; it shipped in GL JS 6.2.0 and works on web (#957). - Android, iOS, Web:
clusterMinPointson a GeoJSON source sets how many points have to fall together before they become a cluster, instead of the fixed default of two (#957, #981). - Android, iOS:
attributionButtonColortints the attribution button, for styles where the default tint is hard to see. No effect on web (#805). - iOS:
LocationEnginePlatforms.iOStakesintervalMsandpulseWindowMsto pulse GPS instead of tracking continuously, easing battery use on maps that stay open a long time. The default keeps continuous tracking (#901). - Android:
volatileon vector, raster and raster-dem sources keeps their tiles out of the on-disk cache, for tiles that change often or must not be stored. The iOS SDK exposes no equivalent and MapLibre GL JS will not implement one, so it has no effect there (#957, #981). - Web: properties MapLibre GL JS supports but MapLibre Native does not implement yet are exposed too:
iconOverlapandtextOverlapon symbols,fillLayerOpacityandlineLayerOpacity,resamplingon raster and hillshade layers,filteron GeoJSON sources, thecustomraster-dem encoding with its factors, and theExpressions.globalState,joinandsplitexpressions. Android and iOS ignore them, except the custom encoding, which now throws, andjoinandsplit, which work on Android since 13.5.0 (#957, #981).
Fixed
- Android: a map no longer stays blank for good after its activity is recreated, whether by "Don't keep activities", memory pressure or rotation; the camera position comes back with it (#805).
- Android: icons added with
addImageare visible again, at the right size on high-density screens. Since 0.26.0 they could be dropped whenever draggable annotations were in use, which is the default. Undecodable bytes now report a clear error instead of crashing (#866, #868). - Android, iOS: symbols added with
addSymbolare visible again on styles whose glyph server does not host the old default font; a missing font used to hide the whole symbol, icon included. The default is nowNoto Sans Regular; for another font useaddSymbolLayerwithtextFont(#940). - Android, iOS: losing the network no longer cancels an offline region download, nor deletes the region with it on iOS. The SDK retries those failures itself once the connection is back; only the tile count limit stops a download now (#986).
- Android, iOS: adding or updating a GeoJSON source with a large payload no longer blocks the UI for the whole encode. Large payloads are encoded in the background, cutting the blocking time by a factor of two to three (#366).
- Android: a hillshade layer takes its colours again.
hillshadeShadowColorand its three companions became arrays in MapLibre Native 6.24 for multidirectional hillshading, so a single value was rejected withExpected array<color> but found string insteadand the layer silently kept the default black and white. A single value is now wrapped for you on Android and iOS, and a list is passed through (#957). - Android, iOS, Web:
queryRenderedFeaturesInRect()applies thefilterit is given; no platform decoded it, so the answer held every feature in the rectangle. Note that this call takes the filter as a JSON string, unlikequeryRenderedFeatures()(#949, #953). - A map that fails to be created now reports the failure. Code awaiting the controller,
onMapCreatedincluded, used to wait forever for a map that never arrived, with only an unhandled error in the console (#943). - Android, iOS: downloading an area that is already downloaded replaces its region instead of adding a duplicate. iOS keeps the region id the app already knows; Android assigns a new one, so read it back from the returned
OfflineRegion(#886). - Android, iOS:
setLayerProperties()works on fill-extrusion and heatmap layers too; both used to answerUNSUPPORTED_LAYER_TYPE(#960). - Android:
maxzoomon a GeoJSON source is applied again. The converter read a camel-cased key the Dart side never sends, so the value was dropped on Android while iOS and web honoured it (#981). - Android:
queryRenderedFeatures()andquerySourceFeatures()say what is wrong with a call they cannot answer:STYLE_NOT_READYbefore the style has loaded,INVALID_ARGUMENTfor a missingsourceId,layerIdsor query geometry. The failure used to arrive as a bareerrorcarrying aNullPointerExceptionmessage (#954). - Android: merging an offline database whose regions carry no metadata, such as one produced by maplibre-native, no longer fails with
type 'Null' is not a subtype of type 'Map<String, dynamic>'(#865). - iOS:
queryRenderedFeatures()andquerySourceFeatures()no longer skip a feature that failed to serialize without telling you, and no longer hang on a call they cannot answer, such as one made before the style has loaded (#949). - iOS:
queryCameraPosition()returns the camera position even whentrackCameraPositionisfalse, matching Android. It used to returnnull(#892). - iOS:
controller.cameraPositionno longer sticks on aNaNzoom from a camera event that arrived before the first layout, which misplaced camera-anchored content on maps the user had not touched (#903). - Web:
onMapIdlenow fires, matching Android and iOS; code waiting on it never ran (#857). - Web:
getFeatureState()returns the state instead of throwing, and reports no state as null rather than an empty map.removeFeatureState(sourceId)with no feature id now resets the whole source instead of doing nothing. AstateKeywith nofeatureIdis rejected. Both match Android (#889). - Web:
querySourceFeatures()now reports an error when it is called before the style has loaded, matching Android and iOS. It answered with an empty list, which the caller cannot tell apart from a source holding no features (#952). - Web:
queryCameraPosition()is implemented; it used to throwUnimplementedError(#892). - Web:
updateContentInsetsand the newsetPaddingno longer throwUnimplementedError(#258). - The bundled LICENSE no longer breaks Flutter's license collector, which showed an untitled, truncated first entry on every dependent app's
showLicensePage()(#895).
Changed
- Web: MapLibre GL JS upgraded from 5 to 6.4.1; see Actions needed above. Over 6.2 this fixes a permanent frame-rate drop after a style switch, a rejected missing-image resolver taking the rest of its batch down with it, globe zoom drifting away from the pointer, globe panning stalling at the poles, and an attribute-sanitising hole in popup and marker HTML (#943).
- Android: MapLibre Native upgraded from 13.3.0 to 13.5.0 (13.4.0, 13.4.1, 13.5.0), plus OkHttp 5.4.0, Play Services Location 21.4.0 and androidx.core-ktx 1.18.0. 13.5.0 repaints symbol paint properties driven by feature state, fixes a surface-changed ANR and works around a device-lost crash on Adreno GPUs (#877, #919, #929).
- iOS: MapLibre Native upgraded from 6.27.0 to 6.28.0 (release notes): the map view is no longer blurry in landscape on iPad (#929).
- iOS: the plugin supports Flutter's Swift Package Manager integration. The CocoaPods podspec still ships, so CocoaPods apps need no migration (#891).
- Android, iOS: a raster-dem source with
encoding: "custom"now throws anUnsupportedErrorfromaddSource(). MapLibre Native decodes only themapboxandterrariumformulas and used to read custom tiles as mapbox-encoded, drawing a plausible map from wrong elevations. OnlyaddSource()is checked: the same encoding declared insideMapLibreMap.styleStringis still decoded as mapbox without an error. Custom encoding keeps working on web (#981). - Android, iOS: panning a pitched map no longer moves the camera past the horizon, and changing a layer's
source-layerorsource-idnow takes effect (#929). - The style spec the code is generated from is now a verbatim copy of a pinned upstream release (
@maplibre/maplibre-gl-style-spec, currently 26.2.1). A weekly workflow reports what a newer release would bring to each platform and opens the update PR, and properties the native SDKs do not implement yet are generated for web only, so upgrading the SDKs unlocks them automatically (#957). - Every generated layer property, source option and expression now documents which platforms implement it, from the spec's own
sdk-supportmetadata:iconOverlapreadsbasic functionality with js (not on android, ios)instead of claiming all three. Where the spec credits a platform whose SDK exposes no such API, the docs say so rather than repeat the spec (#957, #981). - The error from
addSymbol,addCircle,addLineandaddFillwhen the annotation manager is missing now names the type and both causes: the style has not finished loading, or that type is not in the widget'sannotationOrder(#910). - Android: the Kotlin Gradle Plugin is applied only below AGP 9, so builds on AGP 9 or later no longer break. Nothing changes on AGP 8 (#905).
- Android: the unused
android-plugin-annotation-v9andandroid-plugin-offline-v9dependencies are dropped, so apps pull two fewer artifacts (#929). - Android: the plugin builds against NDK 28.2.13676358, matching Flutter's default (#956).
Docs
- New guides for user location, startup and performance and feature state (#840, #867, #889).
- Annotations: the two conditions every annotation depends on, and the constraints of both APIs, are now stated in one place (#910).
- Android:
MapLibreMap.useHybridCompositionwas documented with the wrong default; it has beenfalsesince 0.16.0. Its docs and the performance page now say what each value selects (#816). - Example app: new Manual Location Source and Feature State pages, and the Offline Regions demo now walks through the export and import round-trip (#840, #886, #889).
- Example app: the Data-Driven Expressions demo drew the USA as a triangle across the Atlantic, because one coordinate was missing its minus sign. Its polygon is now a bounding box over the contiguous states (#956).
Contributors
- @m-schmale made their first contribution in #824
- @RyanHolanda made their first contribution in #867
- @Nico04 made their first contribution in #887
- @AlexRepaire made their first contribution in #901
- @JulianBissekkou
- @gabbopalma
Full Changelog: v0.26.2...v0.27.0
Release notes
Open source →The plugin has a documentation site now, at maplibre.org/flutter-maplibre-gl: a guide for every part of the API, each with a live map you can pan and click.
This release regenerates the whole style property surface from the current MapLibre style spec, closes long-standing gaps between the three platforms, and cuts start-up time and the cost of large data updates. Upgrading costs little: the only compile-time change is
SourceProperties.copyWithmoving to named parameters, plus one small change for Android apps and one or two for web apps, all below.Actions needed
- Android: a map now survives its activity being destroyed and recreated, but your style content does not come back with it. Add sources, layers and images inside
onStyleLoadedCallback, which fires again after every recreation, rather than inonMapCreatedorinitState. See the migration guide (#805). - Web: the plugin now loads MapLibre GL JS itself. Delete the
maplibre-gl.jsscript tag and themaplibre-gl.csslink tag fromweb/index.html: if they stay, your pinned copy silently overrides the version the plugin is tested against. See the migration guide (#928). - Web: MapLibre GL JS 6 requires WebGL2 and no longer falls back to WebGL1, so a browser without it (Safari and iOS before 15) shows no map. Point
MapLibreMap.webLibrarySourceat a version 5 build to keep those browsers working. Version 6 also slices vector tiles instead of overscaling them, soqueryRenderedFeaturescan return a different set of features. See the migration guide (#943). SourceProperties.copyWithtakes named parameters instead of a dozen required positional ones, soprops.copyWith(cluster: true)works and future spec additions stop breaking every caller. Calls that passed values positionally need the parameter names added (#957).Expressions.xornever meant xor:^is the style spec's exponentiation operator, so the expression raised the first input to the power of the second. It is nowExpressions.power, andExpressions.moduloreplaces the misspelledExpressions.precent. The old names still work as deprecated aliases, so nothing stops compiling, but any style built withxorwas doing something else (#957).- Android, iOS: the two offline download errors that carried a vendor name are renamed,
mapboxTileCountLimitExceededtotileCountLimitExceededandmapboxInvalidRegionDefinitiontoinvalidRegionDefinition. When they fire does not change, but acatchmatching either oldPlatformExceptioncode needs the new one (#956).
Added
- Android, iOS, Web:
addColorReliefLayer()colours the terrain by elevation from a raster DEM source, the hypsometric tint of a physical map. The colour ramp is acolorReliefColorexpression overExpressions.elevation, andcolorReliefOpacitysets how strongly it covers what is below. See the color relief guide (#958). - Android, iOS, Web:
addBackgroundLayer()paints the whole map withbackgroundColoror tiles it withbackgroundPattern, the one layer type with no source. PassbelowLayerIdto place it under the layers it backs. Most published styles already carry a layer calledbackground, so reusing that id fails withlayerAlreadyExists. Changing its properties after adding it can stop it drawing while the style's own background layer is still there (maplibre-native#4502). See the background layer guide (#959). - Web:
setProjection()switches between themercator,globeandvertical-perspectiveprojections, or interpolates between them by zoom.setTerrain()raises the map by the elevation of a raster DEM source, withnullto flatten it again, andsetSky()draws the sky and the atmosphere above the horizon. All three throw anUnsupportedErroron Android and iOS, where MapLibre Native implements none of them yet. See the globe, terrain and sky guide (#960). - Android, iOS, Web: the style property surface is regenerated from the current MapLibre style spec instead of a four-year-old copy. New layer properties:
textVariableAnchorOffseton symbols,hillshadeMethodandhillshadeIlluminationAltitudefor multidirectional hillshading. New expressions:Expressions.distance,within,indexOf,sliceandelevation(#957). MapLibreMap.preWarm()starts the map engine during app start-up, for apps whose first screen is a map. Saves roughly 170 to 480 ms on Android, 45 to 165 ms on iOS and 10 to 50 ms on web (#867).- Android: feature state (
setFeatureState,getFeatureState,removeFeatureState) works on Android as well as web, so single features can be restyled without re-feeding the source. iOS throws; its SDK does not expose the API yet.promoteIdstays web-only, so Android features need a top-levelidin the GeoJSON. See the feature state guide (#889). - Android, iOS: offline regions can move between devices.
exportOfflineDatabase()writes a shareable copy,mergeOfflineRegions()imports one (now on iOS too), andgetOfflineDatabasePath()locates the store. See the offline regions guide (#886). - Android, iOS, Web: the location puck can be driven from your own position updates instead of the device GPS, with no location permission needed:
locationSource: ManualLocationSource()pluscontroller.updateManualLocation(). See the user location guide (#840). - Android, iOS, Web:
getClusterExpansionZoom()gives the zoom at which a cluster splits, so a cluster tap can zoom to exactly that instead of guessing withzoom + 2.getClusterLeaves()andgetClusterChildren()read the points behind a cluster. All three take the cluster feature'scluster_id. See the cluster guide (#896). getLayerProperties()andgetSourceProperties()read a layer's or source's properties by id, in the same shape on every platform, ornullif the id is unknown. On iOS only what came with the style is readable, so a layer or source you added at runtime answersnullthere while Android and web answer normally (#513, #985).- Android, iOS, Web:
setLight()sets the style's light source, which shades extruded geometries:anchor,position,colorandintensity. Android and iOS take constant values, web also accepts expressions; Android answersINVALID_ARGUMENTfor a value it cannot take. See the globe, terrain and sky guide (#960). setPadding()keeps map content centred while a bottom sheet or side panel covers part of the map, instead of passing padding to every camera call (#258).pauseMap()andresumeMap()stop and restart rendering for a map that is alive but off screen, such as one on an inactive tab. No-op on web (#805).- Android, iOS:
setTrackingCameraOptions()pitches the camera without giving up the active tracking mode, for a navigation-style view that stays tilted while it keeps following the user. On web it throws anUnsupportedError. See the user location guide (#888). - Web:
setGlobalStateProperty()sets a value in the style's global state, which theExpressions.globalStateexpression reads, so one switch restyles any number of layers at once. Android and iOS throw anUnsupportedError. See the expressions guide (#960). - Web:
MapLibreMap.webLibrarySourcechooses where MapLibre GL JS comes from: the build the plugin is tested against, a self-hosted copy, or one the page loads itself.MapLibreMap.ensureWebLibraryLoaded()completes once MapLibre GL JS is loaded, for calling into it directly, for exampleaddProtocol(#928). - Android, iOS, Web:
fillExtrusionRoundedCornerDistancerounds the corners of extruded shapes. Its generated dartdoc still readsnot on js, because the pinned style spec records MapLibre GL JS support for it as an open issue; it shipped in GL JS 6.2.0 and works on web (#957). - Android, iOS, Web:
clusterMinPointson a GeoJSON source sets how many points have to fall together before they become a cluster, instead of the fixed default of two (#957, #981). - Android, iOS:
attributionButtonColortints the attribution button, for styles where the default tint is hard to see. No effect on web (#805). - iOS:
LocationEnginePlatforms.iOStakesintervalMsandpulseWindowMsto pulse GPS instead of tracking continuously, easing battery use on maps that stay open a long time. The default keeps continuous tracking (#901). - Android:
volatileon vector, raster and raster-dem sources keeps their tiles out of the on-disk cache, for tiles that change often or must not be stored. The iOS SDK exposes no equivalent and MapLibre GL JS will not implement one, so it has no effect there (#957, #981). - Web: properties MapLibre GL JS supports but MapLibre Native does not implement yet are exposed too:
iconOverlapandtextOverlapon symbols,fillLayerOpacityandlineLayerOpacity,resamplingon raster and hillshade layers,filteron GeoJSON sources, thecustomraster-dem encoding with its factors, and theExpressions.globalState,joinandsplitexpressions. Android and iOS ignore them, except the custom encoding, which now throws, andjoinandsplit, which work on Android since 13.5.0 (#957, #981).
Fixed
- Android: a map no longer stays blank for good after its activity is recreated, whether by "Don't keep activities", memory pressure or rotation; the camera position comes back with it (#805).
- Android: icons added with
addImageare visible again, at the right size on high-density screens. Since 0.26.0 they could be dropped whenever draggable annotations were in use, which is the default. Undecodable bytes now report a clear error instead of crashing (#866, #868). - Android, iOS: symbols added with
addSymbolare visible again on styles whose glyph server does not host the old default font; a missing font used to hide the whole symbol, icon included. The default is nowNoto Sans Regular; for another font useaddSymbolLayerwithtextFont(#940). - Android, iOS: losing the network no longer cancels an offline region download, nor deletes the region with it on iOS. The SDK retries those failures itself once the connection is back; only the tile count limit stops a download now (#986).
- Android, iOS: adding or updating a GeoJSON source with a large payload no longer blocks the UI for the whole encode. Large payloads are encoded in the background, cutting the blocking time by a factor of two to three (#366).
- Android: a hillshade layer takes its colours again.
hillshadeShadowColorand its three companions became arrays in MapLibre Native 6.24 for multidirectional hillshading, so a single value was rejected withExpected array<color> but found string insteadand the layer silently kept the default black and white. A single value is now wrapped for you on Android and iOS, and a list is passed through (#957). - Android, iOS, Web:
queryRenderedFeaturesInRect()applies thefilterit is given; no platform decoded it, so the answer held every feature in the rectangle. Note that this call takes the filter as a JSON string, unlikequeryRenderedFeatures()(#949, #953). - A map that fails to be created now reports the failure. Code awaiting the controller,
onMapCreatedincluded, used to wait forever for a map that never arrived, with only an unhandled error in the console (#943). - Android, iOS: downloading an area that is already downloaded replaces its region instead of adding a duplicate. iOS keeps the region id the app already knows; Android assigns a new one, so read it back from the returned
OfflineRegion(#886). - Android, iOS:
setLayerProperties()works on fill-extrusion and heatmap layers too; both used to answerUNSUPPORTED_LAYER_TYPE(#960). - Android:
maxzoomon a GeoJSON source is applied again. The converter read a camel-cased key the Dart side never sends, so the value was dropped on Android while iOS and web honoured it (#981). - Android:
queryRenderedFeatures()andquerySourceFeatures()say what is wrong with a call they cannot answer:STYLE_NOT_READYbefore the style has loaded,INVALID_ARGUMENTfor a missingsourceId,layerIdsor query geometry. The failure used to arrive as a bareerrorcarrying aNullPointerExceptionmessage (#954). - Android: merging an offline database whose regions carry no metadata, such as one produced by maplibre-native, no longer fails with
type 'Null' is not a subtype of type 'Map<String, dynamic>'(#865). - iOS:
queryRenderedFeatures()andquerySourceFeatures()no longer skip a feature that failed to serialize without telling you, and no longer hang on a call they cannot answer, such as one made before the style has loaded (#949). - iOS:
queryCameraPosition()returns the camera position even whentrackCameraPositionisfalse, matching Android. It used to returnnull(#892). - iOS:
controller.cameraPositionno longer sticks on aNaNzoom from a camera event that arrived before the first layout, which misplaced camera-anchored content on maps the user had not touched (#903). - Web:
onMapIdlenow fires, matching Android and iOS; code waiting on it never ran (#857). - Web:
getFeatureState()returns the state instead of throwing, and reports no state as null rather than an empty map.removeFeatureState(sourceId)with no feature id now resets the whole source instead of doing nothing. AstateKeywith nofeatureIdis rejected. Both match Android (#889). - Web:
querySourceFeatures()now reports an error when it is called before the style has loaded, matching Android and iOS. It answered with an empty list, which the caller cannot tell apart from a source holding no features (#952). - Web:
queryCameraPosition()is implemented; it used to throwUnimplementedError(#892). - Web:
updateContentInsetsand the newsetPaddingno longer throwUnimplementedError(#258). - The bundled LICENSE no longer breaks Flutter's license collector, which showed an untitled, truncated first entry on every dependent app's
showLicensePage()(#895).
Changed
- Web: MapLibre GL JS upgraded from 5 to 6.4.1; see Actions needed above. Over 6.2 this fixes a permanent frame-rate drop after a style switch, a rejected missing-image resolver taking the rest of its batch down with it, globe zoom drifting away from the pointer, globe panning stalling at the poles, and an attribute-sanitising hole in popup and marker HTML (#943).
- Android: MapLibre Native upgraded from 13.3.0 to 13.5.0 (13.4.0, 13.4.1, 13.5.0), plus OkHttp 5.4.0, Play Services Location 21.4.0 and androidx.core-ktx 1.18.0. 13.5.0 repaints symbol paint properties driven by feature state, fixes a surface-changed ANR and works around a device-lost crash on Adreno GPUs (#877, #919, #929).
- iOS: MapLibre Native upgraded from 6.27.0 to 6.28.0 (release notes): the map view is no longer blurry in landscape on iPad (#929).
- iOS: the plugin supports Flutter's Swift Package Manager integration. The CocoaPods podspec still ships, so CocoaPods apps need no migration (#891).
- Android, iOS: a raster-dem source with
encoding: "custom"now throws anUnsupportedErrorfromaddSource(). MapLibre Native decodes only themapboxandterrariumformulas and used to read custom tiles as mapbox-encoded, drawing a plausible map from wrong elevations. OnlyaddSource()is checked: the same encoding declared insideMapLibreMap.styleStringis still decoded as mapbox without an error. Custom encoding keeps working on web (#981). - Android, iOS: panning a pitched map no longer moves the camera past the horizon, and changing a layer's
source-layerorsource-idnow takes effect (#929). - The style spec the code is generated from is now a verbatim copy of a pinned upstream release (
@maplibre/maplibre-gl-style-spec, currently 26.2.1). A weekly workflow reports what a newer release would bring to each platform and opens the update PR, and properties the native SDKs do not implement yet are generated for web only, so upgrading the SDKs unlocks them automatically (#957). - Every generated layer property, source option and expression now documents which platforms implement it, from the spec's own
sdk-supportmetadata:iconOverlapreadsbasic functionality with js (not on android, ios)instead of claiming all three. Where the spec credits a platform whose SDK exposes no such API, the docs say so rather than repeat the spec (#957, #981). - The error from
addSymbol,addCircle,addLineandaddFillwhen the annotation manager is missing now names the type and both causes: the style has not finished loading, or that type is not in the widget'sannotationOrder(#910). - Android: the Kotlin Gradle Plugin is applied only below AGP 9, so builds on AGP 9 or later no longer break. Nothing changes on AGP 8 (#905).
- Android: the unused
android-plugin-annotation-v9andandroid-plugin-offline-v9dependencies are dropped, so apps pull two fewer artifacts (#929). - Android: the plugin builds against NDK 28.2.13676358, matching Flutter's default (#956).
Docs
- New guides for user location, startup and performance and feature state (#840, #867, #889).
- Annotations: the two conditions every annotation depends on, and the constraints of both APIs, are now stated in one place (#910).
- Android:
MapLibreMap.useHybridCompositionwas documented with the wrong default; it has beenfalsesince 0.16.0. Its docs and the performance page now say what each value selects (#816). - Example app: new Manual Location Source and Feature State pages, and the Offline Regions demo now walks through the export and import round-trip (#840, #886, #889).
- Example app: the Data-Driven Expressions demo drew the USA as a triangle across the Atlantic, because one coordinate was missing its minus sign. Its polygon is now a bounding box over the contiguous states (#956).
Release notes
Open source →See the top-level CHANGELOG for full details.
The
MapLibrePlatformmembers added below have no default implementation, so an external platform package, or a mock in tests, has to add them. Apps calling the API are unaffected.Added
shapeStyleProperties()normalizes a style entry into the shape every platform answers with, sogetLayerProperties()andgetSourceProperties()agree. JavaScript has one number type, so integral values become ints and only genuinely fractional ones stay doubles; read numbers asnum(#513).getLayerProperties(layerId)andgetSourceProperties(sourceId), returning a layer's or source's properties as a style-spec map, ornullfor an unknown id (#513).pauseMap()andresumeMap(), forwarded over the channel asmap#pauseandmap#resume, to stop and restart rendering for a map that is alive but off screen (#805).LocationEnginePlatforms.iOSacceptsintervalMsandpulseWindowMs, forwarded to the iOS location engine so GPS can be pulsed instead of tracked continuously (#901).- An app-provided location source. Adds
LocationSourcewithManualLocationSourceandPlatformLocationSource, theManualLocationUpdatemodel, andsetManualLocation, forwarded over the channel aslocationComponent#setManualLocation. Which source a map uses arrives as thelocationSourcekey in the map options (#840). MapLibreJsSource, describing where the web implementation loads MapLibre GL JS from. It lives here so apps can configure it throughmaplibre_glwithout importing the web package; Android and iOS ignore it (#928).MapLibreGlobalPlatform, for calls global to the plugin rather than tied to a single map, withMapLibreGlobalMethodChannelas the default. The web package replaces the instance at registration, routingpreWarm()andensureWebLibraryLoaded()to the web implementation (#928).setFeatureState,removeFeatureStateandgetFeatureStateare forwarded over the channel instead of throwingUnimplementedError, so feature state works on Android. iOS throws anUnsupportedErrornaming the platform (#889).getClusterExpansionZoom,getClusterChildrenandgetClusterLeaves, forwarded over the channel assource#getCluster*. Each takes the cluster's integercluster_id; the two feature calls decode a list of JSON strings, asquerySourceFeaturesdoes (#896).setTrackingCameraOptions, forwarded over the channel aslocationComponent#setTrackingCameraOptionswith atiltand an optionalduration. It returns whether the pitch animation ran (#888).
Fixed
- A large GeoJSON payload is encoded on a background isolate instead of blocking the UI for the whole encode. Smaller ones keep the faster synchronous path, and writes to the same source id stay in the order they were issued (#366).
- Android: a map now survives its activity being destroyed and recreated, but your style content does not come back with it. Add sources, layers and images inside
-
0.26.219 Jun 2026Release notes
Open source →Note: This release enforces a minimum Flutter version of 3.29, which was already required in practice since 0.26.0 but not reflected in the package constraints (#823).
Added
- A live web demo of the example app is now available at maplibre.github.io/flutter-maplibre-gl.
Fixed
- Setting map options inside a widget that rebuilds frequently (e.g. with
setState) no longer causes unnecessary map updates. Options containing nested lists such ascameraTargetBoundswere always treated as changed, even when the value was identical (#849). - Android, iOS:
doubleClickZoomEnabled: falsenow works correctly. Previously this option was only respected on web, so single taps on Android and iOS always had a ~300 ms delay while the platform waited to rule out a double-tap (#829). - iOS:
setCustomHeadersandsetHttpHeadersnow correctly apply to all map network requests (tiles, styles, sprites, glyphs). Both APIs were previously silently ignored on iOS (#831). - iOS:
setMapLanguagenow correctly changes map labels on non-Mapbox styles (e.g. OpenFreeMap Liberty). Previously, callingsetMapLanguageon iOS had no effect and place names were displayed using the style's default language (#830). A new Map Language example in the example app demonstrates this across several languages. - iOS: Layer color properties now accept any valid CSS color string (
rgb(),rgba(),hsl(),hsla(), named colors). Previously only hex colors were supported and anything else rendered as transparent (#832). - iOS: Fixed a crash that could occur when the app was sent to the background while using PMTiles sources (#833).
- iOS: Fixed a crash on cold launch when the map was first displayed at zero size (e.g. inside a hidden widget or during app startup) (#841).
- iOS: Fixed a memory leak where map resources were not fully released when the map widget was disposed (#837).
- Android: Fixed a crash when style API methods were called while the map style was still loading.
Changed
- Android: MapLibre Android SDK upgraded from 13.1.0 to 13.3.0.
- iOS: MapLibre iOS upgraded from 6.26.0 to 6.27.0.
Contributors
- @wilinz made their first contribution in #841
- @frenradar made their first contribution in #837
- @gonuit made their first contribution in #832
- @L36951 made their first contribution in #830
- @stefanschaller
- @gabbopalma
Full Changelog: v0.26.1...v0.26.2
Release notes
Open source →Note: This release enforces a minimum Flutter version of 3.29, which was already required in practice since 0.26.0 but not reflected in the package constraints (#823).
Added
- A live web demo of the example app is now available at maplibre.org/flutter-maplibre-gl.
Fixed
- Setting map options inside a widget that rebuilds frequently (e.g. with
setState) no longer causes unnecessary map updates. Options containing nested lists such ascameraTargetBoundswere always treated as changed, even when the value was identical (#849). - Android, iOS:
doubleClickZoomEnabled: falsenow works correctly. Previously this option was only respected on web, so single taps on Android and iOS always had a ~300 ms delay while the platform waited to rule out a double-tap (#829). - iOS:
setCustomHeadersandsetHttpHeadersnow correctly apply to all map network requests (tiles, styles, sprites, glyphs). Both APIs were previously silently ignored on iOS (#831). - iOS:
setMapLanguagenow correctly changes map labels on non-Mapbox styles (e.g. OpenFreeMap Liberty). Previously, callingsetMapLanguageon iOS had no effect and place names were displayed using the style's default language (#830). A new Map Language example in the example app demonstrates this across several languages. - iOS: Layer color properties now accept any valid CSS color string (
rgb(),rgba(),hsl(),hsla(), named colors). Previously only hex colors were supported and anything else rendered as transparent (#832). - iOS: Fixed a crash that could occur when the app was sent to the background while using PMTiles sources (#833).
- iOS: Fixed a crash on cold launch when the map was first displayed at zero size (e.g. inside a hidden widget or during app startup) (#841).
- iOS: Fixed a memory leak where map resources were not fully released when the map widget was disposed (#837).
- Android: Fixed a crash when style API methods were called while the map style was still loading.
Changed
- Android: MapLibre Android SDK upgraded from 13.1.0 to 13.3.0.
- iOS: MapLibre iOS upgraded from 6.26.0 to 6.27.0.
Release notes
Open source →No platform-interface changes; version aligned with the
maplibre_gl0.26.2 release. See the top-level CHANGELOG for full details. -
0.26.114 May 2026Release notes
Open source →0.26.1
Note: Several users reported crashes on a range of Android devices after upgrading to 0.26.0, particularly on older / less recent hardware. These issues are addressed in 0.26.1 (see the Android fixes below).
Fixed
- Android: Hybrid composition now correctly enables
textureModewhen necessary, preventing crashes and rendering and issues with platform views (#816). - Android: Null-check
mapViewinside theonResumerepaint runnable to avoidNullPointerExceptionwhen the map is disposed (e.g. dialogs/bottom sheets) before the posted runnable drains (#809). - De-register the annotation drag callback on
AnnotationManager.dispose()to prevent jumpy drags and_idToAnnotation.containsKeycrashes after style reloads on Android and iOS (#806).
Changed
- Android: MapLibre Android SDK upgraded from 13.0.2 to 13.1.0 (#811).
- iOS: MapLibre iOS upgraded from 6.25.1 to 6.26.0.
Docs
- Web: Updated
maplibre-glJavaScript and CSS version to5.24.0inREADME.mdto avoidNoSuchMethodErroronMapLibreMapdispose with the previously referenced 4.3.0 version (#814).
Contributors
- @heyteacher made their first contribution in #814
- @RumataEstorsky made their first contribution in #809
- @hamadcc made their first contribution in #806
- @srmncnk
- @gabbopalma
Full Changelog: v0.26.0...v0.26.1
Release notes
Open source →Note: Several users reported crashes on a range of Android devices after upgrading to 0.26.0, particularly on older / less recent hardware. These issues are addressed in 0.26.1 (see the Android fixes below).
Fixed
- Android: Hybrid composition now correctly enables
textureModewhen necessary, preventing crashes and rendering and issues with platform views (#816). - Android: Null-check
mapViewinside theonResumerepaint runnable to avoidNullPointerExceptionwhen the map is disposed (e.g. dialogs/bottom sheets) before the posted runnable drains (#809). - De-register the annotation drag callback on
AnnotationManager.dispose()to prevent jumpy drags and_idToAnnotation.containsKeycrashes after style reloads on Android and iOS (#806).
Changed
- Android: MapLibre Android SDK upgraded from 13.0.2 to 13.1.0 (#811).
- iOS: MapLibre iOS upgraded from 6.25.1 to 6.26.0.
Docs
- Web: Updated
maplibre-glJavaScript and CSS version to5.24.0inREADME.mdto avoidNoSuchMethodErroronMapLibreMapdispose with the previously referenced 4.3.0 version (#814).
Release notes
Open source →See the top-level CHANGELOG for full details.
Fixed
- Android: Forward
textureModethrough the method channel so hybrid composition can enable it when necessary (#816).
- Android: Hybrid composition now correctly enables
-
0.26.024 Apr 2026Release notes
Open source →Version 0.26.0 marks a milestone for
flutter-maplibre-glThis release resolves numerous long-standing bugs accumulated over the years and completes the transition to WASM compilation for the web platform, ensuring full compatibility with Flutter's modern web toolchain.
It also introduces a new Example App for users to explore the latest features - see maplibre_gl_example for details.Breaking
initialCameraPositionis now nullable to support style-defined camera options (#769).- Removed
LocationEngineAndroidProperties. All fields flattened intoLocationEnginePlatformswith nullable platform-specific fields.
Use Platform-specific constructors:LocationEnginePlatforms.android(),.iOS(),.web()instead. - Removed deprecated typedefs:
MaplibreMapController,MaplibreMap,MaplibreStyles. UseMapLibreMapController,MapLibreMap,MapLibreStylesinstead. - Removed deprecated callback:
onInfoWindowTappedfromMapLibreMapController. - Removed deprecated methods:
removeImageSource(useremoveSource) andaddLayerBelow(useaddImageLayerBelow).
Added
- Cross-platform map snapshot functionality via
takeSnapshot()(#726). featureTapsTriggersMapClickoption to control whether feature taps also trigger map click callbacks, defaults tofalse(#729).- Fire
onMapClickfor all map taps, including after interactive features (#707). - Unit tests for core packages (#765).
- Offline Regions: richer control and observability over downloads on Android and iOS (#795).
pauseOfflineRegionDownload/resumeOfflineRegionDownloadto control in-progress downloads.getOfflineRegionStatusreturningOfflineRegionStatuswith resource counts, bytes, progress and completion.InProgressevents now carrycompletedResourceCount,requiredResourceCount, andcompletedResourceSizefor tile/byte progress in addition to the percentage.clearAmbientCacheandresetOfflineDatabaseglobals to evict unpinned tiles or fully reset the offline DB (in-flight downloads are terminated Dart-side before reset/deletion).setOfflineMaxConcurrentRequeststo cap tile concurrency (total on Android, per-host on both) and avoid upstream rate limiting.
- clusterProperties: Introduced native implementation of
clusterPropertiesfor clustered GeoJSON sources. Both the simple operator-string form (e.g.{'sum': ['+', ['get', 'x']]}) and the explicit reduce-expression form are now applied natively; previously the property was serialized from Dart but ignored by both native converters (#792). - easeCamera interpolation:
easeCameraaccepts an optionalCameraAnimationInterpolationto control the animation easing curve (linear,easeInOut,easeOut,fastOutLinearIn). UseCameraAnimationInterpolation.linearfor smooth continuous tracking (e.g. following a moving GPS target) without velocity discontinuities between successive calls. Omitting the parameter preserves the previous default behavior (#789).- iOS: all four curves are supported exactly;
fastOutLinearInis implemented viaCAMediaTimingFunction(controlPoints: 0.4, 0.0, 1.0, 1.0)(Material Design cubic Bezier). - Android: MapLibre Android only exposes a boolean easing flag on
easeCamera, so onlylinearis distinct —easeInOut,easeOut, andfastOutLinearInall map to the native ease-in/ease-out. SeeCameraAnimationInterpolationdartdoc for per-value details. - Web:
easeCamerais now fully implemented via MapLibre GL JSmap.easeTo({easing}). Each interpolation value maps to a cubic-bezier callback (easeInOut→(0.42, 0, 0.58, 1),easeOut→(0, 0, 0.58, 1),fastOutLinearIn→(0.4, 0, 1, 1)). Previously threwUnimplementedError.
- iOS: all four curves are supported exactly;
- iOS: Implemented
setMaximumFpsto control the preferred frame rate (#739). - Android: Google Mobile Services (GMS) Location Engine support (#721).
- Web: Exposed
onMouseMoveand added feature state management (setFeatureState,getFeatureState,removeFeatureState) (#718). - Web: Added
getLayerVisibility, web snapshot, and map sizing features (#722). - Web: Added Scale Control (#720).
- iOS: Location engine support —
enableHighAccuracyanddisplacementconfigurable viaLocationEnginePlatforms.iOS(). - Web: Location engine properties (
enableHighAccuracy,maximumAge,timeout) viaLocationEnginePlatforms.web(). - Platform-specific constructors for
LocationEnginePlatforms:.android(),.iOS(),.web().
Changed
- Android: Reduced MapLibre SDK logging verbosity to minimize log spam (#752).
- Android: Enhanced GeoJSON source handling with type checks and error logging (#764).
- Android: Check style exists and is loaded before adding a Layer (#768).
- Android: Check source exists before adding (#734).
- Android: MapLibre Android SDK upgraded from 13.0.0 to 13.0.2, switched to OpenGL renderer variant (
android-sdk-opengl) for better stability and performance on older devices. - iOS: Updated project settings for UISceneDelegate compatibility (#767).
- iOS: MapLibre iOS SDK upgraded from 6.19.1 to 6.25.1.
- Web: Upgraded MapLibre GL JS from 4.7.1 to 5.24.0 (#761, #651).
- Web: Migrated
preserveDrawingBuffer,antialias, andfailIfMajorPerformanceCaveatfrom top-levelMapOptionstocanvasContextAttributes. - Web: Updated
on()/off()/once()event methods to handle v5'sSubscriptionreturn type instead of map instance. - Web: Removed obsolete
customAttributionfromMapOptions(now part ofAttributionControloptions in v5). - GitHub Actions:
actions/upload-artifactupdated from v6 to v7 (#748). - Bumped Dart and melos version to latest (#762).
- Minimum Dart SDK version bumped from
3.5.0to3.7.0(#762). - Gradle wrapper updated to 9.4.0, Kotlin to 2.3.10, Android Gradle Plugin to 9.1.0 (#753-#758).
Fixed
- Fix data properties not being added to Annotation created in AnnotationManager (#770).
- Fix double JSON encoding in layer properties causing Android/iOS type errors (#747).
- iOS:
icon-text-fit-paddinginsets now use the correct style-spec order[top, right, bottom, left]—leftandrightwere previously swapped (#792). - Fix
text-fontproperty handling on Android and iOS to correctly accept font stacks as string arrays instead of only expressions. - Fix
textFontinSymbolManagerto pass font names as a simple string array, resolving rendering issues on native platforms. - Add DEM encoding support (
terrarium/mapbox) for raster-dem tile sources on Android and iOS. - Fix heatmap color expressions in example app to use proper
Expressions.rgba/Expressions.rgbsyntax. - Android: Fix map partially not responsive in split screen (#771).
- Android: GeoJSON source updates are now synchronous when drag is enabled, preventing stale feature positions during drag interactions and improved performance (#716).
- Android: Disabled texture mode by default and improved MapView lifecycle management (#723).
- Android: Removed unnecessary
OfflineActivityfromAndroidManifest.xml(#724). - Offline Regions: retain download
StreamSubscriptions in a module-level map so Dart's GC can't drop native events while a download is paused (#795). - Android (Offline): throttle progress events to 100ms and discard non-monotonic counts so cache-served bursts don't starve the isolate and block pause taps; track in-flight downloads to support pause/resume/status (#795).
- iOS (Offline): track active
MLNOfflinePackinstances so pause/resume/status operate on the live pack rather than reloading from storage (#795). - iOS: Deferred
onStyleLoadedcallback to avoid race conditions (#719). - Web: Improved
styleimagemissinghandling (#725). - Web: Fixed JS Interop and WASM compilation in release mode (#714).
- Web: Fixed missing prototype on empty JS object created via interop.
- Web:
removeLayerandremoveSourceno longer throw when the layer/source doesn't exist. - Web:
setGeoJsonSourcereturns early instead of crashing when the source doesn't exist. - Web:
GeolocateControlnow respectsMyLocationTrackingModeand triggers programmatically. - Example: GPS location page. Fixed web permission check, wired
onUserLocationUpdated, web-specific tracking modes. - Example: GeoJSON cluster. Added
['has', 'point_count']filter to fix null property errors on unclustered points.
Contributors: @MichaelNeufeld, @danieljosua1, @EyreFree, @skol-pro, @gabbopalma
Full Changelog: v0.25.0...v0.26.0Release notes
Open source →Version 0.26.0 is a milestone release for flutter-maplibre-gl.
This release addresses numerous long-standing bugs that have accumulated over the years and completes the transition to the WASM compilation for the web platform, ensuring full compatibility with Flutter's modern web toolchain.Breaking
initialCameraPositionis now nullable to support style-defined camera options (#769).- Removed
LocationEngineAndroidProperties. All fields flattened intoLocationEnginePlatformswith nullable platform-specific fields.
Use Platform-specific constructors:LocationEnginePlatforms.android(),.iOS(),.web()instead. - Removed deprecated typedefs:
MaplibreMapController,MaplibreMap,MaplibreStyles. UseMapLibreMapController,MapLibreMap,MapLibreStylesinstead. - Removed deprecated callback:
onInfoWindowTappedfromMapLibreMapController. - Removed deprecated methods:
removeImageSource(useremoveSource) andaddLayerBelow(useaddImageLayerBelow).
Added
- Cross-platform map snapshot functionality via
takeSnapshot()(#726). featureTapsTriggersMapClickoption to control whether feature taps also trigger map click callbacks, defaults tofalse(#729).- Fire
onMapClickfor all map taps, including after interactive features (#707). - Unit tests for core packages (#765).
- Offline Regions: richer control and observability over downloads on Android and iOS (#795).
pauseOfflineRegionDownload/resumeOfflineRegionDownloadto control in-progress downloads.getOfflineRegionStatusreturningOfflineRegionStatuswith resource counts, bytes, progress and completion.InProgressevents now carrycompletedResourceCount,requiredResourceCount, andcompletedResourceSizefor tile/byte progress in addition to the percentage.clearAmbientCacheandresetOfflineDatabaseglobals to evict unpinned tiles or fully reset the offline DB (in-flight downloads are terminated Dart-side before reset/deletion).setOfflineMaxConcurrentRequeststo cap tile concurrency (total on Android, per-host on both) and avoid upstream rate limiting.
- clusterProperties: Introduced native implementation of
clusterPropertiesfor clustered GeoJSON sources. Both the simple operator-string form (e.g.{'sum': ['+', ['get', 'x']]}) and the explicit reduce-expression form are now applied natively; previously the property was serialized from Dart but ignored by both native converters (#792). - easeCamera interpolation:
easeCameraaccepts an optionalCameraAnimationInterpolationto control the animation easing curve (linear,easeInOut,easeOut,fastOutLinearIn). UseCameraAnimationInterpolation.linearfor smooth continuous tracking (e.g. following a moving GPS target) without velocity discontinuities between successive calls. Omitting the parameter preserves the previous default behavior (#789).- iOS: all four curves are supported exactly;
fastOutLinearInis implemented viaCAMediaTimingFunction(controlPoints: 0.4, 0.0, 1.0, 1.0)(Material Design cubic Bezier). - Android: MapLibre Android only exposes a boolean easing flag on
easeCamera, so onlylinearis distinct —easeInOut,easeOut, andfastOutLinearInall map to the native ease-in/ease-out. SeeCameraAnimationInterpolationdartdoc for per-value details. - Web:
easeCamerais now fully implemented via MapLibre GL JSmap.easeTo({easing}). Each interpolation value maps to a cubic-bezier callback (easeInOut→(0.42, 0, 0.58, 1),easeOut→(0, 0, 0.58, 1),fastOutLinearIn→(0.4, 0, 1, 1)). Previously threwUnimplementedError.
- iOS: all four curves are supported exactly;
- iOS: Implemented
setMaximumFpsto control the preferred frame rate (#739). - Android: Google Mobile Services (GMS) Location Engine support (#721).
- Web: Exposed
onMouseMoveand added feature state management (setFeatureState,getFeatureState,removeFeatureState) (#718). - Web: Added
getLayerVisibility, web snapshot, and map sizing features (#722). - Web: Added Scale Control (#720).
- iOS: Location engine support —
enableHighAccuracyanddisplacementconfigurable viaLocationEnginePlatforms.iOS(). - Web: Location engine properties (
enableHighAccuracy,maximumAge,timeout) viaLocationEnginePlatforms.web(). - Platform-specific constructors for
LocationEnginePlatforms:.android(),.iOS(),.web().
Changed
- Android: Reduced MapLibre SDK logging verbosity to minimize log spam (#752).
- Android: Enhanced GeoJSON source handling with type checks and error logging (#764).
- Android: Check style exists and is loaded before adding a Layer (#768).
- Android: Check source exists before adding (#734).
- Android: MapLibre Android SDK upgraded from 13.0.0 to 13.0.2, switched to OpenGL renderer variant (
android-sdk-opengl) for better stability and performance on older devices. - iOS: Updated project settings for UISceneDelegate compatibility (#767).
- iOS: MapLibre iOS SDK upgraded from 6.19.1 to 6.25.1.
- Web: Upgraded MapLibre GL JS from 4.7.1 to 5.24.0 (#761, #651).
- Web: Migrated
preserveDrawingBuffer,antialias, andfailIfMajorPerformanceCaveatfrom top-levelMapOptionstocanvasContextAttributes. - Web: Updated
on()/off()/once()event methods to handle v5'sSubscriptionreturn type instead of map instance. - Web: Removed obsolete
customAttributionfromMapOptions(now part ofAttributionControloptions in v5). - GitHub Actions:
actions/upload-artifactupdated from v6 to v7 (#748). - Bumped Dart and melos version to latest (#762).
- Minimum Dart SDK version bumped from
3.5.0to3.7.0(#762). - Gradle wrapper updated to 9.4.0, Kotlin to 2.3.10, Android Gradle Plugin to 9.1.0 (#753-#758).
Fixed
- Fix data properties not being added to Annotation created in AnnotationManager (#770).
- Fix double JSON encoding in layer properties causing Android/iOS type errors (#747).
- iOS:
icon-text-fit-paddinginsets now use the correct style-spec order[top, right, bottom, left]—leftandrightwere previously swapped (#792). - Fix
text-fontproperty handling on Android and iOS to correctly accept font stacks as string arrays instead of only expressions. - Fix
textFontinSymbolManagerto pass font names as a simple string array, resolving rendering issues on native platforms. - Add DEM encoding support (
terrarium/mapbox) for raster-dem tile sources on Android and iOS. - Fix heatmap color expressions in example app to use proper
Expressions.rgba/Expressions.rgbsyntax. - Android: Fix map partially not responsive in split screen (#771).
- Android: GeoJSON source updates are now synchronous when drag is enabled, preventing stale feature positions during drag interactions and improved performance (#716).
- Android: Disabled texture mode by default and improved MapView lifecycle management (#723).
- Android: Removed unnecessary
OfflineActivityfromAndroidManifest.xml(#724). - Offline Regions: retain download
StreamSubscriptions in a module-level map so Dart's GC can't drop native events while a download is paused (#795). - Android (Offline): throttle progress events to 100ms and discard non-monotonic counts so cache-served bursts don't starve the isolate and block pause taps; track in-flight downloads to support pause/resume/status (#795).
- iOS (Offline): track active
MLNOfflinePackinstances so pause/resume/status operate on the live pack rather than reloading from storage (#795). - iOS: Deferred
onStyleLoadedcallback to avoid race conditions (#719). - Web: Improved
styleimagemissinghandling (#725). - Web: Fixed JS Interop and WASM compilation in release mode (#714).
- Web: Fixed missing prototype on empty JS object created via interop.
- Web:
removeLayerandremoveSourceno longer throw when the layer/source doesn't exist. - Web:
setGeoJsonSourcereturns early instead of crashing when the source doesn't exist. - Web:
GeolocateControlnow respectsMyLocationTrackingModeand triggers programmatically. - Example: GPS location page. Fixed web permission check, wired
onUserLocationUpdated, web-specific tracking modes. - Example: GeoJSON cluster. Added
['has', 'point_count']filter to fix null property errors on unclustered points.
Full Changelog: v0.25.0...v0.26.0
Release notes
Open source →See the top-level CHANGELOG for full details.
Breaking
initialCameraPositionis now nullable to support style-defined camera options (#769).LocationEnginePlatformsunnamed constructor is now private. Use.android(),.iOS(),.web(), or.defaultPlatform.- Removed
LocationEngineAndroidProperties. All fields flattened intoLocationEnginePlatformswith nullable platform-specific fields. MapLibrePlatform.easeCameragained an optional named parameterCameraAnimationInterpolation? interpolation. Callers are unaffected, but subclasses that overrideeaseCameramust add the new parameter to their signature (#789).
Added
- Cross-platform map snapshot functionality via
takeSnapshot()(#726). featureTapsTriggersMapClickoption to control whether feature taps also trigger map click callbacks (#729).- Feature state management APIs (
setFeatureState,getFeatureState,removeFeatureState) (#718). - Platform-specific constructors:
LocationEnginePlatforms.android(),.iOS(),.web(). - iOS and web serialization support in
toList(). - Expanded unit tests for platform-specific serialization and constructor behavior.
CameraAnimationInterpolationenum (linear,easeInOut,easeOut,fastOutLinearIn) and correspondinginterpolationparameter on thecamera#easemethod channel (#789).
Changed
- Updated to align with main package v0.26.0.
-
0.25.007 Jan 2026Release notes
Open source →Flutter MapLibre GL v0.25.0
⚠️ Breaking changes?
No breaking changes for users. Your existing code works without modifications.
The web platform was migrated internally to support WASM and Flutter 3.38.4+, but the public API remains unchanged.
🚀 What you can do now
Added
Logo Customization
You can now control the MapLibre logo visibility and position on your maps:
MapLibreMap( logoSettings: LogoSettings( enabled: true, // Show the MapLibre logo! position: LogoPosition.bottomLeft, // Or bottomRight, topLeft, topRight ), )
New Web Platform Methods
The web implementation now supports additional methods previously only available on mobile:
controller.getStyle()- Returns the current map style as a JSON stringcontroller.getSourceIds()- Returns a list of all source IDs in the current stylecontroller.getLayers()- Improved with safe null handling
Explicit Annotation Manager Initialization (#668)
Annotation methods now enforce explicit initialization with clear exceptions when the style is not loaded. This helps you catch issues early instead of getting silent failures or null dereferences:
- Calling
add*methods before style load now fails fast with a clear Exception - Better null safety for annotation collections (symbols, lines, circles, fills)
- More predictable behavior across platforms
Camera Target Bounds (#8bcd74a)
Refactored
cameraTargetBoundsimplementation for consistent behavior across platforms. You can now reliably constrain the camera to specific geographic bounds on both Android and iOS.iOS Attribution Support
Source attribution strings are now properly displayed on iOS with clickable links. The implementation parses HTML attribution from source properties and creates native iOS attribution dialogs that open URLs when tapped.
Changed
WASM Compatible Web Platform (#687)
- Migrated from deprecated
dart:js_utilto moderndart:js_interopAPI - Fully compatible with Flutter's WASM compilation target
- Required for Flutter 3.38.4+ compatibility
- Enhanced type safety for JavaScript ↔ Dart conversions
MapLibre Android SDK v12.3.0 (#690)
- Synchronous GeoJSON source updates
- Support for MLT-format vector tile sources
- Better frustum offset support
- Improved stability and performance
Example App Refactor
- Complete UI redesign with responsive layouts
- Maps now use 50-60% of screen height for better visibility
- Improved button and control layouts across different screen sizes
Fixed
iOS
- Min/max zoom preferences now work correctly (#5230fab)
queryRenderedFeatureswith empty layer list now returns all targets, matching Android behavior (#680)- Enhanced LayerPropertyConverter to handle null values and improve expression parsing (#98660dc)
- Better handling of null values in layer properties
- Improved expression parsing for complex layer configurations
Web
setPaintPropertyandsetLayoutPropertynow handle nullableJSAnyvalues correctly (#12dfad2)- Improved
jsifyfunction to create JS arrays correctly - Pattern images now load properly with correct RGBA format conversion (#9ce52a6)
Cross-Platform
- Fixed
lineDasharrayand pattern properties reset to null in layer properties (#2b550ed) - Fixed pattern images loading - no more "mismatched image size" errors (#9ce52a6)
- Improved MapLibreMapController disposing to prevent memory leaks
- Removed unnecessary disposing of mapController in example app - improved stability (#f989797)
- Refactored
cameraTargetBoundsfor consistent behavior on Android and iOS (#8bcd74a)
📦 Upgrade
dependencies: maplibre_gl: ^0.25.0
That's it. No code changes needed.
👪 Contributors
A big thank you to everyone who contributed to this release!
@srmncnk, @albertmoravec, and all community members who reported issues and provided feedback.
📝 More Info
- Full Changelog: v0.24.1...v0.25.0
- Documentation: pub.dev/packages/maplibre_gl
- Leave a comment: Release v0.25.0
Happy mapping! 🗺️ 💙
Release notes
Open source →Added
- Logo customization options including visibility and position settings (#b4fb174).
- Explicit annotation manager initialization with clear error handling (#668).
- iOS: Attribution support for tile and raster sources with HTML link parsing.
Changed
- MapLibre Android SDK upgraded from
11.13.5to12.3.0(#690).- Includes synchronous GeoJSON source updates
- Support for MLT-format vector tile sources
- Better frustum offset support
- See MapLibre Native Android 12.3.0 release notes
- OkHttp updated from
4.12.0to5.3.2for Node.js 24 compatibility (#676, #700). - Kotlin updated to
2.3.0(#697, #698). - Android Gradle Plugin updated to
8.13.2(#695, #674). - Android Application Plugin updated to
8.13.2(#696, #689). - GitHub Actions:
actions/checkoutupdated from v5 to v6 (#672, #693). - GitHub Actions:
actions/upload-artifactupdated from v4 to v6 (#688, #694).
Fixed
- Min/max zoom preference on iOS (#5230fab).
queryRenderedFeaturesnow returns all targets when supplying empty layers list on iOS, aligning behavior with Android (#680).- iOS: Enhanced LayerPropertyConverter to handle null values and improve expression parsing (#98660dc).
- Fixed
lineDasharrayand patterns reset to null in layer properties (#2b550ed). - Improved MapLibreMapController disposing to prevent memory leaks.
- Removed unnecessary disposing of mapController in example app (#f989797).
- Fixed
setLayerPropertiesand pattern images on web and Android (#9ce52a6).- Pattern images now correctly converted to RGBA format on web
- Fixed mismatched image size error when loading pattern images
Refactor
- Complete refactor of example app with new UI and improved user experience (#ac877a4).
- Refactored
cameraTargetBoundsimplementation on Android and iOS for consistent behavior (#8bcd74a).
Full Changelog: v0.24.1...v0.25.0
Release notes
Open source →See the top-level CHANGELOG for full details.
Changed
- Updated to align with main package v0.25.0.
- No breaking changes to the platform interface in this release.
-
0.24.120 Oct 2025Release notes
Open source →What's Changed
Added
- Added
onCameraMovecallback in the controller and in MapLibreMap class. (#643)
Changed
- Rollback maplibre-gl to
4.7.1version. (#660)
Fixed
- Annotation tap call callbacks twice. (#652)
- Annotation APIs: use null-aware access for manager-backed collections (symbols, lines, circles, fills) to avoid null errors before style load. (#657)
- Add methods enforce explicit manager initialization with clear exceptions when style is not loaded. (#657)
- Calling add* before style load now fails fast with a clear Exception instead of risking null dereferences or silent failures. (#657)
A big thank you to everyone who contributed to this update!
Contributors: @andynewman10, @andrea689, @gabbopalma
Full Changelog: v0.24.0...v0.24.1Release notes
Open source →Fixed
- Annotation tap call callbacks twice. (#652)
- Annotation APIs: use null-aware access for manager-backed collections (symbols, lines, circles, fills) to avoid null errors before style load. (#657)
- Add methods enforce explicit manager initialization with clear exceptions when style is not loaded. (#657)
- Calling add* before style load now fails fast with a clear Exception instead of risking null dereferences or silent failures. (#657)
Changed
- Rollback maplibre-gl to
4.7.1version. (#660)
Added
- Added
onCameraMovecallback in the controller and in MapLibreMap class. (#643)
- Added
-
0.24.002 Oct 2025Release notes
Open source →What's Changed
Note
This release has breaking changes.
We apologize for the quick change in 0.24.0: this version definitively stabilizes the signatures of feature interaction callbacks.This release restores the feature id and makes the
Annotationparameter nullable for all feature interaction callbacks (tap/drag/hover).
This unblocks interaction with style-layer features not managed by annotation managers (i.e. added viaaddLayer*/ style APIs).Warning
Breaking Changes
-
Tap:
OnFeatureInteractionCallback→(Point<double> point, LatLng coordinates, String id, String layerId, Annotation? annotation). -
Drag:
OnFeatureDragCallback→(Point<double> point, LatLng origin, LatLng current, LatLng delta, String id, Annotation? annotation, DragEventType eventType). -
Hover:
OnFeatureHoverCallback→Point<double> point, LatLng coordinates, String id, Annotation? annotation, HoverEventType eventType). -
Update existing listeners: The short‑lived 0.23.0-only signatures (without
id) are removed.- For unmanaged style layer features
annotationisnull(unmanagedmeans sources/layers you add via style APIs likeaddGeoJsonSource+addSymbolLayer). - For managed annotations it is the
Annotationobject.
- For unmanaged style layer features
Reasoning
In 0.23.0 the move to annotation objects inadvertently dropped interaction for unmanaged style features. Reintroducing
id(and makingannotationnullable) normalizes all three interaction paths without creating phantom annotation wrappers.Migration Example
Before (0.23.0):
controller.onFeatureTapped.add((p, latLng, annotation, layerId) { print(annotation.id); });After (>=0.24.0):
controller.onFeatureTapped.add((p, latLng, id, layerId, annotation) { print('feature id=$id managed=${annotation != null}'); });Refactor / Quality
- (web) Refactored
onMapClick(degenerate bbox + interactive layer filter) to surface features inserted via style APIs (unmanaged style-layer features) inonFeatureTapped(previously skipped; returned now withid,layerIdandannotation = null) (#646). - (web) Ensure map container stretches vertically by adding
style.height = '100%'to the registered div (prevents occasional zero-height layout issues in flexible parents) (#641)
Contributors: @andynewman10, @gabbopalma
Full Changelog: v0.23.0...v0.24.0Release notes
Open source →Note: This release has breaking changes.
We apologize for the quick change in 0.24.0: this version definitively stabilizes the signatures of feature interaction callbacks.This release restores the feature id and makes the
Annotationparameter nullable for all feature interaction callbacks (tap/drag/hover).
This unblocks interaction with style-layer features not managed by annotation managers (i.e. added viaaddLayer*/ style APIs).Breaking Changes
-
Tap:
OnFeatureInteractionCallback→(Point<double> point, LatLng coordinates, String id, String layerId, Annotation? annotation). -
Drag:
OnFeatureDragCallback→(Point<double> point, LatLng origin, LatLng current, LatLng delta, String id, Annotation? annotation, DragEventType eventType). -
Hover:
OnFeatureHoverCallback→Point<double> point, LatLng coordinates, String id, Annotation? annotation, HoverEventType eventType). -
Update existing listeners: The short‑lived 0.23.0-only signatures (without
id) are removed.- For unmanaged style layer features
annotationisnull(unmanagedmeans sources/layers you add via style APIs likeaddGeoJsonSource+addSymbolLayer). - For managed annotations it is the
Annotationobject.
- For unmanaged style layer features
Reasoning
In 0.23.0 the move to annotation objects inadvertently dropped interaction for unmanaged style features. Reintroducing
id(and makingannotationnullable) normalizes all three interaction paths without creating phantom annotation wrappers.Migration Example
Before (0.23.0):
controller.onFeatureTapped.add((p, latLng, annotation, layerId) { print(annotation.id); });After (>=0.24.0):
controller.onFeatureTapped.add((p, latLng, id, layerId, annotation) { print('feature id=$id managed=${annotation != null}'); });Refactor / Quality
- (web) Refactored
onMapClick(degenerate bbox + interactive layer filter) to surface features inserted via style APIs (unmanaged style-layer features) inonFeatureTapped(previously skipped; returned now withid,layerIdandannotation = null) (#646). - (web) Ensure map container stretches vertically by adding
style.height = '100%'to the registered div (prevents occasional zero-height layout issues in flexible parents) (#641)
Full Changelog: v0.23.0...v0.24.0
-
-
0.23.030 Sep 2025Release notes
Open source →What's Changed
Caution
USE 0.24.0 VERSION INSTEAD OF THIS ONE!
This consolidated release delivers runtime style switching, hover interactions, heatmap & visibility features, native SDK updates, and broad naming / enum casing harmonization. It also fixes several interaction and stability issues across web and mobile.
If you are upgrading from <= 0.22.x:
- Review the breaking rename (
Maplibre->MapLibre) and enum / const lowerCamelCase migration. - Adapt feature interaction callbacks:
onFeatureTapped/onFeatureDragnow receive anAnnotationinstead of anidargument. - Ensure any style access happens after
onStyleLoadeddue to stricter style readiness checks.
A big thank you to everyone who contributed to this update!
Warning
Breaking changes
Added / Features
- Runtime style switching APIs on controller (#444) and raw style JSON setting on iOS / Web (#603).
- Hover interaction events (
onFeatureHover) (#614). - Heatmap layer support (#365).
- Bounds fitting API to change viewport to given bounds (#133).
- Layer visibility control (#138).
LatLngBounds.containsconvenience (#498).
Changed / Updates
- MapLibre Native: Android 11.13.5 & iOS 6.19.1.
- Flutter / Gradle plugin & tooling compatibility update (#542).
- Lint and analysis alignment via very_good_analysis and flutter_lints (#452, #434, #414, #419).
- Package link updates & style resource relocation (
MaplibreStylesmoved to main package) (#435, #413).
Fixed
- iOS code generation (Offset / Translate / expression arrays) (#481).
- Annotation tap consumption now properly respected (
annotationConsumeTapEvents). - Prevent calling
notifyListeners()after controller disposal (#621). - Web: event listener cancellation & hover handling robustness (#623).
- Offline region download crash in example (#569).
- Added style loaded safety checks (#563).
- Aligned example and web pubspec versions (#476).
- Web: enforce maplibre-gl-js 4.x & remove shadow root stylesheet workaround (#409).
Refactor / Quality
- Enable and fix additional lint rules (#452).
New Contributors
Contributors: @AlexanderThiele, @mhernz, @TarekTolba1, @srmncnk, @itheamc, @kuhnroyal, @albertmoravec, @gabbopalma
Full Changelog: v0.22.0...v0.23.0Release notes
Open source →Note: This release has breaking changes.
This release aligns the plugin with the latest MapLibre Native (Android 11.9.0 / iOS 6.14.0), introduces runtime style switching APIs, hover interaction callbacks, and several annotation interaction improvements. It also contains a small breaking change for feature interaction callbacks.
A big thank you to everyone who contributed to this update!
Breaking Changes
onFeatureDrag/onFeatureTappedcallback signatures now provide anAnnotation annotationobject instead of anidparameter. Update your handlers to remove theidargument and useannotation.id(or other annotation fields) as needed.
Highlights
- Runtime style switching via controller (
setStyle…) without tearing down the map (#444, #603). - Hover interaction events (
onFeatureHover) for richer desktop/web UX (#614). - Improved event handling reliability (cancellation & consumption fixes) (#621, #623).
- Offline region download crash fix in example (#569) and style loaded safety checks (#563).
- Updated MapLibre Native bringing PMTiles & performance improvements (#552, #582).
Added / Updated
- Feature: added set style method on controller (#444) & support setting raw style JSON on iOS/web (#603).
- Feature: expose hovering events (
onFeatureHover) (#614). - Update: bump Android to 11.9.0 & iOS to 6.14.0 (#582).
- Update: update maplibre-native to the latest versions / PMTiles support (#552).
- CI/Tooling: upgrade Flutter Gradle Plugin & compatibility with Flutter 3.29.0 (#542).
Fixed
- iOS code generation: corrected handling of Offset / Translate / expression arrays in generated bindings (#481).
- Annotation tap consumption now respected (
annotationConsumeTapEvents). - Prevent calling
notifyListeners()after controller disposal (#621). - Web: event listener cancellation & hover handling robustness (#623).
- Example: offline region download crash (#569).
- Added style readiness checks before access (#563).
Refactor / Quality
- Enable and fix additional lint rules to enforce consistency (#452).
Full Changelog: v0.22.0...v0.23.0
- Review the breaking rename (
-
0.22.005 Jun 2025Release notes
Open source →This PR addresses several crashes that occurred when attempting to add
layers and sources that already exist.The fix introduces appropriate guard statements and ensures that errors
are correctly propagated to the Flutter layer when necessary.Previously, such issues would result in a crash. With this change, they
now raise a platform exception instead.
Co-authored-by: Alexander Thiele [email protected]
Release notes
Open source →Breaking changes
- Updated maplibre-native for iOS to v6.14.0. This mainly introduces PMTiles support. See the maplibre-native changelog for more information.
- Updated maplibre-native for Android to v11.9.0. This mainly introduces PMTiles support. Flutter version packed with OpenGL ES 3.0 build for now, later we could probably switch to Vulkan. See the maplibre-native changelog for more information.
- queryRenderedFeaturesInRect support string feature ids on web (#576).
Changed
- Added
awaitto alladdLayercalls (#558).
Fixed
- Fixed
Unsupported operationerror on web (#551).
-
0.21.026 Feb 2025Release notes
Open source →What's Changed
- restructure folders with basic melos by @XanderD99 in #453
- Gitignore melos_overrides.yaml and FVM files by @kuhnroyal in #458
- fix: await calls to change overlap in example by @themightychris in #468
- Fix #445 stop listening for updates before stopping/destroying the view by @kuhnroyal in #459
- Update Android plugin Gradle configuration by @kuhnroyal in #460
- Fix the package name for SPM configuration by @kuhnroyal in #467
- refactor: enable and fix some lint rules by @josxha in #452
- Fix #437 toggling myLocationEnabled in example by @kuhnroyal in #457
- Bump very_good_analysis from 5.1.0 to 6.0.0 by @dependabot in #470
- chore: set
melos analyseexit code by @josxha in #471 - Fix: Aligned example and maplibre_gl_web pubspec versions. by @gabbopalma in #476
- Implementation of clearAmbientCache functionality by @danieljosua1 in #502
- feat: contains method for
LatLngBoundsby @ishafiul in #498 - [FEATURE] Returns layer Id on Feature Tap & update NDK version to fix crash on Android 15 by @LouisRaverdy in #475
- Set LocationEngine properties in android by @danieljosua1 in #510
- feat: upgrade FGP & compatible with flutter 3.29.0 by @thanhdang198 in #542
- chore: add in code usage and min kotlin version in readme by @smallTrogdor in #543
- chore: update Changelog in preparation of v0.21.0 by @smallTrogdor in #544
- chore: update versions in pubspecs by @smallTrogdor in #545
New Contributors
- @themightychris made their first contribution in #468
- @gabbopalma made their first contribution in #476
- @danieljosua1 made their first contribution in #502
- @ishafiul made their first contribution in #498
- @LouisRaverdy made their first contribution in #475
- @thanhdang198 made their first contribution in #542
Full Changelog: v0.20.0...v0.21.0
Release notes
Open source →Added
- added the
clearAmbientCachefunctionality (#502). - added the
containsfunctionality toLatLngBounds(#498). - added the possibility to set
LocationEnginePlatformsproperties for better device tracking on Android (#510).
Changed
- BREAKING:
onFeatureTapreturns thelayerId(#475). - Changed iOS package name to support Swift Package Manager (#467).
- Move the
maplibre_glpackage to a subdirectory of the repository and add melos to orchestrate all packages (#453).
Removed
- Removed support for Dart SDKs older than
3.4.0(Flutter SDK 3.22.0) (#542)
Fixed
- Fixed exception when destroying mapView on Android by reordering cleanup (#459).
-
0.20.007 Jun 2024Release notes
Open source →A lot of files/classes have been renamed and moved around in this release. If you notice any build errors, please make sure to run
flutter clean.Breaking changes
- All Dart enums have been migrated from mixed cases to lower camelcase
according to the
camel_case_typeslint rule. - Move
MapLibreStylesto the mainmaplibre_glpackage. You can now use the
demo style without addingmaplibre_gl_platform_interfaceas a dependency. - Updated maplibre-native for ios to v6.5.0. This introduces the new iOS Metal renderer and the OpenGL ES renderer now uses OpenGL ES 3.0. Only iOS Devices with an Apple A7 GPU or later are supported onwards. See the maplibre-native changelog for more information.
- Updated maplibre-native for android to v11.0.0. This version uses OpenGL ES 3.0. See the maplibre-native changelog for more information.
- Renamed the method channel to
plugins.flutter.io/maplibre_gl_*in all packages. - Renamed "Maplibre" to "MapLibre" to be in line with maplibre-native
(affects for example the classes
MaplibreMapandMaplibreMapController).
Changes
- Added support for Swift Package Manager usage on iOS.
- Migrated main iOS plugin class from Objective-C to Swift.
- Renamed iOS plugin classes from
MapboxtoMapLibre. - Removed support for Kotlin versions older than
1.9.0(#460).
Full Changelog: v0.19.0+2...v0.20.0
- All Dart enums have been migrated from mixed cases to lower camelcase
according to the
-
0.19.0+222 May 2024Nothing published for this version
-
0.18.025 Dec 2023Release notes
Open source →Breaking Change:
Already since 0.17.0, developers do not need to adapt their Podfile for iOS apps anymore as it was previously described in the Readme. Developers who previously added these lines should remove them, since not removing these lines may cause a build failure on iOS. (This change actually already landed in 0.17.0, but it may not have been sufficiently clear that not removing these lines might break builds).
Other Changes:
- new feature: set arbitrary layer properties by @m0nac0 in #303
- Update release process by @m0nac0 in #315
- Add workflows for automated publishing to pub.dev by @m0nac0 in #328
- Fix example app pubspec by @m0nac0 in #329
- Updated location plugin version for example app by @varunlohade in #334
- Housekeeping: Improve docs and update outdated references to point to MapLibre by @m0nac0 in #330
Full Changelog: 0.17.0...0.18.0
-
0.17.016 Jun 2023Release notes
Open source →- Repository transfer: The project repository was transferred to the MapLibre GitHub organization. More information at #221
- Developers do not need to adapt their Podfile for iOS apps anymore as it was previously described in the Readme. #278
Breaking Change:
maplibre_gl/mapbox_gl.dartwas renamed tomaplibre_gl/maplibre_gl.dart. You can do a replace-all fromimport 'package:maplibre_gl/mapbox_gl.dart';toimport 'package:maplibre_gl/maplibre_gl.dart';useDelayedDisposalwas removed since its now fixed in #259useHybridCompositionOverridewas removed since it was added in the following fix: #203 and we reverted the fix and used another approach to fix the actual issue.- The default for
myLocationRenderModewas changed fromCOMPASStoNORMALin #244, since the previous default value ofCOMPASSimplicitly enables displaying the location on iOS, which could crash apps that didn't want to display the device location. If you want to continue to useMyLocationRenderMode.COMPASS, please explicitly specify it in the constructor like this:
@override Widget build() { return MapLibreMap( myLocationRenderMode: MyLocationRenderMode.COMPASS, // ... ); }- The old api
registerWithwas removed from the MapboxMapsPlugin.java, since there is no need for that. - The
minSdkVersionwas bumped to at least 21 now, since the native android sdk constraint expect that. - Changed the minimum Dart version from sdk:
2.12.0to2.14.0inmaplibre_gl_platform_interface/pubspec.yaml.
Further changes
Note: This list only contains a subset of all contributions, notably excluding those that e.g. only affect the GitHub Actions CI or documentation. See the link at the end for a full changelog.
- feat: add support for reading style json from file in ios by @TimAlber in #132
- Add podspecs in correct Cocoapods layout by @kuhnroyal in #128
- fix: fix the queryRenderedFeatures code on iOS by @TimAlber in #137
- feat: Set layer visibility by @m0nac0 in #138
- feat: add support for changing the receiver’s viewport to fit given bounds by @TimAlber in #133
- Change feature JSON encoding from .ascii to .utf8 by @SunBro-Marko in #142
- web: implement setCameraBounds by @m0nac0 in #145
- Use offical maplibre-gl.js and add README info by @Robbendebiene in #163
- android: adding tileSize to raster source by @mariusvn in #166
- Readme: document git default values for codespaces by @m0nac0 in #170
- query source features by @Grodien in #154
- Trimming styleString to simplify the JSON detection by @mariusvn in #175
- Fix getVisibleRegion method by @BartoszStasiurka in #179
- Reenable textureMode which was disabled in f8b2d1 by @maxammann in #194
- android: Bump MapLibre SDK to 9.6.0 & OkHttp to 4.9.3 by @mariusvn in #184
- Added getSourceIds to the controller by @mariusvn in #197
- Moved EventChannel creation in the downloadOfflineRegion method by @mariusvn in #205
- Fix crash android dispose nullpointerdereference by @GaelleJoubert in #203
- Migrate links in README, pubspec to MapLibre by @kuhnroyal in #224
- Update LICENSE file by @mariusvn in #230
- upgrade dependency image by @m0nac0 in #248
- fix-example-app by @JulianBissekkou in #261
- 162-animate-camera-on-web-fix by @JulianBissekkou in #254
- 243-fix-crash-when-no-location-permission by @JulianBissekkou in #244
- 182-disposal-null-ref-crash by @JulianBissekkou in #259
- New android sdk version by @stefanschaller in #270
- 250-change-language-fixes by @stefanschaller in #275
- upgrade-ios-version by @JulianBissekkou in #277
- Simplify iOS usage instructions and example podfile by @m0nac0 in #278
- Add opportunity to use map in widget tests by @ManoyloK in #281
- fix-layers-prod-build by @stefanschaller in #291
- Fix the codespace by upgrading the docker image by @ouvreboite in #297
- Add
updateImageSource. by @CaviarChen in #271 - fix "unexpected null value" error when onStyleLoadedCallback is null by @m0nac0 in #307
- attributionButtonPosition for web by @ouvreboite in #304
Full Changelog: https://github.com/maplibre/flutter-maplibre-gl/compare/0.16.0...0.17.0
-
0.16.015 Jun 2023Release notes
Open source →- cherry-picked all commits from upstream up to [https://github.com/flutter-mapbox-gl/maps/commit/3496907955cd4b442e4eb905d67e8d46692174f1), including up to release 0.16.0 from upstream
- updated MapLibre GL JS for web