v0.27.0 #991
gabbopalma
announced in
Announcements
v0.27.0
#991
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
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
onStyleLoadedCallback, which fires again after every recreation, rather than inonMapCreatedorinitState. See the migration guide (Android: Survive "Don't keep activities" and config changes #805).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 ([FEATURE] Load maplibre-gl-js from the plugin instead of from every app's index.html #928).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 (feat(web): move the engine to MapLibre GL JS 6 #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 (Regenerate from pinned MapLibre style spec 26.2.1, with per-platform gating and a repeatable drift check #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 (Regenerate from pinned MapLibre style spec 26.2.1, with per-platform gating and a repeatable drift check #957).mapboxTileCountLimitExceededtotileCountLimitExceededandmapboxInvalidRegionDefinitiontoinvalidRegionDefinition. When they fire does not change, but acatchmatching either oldPlatformExceptioncode needs the new one (Release 0.27.0 #956).Added
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 (Add the color-relief layer #958).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 (Add the background layer #959).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 (Expose the style root objects: sky, terrain, projection, light and global state #960).textVariableAnchorOffseton symbols,hillshadeMethodandhillshadeIlluminationAltitudefor multidirectional hillshading. New expressions:Expressions.distance,within,indexOf,sliceandelevation(Regenerate from pinned MapLibre style spec 26.2.1, with per-platform gating and a repeatable drift check #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 (feat: add preWarm() API for Android, iOS, and Web #867).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 ([FEATURE] Support feature-state (setFeatureState / removeFeatureState) on Android & iOS #889).exportOfflineDatabase()writes a shareable copy,mergeOfflineRegions()imports one (now on iOS too), andgetOfflineDatabasePath()locates the store. See the offline regions guide ([BUG]mergeOfflineRegionsnot implemented on iOS (MissingPluginException) #886).locationSource: ManualLocationSource()pluscontroller.updateManualLocation(). See the user location guide ([FEATURE] Support app-provided/manual location source for user location display #840).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 ([FEATURE] Expose getClusterExpansionZoom (and cluster leaves/children) in the Flutter wrapper #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 ([FEATURE] Get SourceProperties and LayerProperties objects by id #513, iOS: getLayerProperties/getSourceProperties return null for runtime-added layers and sources #985).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 (Expose the style root objects: sky, terrain, projection, light and global state #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 (Add support for 'setPadding' #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 (Android: Survive "Don't keep activities" and config changes #805).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 ([FEATURE] Expose native tiltWhileTracking for location tracking modes #888).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 (Expose the style root objects: sky, terrain, projection, light and global state #960).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([FEATURE] Load maplibre-gl-js from the plugin instead of from every app's index.html #928).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 (Regenerate from pinned MapLibre style spec 26.2.1, with per-platform gating and a repeatable drift check #957).clusterMinPointson a GeoJSON source sets how many points have to fall together before they become a cluster, instead of the fixed default of two (Regenerate from pinned MapLibre style spec 26.2.1, with per-platform gating and a repeatable drift check #957, Forward the new source options to the native SDKs, and reject the one they cannot decode #981).attributionButtonColortints the attribution button, for styles where the default tint is hard to see. No effect on web (Android: Survive "Don't keep activities" and config changes #805).LocationEnginePlatforms.iOStakesintervalMsandpulseWindowMsto pulse GPS instead of tracking continuously, easing battery use on maps that stay open a long time. The default keeps continuous tracking (feat(ios): add intervalMs to LocationEnginePlatforms.iOS for GPS pulsing #901).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 (Regenerate from pinned MapLibre style spec 26.2.1, with per-platform gating and a repeatable drift check #957, Forward the new source options to the native SDKs, and reject the one they cannot decode #981).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 (Regenerate from pinned MapLibre style spec 26.2.1, with per-platform gating and a repeatable drift check #957, Forward the new source options to the native SDKs, and reject the one they cannot decode #981).Fixed
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 (fix(android): temporary workaround for icon atlas bug (maplibre-native#4326) #866, fix(android): restore bitmap decode options of addImage #868).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(fix: default SymbolManager text font to Noto Sans Regular #940).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 (Regenerate from pinned MapLibre style spec 26.2.1, with per-platform gating and a repeatable drift check #957).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()([BUG] iOS: queryRenderedFeatures and querySourceFeatures silently drop features that fail to encode #949, fix: honour the filter of queryRenderedFeaturesInRect on Android and web #953).onMapCreatedincluded, used to wait forever for a map that never arrived, with only an unhandled error in the console (feat(web): move the engine to MapLibre GL JS 6 #943).OfflineRegion([BUG]mergeOfflineRegionsnot implemented on iOS (MissingPluginException) #886).setLayerProperties()works on fill-extrusion and heatmap layers too; both used to answerUNSUPPORTED_LAYER_TYPE(Expose the style root objects: sky, terrain, projection, light and global state #960).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 (Forward the new source options to the native SDKs, and reject the one they cannot decode #981).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 (fix(android): say what is wrong with a feature query that cannot be answered #954).type 'Null' is not a subtype of type 'Map<String, dynamic>'([BUG]mergeOfflineRegionsthrows type error whenmetadatais missing #865).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 ([BUG] iOS: queryRenderedFeatures and querySourceFeatures silently drop features that fail to encode #949).queryCameraPosition()returns the camera position even whentrackCameraPositionisfalse, matching Android. It used to returnnull(feat: standardize queryCameraPosition across platforms (fix iOS, implement web) #892).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 ([BUG] iOS: camera events before first layout carry NaN zoom and poison the controller's cached cameraPosition #903).onMapIdlenow fires, matching Android and iOS; code waiting on it never ran (Add onMapIdle callback for detecting render completion #857).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 ([FEATURE] Support feature-state (setFeatureState / removeFeatureState) on Android & iOS #889).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 (fix(web): report querySourceFeatures called before the style has loaded #952).queryCameraPosition()is implemented; it used to throwUnimplementedError(feat: standardize queryCameraPosition across platforms (fix iOS, implement web) #892).updateContentInsetsand the newsetPaddingno longer throwUnimplementedError(Add support for 'setPadding' #258).showLicensePage()([BUG] LICENSE file formatting breaks Flutter's license collector, causing a blank entry on the Flutter "Licenses" screen #895).Changed
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 (Forward the new source options to the native SDKs, and reject the one they cannot decode #981).source-layerorsource-idnow takes effect (chore: bump MapLibre Native (Android 13.4.1, iOS 6.28.0) and drop two unused Android dependencies #929).@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 (Regenerate from pinned MapLibre style spec 26.2.1, with per-platform gating and a repeatable drift check #957).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 (Regenerate from pinned MapLibre style spec 26.2.1, with per-platform gating and a repeatable drift check #957, Forward the new source options to the native SDKs, and reject the one they cannot decode #981).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([BUG] AnnotationMnager not initialised when adding symbols simply #910).android-plugin-annotation-v9andandroid-plugin-offline-v9dependencies are dropped, so apps pull two fewer artifacts (chore: bump MapLibre Native (Android 13.4.1, iOS 6.28.0) and drop two unused Android dependencies #929).Docs
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 (Fixing hybrid composition by enabling textureMode when necessary #816).mergeOfflineRegionsnot implemented on iOS (MissingPluginException) #886, [FEATURE] Support feature-state (setFeatureState / removeFeatureState) on Android & iOS #889).Contributors
mergeOfflineRegionson iOS, export APIs, download de-duplication #887Full Changelog: v0.26.2...v0.27.0
This discussion was created from the release v0.27.0.
All reactions