From 6542f1b41443c0e20577813235095ff8dcead68f Mon Sep 17 00:00:00 2001 From: Felix Horvat Date: Mon, 15 Nov 2021 18:36:31 +0100 Subject: [PATCH 1/3] fixed layer based tap random selection - IOS --- ios/Classes/MapboxMapController.swift | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/ios/Classes/MapboxMapController.swift b/ios/Classes/MapboxMapController.swift index 9fccbfe7c..ced5c8d44 100644 --- a/ios/Classes/MapboxMapController.swift +++ b/ios/Classes/MapboxMapController.swift @@ -810,6 +810,25 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma return trackCameraPosition ? mapView.camera : nil } + /* + * Scan layers from top to bottom and return the first matching feature + */ + private func firstFeatureOnLayers(at: CGPoint) -> MGLFeature? { + guard let style = mapView.style else { return nil} + + // get layers in order (featureLayerIdentifiers is unordered) + let clickableLayers = style.layers.filter{ layer in + return featureLayerIdentifiers.contains(layer.identifier) + } + + for layer in clickableLayers.reversed() { + let features = mapView.visibleFeatures(at: at, styleLayerIdentifiers: [layer.identifier]) + if let feature = features.first { + return feature + } + } + return nil + } /* * UITapGestureRecognizer @@ -818,15 +837,13 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma @objc @IBAction func handleMapTap(sender: UITapGestureRecognizer) { // Get the CGPoint where the user tapped. let point = sender.location(in: mapView) - let coordinate = mapView.convert(point, toCoordinateFrom: mapView) - let features = mapView.visibleFeatures(at: point, styleLayerIdentifiers: featureLayerIdentifiers) - - if let feature = features.last, let id = feature.identifier { + if let feature = firstFeatureOnLayers(at: point), let id = feature.identifier { channel?.invokeMethod("feature#onTap", arguments: [ "featureId": id ]) } else { + let coordinate = mapView.convert(point, toCoordinateFrom: mapView) channel?.invokeMethod("map#onMapClick", arguments: [ "x": point.x, "y": point.y, From 6d7cd3bd8f5264591815d7485f0075aca4de08bb Mon Sep 17 00:00:00 2001 From: Felix Horvat Date: Mon, 15 Nov 2021 18:36:31 +0100 Subject: [PATCH 2/3] fixed feature selection issue for android --- .../mapbox/mapboxgl/MapboxMapController.java | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java index 08d20bfa6..f32d20679 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java @@ -71,6 +71,7 @@ import com.mapbox.mapboxsdk.plugins.annotation.SymbolOptions; import com.mapbox.mapboxsdk.plugins.localization.LocalizationPlugin; import com.mapbox.mapboxsdk.style.expressions.Expression; +import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.layers.RasterLayer; import com.mapbox.mapboxsdk.style.sources.ImageSource; import com.mapbox.mapboxsdk.style.layers.LineLayer; @@ -523,6 +524,25 @@ private String enableFillManager(@NonNull Style style, @Nullable String belowLay return fillManager.getLayerId(); } + private Feature firstFeatureOnLayers(RectF in) { + final List layers = style.getLayers(); + final List layersInOrder = new ArrayList(); + for (Layer layer : layers){ + String id = layer.getId(); + if(featureLayerIdentifiers.contains(id)) + layersInOrder.add(id); + } + Collections.reverse(layersInOrder); + + for(String id: layersInOrder){ + List features = mapboxMap.queryRenderedFeatures(in, id); + if(!features.isEmpty()){ + return features.get(0); + } + } + return null; + } + @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { switch (call.method) { @@ -1276,10 +1296,10 @@ public boolean onMapClick(@NonNull LatLng point) { pointf.x + 10, pointf.y + 10 ); - List featureList = mapboxMap.queryRenderedFeatures(rectF, featureLayerIdentifiers.toArray(new String[0])); - if(!featureList.isEmpty()){ + Feature feature = firstFeatureOnLayers(rectF); + if(feature != null){ final Map arguments = new HashMap<>(1); - arguments.put("featureId", featureList.get(0).id()); + arguments.put("featureId", feature.id()); methodChannel.invokeMethod("feature#onTap", arguments); } else { final Map arguments = new HashMap<>(5); From 1528e37a9cf0cad28b12cafd4d6e4bde6a290a04 Mon Sep 17 00:00:00 2001 From: Felix Horvat Date: Tue, 16 Nov 2021 22:21:32 +0100 Subject: [PATCH 3/3] added null guard --- .../mapbox/mapboxgl/MapboxMapController.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java index f32d20679..a05913666 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java @@ -525,19 +525,21 @@ private String enableFillManager(@NonNull Style style, @Nullable String belowLay } private Feature firstFeatureOnLayers(RectF in) { - final List layers = style.getLayers(); - final List layersInOrder = new ArrayList(); - for (Layer layer : layers){ - String id = layer.getId(); - if(featureLayerIdentifiers.contains(id)) - layersInOrder.add(id); - } - Collections.reverse(layersInOrder); - - for(String id: layersInOrder){ - List features = mapboxMap.queryRenderedFeatures(in, id); - if(!features.isEmpty()){ - return features.get(0); + if(style != null){ + final List layers = style.getLayers(); + final List layersInOrder = new ArrayList(); + for (Layer layer : layers){ + String id = layer.getId(); + if(featureLayerIdentifiers.contains(id)) + layersInOrder.add(id); + } + Collections.reverse(layersInOrder); + + for(String id: layersInOrder){ + List features = mapboxMap.queryRenderedFeatures(in, id); + if(!features.isEmpty()){ + return features.get(0); + } } } return null;