diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java index 23150152e..12154e2ab 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java @@ -26,6 +26,9 @@ import androidx.annotation.NonNull; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.mapbox.android.core.location.LocationEngine; import com.mapbox.android.core.location.LocationEngineCallback; import com.mapbox.android.core.location.LocationEngineProvider; @@ -495,9 +498,13 @@ public void onCancel() { String[] layerIds = ((List) call.argument("layerIds")).toArray(new String[0]); - String filter = (String) call.argument("filter"); - - Expression filterExpression = filter == null ? null : new Expression(filter); + List filter = call.argument("filter"); + JsonElement jsonElement = filter == null ? null : new Gson().toJsonTree(filter); + JsonArray jsonArray = null; + if (jsonElement != null && jsonElement.isJsonArray()) { + jsonArray = jsonElement.getAsJsonArray(); + } + Expression filterExpression = jsonArray == null ? null : Expression.Converter.convert(jsonArray); if (call.hasArgument("x")) { Double x = call.argument("x"); Double y = call.argument("y"); diff --git a/example/lib/map_ui.dart b/example/lib/map_ui.dart index e82200feb..44fa0099c 100644 --- a/example/lib/map_ui.dart +++ b/example/lib/map_ui.dart @@ -54,6 +54,7 @@ class MapUiBodyState extends State { bool _myLocationEnabled = true; bool _telemetryEnabled = true; MyLocationTrackingMode _myLocationTrackingMode = MyLocationTrackingMode.Tracking; + List _featureQueryFilter; @override void initState() { @@ -90,6 +91,21 @@ class MapUiBodyState extends State { ); } + Widget _queryFilterToggler() { + return FlatButton( + child: Text('filter zoo on click ${ _featureQueryFilter == null ? 'disabled' : 'enabled'}'), + onPressed: () { + setState(() { + if (_featureQueryFilter == null) { + _featureQueryFilter = ["==", ["get", "type"] , "zoo"]; + } else { + _featureQueryFilter = null; + } + }); + }, + ); + } + Widget _compassToggler() { return FlatButton( child: Text('${_compassEnabled ? 'disable' : 'enable'} compasss'), @@ -240,14 +256,15 @@ class MapUiBodyState extends State { myLocationRenderMode: MyLocationRenderMode.GPS, onMapClick: (point, latLng) async { print("Map click: ${point.x},${point.y} ${latLng.latitude}/${latLng.longitude}"); - List features = await mapController.queryRenderedFeatures(point, [],null); + print("Filter $_featureQueryFilter"); + List features = await mapController.queryRenderedFeatures(point, [], _featureQueryFilter); if (features.length>0) { print(features[0]); } }, onMapLongClick: (point, latLng) async { print("Map long press: ${point.x},${point.y} ${latLng.latitude}/${latLng.longitude}"); - List features = await mapController.queryRenderedFeatures(point, [],null); + List features = await mapController.queryRenderedFeatures(point, [], null); if (features.length>0) { print(features[0]); } @@ -284,6 +301,7 @@ class MapUiBodyState extends State { Text('camera zoom: ${_position.zoom}'), Text('camera tilt: ${_position.tilt}'), Text(_isMoving ? '(Camera moving)' : '(Camera idle)'), + _queryFilterToggler(), _compassToggler(), _myLocationTrackingModeCycler(), _latLngBoundsToggler(), diff --git a/ios/Classes/MapboxMapController.swift b/ios/Classes/MapboxMapController.swift index babd0df66..c0cb11081 100644 --- a/ios/Classes/MapboxMapController.swift +++ b/ios/Classes/MapboxMapController.swift @@ -118,6 +118,34 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma style.localizeLabels(into: locale) } result(nil) + case "map#queryRenderedFeatures": + guard let arguments = methodCall.arguments as? [String: Any] else { return } + let layerIds = arguments["layerIds"] as? Set + var filterExpression: NSPredicate? + if let filter = arguments["filter"] as? [Any] { + filterExpression = NSPredicate(mglJSONObject: filter) + } + var reply = [String: NSObject]() + var features:[MGLFeature] = [] + if let x = arguments["x"] as? Double, let y = arguments["y"] as? Double { + features = mapView.visibleFeatures(at: CGPoint(x: x, y: y), styleLayerIdentifiers: layerIds, predicate: filterExpression) + } + if let top = arguments["top"] as? Double, + let bottom = arguments["bottom"] as? Double, + let left = arguments["left"] as? Double, + let right = arguments["right"] as? Double { + features = mapView.visibleFeatures(in: CGRect(x: left, y: top, width: right, height: bottom), styleLayerIdentifiers: layerIds, predicate: filterExpression) + } + var featuresJson = [String]() + for feature in features { + let dictionary = feature.geoJSONDictionary() + if let theJSONData = try? JSONSerialization.data(withJSONObject: dictionary, options: []), + let theJSONText = String(data: theJSONData, encoding: .ascii) { + featuresJson.append(theJSONText) + } + } + reply["features"] = featuresJson as NSObject + result(reply) case "map#setTelemetryEnabled": guard let arguments = methodCall.arguments as? [String: Any] else { return } let telemetryEnabled = arguments["enabled"] as? Bool @@ -489,9 +517,7 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma circleAnnotationController?.delegate = self mapReadyResult?(nil) - print("asdasd\(channel)") if let channel = channel { - print("asdasd2 ") channel.invokeMethod("map#onStyleLoaded", arguments: nil) } } diff --git a/lib/src/controller.dart b/lib/src/controller.dart index bee93b804..83ed1f2a5 100644 --- a/lib/src/controller.dart +++ b/lib/src/controller.dart @@ -583,7 +583,7 @@ class MapboxMapController extends ChangeNotifier { } Future queryRenderedFeatures( - Point point, List layerIds, String filter) async { + Point point, List layerIds, List filter) async { return MapboxGlPlatform.getInstance(_id) .queryRenderedFeatures(point, layerIds, filter); } 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 b55d11870..da022c739 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 @@ -161,7 +161,7 @@ abstract class MapboxGlPlatform { } Future queryRenderedFeatures( - Point point, List layerIds, String filter) async { + Point point, List layerIds, List filter) async { throw UnimplementedError( 'queryRenderedFeatures() has not been implemented.'); } 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 71698c199..e1513daf7 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 @@ -305,7 +305,7 @@ class MethodChannelMapboxGl extends MapboxGlPlatform { @override Future queryRenderedFeatures( - Point point, List layerIds, String filter) async { + Point point, List layerIds, List filter) async { try { final Map reply = await _channel.invokeMethod( 'map#queryRenderedFeatures', diff --git a/mapbox_gl_web/lib/src/mapbox_map_controller.dart b/mapbox_gl_web/lib/src/mapbox_map_controller.dart index 67f72ff73..a0e5a9890 100644 --- a/mapbox_gl_web/lib/src/mapbox_map_controller.dart +++ b/mapbox_gl_web/lib/src/mapbox_map_controller.dart @@ -227,7 +227,7 @@ class MapboxMapController extends MapboxGlPlatform @override Future queryRenderedFeatures( - Point point, List layerIds, String filter) async { + Point point, List layerIds, List filter) async { Map options = {}; if (layerIds.length > 0) { options['layers'] = layerIds; diff --git a/pubspec.lock b/pubspec.lock index bac8dbf94..f15493608 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -78,15 +78,19 @@ packages: dependency: "direct main" description: path: mapbox_gl_platform_interface - relative: true - source: path + ref: HEAD + resolved-ref: fa9dac81b6d0f3a5f01688a6695ee938b71874e5 + url: "https://github.com/tobrun/flutter-mapbox-gl.git" + source: git version: "0.7.0" mapbox_gl_web: dependency: "direct main" description: path: mapbox_gl_web - relative: true - source: path + ref: HEAD + resolved-ref: fa9dac81b6d0f3a5f01688a6695ee938b71874e5 + url: "https://github.com/tobrun/flutter-mapbox-gl.git" + source: git version: "0.7.0" meta: dependency: transitive