diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java index 897a1edc6..f45556c9f 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java @@ -404,6 +404,9 @@ private void addSymbolLayer( if (maxZoom != null) { symbolLayer.setMaxZoom(maxZoom); } + if (filter != null) { + symbolLayer.setFilter(filter); + } if (belowLayerId != null) { style.addLayerBelow(symbolLayer, belowLayerId); } else { @@ -435,6 +438,9 @@ private void addLineLayer( if (maxZoom != null) { lineLayer.setMaxZoom(maxZoom); } + if (filter != null) { + lineLayer.setFilter(filter); + } if (belowLayerId != null) { style.addLayerBelow(lineLayer, belowLayerId); } else { @@ -466,6 +472,9 @@ private void addFillLayer( if (maxZoom != null) { fillLayer.setMaxZoom(maxZoom); } + if (filter != null) { + fillLayer.setFilter(filter); + } if (belowLayerId != null) { style.addLayerBelow(fillLayer, belowLayerId); } else { @@ -497,6 +506,9 @@ private void addCircleLayer( if (maxZoom != null) { circleLayer.setMaxZoom(maxZoom); } + if (filter != null) { + circleLayer.setFilter(filter); + } if (belowLayerId != null) { style.addLayerBelow(circleLayer, belowLayerId); } else { @@ -505,7 +517,12 @@ private void addCircleLayer( if (enableInteraction) { interactiveFeatureLayerIds.add(layerName); } - ; + } + + private Expression parseFilter(String filter) { + JsonParser parser = new JsonParser(); + JsonElement filterJsonElement = parser.parse(filter); + return filterJsonElement.isJsonNull() ? null : Expression.Converter.convert(filterJsonElement); } private void addRasterLayer( @@ -825,9 +842,13 @@ public void onError(@NonNull String message) { final String sourceLayer = call.argument("sourceLayer"); final Double minzoom = call.argument("minzoom"); final Double maxzoom = call.argument("maxzoom"); + final String filter = call.argument("filter"); final boolean enableInteraction = call.argument("enableInteraction"); final PropertyValue[] properties = LayerPropertyConverter.interpretSymbolLayerProperties(call.argument("properties")); + + Expression filterExpression = parseFilter(filter); + addSymbolLayer( layerId, sourceId, @@ -837,7 +858,7 @@ public void onError(@NonNull String message) { maxzoom != null ? maxzoom.floatValue() : null, properties, enableInteraction, - null); + filterExpression); updateLocationComponentLayer(); result.success(null); @@ -851,9 +872,13 @@ public void onError(@NonNull String message) { final String sourceLayer = call.argument("sourceLayer"); final Double minzoom = call.argument("minzoom"); final Double maxzoom = call.argument("maxzoom"); + final String filter = call.argument("filter"); final boolean enableInteraction = call.argument("enableInteraction"); final PropertyValue[] properties = LayerPropertyConverter.interpretLineLayerProperties(call.argument("properties")); + + Expression filterExpression = parseFilter(filter); + addLineLayer( layerId, sourceId, @@ -863,7 +888,7 @@ public void onError(@NonNull String message) { maxzoom != null ? maxzoom.floatValue() : null, properties, enableInteraction, - null); + filterExpression); updateLocationComponentLayer(); result.success(null); @@ -877,9 +902,13 @@ public void onError(@NonNull String message) { final String sourceLayer = call.argument("sourceLayer"); final Double minzoom = call.argument("minzoom"); final Double maxzoom = call.argument("maxzoom"); + final String filter = call.argument("filter"); final boolean enableInteraction = call.argument("enableInteraction"); final PropertyValue[] properties = LayerPropertyConverter.interpretFillLayerProperties(call.argument("properties")); + + Expression filterExpression = parseFilter(filter); + addFillLayer( layerId, sourceId, @@ -889,7 +918,7 @@ public void onError(@NonNull String message) { maxzoom != null ? maxzoom.floatValue() : null, properties, enableInteraction, - null); + filterExpression); updateLocationComponentLayer(); result.success(null); @@ -903,9 +932,13 @@ public void onError(@NonNull String message) { final String sourceLayer = call.argument("sourceLayer"); final Double minzoom = call.argument("minzoom"); final Double maxzoom = call.argument("maxzoom"); + final String filter = call.argument("filter"); final boolean enableInteraction = call.argument("enableInteraction"); final PropertyValue[] properties = LayerPropertyConverter.interpretCircleLayerProperties(call.argument("properties")); + + Expression filterExpression = parseFilter(filter); + addCircleLayer( layerId, sourceId, @@ -915,7 +948,7 @@ public void onError(@NonNull String message) { maxzoom != null ? maxzoom.floatValue() : null, properties, enableInteraction, - null); + filterExpression); updateLocationComponentLayer(); result.success(null); diff --git a/example/lib/layer.dart b/example/lib/layer.dart index 2734720b9..240383629 100644 --- a/example/lib/layer.dart +++ b/example/lib/layer.dart @@ -82,6 +82,7 @@ class LayerState extends State { 'green' ], fillOpacity: 0.4), belowLayerId: "water", + filter: ['==', 'id', filteredId], ); await controller.addLineLayer( @@ -143,7 +144,6 @@ class LayerState extends State { controller.setGeoJsonSource("moving", _movingFeature(t.tick / 2000)); }); - controller.setFilter('fills', ['==', 'id', filteredId]); filterTimer = Timer.periodic(Duration(seconds: 3), (t) { filteredId = filteredId == 0 ? 1 : 0; controller.setFilter('fills', ['==', 'id', filteredId]); diff --git a/ios/Classes/MapboxMapController.swift b/ios/Classes/MapboxMapController.swift index 6fae4af39..e1d55b8ab 100644 --- a/ios/Classes/MapboxMapController.swift +++ b/ios/Classes/MapboxMapController.swift @@ -351,17 +351,23 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma let sourceLayer = arguments["sourceLayer"] as? String let minzoom = arguments["minzoom"] as? Double let maxzoom = arguments["maxzoom"] as? Double - addSymbolLayer( + let filter = arguments["filter"] as? String + + let addResult = addSymbolLayer( sourceId: sourceId, layerId: layerId, belowLayerId: belowLayerId, sourceLayerIdentifier: sourceLayer, minimumZoomLevel: minzoom, maximumZoomLevel: maxzoom, + filter: filter, enableInteraction: enableInteraction, properties: properties ) - result(nil) + switch addResult { + case .success: result(nil) + case let .failure(error): result(error.flutterError) + } case "lineLayer#add": guard let arguments = methodCall.arguments as? [String: Any] else { return } @@ -373,17 +379,23 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma let sourceLayer = arguments["sourceLayer"] as? String let minzoom = arguments["minzoom"] as? Double let maxzoom = arguments["maxzoom"] as? Double - addLineLayer( + let filter = arguments["filter"] as? String + + let addResult = addLineLayer( sourceId: sourceId, layerId: layerId, belowLayerId: belowLayerId, sourceLayerIdentifier: sourceLayer, minimumZoomLevel: minzoom, maximumZoomLevel: maxzoom, + filter: filter, enableInteraction: enableInteraction, properties: properties ) - result(nil) + switch addResult { + case .success: result(nil) + case let .failure(error): result(error.flutterError) + } case "fillLayer#add": guard let arguments = methodCall.arguments as? [String: Any] else { return } @@ -395,17 +407,23 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma let sourceLayer = arguments["sourceLayer"] as? String let minzoom = arguments["minzoom"] as? Double let maxzoom = arguments["maxzoom"] as? Double - addFillLayer( + let filter = arguments["filter"] as? String + + let addResult = addFillLayer( sourceId: sourceId, layerId: layerId, belowLayerId: belowLayerId, sourceLayerIdentifier: sourceLayer, minimumZoomLevel: minzoom, maximumZoomLevel: maxzoom, + filter: filter, enableInteraction: enableInteraction, properties: properties ) - result(nil) + switch addResult { + case .success: result(nil) + case let .failure(error): result(error.flutterError) + } case "circleLayer#add": guard let arguments = methodCall.arguments as? [String: Any] else { return } @@ -417,17 +435,23 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma let sourceLayer = arguments["sourceLayer"] as? String let minzoom = arguments["minzoom"] as? Double let maxzoom = arguments["maxzoom"] as? Double - addCircleLayer( + let filter = arguments["filter"] as? String + + let addResult = addCircleLayer( sourceId: sourceId, layerId: layerId, belowLayerId: belowLayerId, sourceLayerIdentifier: sourceLayer, minimumZoomLevel: minzoom, maximumZoomLevel: maxzoom, + filter: filter, enableInteraction: enableInteraction, properties: properties ) - result(nil) + switch addResult { + case .success: result(nil) + case let .failure(error): result(error.flutterError) + } case "hillshadeLayer#add": guard let arguments = methodCall.arguments as? [String: Any] else { return } @@ -640,30 +664,9 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma result(nil) return } - - do { - let filter = try JSONSerialization.jsonObject( - with: filter.data(using: .utf8)!, - options: .fragmentsAllowed - ) - let predicate = NSPredicate(mglJSONObject: filter) - if let layer = layer as? MGLVectorStyleLayer { - layer.predicate = predicate - } else { - result(FlutterError( - code: "invalidLayerType", - message: "Invalid layer type", - details: "Layer '\(layerId)' does not support filtering." - )) - return - } - result(nil) - } catch { - result(FlutterError( - code: "invalidExpression", - message: "Invalid filter expression", - details: "Could not parse filter expression." - )) + switch setFilter(layer, filter) { + case .success: result(nil) + case let .failure(error): result(error.flutterError) } case "source#addGeoJson": @@ -977,9 +980,10 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma sourceLayerIdentifier: String?, minimumZoomLevel: Double?, maximumZoomLevel: Double?, + filter: String?, enableInteraction: Bool, properties: [String: String] - ) { + ) -> Result { if let style = mapView.style { if let source = style.source(withIdentifier: sourceId) { let layer = MGLSymbolStyleLayer(identifier: layerId, source: source) @@ -996,6 +1000,11 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma if let maximumZoomLevel = maximumZoomLevel { layer.maximumZoomLevel = Float(maximumZoomLevel) } + if let filter = filter { + if case let .failure(error) = setFilter(layer, filter) { + return .failure(error) + } + } if let id = belowLayerId, let belowLayer = style.layer(withIdentifier: id) { style.insertLayer(layer, below: belowLayer) } else { @@ -1006,6 +1015,7 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma } } } + return .success(()) } func addLineLayer( @@ -1015,9 +1025,10 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma sourceLayerIdentifier: String?, minimumZoomLevel: Double?, maximumZoomLevel: Double?, + filter: String?, enableInteraction: Bool, properties: [String: String] - ) { + ) -> Result { if let style = mapView.style { if let source = style.source(withIdentifier: sourceId) { let layer = MGLLineStyleLayer(identifier: layerId, source: source) @@ -1031,6 +1042,11 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma if let maximumZoomLevel = maximumZoomLevel { layer.maximumZoomLevel = Float(maximumZoomLevel) } + if let filter = filter { + if case let .failure(error) = setFilter(layer, filter) { + return .failure(error) + } + } if let id = belowLayerId, let belowLayer = style.layer(withIdentifier: id) { style.insertLayer(layer, below: belowLayer) } else { @@ -1041,6 +1057,7 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma } } } + return .success(()) } func addFillLayer( @@ -1050,9 +1067,10 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma sourceLayerIdentifier: String?, minimumZoomLevel: Double?, maximumZoomLevel: Double?, + filter: String?, enableInteraction: Bool, properties: [String: String] - ) { + ) -> Result { if let style = mapView.style { if let source = style.source(withIdentifier: sourceId) { let layer = MGLFillStyleLayer(identifier: layerId, source: source) @@ -1066,6 +1084,11 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma if let maximumZoomLevel = maximumZoomLevel { layer.maximumZoomLevel = Float(maximumZoomLevel) } + if let filter = filter { + if case let .failure(error) = setFilter(layer, filter) { + return .failure(error) + } + } if let id = belowLayerId, let belowLayer = style.layer(withIdentifier: id) { style.insertLayer(layer, below: belowLayer) } else { @@ -1076,6 +1099,7 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma } } } + return .success(()) } func addCircleLayer( @@ -1085,9 +1109,10 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma sourceLayerIdentifier: String?, minimumZoomLevel: Double?, maximumZoomLevel: Double?, + filter: String?, enableInteraction: Bool, properties: [String: String] - ) { + ) -> Result { if let style = mapView.style { if let source = style.source(withIdentifier: sourceId) { let layer = MGLCircleStyleLayer(identifier: layerId, source: source) @@ -1104,6 +1129,11 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma if let maximumZoomLevel = maximumZoomLevel { layer.maximumZoomLevel = Float(maximumZoomLevel) } + if let filter = filter { + if case let .failure(error) = setFilter(layer, filter) { + return .failure(error) + } + } if let id = belowLayerId, let belowLayer = style.layer(withIdentifier: id) { style.insertLayer(layer, below: belowLayer) } else { @@ -1114,6 +1144,30 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma } } } + return .success(()) + } + + func setFilter(_ layer: MGLStyleLayer, _ filter: String) -> Result { + do { + let filter = try JSONSerialization.jsonObject( + with: filter.data(using: .utf8)!, + options: .fragmentsAllowed + ) + if filter is NSNull { + return .success(()) + } + let predicate = NSPredicate(mglJSONObject: filter) + if let layer = layer as? MGLVectorStyleLayer { + layer.predicate = predicate + } else { + return .failure(MethodCallError.invalidLayerType( + details: "Layer '\(layer.identifier)' does not support filtering." + )) + } + return .success(()) + } catch { + return .failure(MethodCallError.invalidExpression) + } } func addHillshadeLayer( diff --git a/ios/Classes/MethodCallError.swift b/ios/Classes/MethodCallError.swift new file mode 100644 index 000000000..8806bec33 --- /dev/null +++ b/ios/Classes/MethodCallError.swift @@ -0,0 +1,41 @@ +import Flutter + +enum MethodCallError: Error { + case invalidLayerType(details: String) + case invalidExpression + + var code: String { + switch self { + case .invalidLayerType: + return "invalidLayerType" + case .invalidExpression: + return "invalidExpression" + } + } + + var message: String { + switch self { + case .invalidLayerType: + return "Invalid layer type" + case .invalidExpression: + return "Invalid expression" + } + } + + var details: String { + switch self { + case let .invalidLayerType(details): + return details + case .invalidExpression: + return "Could not parse expression." + } + } + + var flutterError: FlutterError { + return FlutterError( + code: code, + message: message, + details: details + ) + } +} diff --git a/lib/src/controller.dart b/lib/src/controller.dart index 43d35e097..1d4583f13 100644 --- a/lib/src/controller.dart +++ b/lib/src/controller.dart @@ -339,13 +339,18 @@ class MapboxMapController extends ChangeNotifier { /// Setting [belowLayerId] adds the new layer below the given id. /// If [enableInteraction] is set the layer is considered for touch or drag /// events. [sourceLayer] is used to selected a specific source layer from - /// Vector source + /// Vector source. + /// [filter] determines which features should be rendered in the layer. + /// Filters are written as [expressions]. + /// + /// [expressions]: https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions Future addSymbolLayer( String sourceId, String layerId, SymbolLayerProperties properties, {String? belowLayerId, String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, bool enableInteraction = true}) async { await _mapboxGlPlatform.addSymbolLayer( sourceId, @@ -355,6 +360,7 @@ class MapboxMapController extends ChangeNotifier { sourceLayer: sourceLayer, minzoom: minzoom, maxzoom: maxzoom, + filter: filter, enableInteraction: enableInteraction, ); } @@ -369,13 +375,18 @@ class MapboxMapController extends ChangeNotifier { /// Setting [belowLayerId] adds the new layer below the given id. /// If [enableInteraction] is set the layer is considered for touch or drag /// events. [sourceLayer] is used to selected a specific source layer from - /// Vector source + /// Vector source. + /// [filter] determines which features should be rendered in the layer. + /// Filters are written as [expressions]. + /// + /// [expressions]: https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions Future addLineLayer( String sourceId, String layerId, LineLayerProperties properties, {String? belowLayerId, String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, bool enableInteraction = true}) async { await _mapboxGlPlatform.addLineLayer( sourceId, @@ -385,6 +396,7 @@ class MapboxMapController extends ChangeNotifier { sourceLayer: sourceLayer, minzoom: minzoom, maxzoom: maxzoom, + filter: filter, enableInteraction: enableInteraction, ); } @@ -399,13 +411,18 @@ class MapboxMapController extends ChangeNotifier { /// Setting [belowLayerId] adds the new layer below the given id. /// If [enableInteraction] is set the layer is considered for touch or drag /// events. [sourceLayer] is used to selected a specific source layer from - /// Vector source + /// Vector source. + /// [filter] determines which features should be rendered in the layer. + /// Filters are written as [expressions]. + /// + /// [expressions]: https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions Future addFillLayer( String sourceId, String layerId, FillLayerProperties properties, {String? belowLayerId, String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, bool enableInteraction = true}) async { await _mapboxGlPlatform.addFillLayer( sourceId, @@ -415,6 +432,7 @@ class MapboxMapController extends ChangeNotifier { sourceLayer: sourceLayer, minzoom: minzoom, maxzoom: maxzoom, + filter: filter, enableInteraction: enableInteraction, ); } @@ -429,13 +447,18 @@ class MapboxMapController extends ChangeNotifier { /// Setting [belowLayerId] adds the new layer below the given id. /// If [enableInteraction] is set the layer is considered for touch or drag /// events. [sourceLayer] is used to selected a specific source layer from - /// Vector source + /// Vector source. + /// [filter] determines which features should be rendered in the layer. + /// Filters are written as [expressions]. + /// + /// [expressions]: https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions Future addCircleLayer( String sourceId, String layerId, CircleLayerProperties properties, {String? belowLayerId, String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, bool enableInteraction = true}) async { await _mapboxGlPlatform.addCircleLayer( sourceId, @@ -445,6 +468,7 @@ class MapboxMapController extends ChangeNotifier { sourceLayer: sourceLayer, minzoom: minzoom, maxzoom: maxzoom, + filter: filter, enableInteraction: enableInteraction, ); } @@ -1105,48 +1129,64 @@ class MapboxMapController extends ChangeNotifier { /// [HillshadeLayerProperties]. /// [sourceLayer] is used to selected a specific source layer from Vector /// source. + /// [filter] determines which features should be rendered in the layer. + /// Filters are written as [expressions]. + /// [filter] is not supported by RasterLayer and HillshadeLayer. + /// + /// [expressions]: https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions Future addLayer( String sourceId, String layerId, LayerProperties properties, {String? belowLayerId, bool enableInteraction = true, String? sourceLayer, double? minzoom, - double? maxzoom}) async { + double? maxzoom, + dynamic filter}) async { if (properties is FillLayerProperties) { addFillLayer(sourceId, layerId, properties, belowLayerId: belowLayerId, enableInteraction: enableInteraction, sourceLayer: sourceLayer, minzoom: minzoom, - maxzoom: maxzoom); + maxzoom: maxzoom, + filter: filter); } else if (properties is LineLayerProperties) { addLineLayer(sourceId, layerId, properties, belowLayerId: belowLayerId, enableInteraction: enableInteraction, sourceLayer: sourceLayer, minzoom: minzoom, - maxzoom: maxzoom); + maxzoom: maxzoom, + filter: filter); } else if (properties is SymbolLayerProperties) { addSymbolLayer(sourceId, layerId, properties, belowLayerId: belowLayerId, enableInteraction: enableInteraction, sourceLayer: sourceLayer, minzoom: minzoom, - maxzoom: maxzoom); + maxzoom: maxzoom, + filter: filter); } else if (properties is CircleLayerProperties) { addCircleLayer(sourceId, layerId, properties, belowLayerId: belowLayerId, enableInteraction: enableInteraction, sourceLayer: sourceLayer, minzoom: minzoom, - maxzoom: maxzoom); + maxzoom: maxzoom, + filter: filter); } else if (properties is RasterLayerProperties) { + if (filter != null) { + throw UnimplementedError("RasterLayer does not support filter"); + } addRasterLayer(sourceId, layerId, properties, belowLayerId: belowLayerId, sourceLayer: sourceLayer, minzoom: minzoom, maxzoom: maxzoom); } else if (properties is HillshadeLayerProperties) { + if (filter != null) { + throw UnimplementedError("HillShadeLayer does not support filter"); + } addHillshadeLayer(sourceId, layerId, properties, belowLayerId: belowLayerId, sourceLayer: sourceLayer, diff --git a/mapbox_gl_platform_interface/lib/src/mapbox_gl_platform_interface.dart b/mapbox_gl_platform_interface/lib/src/mapbox_gl_platform_interface.dart index 9fc41911e..49cacae91 100644 --- a/mapbox_gl_platform_interface/lib/src/mapbox_gl_platform_interface.dart +++ b/mapbox_gl_platform_interface/lib/src/mapbox_gl_platform_interface.dart @@ -112,6 +112,7 @@ abstract class MapboxGlPlatform { String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}); Future addLineLayer( @@ -120,6 +121,7 @@ abstract class MapboxGlPlatform { String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}); Future addCircleLayer( @@ -128,6 +130,7 @@ abstract class MapboxGlPlatform { String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}); Future addFillLayer( @@ -136,6 +139,7 @@ abstract class MapboxGlPlatform { String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}); Future addRasterLayer( diff --git a/mapbox_gl_platform_interface/lib/src/method_channel_mapbox_gl.dart b/mapbox_gl_platform_interface/lib/src/method_channel_mapbox_gl.dart index 0bd62f1aa..38da956cf 100644 --- a/mapbox_gl_platform_interface/lib/src/method_channel_mapbox_gl.dart +++ b/mapbox_gl_platform_interface/lib/src/method_channel_mapbox_gl.dart @@ -536,6 +536,7 @@ class MethodChannelMapboxGl extends MapboxGlPlatform { String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}) async { await _channel.invokeMethod('symbolLayer#add', { 'sourceId': sourceId, @@ -544,6 +545,7 @@ class MethodChannelMapboxGl extends MapboxGlPlatform { 'sourceLayer': sourceLayer, 'minzoom': minzoom, 'maxzoom': maxzoom, + 'filter': jsonEncode(filter), 'enableInteraction': enableInteraction, 'properties': properties .map((key, value) => MapEntry(key, jsonEncode(value))) @@ -557,6 +559,7 @@ class MethodChannelMapboxGl extends MapboxGlPlatform { String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}) async { await _channel.invokeMethod('lineLayer#add', { 'sourceId': sourceId, @@ -565,6 +568,7 @@ class MethodChannelMapboxGl extends MapboxGlPlatform { 'sourceLayer': sourceLayer, 'minzoom': minzoom, 'maxzoom': maxzoom, + 'filter': jsonEncode(filter), 'enableInteraction': enableInteraction, 'properties': properties .map((key, value) => MapEntry(key, jsonEncode(value))) @@ -578,6 +582,7 @@ class MethodChannelMapboxGl extends MapboxGlPlatform { String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}) async { await _channel.invokeMethod('circleLayer#add', { 'sourceId': sourceId, @@ -586,6 +591,7 @@ class MethodChannelMapboxGl extends MapboxGlPlatform { 'sourceLayer': sourceLayer, 'minzoom': minzoom, 'maxzoom': maxzoom, + 'filter': jsonEncode(filter), 'enableInteraction': enableInteraction, 'properties': properties .map((key, value) => MapEntry(key, jsonEncode(value))) @@ -599,6 +605,7 @@ class MethodChannelMapboxGl extends MapboxGlPlatform { String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}) async { await _channel.invokeMethod('fillLayer#add', { 'sourceId': sourceId, @@ -607,6 +614,7 @@ class MethodChannelMapboxGl extends MapboxGlPlatform { 'sourceLayer': sourceLayer, 'minzoom': minzoom, 'maxzoom': maxzoom, + 'filter': jsonEncode(filter), 'enableInteraction': enableInteraction, 'properties': properties .map((key, value) => MapEntry(key, jsonEncode(value))) diff --git a/mapbox_gl_web/lib/src/mapbox_web_gl_platform.dart b/mapbox_gl_web/lib/src/mapbox_web_gl_platform.dart index 69a10045b..8a506b8a5 100644 --- a/mapbox_gl_web/lib/src/mapbox_web_gl_platform.dart +++ b/mapbox_gl_web/lib/src/mapbox_web_gl_platform.dart @@ -703,12 +703,14 @@ class MapboxWebGlPlatform extends MapboxGlPlatform String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}) async { return _addLayer(sourceId, layerId, properties, "circle", belowLayerId: belowLayerId, sourceLayer: sourceLayer, minzoom: minzoom, maxzoom: maxzoom, + filter: filter, enableInteraction: enableInteraction); } @@ -719,12 +721,14 @@ class MapboxWebGlPlatform extends MapboxGlPlatform String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}) async { return _addLayer(sourceId, layerId, properties, "fill", belowLayerId: belowLayerId, sourceLayer: sourceLayer, minzoom: minzoom, maxzoom: maxzoom, + filter: filter, enableInteraction: enableInteraction); } @@ -735,12 +739,14 @@ class MapboxWebGlPlatform extends MapboxGlPlatform String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}) async { return _addLayer(sourceId, layerId, properties, "line", belowLayerId: belowLayerId, sourceLayer: sourceLayer, minzoom: minzoom, maxzoom: maxzoom, + filter: filter, enableInteraction: enableInteraction); } @@ -751,12 +757,14 @@ class MapboxWebGlPlatform extends MapboxGlPlatform String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}) async { return _addLayer(sourceId, layerId, properties, "symbol", belowLayerId: belowLayerId, sourceLayer: sourceLayer, minzoom: minzoom, maxzoom: maxzoom, + filter: filter, enableInteraction: enableInteraction); } @@ -796,6 +804,7 @@ class MapboxWebGlPlatform extends MapboxGlPlatform String? sourceLayer, double? minzoom, double? maxzoom, + dynamic filter, required bool enableInteraction}) async { final layout = Map.fromEntries( properties.entries.where((entry) => isLayoutProperty(entry.key))); @@ -811,6 +820,7 @@ class MapboxWebGlPlatform extends MapboxGlPlatform if (sourceLayer != null) 'source-layer': sourceLayer, if (minzoom != null) 'minzoom': minzoom, if (maxzoom != null) 'maxzoom': maxzoom, + if (filter != null) 'filter': filter, }, belowLayerId); if (enableInteraction) {