From ae2a75850f9137359a40c26563daf7b133e93d95 Mon Sep 17 00:00:00 2001 From: Jean-Francis Devezi Savula <125267331+JeanTapped@users.noreply.github.com> Date: Mon, 22 Jul 2024 07:07:08 +0100 Subject: [PATCH] Hide map attribution (#73) * Add isAttributionTextVisible to hide map attribution * Add isAttributionTextVisible for iOS * Add dependency_overrides * implement changing attribution text --------- Co-authored-by: Julian Bissekkou --- .../lib/src/arcgis_location_display.dart | 1 + .../lib/src/arcgis_map_controller.dart | 5 +++ arcgis_map_sdk/lib/src/arcgis_map_sdk.dart | 10 ++++++ .../arcgis_map_sdk_android/ArcgisMapView.kt | 19 ++++++++++- .../model/ArcgisMapOptions.kt | 1 + .../ios/Classes/ArcgisMapView.swift | 15 +++++++++ .../ios/Classes/Models/ArcgisMapOptions.swift | 1 + .../src/method_channel_arcgis_map_plugin.dart | 11 +++++++ .../lib/src/model_extension.dart | 1 + .../arcgis_map_sdk_platform_interface.dart | 9 +++++ .../lib/src/types/arcgis_map_options.dart | 7 ++-- example/ios/Flutter/AppFrameworkInfo.plist | 2 +- example/ios/Podfile.lock | 2 +- example/ios/Runner.xcodeproj/project.pbxproj | 8 ++--- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- example/lib/vector_layer_example_page.dart | 33 +++++++++++++++---- example/pubspec.lock | 28 ++++++++-------- example/pubspec.yaml | 14 ++++++++ 18 files changed, 137 insertions(+), 32 deletions(-) diff --git a/arcgis_map_sdk/lib/src/arcgis_location_display.dart b/arcgis_map_sdk/lib/src/arcgis_location_display.dart index 59fd3cf5d..a0a70b6a1 100644 --- a/arcgis_map_sdk/lib/src/arcgis_location_display.dart +++ b/arcgis_map_sdk/lib/src/arcgis_location_display.dart @@ -32,6 +32,7 @@ class ArcgisLocationDisplay { ArcgisLocationDisplay({int? mapId}) : _mapId = mapId; + // ignore: use_setters_to_change_properties void attachToMap(int mapId) => _mapId = mapId; void deattachFromMap() => _mapId = null; diff --git a/arcgis_map_sdk/lib/src/arcgis_map_controller.dart b/arcgis_map_sdk/lib/src/arcgis_map_controller.dart index dd65272a7..5ed62cf8f 100644 --- a/arcgis_map_sdk/lib/src/arcgis_map_controller.dart +++ b/arcgis_map_sdk/lib/src/arcgis_map_controller.dart @@ -320,4 +320,9 @@ class ArcgisMapController { }, ); } + + Future updateIsAttributionTextVisible(bool isAttributionTextVisible) { + return ArcgisMapPlatform.instance + .updateIsAttributionTextVisible(mapId, isAttributionTextVisible); + } } diff --git a/arcgis_map_sdk/lib/src/arcgis_map_sdk.dart b/arcgis_map_sdk/lib/src/arcgis_map_sdk.dart index cef663030..b807ca7f4 100644 --- a/arcgis_map_sdk/lib/src/arcgis_map_sdk.dart +++ b/arcgis_map_sdk/lib/src/arcgis_map_sdk.dart @@ -40,6 +40,7 @@ class ArcgisMap extends StatefulWidget { this.yMax = 66, this.onMapCreated, this.vectorTileLayerUrls, + this.isAttributionTextVisible, super.key, }) : assert( basemap != null || @@ -70,6 +71,7 @@ class ArcgisMap extends StatefulWidget { final double xMax; final double yMin; final double yMax; + final bool? isAttributionTextVisible; /// Adds vector tile layers to the map. You can add more than one. /// When the [vectorTileLayerUrls] is not empty, the [basemap] field @@ -110,6 +112,7 @@ class _ArcgisMapState extends State { yMin: widget.yMin, yMax: widget.yMax, vectorTilesUrls: widget.vectorTileLayerUrls, + isAttributionTextVisible: widget.isAttributionTextVisible, ); Future onPlatformViewCreated(int id) async { @@ -138,6 +141,12 @@ class _ArcgisMapState extends State { if ((widget.basemap != null) && oldWidget.basemap != widget.basemap) { controller.toggleBaseMap(baseMap: widget.basemap!); } + if (widget.isAttributionTextVisible != null && + widget.isAttributionTextVisible != oldWidget.isAttributionTextVisible) { + controller.updateIsAttributionTextVisible( + widget.isAttributionTextVisible!, + ); + } _arcgisMapOptions = ArcgisMapOptions( apiKey: widget.apiKey, licenseKey: widget.licenseKey, @@ -161,6 +170,7 @@ class _ArcgisMapState extends State { yMax: widget.yMax, vectorTilesUrls: widget.vectorTileLayerUrls, defaultUiList: widget.defaultUiList, + isAttributionTextVisible: widget.isAttributionTextVisible, ); } diff --git a/arcgis_map_sdk_android/android/src/main/kotlin/dev/fluttercommunity/arcgis_map_sdk_android/ArcgisMapView.kt b/arcgis_map_sdk_android/android/src/main/kotlin/dev/fluttercommunity/arcgis_map_sdk_android/ArcgisMapView.kt index b921c5c0a..b6cc4036a 100644 --- a/arcgis_map_sdk_android/android/src/main/kotlin/dev/fluttercommunity/arcgis_map_sdk_android/ArcgisMapView.kt +++ b/arcgis_map_sdk_android/android/src/main/kotlin/dev/fluttercommunity/arcgis_map_sdk_android/ArcgisMapView.kt @@ -79,8 +79,9 @@ internal class ArcgisMapView( mapView = view.findViewById(R.id.mapView) - map.apply { + mapOptions.isAttributionTextVisible?.let { mapView.isAttributionTextVisible = it } + map.apply { basemap = if (mapOptions.basemap != null) { Basemap(mapOptions.basemap) } else { @@ -182,11 +183,27 @@ internal class ArcgisMapView( result ) + "update_is_attribution_text_visible" -> onUpdateIsAttributionTextVisible( + call, + result + ) + else -> result.notImplemented() } } } + private fun onUpdateIsAttributionTextVisible(call: MethodCall, result: MethodChannel.Result) { + val isVisible = call.arguments as? Boolean + if (isVisible == null) { + result.error("invalid_argument", "isAttributionTextVisible must be a boolean", null) + return + } + + mapView.isAttributionTextVisible = isVisible + result.success(true) + } + private fun onStartLocationDisplayDataSource(result: MethodChannel.Result) { result.finishWithFuture { mapView.locationDisplay.locationDataSource.startAsync() } } diff --git a/arcgis_map_sdk_android/android/src/main/kotlin/dev/fluttercommunity/arcgis_map_sdk_android/model/ArcgisMapOptions.kt b/arcgis_map_sdk_android/android/src/main/kotlin/dev/fluttercommunity/arcgis_map_sdk_android/model/ArcgisMapOptions.kt index 693edb771..546b1a41c 100644 --- a/arcgis_map_sdk_android/android/src/main/kotlin/dev/fluttercommunity/arcgis_map_sdk_android/model/ArcgisMapOptions.kt +++ b/arcgis_map_sdk_android/android/src/main/kotlin/dev/fluttercommunity/arcgis_map_sdk_android/model/ArcgisMapOptions.kt @@ -20,4 +20,5 @@ data class ArcgisMapOptions( val xMax: Double, val yMin: Double, val yMax: Double, + val isAttributionTextVisible: Boolean?, ) diff --git a/arcgis_map_sdk_ios/ios/Classes/ArcgisMapView.swift b/arcgis_map_sdk_ios/ios/Classes/ArcgisMapView.swift index 8875e3869..44b0ea7c2 100644 --- a/arcgis_map_sdk_ios/ios/Classes/ArcgisMapView.swift +++ b/arcgis_map_sdk_ios/ios/Classes/ArcgisMapView.swift @@ -75,6 +75,10 @@ class ArcgisMapView: NSObject, FlutterPlatformView { mapView = AGSMapView.init(frame: frame) super.init() + + if let isAttributionTextVisible = mapOptions.isAttributionTextVisible { + mapView.isAttributionTextVisible = isAttributionTextVisible + } if mapOptions.basemap != nil { map.basemap = AGSBasemap(style: parseBaseMapStyle(mapOptions.basemap!)) @@ -153,6 +157,7 @@ class ArcgisMapView: NSObject, FlutterPlatformView { case "location_display_set_use_course_symbol_on_move" : onSetLocationDisplayUseCourseSymbolOnMove(call, result) case "location_display_update_display_source_position_manually" : onUpdateLocationDisplaySourcePositionManually(call, result) case "location_display_set_data_source_type" : onSetLocationDisplayDataSourceType(call, result) + case "update_is_attribution_text_visible": onUpdateIsAttributionTextVisible(call, result) default: result(FlutterError(code: "Unimplemented", message: "No method matching the name \(call.method)", details: nil)) } @@ -501,6 +506,16 @@ class ArcgisMapView: NSObject, FlutterPlatformView { result(FlutterError(code: "invalid_data", message: "Unknown data source type \(String(describing: type))", details: nil)) } } + + private func onUpdateIsAttributionTextVisible(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { + guard let isVisible = call.arguments as? Bool else { + result(FlutterError(code: "missing_data", message: "Invalid arguments", details: nil)) + return + } + + mapView.isAttributionTextVisible = isVisible + result(true) + } private func operationWithSymbol(_ call: FlutterMethodCall, _ result: @escaping FlutterResult, handler: (AGSSymbol) -> Void) { do { diff --git a/arcgis_map_sdk_ios/ios/Classes/Models/ArcgisMapOptions.swift b/arcgis_map_sdk_ios/ios/Classes/Models/ArcgisMapOptions.swift index bb3cb8f8c..2c49e048e 100644 --- a/arcgis_map_sdk_ios/ios/Classes/Models/ArcgisMapOptions.swift +++ b/arcgis_map_sdk_ios/ios/Classes/Models/ArcgisMapOptions.swift @@ -23,4 +23,5 @@ struct ArcgisMapOptions: Codable { let xMax: Int let yMin: Int let yMax: Int + let isAttributionTextVisible: Bool? } diff --git a/arcgis_map_sdk_method_channel/lib/src/method_channel_arcgis_map_plugin.dart b/arcgis_map_sdk_method_channel/lib/src/method_channel_arcgis_map_plugin.dart index 014b45283..0eb074793 100644 --- a/arcgis_map_sdk_method_channel/lib/src/method_channel_arcgis_map_plugin.dart +++ b/arcgis_map_sdk_method_channel/lib/src/method_channel_arcgis_map_plugin.dart @@ -304,4 +304,15 @@ class MethodChannelArcgisMapPlugin extends ArcgisMapPlatform { type, ); } + + @override + Future updateIsAttributionTextVisible( + int mapId, + bool isAttributionTextVisible, + ) { + return _methodChannelBuilder(mapId).invokeMethod( + "update_is_attribution_text_visible", + isAttributionTextVisible, + ); + } } diff --git a/arcgis_map_sdk_method_channel/lib/src/model_extension.dart b/arcgis_map_sdk_method_channel/lib/src/model_extension.dart index 5a7fa33e0..1b4c83b90 100644 --- a/arcgis_map_sdk_method_channel/lib/src/model_extension.dart +++ b/arcgis_map_sdk_method_channel/lib/src/model_extension.dart @@ -47,6 +47,7 @@ extension ArcgisMapOptionsJsonExtension on ArcgisMapOptions { 'xMax': xMax, 'yMin': yMin, 'yMax': yMax, + 'isAttributionTextVisible': isAttributionTextVisible, }; } } diff --git a/arcgis_map_sdk_platform_interface/lib/src/arcgis_map_sdk_platform_interface.dart b/arcgis_map_sdk_platform_interface/lib/src/arcgis_map_sdk_platform_interface.dart index 7e2d8c42f..7a8a90926 100644 --- a/arcgis_map_sdk_platform_interface/lib/src/arcgis_map_sdk_platform_interface.dart +++ b/arcgis_map_sdk_platform_interface/lib/src/arcgis_map_sdk_platform_interface.dart @@ -277,4 +277,13 @@ class ArcgisMapPlatform extends PlatformInterface { 'setLocationDisplay() has not been implemented.', ); } + + Future updateIsAttributionTextVisible( + int mapId, + bool isAttributionTextVisible, + ) { + throw UnimplementedError( + 'updateIsAttributionTextVisible() has not been implemented.', + ); + } } diff --git a/arcgis_map_sdk_platform_interface/lib/src/types/arcgis_map_options.dart b/arcgis_map_sdk_platform_interface/lib/src/types/arcgis_map_options.dart index aea7b3ac4..396ab21a7 100644 --- a/arcgis_map_sdk_platform_interface/lib/src/types/arcgis_map_options.dart +++ b/arcgis_map_sdk_platform_interface/lib/src/types/arcgis_map_options.dart @@ -6,8 +6,7 @@ import 'package:arcgis_map_sdk_platform_interface/arcgis_map_sdk_platform_interf /// /// [xMin], [xMax], [yMin] and [yMax] are the coordinates of an extent envelope that constrains the panning in the map. /// -/// Warning!! If [hideAttribution] is set to true, -/// an attribution must still be provided, according to following layout and design guidelines from Esri +/// [isAttributionTextVisible] will hide the map attribution (e.g. the logo). Review the guidelines before disabling the attribution: /// https://developers.arcgis.com/documentation/mapping-apis-and-services/deployment/basemap-attribution/#layout-and-design-guidelines class ArcgisMapOptions { final String? apiKey; @@ -33,6 +32,7 @@ class ArcgisMapOptions { final List? vectorTilesUrls; final List defaultUiList; final bool isPopupEnabled; + final bool? isAttributionTextVisible; const ArcgisMapOptions({ required this.apiKey, @@ -58,11 +58,12 @@ class ArcgisMapOptions { this.ground, this.vectorTilesUrls, this.isPopupEnabled = false, + this.isAttributionTextVisible, }); @override String toString() { - return 'ArcgisMapOptions{apiKey: $apiKey, licenseKey: $licenseKey, mapStyle: $mapStyle, initialCenter: $initialCenter, showLabelsBeneathGraphics: $showLabelsBeneathGraphics, isInteractive: $isInteractive, zoom: $zoom, tilt: $tilt, initialHeight: $initialHeight, heading: $heading, padding: $padding, rotationEnabled: $rotationEnabled, minZoom: $minZoom, maxZoom: $maxZoom, xMin: $xMin, xMax: $xMax, yMin: $yMin, yMax: $yMax, basemap: $basemap, ground: $ground, vectorTilesUrls: $vectorTilesUrls, defaultUiList: $defaultUiList, isPopupEnabled: $isPopupEnabled}'; + return 'ArcgisMapOptions{apiKey: $apiKey, licenseKey: $licenseKey, mapStyle: $mapStyle, initialCenter: $initialCenter, showLabelsBeneathGraphics: $showLabelsBeneathGraphics, isInteractive: $isInteractive, zoom: $zoom, tilt: $tilt, initialHeight: $initialHeight, heading: $heading, padding: $padding, rotationEnabled: $rotationEnabled, minZoom: $minZoom, maxZoom: $maxZoom, xMin: $xMin, xMax: $xMax, yMin: $yMin, yMax: $yMax, basemap: $basemap, ground: $ground, vectorTilesUrls: $vectorTilesUrls, defaultUiList: $defaultUiList, isPopupEnabled: $isPopupEnabled, isAttributionTextVisible: $isAttributionTextVisible}'; } } diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index 9625e105d..7c5696400 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 150040d06..0a567ab1b 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -31,7 +31,7 @@ SPEC CHECKSUMS: ArcGIS-Runtime-SDK-iOS: 6ab51d28f8831ac73c00d34998cff3a555fe304f ArcGIS-Runtime-Toolkit-iOS: e30bb45bd0bd0152bcb1ec73f9b99022a5c7d02d arcgis_map_sdk_ios: ee1d8dee42e0c11c95cd26afa2a8cb0e7a69cb23 - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 geolocator_apple: cc556e6844d508c95df1e87e3ea6fa4e58c50401 PODFILE CHECKSUM: cc1f88378b4bfcf93a6ce00d2c587857c6008d3b diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 7ef472d80..b475bba3b 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -157,7 +157,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -344,7 +344,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -422,7 +422,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -471,7 +471,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a33..5e31d3d34 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ { + bool _isAttributionTextVisible = true; + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), - body: ArcgisMap( - apiKey: arcGisApiKey, - initialCenter: const LatLng(51.16, 10.45), - zoom: 13, - vectorTileLayerUrls: const [ - "https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer", + body: Stack( + alignment: Alignment.bottomLeft, + children: [ + ArcgisMap( + apiKey: arcGisApiKey, + initialCenter: const LatLng(51.16, 10.45), + zoom: 13, + vectorTileLayerUrls: const [ + "https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer", + ], + mapStyle: MapStyle.twoD, + isAttributionTextVisible: _isAttributionTextVisible, + ), + Padding( + padding: const EdgeInsets.all(16), + child: ElevatedButton( + onPressed: () { + setState(() { + _isAttributionTextVisible = !_isAttributionTextVisible; + }); + }, + child: Text("Toggle isAttributionTextVisible"), + ), + ), ], - mapStyle: MapStyle.twoD, ), ); } diff --git a/example/pubspec.lock b/example/pubspec.lock index 0e4f90b89..5099df711 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -198,26 +198,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.0" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "2.0.1" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "2.0.1" lint: dependency: "direct dev" description: @@ -246,10 +246,10 @@ packages: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.11.0" path: dependency: transitive description: @@ -323,10 +323,10 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.6.1" typed_data: dependency: transitive description: @@ -355,10 +355,10 @@ packages: dependency: transitive description: name: vm_service - sha256: a75f83f14ad81d5fe4b3319710b90dec37da0e22612326b696c9e1b8f34bbf48 + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 url: "https://pub.dev" source: hosted - version: "14.2.0" + version: "13.0.0" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + dart: ">=3.2.0-0 <4.0.0" + flutter: ">=3.10.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 44bf06e79..e51219389 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -29,3 +29,17 @@ flutter: assets: - assets/ uses-material-design: true + +dependency_overrides: + arcgis_map_sdk: + path: ../arcgis_map_sdk + arcgis_map_sdk_android: + path: ../arcgis_map_sdk_android + arcgis_map_sdk_ios: + path: ../arcgis_map_sdk_ios + arcgis_map_sdk_method_channel: + path: ../arcgis_map_sdk_method_channel + arcgis_map_sdk_platform_interface: + path: ../arcgis_map_sdk_platform_interface + arcgis_map_sdk_web: + path: ../arcgis_map_sdk_web \ No newline at end of file