From dafcf817d9d1d27074e3286d9daf87e1c5f9b260 Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 17 Dec 2024 12:58:48 +0100 Subject: [PATCH 1/7] Add func setUserLocationAnchor for iOS --- .../maplibre_gl/MapLibreMapController.swift | 18 ++++++++++++++++++ maplibre_gl/lib/src/controller.dart | 11 +++++++++++ .../src/maplibre_gl_platform_interface.dart | 1 + .../lib/src/method_channel_maplibre_gl.dart | 9 +++++++++ 4 files changed, 39 insertions(+) diff --git a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapController.swift b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapController.swift index 6bfcf1fc1..456d06c6a 100644 --- a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapController.swift +++ b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapController.swift @@ -19,6 +19,7 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate, private var initialTilt: CGFloat? private var cameraTargetBounds: MLNCoordinateBounds? + private var userLocationAnchorOffset: CGPoint? private var trackCameraPosition = false private var myLocationEnabled = false private var scrollingEnabled = true @@ -125,6 +126,13 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate, return true } + func mapViewUserLocationAnchorPoint(_ mapView: MLNMapView) -> CGPoint { + if let offset = userLocationAnchorOffset { + return offset + } + return CGPoint(x: mapView.bounds.midX, y: mapView.bounds.midY) + } + func onMethodCall(methodCall: FlutterMethodCall, result: @escaping FlutterResult) { switch methodCall.method { case "map#waitForMap": @@ -167,6 +175,12 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate, result(nil) } } + case "map#setUserLocationAnchor": + guard let arguments = methodCall.arguments as? [String: Any] else { return } + guard let x = arguments["x"] as? Double else { return } + guard let y = arguments["y"] as? Double else { return } + setUserLocationAnchorOffset(x: x, y: y) + result(nil) case "map#updateMyLocationTrackingMode": guard let arguments = methodCall.arguments as? [String: Any] else { return } if let myLocationTrackingMode = arguments["mode"] as? UInt, @@ -1753,6 +1767,10 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate, } } + func setUserLocationAnchorOffset(x: Double, y: Double) { + userLocationAnchorOffset = CGPoint(x: x, y: y) + } + func setLogoViewMargins(x: Double, y: Double) { mapView.logoViewMargins = CGPoint(x: x, y: y) } diff --git a/maplibre_gl/lib/src/controller.dart b/maplibre_gl/lib/src/controller.dart index 192a8cff9..e539d76ee 100644 --- a/maplibre_gl/lib/src/controller.dart +++ b/maplibre_gl/lib/src/controller.dart @@ -260,6 +260,17 @@ class MapLibreMapController extends ChangeNotifier { notifyListeners(); } + /// Set the user location anchor point + /// + /// [anchor] is the position of the user location icon relative to + /// the map view. + /// + /// The returned [Future] completes after the change has been made on the + /// platform side. + Future setUserLocationAnchor(Point anchor) async { + await _maplibrePlatform.setUserLocationAnchor(anchor); + } + /// Triggers a resize event for the map on web (ignored on Android or iOS). /// /// Checks first if a resize is required or if it looks like it is already correctly resized. diff --git a/maplibre_gl_platform_interface/lib/src/maplibre_gl_platform_interface.dart b/maplibre_gl_platform_interface/lib/src/maplibre_gl_platform_interface.dart index d748807c1..b5f67320b 100644 --- a/maplibre_gl_platform_interface/lib/src/maplibre_gl_platform_interface.dart +++ b/maplibre_gl_platform_interface/lib/src/maplibre_gl_platform_interface.dart @@ -52,6 +52,7 @@ abstract class MapLibrePlatform { Future updateMapOptions(Map optionsUpdate); Future animateCamera(CameraUpdate cameraUpdate, {Duration? duration}); Future moveCamera(CameraUpdate cameraUpdate); + Future setUserLocationAnchor(Point anchor); Future updateMyLocationTrackingMode( MyLocationTrackingMode myLocationTrackingMode); diff --git a/maplibre_gl_platform_interface/lib/src/method_channel_maplibre_gl.dart b/maplibre_gl_platform_interface/lib/src/method_channel_maplibre_gl.dart index 3272a2501..386460b4c 100644 --- a/maplibre_gl_platform_interface/lib/src/method_channel_maplibre_gl.dart +++ b/maplibre_gl_platform_interface/lib/src/method_channel_maplibre_gl.dart @@ -209,6 +209,15 @@ class MapLibreMethodChannel extends MapLibrePlatform { }); } + @override + Future setUserLocationAnchor(Point anchor) async { + await _channel + .invokeMethod('map#setUserLocationAnchor', { + 'x': anchor.x, + 'y': anchor.y, + }); + } + @override Future updateMyLocationTrackingMode( MyLocationTrackingMode myLocationTrackingMode) async { From 8f43ab201264faf488a1ca100356a97e8a46ad92 Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 17 Dec 2024 13:09:21 +0100 Subject: [PATCH 2/7] Fix colors depreciated --- maplibre_gl/lib/src/color_tools.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/maplibre_gl/lib/src/color_tools.dart b/maplibre_gl/lib/src/color_tools.dart index d0ac9c1cc..cc2a85f30 100644 --- a/maplibre_gl/lib/src/color_tools.dart +++ b/maplibre_gl/lib/src/color_tools.dart @@ -2,9 +2,9 @@ part of '../maplibre_gl.dart'; extension MapLibreColorConversion on Color { String toHexStringRGB() { - final r = red.toRadixString(16).padLeft(2, '0'); - final g = green.toRadixString(16).padLeft(2, '0'); - final b = blue.toRadixString(16).padLeft(2, '0'); + final r = this.r.toRadixString(16).padLeft(2, '0'); + final g = this.g.toRadixString(16).padLeft(2, '0'); + final b = this.b.toRadixString(16).padLeft(2, '0'); return '#$r$g$b'; } } From 4c8d43f0346edfa9f3d7da5af9147a120d9d495a Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 17 Dec 2024 13:18:01 +0100 Subject: [PATCH 3/7] Show unsuported for more clarity --- .../maplibregl/MapLibreMapController.java | 16 ++++++++++++++++ .../lib/src/maplibre_web_gl_platform.dart | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/MapLibreMapController.java b/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/MapLibreMapController.java index c856ed80c..841e55584 100644 --- a/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/MapLibreMapController.java +++ b/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/MapLibreMapController.java @@ -126,6 +126,7 @@ final class MapLibreMapController private boolean trackCameraPosition = false; private boolean myLocationEnabled = false; private int myLocationTrackingMode = 0; + private PointF userLocationAnchorOffset = null; private int myLocationRenderMode = 0; private boolean disposed = false; private boolean dragEnabled = true; @@ -690,6 +691,14 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { result.success(Convert.toJson(getCameraPosition())); break; } + case "map#setUserLocationAnchor": + { + float x = call.argument("x"); + float y = call.argument("y"); + setUserLocationAnchor(x, y); + result.success(null); + break; + } case "map#updateMyLocationTrackingMode": { int myLocationTrackingMode = call.argument("mode"); @@ -1936,6 +1945,13 @@ public void setMyLocationRenderMode(int myLocationRenderMode) { } } + @Override + public void setUserLocationAnchorOffset(float x, float y) { + userLocationAnchorOffset = new PointF(x, y); + Log.d(TAG, "setUserLocationAnchor not supported on Android"); + + } + public void setLogoViewMargins(int x, int y) { mapLibreMap.getUiSettings().setLogoMargins(x, 0, 0, y); } diff --git a/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart b/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart index a6ad2b7ec..cc2fb4137 100644 --- a/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart +++ b/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart @@ -690,6 +690,11 @@ class MapLibreMapController extends MapLibrePlatform } } + @override + void setUserLocationAnchor(Point anchor) { + print('setUserLocationAnchor not available in web'); + } + @override void setStyleString(String? styleString) { //remove old mouseenter callbacks to avoid multicalling From 81ab67bb431c8a29cd8df2fc423acbebc89a02a1 Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 17 Dec 2024 13:23:32 +0100 Subject: [PATCH 4/7] Update maplibre_web_gl_platform.dart --- maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart b/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart index cc2fb4137..3c6757aa2 100644 --- a/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart +++ b/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart @@ -691,8 +691,9 @@ class MapLibreMapController extends MapLibrePlatform } @override - void setUserLocationAnchor(Point anchor) { + Future setUserLocationAnchor(Point anchor) async { print('setUserLocationAnchor not available in web'); + return; } @override From 87047a08464ddc584a617e52cbd259dedc9558fb Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 17 Dec 2024 13:27:51 +0100 Subject: [PATCH 5/7] Update color_tools.dart --- maplibre_gl/lib/src/color_tools.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/maplibre_gl/lib/src/color_tools.dart b/maplibre_gl/lib/src/color_tools.dart index cc2a85f30..d0ac9c1cc 100644 --- a/maplibre_gl/lib/src/color_tools.dart +++ b/maplibre_gl/lib/src/color_tools.dart @@ -2,9 +2,9 @@ part of '../maplibre_gl.dart'; extension MapLibreColorConversion on Color { String toHexStringRGB() { - final r = this.r.toRadixString(16).padLeft(2, '0'); - final g = this.g.toRadixString(16).padLeft(2, '0'); - final b = this.b.toRadixString(16).padLeft(2, '0'); + final r = red.toRadixString(16).padLeft(2, '0'); + final g = green.toRadixString(16).padLeft(2, '0'); + final b = blue.toRadixString(16).padLeft(2, '0'); return '#$r$g$b'; } } From 74d0557f4efd633cf5dc5ffc286befd595d04ced Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 17 Dec 2024 13:56:45 +0100 Subject: [PATCH 6/7] Fix compiling --- .../java/org/maplibre/maplibregl/MapLibreMapController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/MapLibreMapController.java b/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/MapLibreMapController.java index 841e55584..31769a60e 100644 --- a/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/MapLibreMapController.java +++ b/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/MapLibreMapController.java @@ -1946,7 +1946,7 @@ public void setMyLocationRenderMode(int myLocationRenderMode) { } @Override - public void setUserLocationAnchorOffset(float x, float y) { + public void setUserLocationAnchor(float x, float y) { userLocationAnchorOffset = new PointF(x, y); Log.d(TAG, "setUserLocationAnchor not supported on Android"); From 41324d4b92346f8258051dbcf7deb418d5c72264 Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 17 Dec 2024 14:37:46 +0100 Subject: [PATCH 7/7] Update converters --- .../src/main/java/org/maplibre/maplibregl/Convert.java | 6 ++++++ .../Sources/maplibre_gl/MapLibreMapController.swift | 4 ++-- .../Sources/maplibre_gl/MapLibreMapOptionsSink.swift | 1 + maplibre_gl_web/lib/src/convert.dart | 4 ++++ maplibre_gl_web/lib/src/options_sink.dart | 2 ++ 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/Convert.java b/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/Convert.java index c15fc69be..ed9430f37 100644 --- a/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/Convert.java +++ b/maplibre_gl/android/src/main/java/org/maplibre/maplibregl/Convert.java @@ -256,6 +256,12 @@ static void interpretMapLibreMapOptions(Object o, MapLibreMapOptionsSink sink, C if (myLocationTrackingMode != null) { sink.setMyLocationTrackingMode(toInt(myLocationTrackingMode)); } + final Object userLocationAnchor = data.get("userLocationAnchor"); + if (userLocationAnchor != null) { + final List userLocationAnchorData = toList(userLocationAnchor); + final Point point = toPoint(userLocationAnchorData, metrics.density); + sink.setUserLocationAnchor(point.x, point.y); + } final Object myLocationRenderMode = data.get("myLocationRenderMode"); if (myLocationRenderMode != null) { sink.setMyLocationRenderMode(toInt(myLocationRenderMode)); diff --git a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapController.swift b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapController.swift index 456d06c6a..90b74706c 100644 --- a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapController.swift +++ b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapController.swift @@ -179,7 +179,7 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate, guard let arguments = methodCall.arguments as? [String: Any] else { return } guard let x = arguments["x"] as? Double else { return } guard let y = arguments["y"] as? Double else { return } - setUserLocationAnchorOffset(x: x, y: y) + setUserLocationAnchor(x: x, y: y) result(nil) case "map#updateMyLocationTrackingMode": guard let arguments = methodCall.arguments as? [String: Any] else { return } @@ -1767,7 +1767,7 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate, } } - func setUserLocationAnchorOffset(x: Double, y: Double) { + func setUserLocationAnchor(x: Double, y: Double) { userLocationAnchorOffset = CGPoint(x: x, y: y) } diff --git a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapOptionsSink.swift b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapOptionsSink.swift index c0468c06d..659d299ca 100644 --- a/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapOptionsSink.swift +++ b/maplibre_gl/ios/maplibre_gl/Sources/maplibre_gl/MapLibreMapOptionsSink.swift @@ -13,6 +13,7 @@ protocol MapLibreMapOptionsSink { func setMyLocationEnabled(myLocationEnabled: Bool) func setMyLocationTrackingMode(myLocationTrackingMode: MLNUserTrackingMode) func setMyLocationRenderMode(myLocationRenderMode: MyLocationRenderMode) + func setUserLocationAnchor(anchorPoint: CGPoint) func setLogoViewMargins(x: Double, y: Double) func setCompassViewPosition(position: MLNOrnamentPosition) func setCompassViewMargins(x: Double, y: Double) diff --git a/maplibre_gl_web/lib/src/convert.dart b/maplibre_gl_web/lib/src/convert.dart index 1f8e2245c..61a2aa8ac 100644 --- a/maplibre_gl_web/lib/src/convert.dart +++ b/maplibre_gl_web/lib/src/convert.dart @@ -62,6 +62,10 @@ class Convert { CompassViewPosition.values[options['compassViewPosition']]; sink.setCompassAlignment(position); } + if (options.containsKey('userLocationAnchor')) { + sink.setUserLocationAnchor( + options['userLocationAnchor'][0], options['userLocationAnchor'][1]); + } if (options.containsKey('compassViewMargins')) { sink.setCompassViewMargins( options['compassViewMargins'][0], options['compassViewMargins'][1]); diff --git a/maplibre_gl_web/lib/src/options_sink.dart b/maplibre_gl_web/lib/src/options_sink.dart index 10fdfadec..74e708707 100644 --- a/maplibre_gl_web/lib/src/options_sink.dart +++ b/maplibre_gl_web/lib/src/options_sink.dart @@ -27,6 +27,8 @@ abstract class MapLibreMapOptionsSink { void setMyLocationRenderMode(int myLocationRenderMode); + void setUserLocationAnchor(double x, double y); + void setLogoViewMargins(int x, int y); void setCompassAlignment(CompassViewPosition position);