From f2a2c61ea9dabe10c1e9a4ae3c602b6b05f9ce97 Mon Sep 17 00:00:00 2001 From: Amit Chaudhary Date: Sun, 2 Jun 2024 08:59:54 +0545 Subject: [PATCH 1/6] Added setStyle method on MaplibreMapController for updating style without rebuilding map --- .../mapbox/mapboxgl/MapboxMapController.java | 21 +++++++++++++++++++ example/lib/local_style.dart | 19 ++++++++++------- ios/Classes/MapboxMapController.swift | 7 ++++++- lib/src/controller.dart | 6 ++++++ .../src/maplibre_gl_platform_interface.dart | 15 +++++++++++++ .../lib/src/method_channel_maplibre_gl.dart | 17 +++++++++++++++ .../lib/src/maplibre_web_gl_platform.dart | 12 +++++++++++ 7 files changed, 89 insertions(+), 8 deletions(-) diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java index d9187fd6..1d9a7f83 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java @@ -1589,6 +1589,27 @@ public void onFailure(@NonNull Exception exception) { result.success(reply); break; } + case "style#setStyle": + { + // Getting style json, url, path etc. from the flutter side + String styleString = call.argument("style"); + + // Checking if style is null or not + if (styleString != null) { + // If style is not null setting style + setStyleString(styleString); + result.success(null); + } else { + + // else throwing error + result.error( + "STYLE STRING IS NULL", + "The style string is null.", + null + ); + } + break; + } default: result.notImplemented(); } diff --git a/example/lib/local_style.dart b/example/lib/local_style.dart index 5d49778c..7c1f327c 100644 --- a/example/lib/local_style.dart +++ b/example/lib/local_style.dart @@ -55,8 +55,6 @@ class LocalStyleState extends State { @override Widget build(BuildContext context) { - final styleAbsoluteFilePath = this.styleAbsoluteFilePath; - if (styleAbsoluteFilePath == null) { return const Scaffold( body: Center(child: Text('Creating local style file...')), @@ -64,12 +62,19 @@ class LocalStyleState extends State { } return Scaffold( + floatingActionButton: FloatingActionButton.small( + child: const Icon(Icons.layers_outlined), + onPressed: () async { + if (styleAbsoluteFilePath != null) { + await mapController?.setStyle(styleAbsoluteFilePath!); + } + }, + ), body: MaplibreMap( - styleString: styleAbsoluteFilePath, - onMapCreated: _onMapCreated, - initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)), - onStyleLoadedCallback: onStyleLoadedCallback, - )); + onMapCreated: _onMapCreated, + initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)), + onStyleLoadedCallback: onStyleLoadedCallback, + )); } void onStyleLoadedCallback() {} diff --git a/ios/Classes/MapboxMapController.swift b/ios/Classes/MapboxMapController.swift index bc7aacd4..3d97a068 100644 --- a/ios/Classes/MapboxMapController.swift +++ b/ios/Classes/MapboxMapController.swift @@ -932,7 +932,12 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma var reply = [String: NSObject]() reply["filter"] = currentLayerFilter as NSObject result(reply) - + + case "style#setStyle": + guard let arguments = methodCall.arguments as? [String: Any] else { return } + guard let style = arguments["style"] as? String else { return } + setStyleString(styleString: style) + result(nil) default: result(FlutterMethodNotImplemented) } diff --git a/lib/src/controller.dart b/lib/src/controller.dart index e6bbd193..ca4f8f41 100644 --- a/lib/src/controller.dart +++ b/lib/src/controller.dart @@ -1426,6 +1426,12 @@ class MaplibreMapController extends ChangeNotifier { .toList(); } + /// Method to set style string + /// [styleString] -> It will take json, url, absolute path or asset path + Future setStyle(String styleString) async { + return await _maplibreGlPlatform.setStyle(styleString); + } + @override void dispose() { super.dispose(); 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 728ed795..0d9f09db 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 @@ -49,26 +49,35 @@ abstract class MapLibreGlPlatform { final onUserLocationUpdatedPlatform = ArgumentCallbacks(); Future initPlatform(int id); + Widget buildView( Map creationParams, OnPlatformViewCreatedCallback onPlatformViewCreated, Set>? gestureRecognizers); + Future updateMapOptions(Map optionsUpdate); + Future animateCamera(CameraUpdate cameraUpdate, {Duration? duration}); + Future moveCamera(CameraUpdate cameraUpdate); + Future updateMyLocationTrackingMode( MyLocationTrackingMode myLocationTrackingMode); Future matchMapLanguageWithDeviceDefault(); void resizeWebMap(); + void forceResizeWebMap(); Future updateContentInsets(EdgeInsets insets, bool animated); + Future setMapLanguage(String language); + Future setTelemetryEnabled(bool enabled); Future getTelemetryEnabled(); + Future queryRenderedFeatures( Point point, List layerIds, List? filter); @@ -77,7 +86,9 @@ abstract class MapLibreGlPlatform { Future querySourceFeatures( String sourceId, String? sourceLayerId, List? filter); + Future invalidateAmbientCache(); + Future requestMyLocationLatLng(); Future getVisibleRegion(); @@ -205,6 +216,10 @@ abstract class MapLibreGlPlatform { Future setLayerVisibility(String layerId, bool visible); + /// Method to set style string + /// [styleString] -> It will take json, url, absolute path or asset path + Future setStyle(String styleString); + @mustCallSuper void dispose() { // clear all callbacks to avoid cyclic refs 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 23973cb4..f52a4b29 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 @@ -833,4 +833,21 @@ class MethodChannelMaplibreGl extends MapLibreGlPlatform { return Future.error(e); } } + + /// Method to set style string + /// [styleString] -> It will take json, url, absolute path or asset path + /// + @override + Future setStyle(String styleString) async { + try { + await _channel.invokeMethod( + 'style#setStyle', + { + 'style': styleString, + }, + ); + } on PlatformException catch (e) { + return Future.error(e); + } + } } 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 4afd49f8..635af117 100644 --- a/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart +++ b/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart @@ -1156,4 +1156,16 @@ class MaplibreMapController extends MapLibreGlPlatform Future getSourceIds() async { throw UnimplementedError(); } + + /// Method to set style string + /// [styleString] -> It will take json, url, absolute path or asset path + /// + @override + Future setStyle(String styleString) async { + try { + _map.setStyle(styleString); + } on PlatformException catch (e) { + return Future.error(e); + } + } } From ad0ae91e3830f9e28b069ac03758d2d9ebb3c0de Mon Sep 17 00:00:00 2001 From: Amit Chaudhary Date: Thu, 6 Jun 2024 09:58:45 +0545 Subject: [PATCH 2/6] replaced _maplibreGlPlatform to _maplibrePlatform on controller setStyle method --- lib/src/controller.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/controller.dart b/lib/src/controller.dart index 87f0ffa6..ba855647 100644 --- a/lib/src/controller.dart +++ b/lib/src/controller.dart @@ -1430,7 +1430,7 @@ class MapLibreMapController extends ChangeNotifier { /// Method to set style string /// [styleString] -> It will take json, url, absolute path or asset path Future setStyle(String styleString) async { - return await _maplibreGlPlatform.setStyle(styleString); + return await _maplibrePlatform.setStyle(styleString); } @override From 2bc6df6f1f5746d49b24c3733da6d1c1cdbf59be Mon Sep 17 00:00:00 2001 From: Amit Chaudhary Date: Fri, 7 Jun 2024 22:51:19 +0545 Subject: [PATCH 3/6] added information regarding the style string format --- maplibre_gl/lib/src/controller.dart | 12 ++++++++++-- .../lib/src/maplibre_gl_platform_interface.dart | 10 +++++++++- .../lib/src/method_channel_maplibre_gl.dart | 3 ++- .../lib/src/maplibre_web_gl_platform.dart | 6 +----- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/maplibre_gl/lib/src/controller.dart b/maplibre_gl/lib/src/controller.dart index ba855647..40838c36 100644 --- a/maplibre_gl/lib/src/controller.dart +++ b/maplibre_gl/lib/src/controller.dart @@ -1428,9 +1428,17 @@ class MapLibreMapController extends ChangeNotifier { } /// Method to set style string - /// [styleString] -> It will take json, url, absolute path or asset path + /// A MapLibre GL style document defining the map's appearance. + /// The style document specification is at [https://maplibre.org/maplibre-style-spec]. + /// A short introduction can be found in the documentation of the [maplibre_gl] library. + /// The [styleString] supports following formats: + /// + /// 1. Passing the URL of the map style. This should be a custom map style served remotely using a URL that start with 'http(s)://' + /// 2. Passing the style as a local asset. Create a JSON file in the `assets` and add a reference in `pubspec.yml`. Set the style string to the relative path for this asset in order to load it into the map. + /// 3. Passing the style as a local file. create an JSON file in app directory (e.g. ApplicationDocumentsDirectory). Set the style string to the absolute path of this JSON file. + /// 4. Passing the raw JSON of the map style. This is only supported on Android. Future setStyle(String styleString) async { - return await _maplibrePlatform.setStyle(styleString); + return _maplibrePlatform.setStyle(styleString); } @override 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 8c9195a3..55d1ab55 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 @@ -217,7 +217,15 @@ abstract class MapLibrePlatform { Future setLayerVisibility(String layerId, bool visible); /// Method to set style string - /// [styleString] -> It will take json, url, absolute path or asset path + /// A MapLibre GL style document defining the map's appearance. + /// The style document specification is at [https://maplibre.org/maplibre-style-spec]. + /// A short introduction can be found in the documentation of the [maplibre_gl] library. + /// The [styleString] supports following formats: + /// + /// 1. Passing the URL of the map style. This should be a custom map style served remotely using a URL that start with 'http(s)://' + /// 2. Passing the style as a local asset. Create a JSON file in the `assets` and add a reference in `pubspec.yml`. Set the style string to the relative path for this asset in order to load it into the map. + /// 3. Passing the style as a local file. create an JSON file in app directory (e.g. ApplicationDocumentsDirectory). Set the style string to the absolute path of this JSON file. + /// 4. Passing the raw JSON of the map style. This is only supported on Android. Future setStyle(String styleString); @mustCallSuper 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 2fb7fac2..11322c78 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 @@ -835,7 +835,6 @@ class MapLibreMethodChannel extends MapLibrePlatform { } /// Method to set style string - /// [styleString] -> It will take json, url, absolute path or asset path /// @override Future setStyle(String styleString) async { @@ -848,6 +847,8 @@ class MapLibreMethodChannel extends MapLibrePlatform { ); } on PlatformException catch (e) { return Future.error(e); + } catch (e) { + return Future.error(e); } } } 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 f691fd5e..8ac00acf 100644 --- a/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart +++ b/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart @@ -1163,10 +1163,6 @@ class MapLibreMapController extends MapLibrePlatform /// @override Future setStyle(String styleString) async { - try { - _map.setStyle(styleString); - } on PlatformException catch (e) { - return Future.error(e); - } + _map.setStyle(styleString); } } From 788a8a177da2c9aa0ec569bb611b87c6e1f8a30d Mon Sep 17 00:00:00 2001 From: Amit Chaudhary Date: Fri, 7 Jun 2024 22:58:40 +0545 Subject: [PATCH 4/6] auto applied style on map created --- example/lib/local_style.dart | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/example/lib/local_style.dart b/example/lib/local_style.dart index bb5803f4..d8874b8d 100644 --- a/example/lib/local_style.dart +++ b/example/lib/local_style.dart @@ -51,6 +51,16 @@ class LocalStyleState extends State { void _onMapCreated(MapLibreMapController controller) { mapController = controller; + + // Adding style to the map with some delay + Future.delayed( + const Duration(milliseconds: 250), + () async { + if (styleAbsoluteFilePath != null) { + await mapController?.setStyle(styleAbsoluteFilePath!); + } + }, + ); } @override @@ -62,19 +72,12 @@ class LocalStyleState extends State { } return Scaffold( - floatingActionButton: FloatingActionButton.small( - child: const Icon(Icons.layers_outlined), - onPressed: () async { - if (styleAbsoluteFilePath != null) { - await mapController?.setStyle(styleAbsoluteFilePath!); - } - }, - ), - body: MapLibreMap( - onMapCreated: _onMapCreated, - initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)), - onStyleLoadedCallback: onStyleLoadedCallback, - )); + body: MapLibreMap( + onMapCreated: _onMapCreated, + initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)), + onStyleLoadedCallback: onStyleLoadedCallback, + ), + ); } void onStyleLoadedCallback() {} From 925ba67b608b68253e61f075238d67bdc1fce2e2 Mon Sep 17 00:00:00 2001 From: Amit Chaudhary Date: Mon, 24 Jun 2024 08:37:03 +0545 Subject: [PATCH 5/6] returning error if style is missing or invalid args --- .../MapLibreMapController.swift | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/maplibre_gl/ios/maplibre_gl_ios/Sources/maplibre_gl_ios/MapLibreMapController.swift b/maplibre_gl/ios/maplibre_gl_ios/Sources/maplibre_gl_ios/MapLibreMapController.swift index 511626c4..4a094d41 100644 --- a/maplibre_gl/ios/maplibre_gl_ios/Sources/maplibre_gl_ios/MapLibreMapController.swift +++ b/maplibre_gl/ios/maplibre_gl_ios/Sources/maplibre_gl_ios/MapLibreMapController.swift @@ -931,10 +931,30 @@ class MapLibreMapController: NSObject, FlutterPlatformView, MLNMapViewDelegate, result(reply) case "style#setStyle": - guard let arguments = methodCall.arguments as? [String: Any] else { return } - guard let style = arguments["style"] as? String else { return } - setStyleString(styleString: style) - result(nil) + if let arguments = methodCall.arguments as? [String: Any] { + if let style = arguments["style"] as? String { + setStyleString(styleString: style) + result(nil) + } else { + // Error for missing style key in argument + result( + FlutterError( + code: "invalidStyleString", + message: "Missing style key in arguments", + details: nil + ) + ) + } + } else { + // Error for invalid arguments type + result( + FlutterError( + code: "invalidArgumentsType", + message: "Arguments not of type [String: Any]", + details: nil + ) + ) + } default: result(FlutterMethodNotImplemented) } From 64e11c6847e57cd64d81bb3a908be12aadc6ce03 Mon Sep 17 00:00:00 2001 From: Amit Chaudhary Date: Tue, 25 Jun 2024 09:37:07 +0545 Subject: [PATCH 6/6] minor changes --- maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart | 1 - 1 file changed, 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 8ac00acf..fafd7704 100644 --- a/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart +++ b/maplibre_gl_web/lib/src/maplibre_web_gl_platform.dart @@ -1160,7 +1160,6 @@ class MapLibreMapController extends MapLibrePlatform /// Method to set style string /// [styleString] -> It will take json, url, absolute path or asset path - /// @override Future setStyle(String styleString) async { _map.setStyle(styleString);