Releases: mapbox/mapbox-maps-flutter
2.3.0-rc.1
Features ✨ and improvements 🏁
- Expose API to clear map data, and to set options to
TileStore
.
You can now clear temporary map data from the data path defined in the given resource options, which is useful when you want reduce the disk usage or in case the disk cache contains invalid data.
await MapboxMapsOptions.clearData();
And, you can now set additional options to a TileStore
. For example, you can set a maximum amount of bytes TileStore can use to store files, a base URL to use for requests to the Mapbox API, or a URL template for making tile requests.
// Set the disk quota to zero, so that tile regions are fully evicted
// when removed.
// This removes the tiles from the predictive cache.
tileStore.setDiskQuota(0);
- Add support for partial GeoJSON updates.
Instead of setting a whole new GeoJSON object anew every time a single feature has changed, now you can apply more granular, partial GeoJSON updates.
If your features have associated identifiers - you can add, update, and remove them on individual basis in your GeoJSONSource
. This is especially beneficial for GeoJSONSource
s hosting a large amount of features - in this case adding a feature can be up to 4x faster with the partial GeoJSON update API.
mapboxMap.style.addGeoJSONSourceFeatures(sourceId, dataId, features)
mapboxMap.style.updateGeoJSONSourceFeatures(sourceId, dataId, features)
mapboxMap.style.removeGeoJSONSourceFeatures(sourceId, dataId, featureIds)
- Expose data-driven properties on annotation managers. Now it's possible to set data-driven properties globally on annotation manager and specify per-annotation overrides.
Previously user had to specify those properties on each annotation and couldn't specify them globally.
In this case each even annotation will have random color, but others will use the global default specified in the annotation manager.
final circleAnnotationManager = await mapboxMap.annotations.createCircleAnnotationManager();
var annotations = <CircleAnnotationOptions>[];
for (var i = 0; i < 2000; i++){
var annotation = CircleAnnotationOptions(
geometry: createRandomPoint(),
circleColor: (i % 2 == 0) ? createRandomColor() : null,
);
annotations.add(annotation);
}
circleAnnotationManager.setCircleColor(Colors.blue.value);
- Expose
autoMaxZoom
property forGeoJsonSource
to fix rendering issues withFillExtrusionLayer
in some cases. - Expose experimental
ClipLayer
to remove 3D data (fill extrusions, landmarks, trees) and symbols. - Deprecate
SlotLayer.sourceId
andSlotLayer.sourceLayer
as they have no effect in this layer. - Expose experimental
SymbolLayer.symbolElevationReference
andSymbolLayer.symbolZOffset
. - Add missing
@experimental
annotations toLayer
'sExpression
properties. - Remove experimental
model-front-cutoff
property fromModelLayer
. - Expose experimental
lineTrimColor
andlineTrimFadeRange
onLineLayer
which allow to set custom color for trimmed line and fade effect for trim. - Add experimental
FillExtrusionLayer.fillExtrusionLineWidth
that can switch fill extrusion rendering into wall rendering mode. Use this property to render the feature with the given width over the outlines of the geometry. - Add experimental
MapboxMap.setSnapshotLegacyMode()
to help avoidingMapboxMap.snapshot()
native crash on some Samsung devices running Android 14.MapboxMap.setSnapshotLegacyMode()
has no effect on iOS.
Bug fixes 🐞
- Fix
StyleManager.getLayer()
failing forModelLayer
,RasterParticleLayer
andSlotLayer
.
Dependency Updates
2.3.0-beta.1
Features ✨ and improvements 🏁
- Add
GestureState
toMapContentGestureContext
to indicate whether gesture has been started, its touches have changed or it has ended.
Bug fixes 🐞
- Fix build errors when using Flutter SDK 3.24.
Dependency Updates
v2.2.1
v2.2.0
Features ✨ and improvements 🏁
- Expose
MapboxStyles.STANDARD_SATELLITE
style, by @evil159. Please read more about this here MapDebugOptions
is superseded byMapWidgetDebugOptions
, expanding existing debug options with the newlight
,camera
, andpadding
debug options in addition to the new Android-specific options:layers2DWireframe
andlayers3DWireframe
, by @evil159- Support local assets for 3D puck and
ModelLayer
. To use a local assets, please specify it withasset://
scheme followed by the path of the asset in the uri, by @maios
mapboxMap.location.updateSettings(LocationComponentSettings(
locationPuck: LocationPuck(
locationPuck3D: LocationPuck3D(
modelUri: "asset://assets/sportcar.glb",
modelScale: [_puckScale, _puckScale, _puckScale]))));
- Fix map view crashing upon host activity destruction when using a cached Flutter engine, by @evil159
- Fix a rare crash happening when map widget is being disposed, by @evil159
- Update Pigeon to 21.1.0
Dependency Updates
2.2.0-rc.1
Features ✨ and improvements 🏁
- Expose
MapboxStyles.STANDARD_SATELLITE
style, by @evil159 MapDebugOptions
is superseded byMapWidgetDebugOptions
, expanding existing debug options with the newlight
,camera
, andpadding
debug options in addition to the new Android-specific options:layers2DWireframe
andlayers3DWireframe
, by @evil159
Dependency Updates
v2.2.0-beta.1
Features ✨ and improvements 🏁
- Support local assets for 3D puck and
ModelLayer
. To use a local assets, please specify it withasset://
scheme followed by the path of the asset in the uri, by @maios
mapboxMap.location.updateSettings(LocationComponentSettings(
locationPuck: LocationPuck(
locationPuck3D: LocationPuck3D(
modelUri: "asset://assets/sportcar.glb",
modelScale: [_puckScale, _puckScale, _puckScale]))));
- Fix map view crashing upon host activity destruction when using a cached Flutter engine, by @evil159
- Fix a rare crash happening when map widget is being disposed, by @evil159
Dependency Updates
2.1.0
Features ✨ and improvements 🏁
- Add ModelLayer API.
- Add support for offline maps, allowing users to download and store map data on their devices for use in environments with limited or no internet connectivity.
- Add layer expressions support. To use, specify expressions when constructing a layer.
Before:
mapboxMap.style.setStyleLayerProperty("layer", "line-gradient",
'["interpolate",["linear"],["line-progress"],0.0,["rgb",255,0,0],0.4,["rgb",0,255,0],1.0,["rgb",0,0,255]]');
After:
LineLayer(
...
lineGradientExpression: [
"interpolate",
["linear"],
["line-progress"],
0.0,
["rgb", 255, 0, 0],
0.4,
["rgb", 0, 255, 0],
1.0,
["rgb", 0, 0, 255]
],
);
- Expose
text-occlusion-opacity
,icon-occlusion-opacity
,line-occlusion-opacity
,model-front-cutoff
, andlineZOffset
as experimental. - Add min/max/default values for most of the style properties.
- Expose
clusterMinPoints
property forGeoJSONSource
. - Expose
SlotLayer
andRasterParticleLayer
. - Expose
LocationComponentSettings.slot
. - Add
@experimental
annotation to relevant APIs. - Expose
LineJoin.NONE
.
Dependency Updates
2.1.0-rc.1
Features ✨ and improvements 🏁
- Expose
text-occlusion-opacity
,icon-occlusion-opacity
,line-occlusion-opacity
,model-front-cutoff
,lineZOffset
as experimental. - Add min/max/default values for most of the style properties.
- Expose
clusterMinPoints
property forGeoJSONSource
. - Expose
SlotLayer
andRasterParticleLayer
. - Expose
LocationComponentSettings.slot
. - Add
@experimental
annotation to relevant APIs.
Dependency Updates
2.1.0-beta.1
Features ✨ and improvements 🏁
- Add ModelLayer API.
- Support for offline map, allowing users to download and store map data on their devices for use in environments with limited or no internet connectivity.
- Layer expressions support. Specify expressions when constructing a layer with all new expression support for layers.
Before:
mapboxMap.style.setStyleLayerProperty("layer", "line-gradient",
'["interpolate",["linear"],["line-progress"],0.0,["rgb",255,0,0],0.4,["rgb",0,255,0],1.0,["rgb",0,0,255]]');
After:
LineLayer(
...
lineGradientExpression: [
"interpolate",
["linear"],
["line-progress"],
0.0,
["rgb", 255, 0, 0],
0.4,
["rgb", 0, 255, 0],
1.0,
["rgb", 0, 0, 255]
],
);
Dependency Updates
2.0.0
⚠️ Breaking changes
Leveraging Turf's geometries as a replacement for Map<String, Any?>
You now have the convenience of directly initializing annotations with Turf's geometries, eliminating the need for converting geometry to JSON.
Geographical position represented by Point
s
Geographical positions denoted by Map<String?, Object?>?
are migrated to Point
type from turf package.
Pass Point
s directly instead of converting them to JSON.
Before:
CameraOptions(
center: Point(
coordinates: Position(
-0.11968,
51.50325,
)).toJson())
After:
CameraOptions(
center: Point(
coordinates: Position(
-0.11968,
51.50325,
)))
Screen and geographical positions in map interaction(gestures) callbacks
MapWidget
's onTapListener
/onLongTapListener
/onScrollListener
now receive MapContentGestureContext
containing both touch position of the gesture, as well as the projected map coordinate corresponding to the touch position.
Before:
onTapListener: { (coordinate)
final lat = coordinate.x;
final lng = coordinate.y;
...
}
After:
onTapListener: { (context)
final coordinates = context.point.coordinates; // Position
final touchPosition = context.touchPosition; // ScreenCoordinate
...
}
Creating an annotation with a given geometry
Before:
PointAnnotationOptions(
geometry: Point(
coordinates: Position(0.381457, 6.687337)
).toJson()
)
PolygonAnnotationOptions(
geometry: Polygon(coordinates: [
[
Position(-3.363937, -10.733102),
Position(1.754703, -19.716317),
Position(-15.747196, -21.085074),
Position(-3.363937, -10.733102)
]
]).toJson()
)
PolylineAnnotationOptions(
geometry: LineString(coordinates: [
Position(1.0, 2.0),
Position(10.0, 20.0)
]).toJson()
)
After:
PointAnnotationOptions(
geometry: Point(
coordinates: Position(0.381457, 6.687337)
)
)
PolygonAnnotationOptions(
geometry: Polygon(coordinates: [
[
Position(-3.363937, -10.733102),
Position(1.754703, -19.716317),
Position(-15.747196, -21.085074),
Position(-3.363937, -10.733102)
]
])
)
PolylineAnnotationOptions(
geometry: LineString(coordinates: [
Position(1.0, 2.0),
Position(10.0, 20.0)
])
)
Features ✨ and improvements 🏁
- [Android] Add Gradle 8 compatibility.
- Add a way to disable default puck's image(s) when using
DefaultLocationPuck2D
. By passing an empty byte array, for example, the following code shows a puck 2D with custom top image, default bearing image and no shadow image.
mapboxMap?.location.updateSettings(LocationComponentSettings(
enabled: true,
puckBearingEnabled: true,
locationPuck:
LocationPuck(locationPuck2D: DefaultLocationPuck2D(topImage: list, shadowImage: Uint8List.fromList([]))))
);
- Introduce experimental
RasterArraySource
, note thatrasterLayers
is a get-only property and cannot be set. - Introduce
TileCacheBudget
, a property to set per-source cache budgets in either megabytes or tiles. - Expose
iconColorSaturation
,rasterArrayBand
,rasterElevation
,rasterEmissiveStrength
,hillshadeEmissiveStrength
, andfillExtrusionEmissiveStrength
on their respective layers. - Mark
MapboxMapsOptions.get/setWorldview()
andMapboxMapsOptions.get/setLanguage()
as experimental.
Snapshots
Standalone snapshotter
Show multiple maps at the same time with no performance penalty. With the all new Snapshotter
you can get image snapshots of the map, styled the same way as MapWidget
.
The Snapshotter
class is highly configurable. You can set the final result at the time of construction using the MapSnapshotOptions
. Once you've configured your snapshot, you can start the snapshotting process.
One of the key features of the Snapshotter
class is the style
object. This object can be manipulated to set different styles for your snapshot, as well as to apply runtime styling to the style, giving you the flexibility to create a snapshot that fits your needs.
final snapshotter = await Snapshotter.create(
options: MapSnapshotOptions(
size: Size(width: 400, height: 400),
pixelRatio: MediaQuery.of(context).devicePixelRatio),
onStyleLoadedListener: (_) {
// apply runtime styling
final layer = CircleLayer(id: "circle-layer", sourceId: "poi-source");
snapshotter?.style.addLayer(layer);
},
);
snapshotter.style.setStyleURI(MapboxStyles.STANDARD);
snapshotter.setCamera(CameraOptions(center: Point(...)));
...
final snapshotImage = await snapshotter.start()
Map widget snapshotting
Create snapshots of the map displayed in the MapWidget
with MapboxMap.snapshot()
. This new feature allows you to capture a static image of the current map view.
The snapshot()
method captures the current state of the Mapbox map, including all visible layers, markers, and user interactions.
To use the snapshot() method, simply call it on your Mapbox map instance. The method will return a Future that resolves to the image of the current map view.
final snapshotImage = await mapboxMap.snapshot();
Please note that the snapshot()
method works best if the Mapbox Map is fully loaded before capturing an image. If the map is not fully loaded, the method might return a blank image.
Bug fixes 🐞
- Fixes race condition in events when method call to subscribe to map events from dart side was competing with early map events.
- [iOS] Fix crash in
onStyleImageMissingListener
. - Fix camera center not applied from map init options.
- [iOS] Free up resources upon map widget disposal. This should help to reduce the amount of used memory when previously shown map widget is removed from the widget tree.
- Fix multi-word enum cases decoding/encoding when being sent to/from the platform side.
Other Changes
- Deprecate
cameraForCoordinates
, please usecameraForCoordinatesPadding
instead.
Dependency Updates
- Bump Mapbox Maps SDK to 11.4.0
- Bump Pigeon to 18.0.0