From f35709343e03439746857a9fbbd23dbb9bbafafc Mon Sep 17 00:00:00 2001 From: Marius Van Nieuwenhuyse Date: Mon, 27 Feb 2023 10:36:31 +0100 Subject: [PATCH] Added getSourceIds to the controller (#197) Added getSourceIds to the controller with the android (tested) and ios (no ability to test here sorry). Not implemented on the web as getLayerIds in not implemented too I made the controller method returning a list of strings (`Future>`) to have an explicit `String` list unlike `getLayerIds` who have a `Future>` --- .../mapbox/mapboxgl/MapboxMapController.java | 19 +++ example/lib/get_map_informations.dart | 121 ++++++++++++++++++ example/lib/main.dart | 2 + ios/Classes/MapboxMapController.swift | 11 ++ lib/src/controller.dart | 9 ++ .../lib/src/mapbox_gl_platform_interface.dart | 2 + .../lib/src/method_channel_mapbox_gl.dart | 11 ++ .../lib/src/mapbox_web_gl_platform.dart | 5 + 8 files changed, 180 insertions(+) create mode 100644 example/lib/get_map_informations.dart diff --git a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java index 868e2607c..48b9d1ec4 100644 --- a/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java +++ b/android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java @@ -1378,6 +1378,25 @@ public void onFailure(@NonNull Exception exception) { result.success(reply); break; } + case "style#getSourceIds": + { + if (style == null) { + result.error( + "STYLE IS NULL", + "The style is null. Has onStyleLoaded() already been invoked?", + null); + } + Map reply = new HashMap<>(); + + List sourceIds = new ArrayList<>(); + for (Source source : style.getSources()) { + sourceIds.add(source.getId()); + } + + reply.put("sources", sourceIds); + result.success(reply); + break; + } default: result.notImplemented(); } diff --git a/example/lib/get_map_informations.dart b/example/lib/get_map_informations.dart new file mode 100644 index 000000000..4bcb6f4a5 --- /dev/null +++ b/example/lib/get_map_informations.dart @@ -0,0 +1,121 @@ +import 'package:flutter/material.dart'; +import 'package:maplibre_gl/mapbox_gl.dart'; + +import 'page.dart'; + +class GetMapInfoPage extends ExamplePage { + GetMapInfoPage() : super(const Icon(Icons.info), 'Get map state'); + + @override + Widget build(BuildContext context) { + return GetMapInfoBody(); + } +} + +class GetMapInfoBody extends StatefulWidget { + const GetMapInfoBody(); + + @override + State createState() => _GetMapInfoBodyState(); +} + +class _GetMapInfoBodyState extends State { + MaplibreMapController? controller; + String data = ''; + + void onMapCreated(MaplibreMapController controller) { + setState(() { + this.controller = controller; + }); + } + + void displaySources() async { + if (controller == null) { + return; + } + List sources = await controller!.getSourceIds(); + setState(() { + data = 'Sources: ${sources.map((e) => '"$e"').join(', ')}'; + }); + } + + void displayLayers() async { + if (controller == null) { + return; + } + List layers = (await controller!.getLayerIds()).cast(); + setState(() { + data = 'Layers: ${layers.map((e) => '"$e"').join(', ')}'; + }); + } + + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Center( + child: SizedBox( + width: 300.0, + height: 200.0, + child: MaplibreMap( + initialCameraPosition: const CameraPosition( + target: LatLng(-33.852, 151.211), + zoom: 11.0, + ), + onMapCreated: onMapCreated, + compassEnabled: false, + annotationOrder: [], + myLocationEnabled: false, + styleString: '''{ + "version": 8, + "sources": { + "OSM": { + "type": "raster", + "tiles": [ + "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png", + "https://b.tile.openstreetmap.org/{z}/{x}/{y}.png", + "https://c.tile.openstreetmap.org/{z}/{x}/{y}.png" + ], + "tileSize": 256, + "attribution": "© OpenStreetMap contributors", + "maxzoom": 18 + } + }, + "layers": [ + { + "id": "OSM-layer", + "source": "OSM", + "type": "raster" + } + ] + }''', + ), + ), + ), + Center( + child: const Text('© OpenStreetMap contributors'), + ), + Expanded( + child: SingleChildScrollView( + child: Column( + children: [ + SizedBox(height: 30), + Center(child: Text(data)), + SizedBox(height: 30), + ElevatedButton( + onPressed: controller == null ? null : displayLayers, + child: const Text('Get map layers'), + ), + ElevatedButton( + onPressed: controller == null ? null : displaySources, + child: const Text('Get map sources'), + ) + ], + ), + )), + ], + ); + } +} diff --git a/example/lib/main.dart b/example/lib/main.dart index 1b74818a9..0b7e217e5 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:location/location.dart'; import 'package:device_info_plus/device_info_plus.dart'; +import 'package:maplibre_gl_example/get_map_informations.dart'; import 'package:maplibre_gl_example/given_bounds.dart'; import 'animate_camera.dart'; @@ -52,6 +53,7 @@ final List _allPages = [ ClickAnnotationPage(), Sources(), GivenBoundsPage(), + GetMapInfoPage(), ]; class MapsDemo extends StatefulWidget { diff --git a/ios/Classes/MapboxMapController.swift b/ios/Classes/MapboxMapController.swift index f4b2fd84f..7b68ac8ca 100644 --- a/ios/Classes/MapboxMapController.swift +++ b/ios/Classes/MapboxMapController.swift @@ -765,6 +765,17 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma var reply = [String: NSObject]() reply["layers"] = layerIds as NSObject result(reply) + + case "style#getSourceIds": + var sourceIds = [String]() + + guard let style = mapView.style else { return } + + style.sources.forEach { source in sourceIds.append(source.identifier) } + + var reply = [String: NSObject]() + reply["sources"] = sourceIds as NSObject + result(reply) case "style#getFilter": guard let arguments = methodCall.arguments as? [String: Any] else { return } diff --git a/lib/src/controller.dart b/lib/src/controller.dart index 2ab8ac039..ecb34262c 100644 --- a/lib/src/controller.dart +++ b/lib/src/controller.dart @@ -1270,6 +1270,15 @@ class MaplibreMapController extends ChangeNotifier { return _mapboxGlPlatform.getLayerIds(); } + /// Retrieve every source ids of the map as a [String] list, including the ones added internally + /// + /// This method is not currently implemented on the web + Future> getSourceIds() async { + return (await _mapboxGlPlatform.getSourceIds()) + .whereType() + .toList(); + } + @override void dispose() { super.dispose(); diff --git a/maplibre_gl_platform_interface/lib/src/mapbox_gl_platform_interface.dart b/maplibre_gl_platform_interface/lib/src/mapbox_gl_platform_interface.dart index c6d16f63a..26ea02704 100644 --- a/maplibre_gl_platform_interface/lib/src/mapbox_gl_platform_interface.dart +++ b/maplibre_gl_platform_interface/lib/src/mapbox_gl_platform_interface.dart @@ -91,6 +91,8 @@ abstract class MapLibreGlPlatform { Future getLayerIds(); + Future getSourceIds(); + Future setFilter(String layerId, dynamic filter); Future getFilter(String layerId); diff --git a/maplibre_gl_platform_interface/lib/src/method_channel_mapbox_gl.dart b/maplibre_gl_platform_interface/lib/src/method_channel_mapbox_gl.dart index 0dae84688..1fef7d5cc 100644 --- a/maplibre_gl_platform_interface/lib/src/method_channel_mapbox_gl.dart +++ b/maplibre_gl_platform_interface/lib/src/method_channel_mapbox_gl.dart @@ -753,4 +753,15 @@ class MethodChannelMaplibreGl extends MapLibreGlPlatform { return new Future.error(e); } } + + @override + Future getSourceIds() async { + try { + final Map reply = + await _channel.invokeMethod('style#getSourceIds'); + return reply['sources'].map((it) => it.toString()).toList(); + } on PlatformException catch (e) { + return new Future.error(e); + } + } } diff --git a/maplibre_gl_web/lib/src/mapbox_web_gl_platform.dart b/maplibre_gl_web/lib/src/mapbox_web_gl_platform.dart index 317805a50..ed52e27df 100644 --- a/maplibre_gl_web/lib/src/mapbox_web_gl_platform.dart +++ b/maplibre_gl_web/lib/src/mapbox_web_gl_platform.dart @@ -1045,4 +1045,9 @@ class MaplibreMapController extends MapLibreGlPlatform Future getLayerIds() async { throw UnimplementedError(); } + + @override + Future getSourceIds() async { + throw UnimplementedError(); + } }