Skip to content

Commit 4ba8d48

Browse files
authored
Merge branch 'main' into main
2 parents 9321b78 + 8246a84 commit 4ba8d48

File tree

10 files changed

+140
-63
lines changed

10 files changed

+140
-63
lines changed

example/lib/layer.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,11 @@ class LayerState extends State {
145145
controller.onFeatureTapped.add(onFeatureTap);
146146
}
147147

148-
void onFeatureTap(dynamic featureId, Point<double> point, LatLng latLng) {
148+
void onFeatureTap(
149+
dynamic featureId, Point<double> point, LatLng latLng, String layerId) {
149150
final snackBar = SnackBar(
150151
content: Text(
151-
'Tapped feature with id $featureId',
152+
'Tapped feature with id $featureId on layer $layerId',
152153
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
153154
),
154155
backgroundColor: Theme.of(context).primaryColor,

maplibre_gl/android/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ android {
3030
}
3131

3232
compileSdkVersion 34
33-
ndkVersion "26.1.10909125"
33+
ndkVersion "27.0.12077973"
3434

3535
defaultConfig {
3636
minSdkVersion 21
@@ -48,9 +48,9 @@ android {
4848
jvmTarget = JavaVersion.VERSION_1_8
4949
}
5050
dependencies {
51-
implementation 'org.maplibre.gl:android-sdk:11.0.0'
52-
implementation 'org.maplibre.gl:android-plugin-annotation-v9:3.0.0'
53-
implementation 'org.maplibre.gl:android-plugin-offline-v9:3.0.0'
51+
implementation 'org.maplibre.gl:android-sdk:11.6.1'
52+
implementation 'org.maplibre.gl:android-plugin-annotation-v9:3.0.2'
53+
implementation 'org.maplibre.gl:android-plugin-offline-v9:3.0.2'
5454
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
5555
}
5656
}

maplibre_gl/android/src/main/java/org/maplibre/maplibregl/MapLibreMapController.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import android.view.TextureView;
2323
import android.view.View;
2424
import android.widget.FrameLayout;
25+
import android.util.Pair;
2526

2627
import androidx.annotation.NonNull;
2728
import androidx.lifecycle.DefaultLifecycleObserver;
@@ -31,8 +32,8 @@
3132
import com.google.gson.JsonArray;
3233
import com.google.gson.JsonElement;
3334
import com.google.gson.JsonParser;
34-
import com.mapbox.android.gestures.AndroidGesturesManager;
35-
import com.mapbox.android.gestures.MoveGestureDetector;
35+
import org.maplibre.android.gestures.AndroidGesturesManager;
36+
import org.maplibre.android.gestures.MoveGestureDetector;
3637
import org.maplibre.geojson.Feature;
3738
import org.maplibre.geojson.FeatureCollection;
3839
import org.maplibre.android.camera.CameraPosition;
@@ -652,7 +653,7 @@ private void addHeatmapLayer(
652653
}
653654
}
654655

655-
private Feature firstFeatureOnLayers(RectF in) {
656+
private Pair<Feature, String> firstFeatureOnLayers(RectF in) {
656657
if (style != null) {
657658
final List<Layer> layers = style.getLayers();
658659
final List<String> layersInOrder = new ArrayList<String>();
@@ -665,7 +666,7 @@ private Feature firstFeatureOnLayers(RectF in) {
665666
for (String id : layersInOrder) {
666667
List<Feature> features = mapLibreMap.queryRenderedFeatures(in, id);
667668
if (!features.isEmpty()) {
668-
return features.get(0);
669+
return new Pair<Feature, String>(features.get(0), id);
669670
}
670671
}
671672
}
@@ -934,6 +935,24 @@ public void onError(@NonNull String message) {
934935
});
935936
break;
936937
}
938+
case "map#clearAmbientCache":
939+
{
940+
OfflineManager fileSource = OfflineManager.Companion.getInstance(context);
941+
942+
fileSource.clearAmbientCache(
943+
new OfflineManager.FileSourceCallback() {
944+
@Override
945+
public void onSuccess() {
946+
result.success(null);
947+
}
948+
949+
@Override
950+
public void onError(@NonNull String message) {
951+
result.error("MAPBOX CACHE ERROR", message, null);
952+
}
953+
});
954+
break;
955+
}
937956
case "source#addGeoJson":
938957
{
939958
final String sourceId = call.argument("sourceId");
@@ -1659,14 +1678,15 @@ public void onDidBecomeIdle() {
16591678
public boolean onMapClick(@NonNull LatLng point) {
16601679
PointF pointf = mapLibreMap.getProjection().toScreenLocation(point);
16611680
RectF rectF = new RectF(pointf.x - 10, pointf.y - 10, pointf.x + 10, pointf.y + 10);
1662-
Feature feature = firstFeatureOnLayers(rectF);
1681+
Pair<Feature, String> featureLayerPair = firstFeatureOnLayers(rectF);
16631682
final Map<String, Object> arguments = new HashMap<>();
16641683
arguments.put("x", pointf.x);
16651684
arguments.put("y", pointf.y);
16661685
arguments.put("lng", point.getLongitude());
16671686
arguments.put("lat", point.getLatitude());
1668-
if (feature != null) {
1669-
arguments.put("id", feature.id());
1687+
if (featureLayerPair != null && featureLayerPair.first != null) {
1688+
arguments.put("layerId", featureLayerPair.second);
1689+
arguments.put("id", featureLayerPair.first.id());
16701690
methodChannel.invokeMethod("feature#onTap", arguments);
16711691
} else {
16721692
methodChannel.invokeMethod("map#onMapClick", arguments);
@@ -2137,8 +2157,8 @@ boolean onMoveBegin(MoveGestureDetector detector) {
21372157
PointF pointf = detector.getFocalPoint();
21382158
LatLng origin = mapLibreMap.getProjection().fromScreenLocation(pointf);
21392159
RectF rectF = new RectF(pointf.x - 10, pointf.y - 10, pointf.x + 10, pointf.y + 10);
2140-
Feature feature = firstFeatureOnLayers(rectF);
2141-
if (feature != null && startDragging(feature, origin)) {
2160+
Pair<Feature, String> featureLayerPair = firstFeatureOnLayers(rectF);
2161+
if (featureLayerPair != null && featureLayerPair.first != null && startDragging(featureLayerPair.first, origin)) {
21422162
invokeFeatureDrag(pointf, "start");
21432163
return true;
21442164
}

maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapController.swift

Lines changed: 56 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
7171
longPress.require(toFail: recognizer)
7272
}
7373
var longPressRecognizerAdded = false
74-
74+
7575
if let args = args as? [String: Any] {
76-
76+
7777
Convert.interpretMapLibreMapOptions(options: args["options"], delegate: self)
7878
if let initialCameraPosition = args["initialCameraPosition"] as? [String: Any],
7979
let camera = MLNMapCamera.fromDict(initialCameraPosition, mapView: mapView),
@@ -158,6 +158,15 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
158158
result(nil)
159159
}
160160
}
161+
case "map#clearAmbientCache":
162+
MLNOfflineStorage.shared.clearAmbientCache {
163+
error in
164+
if let error = error {
165+
result(error)
166+
} else {
167+
result(nil)
168+
}
169+
}
161170
case "map#updateMyLocationTrackingMode":
162171
guard let arguments = methodCall.arguments as? [String: Any] else { return }
163172
if let myLocationTrackingMode = arguments["mode"] as? UInt,
@@ -170,7 +179,7 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
170179
if let langStr = Locale.current.languageCode {
171180
setMapLanguage(language: langStr)
172181
}
173-
182+
174183
result(nil)
175184
case "map#updateContentInsets":
176185
guard let arguments = methodCall.arguments as? [String: Any] else { return }
@@ -316,7 +325,7 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
316325
case "camera#move":
317326
guard let arguments = methodCall.arguments as? [String: Any] else { return }
318327
guard let cameraUpdate = arguments["cameraUpdate"] as? [Any] else { return }
319-
328+
320329
if let camera = Convert.parseCameraUpdate(cameraUpdate: cameraUpdate, mapView: mapView) {
321330
mapView.setCamera(camera, animated: false)
322331
}
@@ -325,12 +334,12 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
325334
guard let arguments = methodCall.arguments as? [String: Any] else { return }
326335
guard let cameraUpdate = arguments["cameraUpdate"] as? [Any] else { return }
327336
guard let camera = Convert.parseCameraUpdate(cameraUpdate: cameraUpdate, mapView: mapView) else { return }
328-
329-
337+
338+
330339
let completion = {
331340
result(nil)
332341
}
333-
342+
334343
if let duration = arguments["duration"] as? TimeInterval {
335344
if let padding = Convert.parseLatLngBoundsPadding(cameraUpdate) {
336345
mapView.fly(to: camera, edgePadding: padding, withDuration: duration / 1000, completionHandler: completion)
@@ -537,7 +546,7 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
537546
properties: properties
538547
)
539548
result(nil)
540-
549+
541550
case "heatmapLayer#add":
542551
guard let arguments = methodCall.arguments as? [String: Any] else { return }
543552
guard let sourceId = arguments["sourceId"] as? String else { return }
@@ -840,11 +849,11 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
840849
}
841850
layer.isVisible = visible
842851
result(nil)
843-
852+
844853
case "map#querySourceFeatures":
845854
guard let arguments = methodCall.arguments as? [String: Any] else { return }
846855
guard let sourceId = arguments["sourceId"] as? String else { return }
847-
856+
848857
var sourceLayerId = Set<String>()
849858
if let layerId = arguments["sourceLayerId"] as? String {
850859
sourceLayerId.insert(layerId)
@@ -853,10 +862,10 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
853862
if let filter = arguments["filter"] as? [Any] {
854863
filterExpression = NSPredicate(mglJSONObject: filter)
855864
}
856-
865+
857866
var reply = [String: NSObject]()
858867
var features: [MLNFeature] = []
859-
868+
860869
guard let style = mapView.style else { return }
861870
if let source = style.source(withIdentifier: sourceId) {
862871
if let vectorSource = source as? MLNVectorTileSource {
@@ -865,7 +874,7 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
865874
features = shapeSource.features(matching: filterExpression)
866875
}
867876
}
868-
877+
869878
var featuresJson = [String]()
870879
for feature in features {
871880
let dictionary = feature.geoJSONDictionary()
@@ -883,11 +892,11 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
883892

884893
case "style#getLayerIds":
885894
var layerIds = [String]()
886-
895+
887896
guard let style = mapView.style else { return }
888-
897+
889898
style.layers.forEach { layer in layerIds.append(layer.identifier) }
890-
899+
891900
var reply = [String: NSObject]()
892901
reply["layers"] = layerIds as NSObject
893902
result(reply)
@@ -902,18 +911,18 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
902911
var reply = [String: NSObject]()
903912
reply["sources"] = sourceIds as NSObject
904913
result(reply)
905-
914+
906915
case "style#getFilter":
907916
guard let arguments = methodCall.arguments as? [String: Any] else { return }
908917
guard let layerId = arguments["layerId"] as? String else { return }
909-
918+
910919
guard let style = mapView.style else { return }
911920
guard let layer = style.layer(withIdentifier: layerId) else { return }
912-
921+
913922
var currentLayerFilter : String = ""
914923
if let vectorLayer = layer as? MLNVectorStyleLayer {
915924
if let layerFilter = vectorLayer.predicate {
916-
925+
917926
let jsonExpression = layerFilter.mgl_jsonExpressionObject
918927
if let data = try? JSONSerialization.data(withJSONObject: jsonExpression, options: []) {
919928
currentLayerFilter = String(data: data, encoding: String.Encoding.utf8) ?? ""
@@ -925,11 +934,11 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
925934
).flutterError)
926935
return;
927936
}
928-
937+
929938
var reply = [String: NSObject]()
930939
reply["filter"] = currentLayerFilter as NSObject
931940
result(reply)
932-
941+
933942
default:
934943
result(FlutterMethodNotImplemented)
935944
}
@@ -967,16 +976,16 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
967976
private func getCamera() -> MLNMapCamera? {
968977
return trackCameraPosition ? mapView.camera : nil
969978
}
970-
979+
971980
private func setMapLanguage(language: String) {
972981
self.mapView.setMapLanguage(language)
973982
}
974983

975984
/*
976985
* Scan layers from top to bottom and return the first matching feature
977986
*/
978-
private func firstFeatureOnLayers(at: CGPoint) -> MLNFeature? {
979-
guard let style = mapView.style else { return nil }
987+
private func firstFeatureOnLayers(at: CGPoint) -> (feature: MLNFeature?, layerId: String?) {
988+
guard let style = mapView.style else { return (nil, nil) }
980989

981990
// get layers in order (interactiveFeatureLayerIds is unordered)
982991
let clickableLayers = style.layers.filter { layer in
@@ -989,10 +998,10 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
989998
styleLayerIdentifiers: [layer.identifier]
990999
)
9911000
if let feature = features.first {
992-
return feature
1001+
return (feature, layer.identifier)
9931002
}
9941003
}
995-
return nil
1004+
return (nil, nil)
9961005
}
9971006

9981007
/*
@@ -1004,13 +1013,15 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
10041013
let point = sender.location(in: mapView)
10051014
let coordinate = mapView.convert(point, toCoordinateFrom: mapView)
10061015

1007-
if let feature = firstFeatureOnLayers(at: point) {
1016+
let result = firstFeatureOnLayers(at: point)
1017+
if let feature = result.feature {
10081018
channel?.invokeMethod("feature#onTap", arguments: [
10091019
"id": feature.identifier,
10101020
"x": point.x,
10111021
"y": point.y,
10121022
"lng": coordinate.longitude,
10131023
"lat": coordinate.latitude,
1024+
"layerId": result.layerId,
10141025
])
10151026
} else {
10161027
channel?.invokeMethod("map#onMapClick", arguments: [
@@ -1053,22 +1064,23 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate,
10531064
let point = sender.location(in: mapView)
10541065
let coordinate = mapView.convert(point, toCoordinateFrom: mapView)
10551066

1056-
if dragFeature == nil, began, sender.numberOfTouches == 1,
1057-
let feature = firstFeatureOnLayers(at: point),
1058-
let draggable = feature.attribute(forKey: "draggable") as? Bool,
1059-
draggable
1060-
{
1061-
sender.state = UIGestureRecognizer.State.began
1062-
dragFeature = feature
1063-
originDragCoordinate = coordinate
1064-
previousDragCoordinate = coordinate
1065-
mapView.allowsScrolling = false
1066-
let eventType = "start"
1067-
invokeFeatureDrag(point, coordinate, eventType)
1068-
for gestureRecognizer in mapView.gestureRecognizers! {
1069-
if let _ = gestureRecognizer as? UIPanGestureRecognizer {
1070-
gestureRecognizer.addTarget(self, action: #selector(handleMapPan))
1071-
break
1067+
if dragFeature == nil, began, sender.numberOfTouches == 1 {
1068+
let result = firstFeatureOnLayers(at: point)
1069+
if let feature = result.feature,
1070+
let draggable = feature.attribute(forKey: "draggable") as? Bool,
1071+
draggable {
1072+
sender.state = UIGestureRecognizer.State.began
1073+
dragFeature = feature
1074+
originDragCoordinate = coordinate
1075+
previousDragCoordinate = coordinate
1076+
mapView.allowsScrolling = false
1077+
let eventType = "start"
1078+
invokeFeatureDrag(point, coordinate, eventType)
1079+
for gestureRecognizer in mapView.gestureRecognizers! {
1080+
if let _ = gestureRecognizer as? UIPanGestureRecognizer {
1081+
gestureRecognizer.addTarget(self, action: #selector(handleMapPan))
1082+
break
1083+
}
10721084
}
10731085
}
10741086
}

maplibre_gl/lib/src/annotation_manager.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ abstract class AnnotationManager<T extends Annotation> {
5555
}
5656
}
5757

58-
_onFeatureTapped(dynamic id, Point<double> point, LatLng coordinates) {
58+
_onFeatureTapped(
59+
dynamic id, Point<double> point, LatLng coordinates, String layerId) {
5960
final annotation = _idToAnnotation[id];
6061
if (annotation != null) {
6162
onTap!(annotation);

0 commit comments

Comments
 (0)