diff --git a/example/lib/pages/camera.dart b/example/lib/pages/camera.dart index 6ee94d22..df9605a1 100644 --- a/example/lib/pages/camera.dart +++ b/example/lib/pages/camera.dart @@ -41,16 +41,23 @@ class _CameraPageState extends ExamplePageState { bool _showCameraUpdates = false; String _latestCameraUpdate = ''; bool _isFollowingLocation = false; + bool _ready = false; // ignore: use_setters_to_change_properties Future _onViewCreated(GoogleNavigationViewController controller) async { - _navigationViewController = controller; - calculateFocusCenter(); - _minZoomLevel = await _navigationViewController.getMinZoomPreference(); - _maxZoomLevel = await _navigationViewController.getMaxZoomPreference(); - - if (mounted) { - setState(() {}); + try { + _navigationViewController = controller; + calculateFocusCenter(); + _minZoomLevel = await _navigationViewController.getMinZoomPreference(); + _maxZoomLevel = await _navigationViewController.getMaxZoomPreference(); + if (mounted) { + setState(() { + _ready = true; + }); + } + } on ViewNotFoundException catch (_) { + // View not found exception is thrown if view is disposed before async + // method is handled on native side. } } @@ -148,7 +155,8 @@ class _CameraPageState extends ExamplePageState { _onCameraStartedFollowingLocation, onCameraStoppedFollowingLocation: _onCameraStoppedFollowingLocation), - getOverlayOptionsButton(context, onPressed: () => toggleOverlay()), + getOverlayOptionsButton(context, + onPressed: _ready ? () => toggleOverlay() : null), if (_showCameraUpdates) Container( width: 180, @@ -246,8 +254,9 @@ class _CameraPageState extends ExamplePageState { setState(() { _minZoomLevel = newMinZoomLevel; }); - } catch (e) { - showMessage(e.toString()); + } on MinZoomRangeException catch (e) { + debugPrint(e.toString()); + showMessage('Cannot set min zoom'); } } @@ -257,8 +266,9 @@ class _CameraPageState extends ExamplePageState { setState(() { _maxZoomLevel = newMaxZoomLevel; }); - } catch (e) { - showMessage(e.toString()); + } on MaxZoomRangeException catch (e) { + debugPrint(e.toString()); + showMessage('Cannot set max zoom'); } } diff --git a/example/lib/pages/circles.dart b/example/lib/pages/circles.dart index 4c3f91cc..752533c6 100644 --- a/example/lib/pages/circles.dart +++ b/example/lib/pages/circles.dart @@ -87,8 +87,16 @@ class _CirclesPageState extends ExamplePageState { Future _updateSelectedCircleWithOptions(CircleOptions options) async { final Circle newCircle = _selectedCircle!.copyWith(options: options); - final List circles = - await _navigationViewController.updateCircles([newCircle]); + final List circles; + try { + circles = + await _navigationViewController.updateCircles([newCircle]); + } on CircleNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Circle not found'); + return; + } + final Circle? circle = circles.firstOrNull; if (circle != null) { setState(() { @@ -102,7 +110,13 @@ class _CirclesPageState extends ExamplePageState { } Future _removeCircle() async { - await _navigationViewController.removeCircles([_selectedCircle!]); + try { + await _navigationViewController.removeCircles([_selectedCircle!]); + } on CircleNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Circle not found'); + return; + } setState(() { _circles = _circles diff --git a/example/lib/pages/map.dart b/example/lib/pages/map.dart index 327d9eaf..9329b241 100644 --- a/example/lib/pages/map.dart +++ b/example/lib/pages/map.dart @@ -39,18 +39,18 @@ class BasicMapPage extends ExamplePage { class _MapPageState extends ExamplePageState { late final GoogleMapViewController _mapViewController; - late bool isMyLocationEnabled = false; - late bool isMyLocationButtonEnabled = true; - late bool consumeMyLocationButtonClickEvent = false; - late bool isZoomGesturesEnabled = true; - late bool isZoomControlsEnabled = true; - late bool isCompassEnabled = true; - late bool isRotateGesturesEnabled = true; - late bool isScrollGesturesEnabled = true; - late bool isScrollGesturesEnabledDuringRotateOrZoom = true; - late bool isTiltGesturesEnabled = true; - late bool isTrafficEnabled = false; - late MapType mapType = MapType.normal; + bool isMyLocationEnabled = false; + bool isMyLocationButtonEnabled = true; + bool consumeMyLocationButtonClickEvent = false; + bool isZoomGesturesEnabled = true; + bool isZoomControlsEnabled = true; + bool isCompassEnabled = true; + bool isRotateGesturesEnabled = true; + bool isScrollGesturesEnabled = true; + bool isScrollGesturesEnabledDuringRotateOrZoom = true; + bool isTiltGesturesEnabled = true; + bool isTrafficEnabled = false; + MapType mapType = MapType.normal; Future setMapType(MapType type) async { mapType = type; @@ -65,13 +65,24 @@ class _MapPageState extends ExamplePageState { Future setMapStyleNight() async { final String jsonString = await rootBundle.loadString('assets/night_style.json'); - await _mapViewController.setMapStyle(jsonString); + + try { + await _mapViewController.setMapStyle(jsonString); + } on MapStyleException catch (e) { + debugPrint(e.toString()); + _showMessage('Unable to set map style'); + } } Future setMapStyleSepia() async { final String jsonString = await rootBundle.loadString('assets/sepia_style.json'); - await _mapViewController.setMapStyle(jsonString); + try { + await _mapViewController.setMapStyle(jsonString); + } on MapStyleException catch (e) { + debugPrint(e.toString()); + _showMessage('Unable to set map style'); + } } // ignore: use_setters_to_change_properties @@ -172,7 +183,7 @@ class _MapPageState extends ExamplePageState { ), ), getOverlayOptionsButton(context, - onPressed: () => toggleOverlay()) + onPressed: () => toggleOverlay()), ], )); } diff --git a/example/lib/pages/markers.dart b/example/lib/pages/markers.dart index f9374699..c3dae859 100644 --- a/example/lib/pages/markers.dart +++ b/example/lib/pages/markers.dart @@ -69,7 +69,14 @@ class _MarkersPageState extends ExamplePageState { } Future _removeMarker() async { - await _navigationViewController.removeMarkers([_selectedMarker!]); + try { + await _navigationViewController.removeMarkers([_selectedMarker!]); + } on MarkerNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Marker not found'); + return; + } + setState(() { _markers.remove(_selectedMarker); _selectedMarker = null; @@ -86,8 +93,16 @@ class _MarkersPageState extends ExamplePageState { Future _updateSelectedMarkerWithOptions(MarkerOptions options) async { final Marker newMarker = _selectedMarker!.copyWith(options: options); - final List markers = - await _navigationViewController.updateMarkers([newMarker]); + final List markers; + try { + markers = + await _navigationViewController.updateMarkers([newMarker]); + } on MarkerNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Marker not found'); + return; + } + final Marker? marker = markers.firstOrNull; if (marker != null) { setState(() { @@ -153,8 +168,16 @@ class _MarkersPageState extends ExamplePageState { await assetImage.obtainKey(configuration); final double imagePixelRatio = assetBundleImageKey.scale; final ByteData imageBytes = await rootBundle.load(assetBundleImageKey.name); - _registeredCustomIcon = await registerBitmapImage( - bitmap: imageBytes, imagePixelRatio: imagePixelRatio); + + try { + _registeredCustomIcon = await registerBitmapImage( + bitmap: imageBytes, imagePixelRatio: imagePixelRatio); + } on ImageDecodingFailedException catch (e) { + debugPrint(e.toString()); + showMessage('Failed to decode image'); + return ImageDescriptor.defaultImage; + } + return _registeredCustomIcon!; } diff --git a/example/lib/pages/multiple_views.dart b/example/lib/pages/multiple_views.dart index 02ac0764..39037cfb 100644 --- a/example/lib/pages/multiple_views.dart +++ b/example/lib/pages/multiple_views.dart @@ -201,7 +201,13 @@ class _MultiplexState extends ExamplePageState { setState(() { _navigationController = controller; }); - await controller.setMyLocationEnabled(true); + + try { + await controller.setMyLocationEnabled(true); + } on ViewNotFoundException catch (_) { + // View not found exception is thrown if view is disposed before async + // method is handled on native side. + } } Future _moveCameras() async { diff --git a/example/lib/pages/navigation.dart b/example/lib/pages/navigation.dart index 1baef64f..75b47235 100644 --- a/example/lib/pages/navigation.dart +++ b/example/lib/pages/navigation.dart @@ -475,7 +475,13 @@ class _NavigationPageState extends ExamplePageState { setState(() { _navigationViewController = controller; }); - await controller.setMyLocationEnabled(true); + + try { + await controller.setMyLocationEnabled(true); + } on ViewNotFoundException catch (_) { + // View not found exception is thrown if view is disposed before async + // method is handled on native side. + } if (_guidanceRunning) { // Guidance is running, enable navigation UI. @@ -611,8 +617,17 @@ class _NavigationPageState extends ExamplePageState { // Update existing marker. final Marker updatedWaypointMarker = _newWaypointMarker!.copyWith(options: markerOptions); - final List updatedMarkers = await _navigationViewController! - .updateMarkers([updatedWaypointMarker]); + + final List updatedMarkers; + try { + updatedMarkers = await _navigationViewController! + .updateMarkers([updatedWaypointMarker]); + } on MarkerNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Marker not found'); + return; + } + if (updatedMarkers.first != null) { _newWaypointMarker = updatedMarkers.first; } else { @@ -623,24 +638,38 @@ class _NavigationPageState extends ExamplePageState { } Future _removeNewWaypointMarker() async { - if (_newWaypointMarker != null) { + if (_newWaypointMarker == null) return; + + try { await _navigationViewController! .removeMarkers([_newWaypointMarker!]); - _newWaypointMarker = null; - setState(() {}); + } on MarkerNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Marker not found'); + return; } + + _newWaypointMarker = null; + setState(() {}); } Future _removeDestinationWaypointMarkers() async { - if (_destinationWaypointMarkers.isNotEmpty) { + if (_destinationWaypointMarkers.isEmpty) return; + + try { await _navigationViewController! .removeMarkers(_destinationWaypointMarkers); - _destinationWaypointMarkers.clear(); - - // Unregister custom marker images - await clearRegisteredImages(); - setState(() {}); + } on MarkerNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Marker not found'); + return; } + + _destinationWaypointMarkers.clear(); + + // Unregister custom marker images + await clearRegisteredImages(); + setState(() {}); } Future _onMapClicked(LatLng location) async { @@ -690,16 +719,25 @@ class _NavigationPageState extends ExamplePageState { final ImageDescriptor waypointMarkerImage = await registerWaypointMarkerImage( index, MediaQuery.of(context).devicePixelRatio); - final List destinationMarkers = - await _navigationViewController!.updateMarkers([ - _newWaypointMarker!.copyWith( - options: _newWaypointMarker!.options.copyWith( - infoWindow: InfoWindow(title: title), - anchor: const MarkerAnchor(u: 0.5, v: 1.2), - icon: waypointMarkerImage, - ), - ) - ]); + + final List destinationMarkers; + try { + destinationMarkers = + await _navigationViewController!.updateMarkers([ + _newWaypointMarker!.copyWith( + options: _newWaypointMarker!.options.copyWith( + infoWindow: InfoWindow(title: title), + anchor: const MarkerAnchor(u: 0.5, v: 1.2), + icon: waypointMarkerImage, + ), + ) + ]); + } on MarkerNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Marker not found'); + return; + } + _destinationWaypointMarkers.add(destinationMarkers.first!); _newWaypointMarker = null; } @@ -723,7 +761,15 @@ class _NavigationPageState extends ExamplePageState { // Remove the first destination marker from the list. if (_destinationWaypointMarkers.isNotEmpty) { final Marker markerToRemove = _destinationWaypointMarkers.first; - await _navigationViewController!.removeMarkers([markerToRemove]); + + try { + await _navigationViewController! + .removeMarkers([markerToRemove]); + } on MarkerNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Marker not found'); + return; + } // Unregister custom marker image. await unregisterImage(markerToRemove.options.icon); diff --git a/example/lib/pages/polygons.dart b/example/lib/pages/polygons.dart index 90a2147c..ef733cc1 100644 --- a/example/lib/pages/polygons.dart +++ b/example/lib/pages/polygons.dart @@ -150,8 +150,16 @@ class _PolygonsPageState extends ExamplePageState { Future _updateSelectedPolygonWithOptions(PolygonOptions options) async { final Polygon newPolygon = _selectedPolygon!.copyWith(options: options); - final List polygons = - await _navigationViewController.updatePolygons([newPolygon]); + final List polygons; + try { + polygons = + await _navigationViewController.updatePolygons([newPolygon]); + } on PolygonNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Polygon not found'); + return; + } + final Polygon? polygon = polygons.firstOrNull; if (polygon != null) { setState(() { @@ -165,8 +173,14 @@ class _PolygonsPageState extends ExamplePageState { } Future _removePolygon() async { - await _navigationViewController - .removePolygons([_selectedPolygon!]); + try { + await _navigationViewController + .removePolygons([_selectedPolygon!]); + } on PolygonNotFoundException catch (e) { + debugPrint(e.toString()); + showMessage('Polygon not found'); + return; + } setState(() { _polygons = _polygons diff --git a/example/lib/pages/polylines.dart b/example/lib/pages/polylines.dart index 9e549967..f8aeca27 100644 --- a/example/lib/pages/polylines.dart +++ b/example/lib/pages/polylines.dart @@ -106,8 +106,16 @@ class _PolylinesPageState extends ExamplePageState { PolylineOptions options) async { final Polyline newPolyline = _selectedPolyline!.copyWith(options: options); - final List polylines = await _navigationViewController - .updatePolylines([newPolyline]); + final List polylines; + try { + polylines = await _navigationViewController + .updatePolylines([newPolyline]); + } on PolylineNotFoundException catch (e) { + debugPrint(e.toString()); + _showMessage('Polyline not found'); + return; + } + final Polyline? polyline = polylines.firstOrNull; if (polyline != null) { setState(() { @@ -121,8 +129,14 @@ class _PolylinesPageState extends ExamplePageState { } Future _removePolyline() async { - await _navigationViewController - .removePolylines([_selectedPolyline!]); + try { + await _navigationViewController + .removePolylines([_selectedPolyline!]); + } on PolylineNotFoundException catch (e) { + debugPrint(e.toString()); + _showMessage('Polyline not found'); + return; + } setState(() { _polylines = _polylines @@ -204,6 +218,23 @@ class _PolylinesPageState extends ExamplePageState { _selectedPolyline!.options.copyWith(zIndex: newZIndex)); } + void _showMessage(String message) { + if (!mounted) { + return; + } + _hideMessage(); + if (isOverlayVisible) { + showOverlaySnackBar(message); + } else { + final SnackBar snackBar = SnackBar(content: Text(message)); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + } + } + + void _hideMessage() { + ScaffoldMessenger.of(context).removeCurrentSnackBar(); + } + @override Widget build(BuildContext context) => buildPage( context, diff --git a/example/lib/utils/waypoint_marker.dart b/example/lib/utils/waypoint_marker.dart index 1c3cc145..3b9212fb 100644 --- a/example/lib/utils/waypoint_marker.dart +++ b/example/lib/utils/waypoint_marker.dart @@ -39,7 +39,15 @@ Future registerWaypointMarkerImage( await image.toByteData(format: ui.ImageByteFormat.png); // Call registerBitmapImage with ByteData - return registerBitmapImage(bitmap: bytes!, imagePixelRatio: imagePixelRatio); + try { + return await registerBitmapImage( + bitmap: bytes!, + imagePixelRatio: imagePixelRatio, + ); + } on ImageDecodingFailedException catch (_) { + debugPrint('Failed to decode image'); + rethrow; + } } class _WaypointMarkerPainter extends CustomPainter { diff --git a/lib/google_navigation_flutter.dart b/lib/google_navigation_flutter.dart index 0c209b3a..e3847a9d 100644 --- a/lib/google_navigation_flutter.dart +++ b/lib/google_navigation_flutter.dart @@ -23,3 +23,4 @@ export 'src/google_maps_map_view.dart'; export 'src/google_maps_map_view_controller.dart'; export 'src/google_maps_navigation_view_controller.dart'; export 'src/google_maps_auto_view_controller.dart'; +export 'src/google_maps_exceptions.dart'; diff --git a/lib/src/google_maps_exceptions.dart b/lib/src/google_maps_exceptions.dart new file mode 100644 index 00000000..c5913494 --- /dev/null +++ b/lib/src/google_maps_exceptions.dart @@ -0,0 +1,252 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import 'package:flutter/services.dart'; + +/// Abstract base class for specific platform exceptions derived from this +/// plugin. +/// +/// This exception serves as a common superclass for more specific exceptions +/// thrown by the plugin's platform channel wrapper. Catching this +/// exception allows handling a broader category of plugin-specific platform +/// errors. It extends [PlatformException] to retain original error details. +/// +/// {@category Navigation View} +/// {@category Map View} +abstract class GoogleMapsNavigationPlatformException extends PlatformException { + /// Default constructor for [GoogleMapsNavigationPlatformException]. + GoogleMapsNavigationPlatformException({ + required super.code, + super.message, + super.details, + super.stacktrace, + }); + + @override + String toString() => '$runtimeType($code, $message, $details, $stacktrace)'; +} + +/// Exception thrown when a platform view is not found. +/// +/// This exception is typically thrown when an asynchronous operation is +/// attempted on a view that has already been disposed. For example, some +/// controller calls could throw this error if the view is no longer available +/// when the method is handled on the native layer. +/// +/// {@category Navigation View} +/// {@category Map View} +class ViewNotFoundException extends GoogleMapsNavigationPlatformException { + /// Creates a [ViewNotFoundException] from an original [PlatformException]. + ViewNotFoundException( + {required PlatformException exception, required StackTrace stacktrace}) + : assert(exception.code == platformCode), + super( + code: exception.code, + message: exception.message ?? 'Platform view not found.', + details: exception.details, + stacktrace: stacktrace.toString(), + ); + + static const platformCode = 'viewNotFound'; +} + +/// [GoogleNavigationViewController.updateMarkers] or +/// [GoogleNavigationViewController.removeMarkers] failed +/// to find the marker given to the method. +/// {@category Navigation View} +/// {@category Map View} +class MarkerNotFoundException extends GoogleMapsNavigationPlatformException { + /// Creates a [MarkerNotFoundException] from an original [PlatformException]. + MarkerNotFoundException({required PlatformException exception}) + : assert(exception.code == platformCode), + super( + code: exception.code, + message: exception.message ?? 'Marker not found.', + details: exception.details, + stacktrace: exception.stacktrace, + ); + + static const platformCode = 'markerNotFound'; +} + +/// [GoogleNavigationViewController.updatePolygons] or +/// [GoogleNavigationViewController.removePolygons] failed +/// to find the polygon given to the method. +/// {@category Navigation View} +/// {@category Map View} +class PolygonNotFoundException extends GoogleMapsNavigationPlatformException { + /// Creates a [PolygonNotFoundException] from an original [PlatformException]. + PolygonNotFoundException({required PlatformException exception}) + : assert(exception.code == platformCode), + super( + code: exception.code, + message: exception.message ?? 'Polygon not found.', + details: exception.details, + stacktrace: exception.stacktrace, + ); + + static const platformCode = 'polygonNotFound'; +} + +/// [GoogleNavigationViewController.updatePolylines] or +/// [GoogleNavigationViewController.removePolylines] failed +/// to find the polyline given to the method. +/// {@category Navigation View} +/// {@category Map View} +class PolylineNotFoundException extends GoogleMapsNavigationPlatformException { + /// Creates a [PolylineNotFoundException] from an original [PlatformException]. + PolylineNotFoundException({required PlatformException exception}) + : assert(exception.code == platformCode), + super( + code: exception.code, + message: exception.message ?? 'Polyline not found.', + details: exception.details, + stacktrace: exception.stacktrace, + ); + + static const platformCode = 'polylineNotFound'; +} + +/// [GoogleNavigationViewController.updateCircles] or +/// [GoogleNavigationViewController.removeCircles] failed +/// to find the circle given to the method. +/// {@category Navigation View} +/// {@category Map View} +class CircleNotFoundException extends GoogleMapsNavigationPlatformException { + /// Creates a [CircleNotFoundException] from an original [PlatformException]. + CircleNotFoundException({required PlatformException exception}) + : assert(exception.code == platformCode), + super( + code: exception.code, + message: exception.message ?? 'Circle not found.', + details: exception.details, + stacktrace: exception.stacktrace, + ); + + static const platformCode = 'circleNotFound'; +} + +/// [GoogleNavigationViewController.setMapStyle] failed to set the map style. +/// {@category Navigation View} +/// {@category Map View} +class MapStyleException extends GoogleMapsNavigationPlatformException { + /// Creates a [MapStyleException] from an original [PlatformException]. + MapStyleException({required PlatformException exception}) + : assert(exception.code == platformCode), + super( + code: exception.code, + message: exception.message ?? 'Failed to set map style.', + details: exception.details, + stacktrace: exception.stacktrace, + ); + + static const platformCode = 'mapStyleError'; +} + +/// [GoogleNavigationViewController.setMaxZoomPreference] failed to set zoom level. +/// {@category Navigation View} +/// {@category Map View} +class MaxZoomRangeException extends GoogleMapsNavigationPlatformException { + /// Creates a [MaxZoomRangeException] from an original [PlatformException]. + MaxZoomRangeException({required PlatformException exception}) + : assert(exception.code == platformCode), + super( + code: exception.code, + message: 'Cannot set max zoom to less than min zoom.', + details: exception.details, + stacktrace: exception.stacktrace, + ); + + // Override toString for potentially more specific default message if needed + @override + String toString() { + return 'MaxZoomRangeException: Cannot set max zoom to less than min zoom'; + } + + static const platformCode = 'maxZoomLessThanMinZoom'; +} + +/// [GoogleNavigationViewController.setMinZoomPreference] failed to set zoom level. +/// {@category Navigation View} +/// {@category Map View} +class MinZoomRangeException extends GoogleMapsNavigationPlatformException { + /// Creates a [MinZoomRangeException] from an original [PlatformException]. + MinZoomRangeException({required PlatformException exception}) + : assert(exception.code == platformCode), + super( + code: exception.code, + message: 'Cannot set min zoom to greater than max zoom.', + details: exception.details, + stacktrace: exception.stacktrace, + ); + + @override + String toString() { + return 'MinZoomRangeException: Cannot set min zoom to greater than max zoom'; + } + + static const platformCode = 'minZoomGreaterThanMaxZoom'; +} + +/// [registerBitmapImage] failed to decode bitmap from byte array. +/// {@category Image Registry} +class ImageDecodingFailedException + extends GoogleMapsNavigationPlatformException { + /// Creates a [ImageDecodingFailedException] from an original [PlatformException]. + ImageDecodingFailedException({required PlatformException exception}) + : assert(exception.code == platformCode), + super( + code: exception.code, + message: exception.message ?? 'Failed to decode bitmap image.', + details: exception.details, + stacktrace: exception.stacktrace, + ); + + static const platformCode = 'imageDecodingFailed'; +} + +/// Converts [exception] to [GoogleMapsNavigationPlatformException] +/// if [exception] is a [PlatformException]. +/// +/// If the [exception] is not a [PlatformException], the original [exception] +/// is returned unchanged. +Object convertPlatformException(Object exception, StackTrace stacktrace) { + if (exception is PlatformException) { + switch (exception.code) { + case MarkerNotFoundException.platformCode: + return MarkerNotFoundException(exception: exception); + case PolygonNotFoundException.platformCode: + return PolygonNotFoundException(exception: exception); + case PolylineNotFoundException.platformCode: + return PolylineNotFoundException(exception: exception); + case CircleNotFoundException.platformCode: + return CircleNotFoundException(exception: exception); + case MapStyleException.platformCode: + return MapStyleException(exception: exception); + case MaxZoomRangeException.platformCode: + return MaxZoomRangeException(exception: exception); + case MinZoomRangeException.platformCode: + return MinZoomRangeException(exception: exception); + case ImageDecodingFailedException.platformCode: + return ImageDecodingFailedException(exception: exception); + case ViewNotFoundException.platformCode: + return ViewNotFoundException( + exception: exception, + stacktrace: stacktrace, + ); + } + } + + return exception; +} diff --git a/lib/src/google_maps_image_registry.dart b/lib/src/google_maps_image_registry.dart index 1485436a..26ad21ce 100644 --- a/lib/src/google_maps_image_registry.dart +++ b/lib/src/google_maps_image_registry.dart @@ -63,10 +63,3 @@ Future clearRegisteredImages() { return GoogleMapsNavigationPlatform.instance.imageRegistryAPI .clearRegisteredImages(); } - -/// [registerBitmapImage] failed to decode bitmap from byte array. -/// {@category Image Registry} -class ImageDecodingFailedException implements Exception { - /// Default constructor for [ImageDecodingFailedException]. - const ImageDecodingFailedException(); -} diff --git a/lib/src/google_navigation_flutter.dart b/lib/src/google_navigation_flutter.dart index 9ce00934..223d99a4 100644 --- a/lib/src/google_navigation_flutter.dart +++ b/lib/src/google_navigation_flutter.dart @@ -338,77 +338,3 @@ class NavigationViewUISettings { .isTrafficEnabled(viewId: _viewId); } } - -/// [GoogleNavigationViewController.updateMarkers] or -/// [GoogleNavigationViewController.removeMarkers] failed -/// to find the marker given to the method. -/// {@category Navigation View} -/// {@category Map View} -class MarkerNotFoundException implements Exception { - /// Default constructor for [MarkerNotFoundException]. - const MarkerNotFoundException(); -} - -/// [GoogleNavigationViewController.updatePolygons] or -/// [GoogleNavigationViewController.removePolygons] failed -/// to find the polygon given to the method. -/// {@category Navigation View} -/// {@category Map View} -class PolygonNotFoundException implements Exception { - /// Default constructor for [PolygonNotFoundException]. - const PolygonNotFoundException(); -} - -/// [GoogleNavigationViewController.updatePolylines] or -/// [GoogleNavigationViewController.removePolylines] failed -/// to find the polyline given to the method. -/// {@category Navigation View} -/// {@category Map View} -class PolylineNotFoundException implements Exception { - /// Default constructor for [PolylineNotFoundException]. - const PolylineNotFoundException(); -} - -/// [GoogleNavigationViewController.updateCircles] or -/// [GoogleNavigationViewController.removeCircles] failed -/// to find the circle given to the method. -/// {@category Navigation View} -/// {@category Map View} -class CircleNotFoundException implements Exception { - /// Default constructor for [CircleNotFoundException]. - const CircleNotFoundException(); -} - -/// [GoogleNavigationViewController.setMapStyle] failed to set the map style. -/// {@category Navigation View} -/// {@category Map View} -class MapStyleException implements Exception { - /// Default constructor for [MapStyleException]. - const MapStyleException(); -} - -/// [GoogleNavigationViewController.setMaxZoomPreference] failed to set zoom level. -/// {@category Navigation View} -/// {@category Map View} -class MaxZoomRangeException implements Exception { - /// Default constructor for [MaxZoomRangeException]. - const MaxZoomRangeException(); - - @override - String toString() { - return 'MaxZoomRangeException: Cannot set max zoom to less than min zoom'; - } -} - -/// [GoogleNavigationViewController.setMinZoomPreference] failed to set zoom level. -/// {@category Navigation View} -/// {@category Map View} -class MinZoomRangeException implements Exception { - /// Default constructor for [MinZoomRangeException]. - const MinZoomRangeException(); - - @override - String toString() { - return 'MinZoomRangeException: Cannot set min zoom to greater than max zoom'; - } -} diff --git a/lib/src/google_navigation_flutter_android.dart b/lib/src/google_navigation_flutter_android.dart index e8d1a364..ef300a93 100644 --- a/lib/src/google_navigation_flutter_android.dart +++ b/lib/src/google_navigation_flutter_android.dart @@ -99,21 +99,19 @@ class GoogleMapsNavigationAndroid extends GoogleMapsNavigationPlatform { // Wait map to be ready before calling [onMapReady] callback await viewAPI.awaitMapReady(viewId: viewId); onMapReady(viewId); + } on ViewNotFoundException catch (_) { + // This exception can happen if the view is disposed before the calls + // are made to the platform side. We can ignore this exception as + // the view is already disposed. + return; } on PlatformException catch (exception, stack) { - if (exception.code == 'viewNotFound') { - // This exeption can happen if the view is disposed before the calls - // are made to the platform side. We can ignore this exception as - // the view is already disposed. - return; - } else { - // Pass other exceptions to the Flutter error handler. - FlutterError.reportError(FlutterErrorDetails( - exception: exception, - stack: stack, - library: 'google_navigation_flutter', - context: ErrorDescription(exception.message ?? ''), - )); - } + // Pass other exceptions to the Flutter error handler. + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'google_navigation_flutter', + context: ErrorDescription(exception.message ?? ''), + )); } }, gestureRecognizers: initializationOptions.gestureRecognizers, diff --git a/lib/src/google_navigation_flutter_ios.dart b/lib/src/google_navigation_flutter_ios.dart index fc3a481c..f1ea8165 100644 --- a/lib/src/google_navigation_flutter_ios.dart +++ b/lib/src/google_navigation_flutter_ios.dart @@ -100,21 +100,19 @@ class GoogleMapsNavigationIOS extends GoogleMapsNavigationPlatform { // Wait map to be ready before calling [onMapReady] callback await viewAPI.awaitMapReady(viewId: viewId); onMapReady(viewId); + } on ViewNotFoundException catch (_) { + // This exception can happen if the view is disposed before the calls + // are made to the platform side. We can ignore this exception as + // the view is already disposed. + return; } on PlatformException catch (exception, stack) { - if (exception.code == 'viewNotFound') { - // This exeption can happen if the view is disposed before the calls - // are made to the platform side. We can ignore this exception as - // the view is already disposed. - return; - } else { - // Pass other exceptions to the Flutter error handler. - FlutterError.reportError(FlutterErrorDetails( - exception: exception, - stack: stack, - library: 'google_navigation_flutter', - context: ErrorDescription(exception.message ?? ''), - )); - } + // Pass other exceptions to the Flutter error handler. + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'google_navigation_flutter', + context: ErrorDescription(exception.message ?? ''), + )); } }, gestureRecognizers: initializationOptions.gestureRecognizers, diff --git a/lib/src/method_channel/auto_view_api.dart b/lib/src/method_channel/auto_view_api.dart index f715990c..4f9e32a2 100644 --- a/lib/src/method_channel/auto_view_api.dart +++ b/lib/src/method_channel/auto_view_api.dart @@ -81,24 +81,40 @@ class AutoMapViewAPIImpl { } /// Get the preference for whether the my location should be enabled or disabled. - Future isMyLocationEnabled() { - return _viewApi.isMyLocationEnabled(); + Future isMyLocationEnabled() async { + try { + return await _viewApi.isMyLocationEnabled(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enabled location in the navigation view. - Future setMyLocationEnabled({required bool enabled}) { - return _viewApi.setMyLocationEnabled(enabled); + Future setMyLocationEnabled({required bool enabled}) async { + try { + await _viewApi.setMyLocationEnabled(enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get the map type. Future getMapType() async { - final MapTypeDto mapType = await _viewApi.getMapType(); - return mapType.toMapType(); + try { + final MapTypeDto mapType = await _viewApi.getMapType(); + return mapType.toMapType(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Modified visible map type. Future setMapType({required MapType mapType}) async { - return _viewApi.setMapType(mapType.toDto()); + try { + await _viewApi.setMapType(mapType.toDto()); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Set map style by json string. @@ -106,188 +122,273 @@ class AutoMapViewAPIImpl { try { // Set the given json to the viewApi or reset the map style if // the styleJson is null. - return await _viewApi.setMapStyle(styleJson ?? '[]'); - } on PlatformException catch (error) { - if (error.code == 'mapStyleError') { - throw const MapStyleException(); - } else { - rethrow; - } + await _viewApi.setMapStyle(styleJson ?? '[]'); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Enables or disables the my-location button. - Future setMyLocationButtonEnabled({required bool enabled}) { - return _viewApi.setMyLocationButtonEnabled(enabled); + Future setMyLocationButtonEnabled({required bool enabled}) async { + try { + await _viewApi.setMyLocationButtonEnabled(enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enables or disables if the my location button consumes click events. Future setConsumeMyLocationButtonClickEventsEnabled( {required bool enabled}) async { - return _viewApi.setConsumeMyLocationButtonClickEventsEnabled(enabled); + try { + await _viewApi.setConsumeMyLocationButtonClickEventsEnabled(enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enables or disables the zoom gestures. - Future setZoomGesturesEnabled({required bool enabled}) { - return _viewApi.setZoomGesturesEnabled(enabled); + Future setZoomGesturesEnabled({required bool enabled}) async { + try { + await _viewApi.setZoomGesturesEnabled(enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enables or disables the zoom controls. Future setZoomControlsEnabled({required bool enabled}) async { try { - return await _viewApi.setZoomControlsEnabled(enabled); - } on PlatformException catch (error) { - if (error.code == 'notSupported') { + await _viewApi.setZoomControlsEnabled(enabled); + } catch (e, stackTrace) { + if (e is PlatformException && e.code == 'notSupported') { throw UnsupportedError('Zoom controls are not supported on iOS.'); } else { - rethrow; + throw convertPlatformException(e, stackTrace); } } } /// Enables or disables the compass. - Future setCompassEnabled({required bool enabled}) { - return _viewApi.setCompassEnabled(enabled); + Future setCompassEnabled({required bool enabled}) async { + try { + await _viewApi.setCompassEnabled(enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the preference for whether rotate gestures should be enabled or disabled. - Future setRotateGesturesEnabled({required bool enabled}) { - return _viewApi.setRotateGesturesEnabled(enabled); + Future setRotateGesturesEnabled({required bool enabled}) async { + try { + await _viewApi.setRotateGesturesEnabled(enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the preference for whether scroll gestures should be enabled or disabled. - Future setScrollGesturesEnabled({required bool enabled}) { - return _viewApi.setScrollGesturesEnabled(enabled); + Future setScrollGesturesEnabled({required bool enabled}) async { + try { + await _viewApi.setScrollGesturesEnabled(enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the preference for whether scroll gestures can take place at the same time as a zoom or rotate gesture. Future setScrollGesturesDuringRotateOrZoomEnabled( - {required bool enabled}) { - return _viewApi.setScrollGesturesDuringRotateOrZoomEnabled(enabled); + {required bool enabled}) async { + try { + await _viewApi.setScrollGesturesDuringRotateOrZoomEnabled(enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the preference for whether tilt gestures should be enabled or disabled. - Future setTiltGesturesEnabled({required bool enabled}) { - return _viewApi.setTiltGesturesEnabled(enabled); + Future setTiltGesturesEnabled({required bool enabled}) async { + try { + await _viewApi.setTiltGesturesEnabled(enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the preference for whether the Map Toolbar should be enabled or disabled. Future setMapToolbarEnabled({required bool enabled}) async { try { - return await _viewApi.setMapToolbarEnabled(enabled); - } on PlatformException catch (error) { - if (error.code == 'notSupported') { + await _viewApi.setMapToolbarEnabled(enabled); + } catch (e, stackTrace) { + if (e is PlatformException && e.code == 'notSupported') { throw UnsupportedError('Map toolbar is not supported on iOS.'); } else { - rethrow; + throw convertPlatformException(e, stackTrace); } } } /// Turns the traffic layer on or off. - Future setTrafficEnabled({required bool enabled}) { - return _viewApi.setTrafficEnabled(enabled); + Future setTrafficEnabled({required bool enabled}) async { + try { + await _viewApi.setTrafficEnabled(enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get the preference for whether the my location button should be enabled or disabled. - Future isMyLocationButtonEnabled() { - return _viewApi.isMyLocationButtonEnabled(); + Future isMyLocationButtonEnabled() async { + try { + return await _viewApi.isMyLocationButtonEnabled(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get the preference for whether the my location button consumes click events. - Future isConsumeMyLocationButtonClickEventsEnabled() { - return _viewApi.isConsumeMyLocationButtonClickEventsEnabled(); + Future isConsumeMyLocationButtonClickEventsEnabled() async { + try { + return await _viewApi.isConsumeMyLocationButtonClickEventsEnabled(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether zoom gestures should be enabled or disabled. - Future isZoomGesturesEnabled() { - return _viewApi.isZoomGesturesEnabled(); + Future isZoomGesturesEnabled() async { + try { + return await _viewApi.isZoomGesturesEnabled(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether zoom controls should be enabled or disabled. Future isZoomControlsEnabled() async { try { return await _viewApi.isZoomControlsEnabled(); - } on PlatformException catch (error) { - if (error.code == 'notSupported') { + } catch (e, stackTrace) { + if (e is PlatformException && e.code == 'notSupported') { throw UnsupportedError('Zoom controls are not supported on iOS.'); } else { - rethrow; + throw convertPlatformException(e, stackTrace); } } } /// Gets the preference for whether compass should be enabled or disabled. - Future isCompassEnabled() { - return _viewApi.isCompassEnabled(); + Future isCompassEnabled() async { + try { + return await _viewApi.isCompassEnabled(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether rotate gestures should be enabled or disabled. - Future isRotateGesturesEnabled() { - return _viewApi.isRotateGesturesEnabled(); + Future isRotateGesturesEnabled() async { + try { + return await _viewApi.isRotateGesturesEnabled(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether scroll gestures should be enabled or disabled. - Future isScrollGesturesEnabled() { - return _viewApi.isScrollGesturesEnabled(); + Future isScrollGesturesEnabled() async { + try { + return await _viewApi.isScrollGesturesEnabled(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether scroll gestures can take place at the same time as a zoom or rotate gesture. - Future isScrollGesturesEnabledDuringRotateOrZoom() { - return _viewApi.isScrollGesturesEnabledDuringRotateOrZoom(); + Future isScrollGesturesEnabledDuringRotateOrZoom() async { + try { + return await _viewApi.isScrollGesturesEnabledDuringRotateOrZoom(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether tilt gestures should be enabled or disabled. - Future isTiltGesturesEnabled() { - return _viewApi.isTiltGesturesEnabled(); + Future isTiltGesturesEnabled() async { + try { + return await _viewApi.isTiltGesturesEnabled(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets whether the Map Toolbar is enabled/disabled. Future isMapToolbarEnabled() async { try { return await _viewApi.isMapToolbarEnabled(); - } on PlatformException catch (error) { - if (error.code == 'notSupported') { + } catch (e, stackTrace) { + if (e is PlatformException && e.code == 'notSupported') { throw UnsupportedError('Map toolbar is not supported on iOS.'); } else { - rethrow; + throw convertPlatformException(e, stackTrace); } } } /// Checks whether the map is drawing traffic data. - Future isTrafficEnabled() { - return _viewApi.isTrafficEnabled(); + Future isTrafficEnabled() async { + try { + return await _viewApi.isTrafficEnabled(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the Camera to follow the location of the user. Future followMyLocation( - {required CameraPerspective perspective, required double? zoomLevel}) { - return _viewApi.followMyLocation(perspective.toDto(), zoomLevel); + {required CameraPerspective perspective, + required double? zoomLevel}) async { + try { + await _viewApi.followMyLocation(perspective.toDto(), zoomLevel); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets users current location. Future getMyLocation() async { - final LatLngDto? myLocation = await _viewApi.getMyLocation(); - if (myLocation == null) { - return null; + try { + final LatLngDto? myLocation = await _viewApi.getMyLocation(); + if (myLocation == null) { + return null; + } + return myLocation.toLatLng(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } - return myLocation.toLatLng(); } /// Gets the current position of the camera. Future getCameraPosition() async { - final CameraPositionDto position = await _viewApi.getCameraPosition(); - return position.toCameraPosition(); + try { + final CameraPositionDto position = await _viewApi.getCameraPosition(); + return position.toCameraPosition(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the current visible area / camera bounds. Future getVisibleRegion() async { - final LatLngBoundsDto bounds = await _viewApi.getVisibleRegion(); - return LatLngBounds( - southwest: bounds.southwest.toLatLng(), - northeast: bounds.northeast.toLatLng(), - ); + try { + final LatLngBoundsDto bounds = await _viewApi.getVisibleRegion(); + return LatLngBounds( + southwest: bounds.southwest.toLatLng(), + northeast: bounds.northeast.toLatLng(), + ); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Animates the movement of the camera. @@ -374,30 +475,38 @@ class AutoMapViewAPIImpl { } /// Returns the minimum zoom level. - Future getMinZoomPreference() { - return _viewApi.getMinZoomPreference(); + Future getMinZoomPreference() async { + try { + return await _viewApi.getMinZoomPreference(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Returns the maximum zoom level for the current camera position. - Future getMaxZoomPreference() { - return _viewApi.getMaxZoomPreference(); + Future getMaxZoomPreference() async { + try { + return await _viewApi.getMaxZoomPreference(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Removes any previously specified upper and lower zoom bounds. - Future resetMinMaxZoomPreference() { - return _viewApi.resetMinMaxZoomPreference(); + Future resetMinMaxZoomPreference() async { + try { + await _viewApi.resetMinMaxZoomPreference(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets a preferred lower bound for the camera zoom. Future setMinZoomPreference({required double minZoomPreference}) async { try { return await _viewApi.setMinZoomPreference(minZoomPreference); - } on PlatformException catch (error) { - if (error.code == 'minZoomGreaterThanMaxZoom') { - throw const MinZoomRangeException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -405,49 +514,53 @@ class AutoMapViewAPIImpl { Future setMaxZoomPreference({required double maxZoomPreference}) async { try { return await _viewApi.setMaxZoomPreference(maxZoomPreference); - } on PlatformException catch (error) { - if (error.code == 'maxZoomLessThanMinZoom') { - throw const MaxZoomRangeException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Get all markers from map view. Future> getMarkers() async { - final List markers = await _viewApi.getMarkers(); - return markers - .whereType() - .map((MarkerDto e) => e.toMarker()) - .toList(); + try { + final List markers = await _viewApi.getMarkers(); + return markers + .whereType() + .map((MarkerDto e) => e.toMarker()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Add markers to map view. Future> addMarkers( {required List markerOptions}) async { - // Convert options to pigeon format - final List options = - markerOptions.map((MarkerOptions opt) => opt.toDto()).toList(); + try { + // Convert options to pigeon format + final List options = + markerOptions.map((MarkerOptions opt) => opt.toDto()).toList(); + + // Create marker objects with new ID's + final List markersToAdd = options + .map((MarkerOptionsDto options) => + MarkerDto(markerId: _createMarkerId(), options: options)) + .toList(); - // Create marker objects with new ID's - final List markersToAdd = options - .map((MarkerOptionsDto options) => - MarkerDto(markerId: _createMarkerId(), options: options)) - .toList(); + // Add markers to map + final List markersAdded = + await _viewApi.addMarkers(markersToAdd); - // Add markers to map - final List markersAdded = - await _viewApi.addMarkers(markersToAdd); + if (markersToAdd.length != markersAdded.length) { + throw Exception('Could not add all markers to map view'); + } - if (markersToAdd.length != markersAdded.length) { - throw Exception('Could not add all markers to map view'); + return markersAdded + .whereType() + .map((MarkerDto markerDto) => markerDto.toMarker()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } - - return markersAdded - .whereType() - .map((MarkerDto markerDto) => markerDto.toMarker()) - .toList(); } /// Update markers on the map view. @@ -461,12 +574,8 @@ class AutoMapViewAPIImpl { .whereType() .map((MarkerDto markerDto) => markerDto.toMarker()) .toList(); - } on PlatformException catch (error) { - if (error.code == 'markerNotFound') { - throw const MarkerNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -476,60 +585,72 @@ class AutoMapViewAPIImpl { final List markerDtos = markers.map((Marker marker) => marker.toDto()).toList(); return await _viewApi.removeMarkers(markerDtos); - } on PlatformException catch (error) { - if (error.code == 'markerNotFound') { - throw const MarkerNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Remove all markers from map view. - Future clearMarkers() { - return _viewApi.clearMarkers(); + Future clearMarkers() async { + try { + await _viewApi.clearMarkers(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Removes all markers, polylines, polygons, overlays, etc from the map. - Future clear() { - return _viewApi.clear(); + Future clear() async { + try { + return await _viewApi.clear(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get all polygons from map view. Future> getPolygons() async { - final List polygons = await _viewApi.getPolygons(); + try { + final List polygons = await _viewApi.getPolygons(); - return polygons - .whereType() - .map((PolygonDto polygon) => polygon.toPolygon()) - .toList(); + return polygons + .whereType() + .map((PolygonDto polygon) => polygon.toPolygon()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Add polygons to map view. Future> addPolygons( {required List polygonOptions}) async { - // Convert options to pigeon format - final List options = - polygonOptions.map((PolygonOptions opt) => opt.toDto()).toList(); + try { + // Convert options to pigeon format + final List options = + polygonOptions.map((PolygonOptions opt) => opt.toDto()).toList(); + + // Create polygon objects with new ID's + final List polygonsToAdd = options + .map((PolygonOptionsDto options) => + PolygonDto(polygonId: _createPolygonId(), options: options)) + .toList(); - // Create polygon objects with new ID's - final List polygonsToAdd = options - .map((PolygonOptionsDto options) => - PolygonDto(polygonId: _createPolygonId(), options: options)) - .toList(); + // Add polygons to map + final List polygonsAdded = + await _viewApi.addPolygons(polygonsToAdd); - // Add polygons to map - final List polygonsAdded = - await _viewApi.addPolygons(polygonsToAdd); + if (polygonsToAdd.length != polygonsAdded.length) { + throw Exception('Could not add all polygons to map view'); + } - if (polygonsToAdd.length != polygonsAdded.length) { - throw Exception('Could not add all polygons to map view'); + return polygonsAdded + .whereType() + .map((PolygonDto polygon) => polygon.toPolygon()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } - - return polygonsAdded - .whereType() - .map((PolygonDto polygon) => polygon.toPolygon()) - .toList(); } /// Update polygons on the map view. @@ -544,12 +665,8 @@ class AutoMapViewAPIImpl { .whereType() .map((PolygonDto polygon) => polygon.toPolygon()) .toList(); - } on PlatformException catch (error) { - if (error.code == 'polygonNotFound') { - throw const PolygonNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -559,55 +676,63 @@ class AutoMapViewAPIImpl { final List navigationViewPolygons = polygons.map((Polygon polygon) => polygon.toDto()).toList(); return await _viewApi.removePolygons(navigationViewPolygons); - } on PlatformException catch (error) { - if (error.code == 'polygonNotFound') { - throw const PolygonNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Remove all polygons from map view. - Future clearPolygons() { - return _viewApi.clearPolygons(); + Future clearPolygons() async { + try { + await _viewApi.clearPolygons(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get all polylines from map view. Future> getPolylines() async { - final List polylines = await _viewApi.getPolylines(); + try { + final List polylines = await _viewApi.getPolylines(); - return polylines - .whereType() - .map((PolylineDto polyline) => polyline.toPolyline()) - .toList(); + return polylines + .whereType() + .map((PolylineDto polyline) => polyline.toPolyline()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Add polylines to map view. Future> addPolylines( {required List polylineOptions}) async { - // Convert options to pigeon format - final List options = - polylineOptions.map((PolylineOptions opt) => opt.toDto()).toList(); + try { + // Convert options to pigeon format + final List options = + polylineOptions.map((PolylineOptions opt) => opt.toDto()).toList(); + + // Create polyline objects with new ID's + final List polylinesToAdd = options + .map((PolylineOptionsDto options) => + PolylineDto(polylineId: _createPolylineId(), options: options)) + .toList(); - // Create polyline objects with new ID's - final List polylinesToAdd = options - .map((PolylineOptionsDto options) => - PolylineDto(polylineId: _createPolylineId(), options: options)) - .toList(); + // Add polylines to map + final List polylinesAdded = + await _viewApi.addPolylines(polylinesToAdd); - // Add polylines to map - final List polylinesAdded = - await _viewApi.addPolylines(polylinesToAdd); + if (polylinesToAdd.length != polylinesAdded.length) { + throw Exception('Could not add all polylines to map view'); + } - if (polylinesToAdd.length != polylinesAdded.length) { - throw Exception('Could not add all polylines to map view'); + return polylinesAdded + .whereType() + .map((PolylineDto polyline) => polyline.toPolyline()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } - - return polylinesAdded - .whereType() - .map((PolylineDto polyline) => polyline.toPolyline()) - .toList(); } /// Update polylines on the map view. @@ -623,12 +748,8 @@ class AutoMapViewAPIImpl { .whereType() .map((PolylineDto polyline) => polyline.toPolyline()) .toList(); - } on PlatformException catch (error) { - if (error.code == 'polylineNotFound') { - throw const PolylineNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -639,55 +760,63 @@ class AutoMapViewAPIImpl { .map((Polyline polyline) => polyline.toNavigationViewPolyline()) .toList(); return await _viewApi.removePolylines(navigationViewPolylines); - } on PlatformException catch (error) { - if (error.code == 'polylineNotFound') { - throw const PolylineNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Remove all polylines from map view. - Future clearPolylines() { - return _viewApi.clearPolylines(); + Future clearPolylines() async { + try { + return await _viewApi.clearPolylines(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get all circles from map view. Future> getCircles() async { - final List circles = await _viewApi.getCircles(); + try { + final List circles = await _viewApi.getCircles(); - return circles - .whereType() - .map((CircleDto circle) => circle.toCircle()) - .toList(); + return circles + .whereType() + .map((CircleDto circle) => circle.toCircle()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Add circles to map view. Future> addCircles( {required List options}) async { - // Convert options to pigeon format - final List optionsDto = - options.map((CircleOptions opt) => opt.toDto()).toList(); + try { + // Convert options to pigeon format + final List optionsDto = + options.map((CircleOptions opt) => opt.toDto()).toList(); + + // Create circle objects with new ID's + final List circlesToAdd = optionsDto + .map((CircleOptionsDto options) => + CircleDto(circleId: _createCircleId(), options: options)) + .toList(); - // Create circle objects with new ID's - final List circlesToAdd = optionsDto - .map((CircleOptionsDto options) => - CircleDto(circleId: _createCircleId(), options: options)) - .toList(); + // Add circles to map + final List circlesAdded = + await _viewApi.addCircles(circlesToAdd); - // Add circles to map - final List circlesAdded = - await _viewApi.addCircles(circlesToAdd); + if (circlesToAdd.length != circlesAdded.length) { + throw Exception('Could not add all circles to map view'); + } - if (circlesToAdd.length != circlesAdded.length) { - throw Exception('Could not add all circles to map view'); + return circlesAdded + .whereType() + .map((CircleDto circle) => circle.toCircle()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } - - return circlesAdded - .whereType() - .map((CircleDto circle) => circle.toCircle()) - .toList(); } /// Update circles on the map view. @@ -702,12 +831,8 @@ class AutoMapViewAPIImpl { .whereType() .map((CircleDto circle) => circle.toCircle()) .toList(); - } on PlatformException catch (error) { - if (error.code == 'circleNotFound') { - throw const CircleNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -717,45 +842,65 @@ class AutoMapViewAPIImpl { final List navigationViewCircles = circles.map((Circle circle) => circle.toDto()).toList(); return await _viewApi.removeCircles(navigationViewCircles); - } on PlatformException catch (error) { - if (error.code == 'circleNotFound') { - throw const CircleNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Remove all circles from map view. - Future clearCircles() { - return _viewApi.clearCircles(); + Future clearCircles() async { + try { + await _viewApi.clearCircles(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Register camera changed listeners. - Future enableOnCameraChangedEvents() { - return _viewApi.enableOnCameraChangedEvents(); + Future enableOnCameraChangedEvents() async { + try { + return await _viewApi.enableOnCameraChangedEvents(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } - Future setPadding({required EdgeInsets padding}) { - return _viewApi.setPadding(MapPaddingDto( - top: padding.top.toInt(), - left: padding.left.toInt(), - bottom: padding.bottom.toInt(), - right: padding.right.toInt())); + Future setPadding({required EdgeInsets padding}) async { + try { + await _viewApi.setPadding( + MapPaddingDto( + top: padding.top.toInt(), + left: padding.left.toInt(), + bottom: padding.bottom.toInt(), + right: padding.right.toInt(), + ), + ); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } // Gets the map padding from the map view. Future getPadding() async { - final MapPaddingDto padding = await _viewApi.getPadding(); - return EdgeInsets.only( + try { + final MapPaddingDto padding = await _viewApi.getPadding(); + return EdgeInsets.only( top: padding.top.toDouble(), left: padding.left.toDouble(), bottom: padding.bottom.toDouble(), - right: padding.right.toDouble()); + right: padding.right.toDouble(), + ); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } - Future isAutoScreenAvailable() { - return _viewApi.isAutoScreenAvailable(); + Future isAutoScreenAvailable() async { + try { + return await _viewApi.isAutoScreenAvailable(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get custom navigation auto event stream from the auto view. diff --git a/lib/src/method_channel/image_api.dart b/lib/src/method_channel/image_api.dart index ee921173..0cc650aa 100644 --- a/lib/src/method_channel/image_api.dart +++ b/lib/src/method_channel/image_api.dart @@ -43,8 +43,8 @@ class ImageRegistryAPIImpl { newImageId, bitmap, imagePixelRatio, width, height); return addedImage.toImageDescriptor(); } on PlatformException catch (error) { - if (error.code == 'imageDecodingFailed') { - throw const ImageDecodingFailedException(); + if (error.code == ImageDecodingFailedException.platformCode) { + throw ImageDecodingFailedException(exception: error); } else { rethrow; } diff --git a/lib/src/method_channel/map_view_api.dart b/lib/src/method_channel/map_view_api.dart index 71e5f0cf..08dd4060 100644 --- a/lib/src/method_channel/map_view_api.dart +++ b/lib/src/method_channel/map_view_api.dart @@ -151,31 +151,51 @@ class MapViewAPIImpl { } /// Awaits the platform view to be ready for communication. - Future awaitMapReady({required int viewId}) { - return _viewApi.awaitMapReady(viewId); + Future awaitMapReady({required int viewId}) async { + try { + await _viewApi.awaitMapReady(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get the preference for whether the my location should be enabled or disabled. - Future isMyLocationEnabled({required int viewId}) { - return _viewApi.isMyLocationEnabled(viewId); + Future isMyLocationEnabled({required int viewId}) async { + try { + return await _viewApi.isMyLocationEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enabled location in the navigation view. Future setMyLocationEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setMyLocationEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + return await _viewApi.setMyLocationEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get the map type. Future getMapType({required int viewId}) async { - final MapTypeDto mapType = await _viewApi.getMapType(viewId); - return mapType.toMapType(); + try { + final MapTypeDto mapType = await _viewApi.getMapType(viewId); + return mapType.toMapType(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Modified visible map type. Future setMapType( {required int viewId, required MapType mapType}) async { - return _viewApi.setMapType(viewId, mapType.toDto()); + try { + await _viewApi.setMapType(viewId, mapType.toDto()); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Set map style by json string. @@ -184,195 +204,282 @@ class MapViewAPIImpl { // Set the given json to the viewApi or reset the map style if // the styleJson is null. return await _viewApi.setMapStyle(viewId, styleJson ?? '[]'); - } on PlatformException catch (error) { - if (error.code == 'mapStyleError') { - throw const MapStyleException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Enables or disables the my-location button. Future setMyLocationButtonEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setMyLocationButtonEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setMyLocationButtonEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enables or disables if the my location button consumes click events. Future setConsumeMyLocationButtonClickEventsEnabled( {required int viewId, required bool enabled}) async { - return _viewApi.setConsumeMyLocationButtonClickEventsEnabled( - viewId, enabled); + try { + await _viewApi.setConsumeMyLocationButtonClickEventsEnabled( + viewId, + enabled, + ); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enables or disables the zoom gestures. Future setZoomGesturesEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setZoomGesturesEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setZoomGesturesEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enables or disables the zoom controls. Future setZoomControlsEnabled( {required int viewId, required bool enabled}) async { try { - return await _viewApi.setZoomControlsEnabled(viewId, enabled); - } on PlatformException catch (error) { - if (error.code == 'notSupported') { + await _viewApi.setZoomControlsEnabled(viewId, enabled); + } catch (e, stackTrace) { + if (e is PlatformException && e.code == 'notSupported') { throw UnsupportedError('Zoom controls are not supported on iOS.'); } else { - rethrow; + throw convertPlatformException(e, stackTrace); } } } /// Enables or disables the compass. - Future setCompassEnabled({required int viewId, required bool enabled}) { - return _viewApi.setCompassEnabled(viewId, enabled); + Future setCompassEnabled( + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setCompassEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the preference for whether rotate gestures should be enabled or disabled. Future setRotateGesturesEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setRotateGesturesEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setRotateGesturesEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the preference for whether scroll gestures should be enabled or disabled. Future setScrollGesturesEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setScrollGesturesEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setScrollGesturesEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the preference for whether scroll gestures can take place at the same time as a zoom or rotate gesture. Future setScrollGesturesDuringRotateOrZoomEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setScrollGesturesDuringRotateOrZoomEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setScrollGesturesDuringRotateOrZoomEnabled( + viewId, + enabled, + ); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the preference for whether tilt gestures should be enabled or disabled. Future setTiltGesturesEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setTiltGesturesEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setTiltGesturesEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets the preference for whether the Map Toolbar should be enabled or disabled. Future setMapToolbarEnabled( {required int viewId, required bool enabled}) async { try { - return await _viewApi.setMapToolbarEnabled(viewId, enabled); - } on PlatformException catch (error) { - if (error.code == 'notSupported') { + await _viewApi.setMapToolbarEnabled(viewId, enabled); + } catch (e, stackTrace) { + if (e is PlatformException && e.code == 'notSupported') { throw UnsupportedError('Map toolbar is not supported on iOS.'); } else { - rethrow; + throw convertPlatformException(e, stackTrace); } } } /// Turns the traffic layer on or off. - Future setTrafficEnabled({required int viewId, required bool enabled}) { - return _viewApi.setTrafficEnabled(viewId, enabled); + Future setTrafficEnabled( + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setTrafficEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get the preference for whether the my location button should be enabled or disabled. - Future isMyLocationButtonEnabled({required int viewId}) { - return _viewApi.isMyLocationButtonEnabled(viewId); + Future isMyLocationButtonEnabled({required int viewId}) async { + try { + return await _viewApi.isMyLocationButtonEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get the preference for whether the my location button consumes click events. Future isConsumeMyLocationButtonClickEventsEnabled( - {required int viewId}) { - return _viewApi.isConsumeMyLocationButtonClickEventsEnabled(viewId); + {required int viewId}) async { + try { + return await _viewApi.isConsumeMyLocationButtonClickEventsEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether zoom gestures should be enabled or disabled. - Future isZoomGesturesEnabled({required int viewId}) { - return _viewApi.isZoomGesturesEnabled(viewId); + Future isZoomGesturesEnabled({required int viewId}) async { + try { + return await _viewApi.isZoomGesturesEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether zoom controls should be enabled or disabled. Future isZoomControlsEnabled({required int viewId}) async { try { return await _viewApi.isZoomControlsEnabled(viewId); - } on PlatformException catch (error) { - if (error.code == 'notSupported') { + } catch (e, stackTrace) { + if (e is PlatformException && e.code == 'notSupported') { throw UnsupportedError('Zoom controls are not supported on iOS.'); } else { - rethrow; + throw convertPlatformException(e, stackTrace); } } } /// Gets the preference for whether compass should be enabled or disabled. - Future isCompassEnabled({required int viewId}) { - return _viewApi.isCompassEnabled(viewId); + Future isCompassEnabled({required int viewId}) async { + try { + return await _viewApi.isCompassEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether rotate gestures should be enabled or disabled. - Future isRotateGesturesEnabled({required int viewId}) { - return _viewApi.isRotateGesturesEnabled(viewId); + Future isRotateGesturesEnabled({required int viewId}) async { + try { + return await _viewApi.isRotateGesturesEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether scroll gestures should be enabled or disabled. - Future isScrollGesturesEnabled({required int viewId}) { - return _viewApi.isScrollGesturesEnabled(viewId); + Future isScrollGesturesEnabled({required int viewId}) async { + try { + return await _viewApi.isScrollGesturesEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether scroll gestures can take place at the same time as a zoom or rotate gesture. Future isScrollGesturesEnabledDuringRotateOrZoom( - {required int viewId}) { - return _viewApi.isScrollGesturesEnabledDuringRotateOrZoom(viewId); + {required int viewId}) async { + try { + return await _viewApi.isScrollGesturesEnabledDuringRotateOrZoom(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the preference for whether tilt gestures should be enabled or disabled. - Future isTiltGesturesEnabled({required int viewId}) { - return _viewApi.isTiltGesturesEnabled(viewId); + Future isTiltGesturesEnabled({required int viewId}) async { + try { + return await _viewApi.isTiltGesturesEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets whether the Map Toolbar is enabled/disabled. Future isMapToolbarEnabled({required int viewId}) async { try { return await _viewApi.isMapToolbarEnabled(viewId); - } on PlatformException catch (error) { - if (error.code == 'notSupported') { + } catch (e, stackTrace) { + if (e is PlatformException && e.code == 'notSupported') { throw UnsupportedError('Map toolbar is not supported on iOS.'); } else { - rethrow; + throw convertPlatformException(e, stackTrace); } } } /// Checks whether the map is drawing traffic data. - Future isTrafficEnabled({required int viewId}) { - return _viewApi.isTrafficEnabled(viewId); + Future isTrafficEnabled({required int viewId}) async { + try { + return await _viewApi.isTrafficEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets users current location. Future getMyLocation({required int viewId}) async { - final LatLngDto? myLocation = await _viewApi.getMyLocation(viewId); - if (myLocation == null) { - return null; + try { + final LatLngDto? myLocation = await _viewApi.getMyLocation(viewId); + if (myLocation == null) { + return null; + } + return myLocation.toLatLng(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } - return myLocation.toLatLng(); } /// Gets the current position of the camera. Future getCameraPosition({required int viewId}) async { - final CameraPositionDto position = await _viewApi.getCameraPosition( - viewId, - ); - return position.toCameraPosition(); + try { + final CameraPositionDto position = await _viewApi.getCameraPosition( + viewId, + ); + return position.toCameraPosition(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Gets the current visible area / camera bounds. Future getVisibleRegion({required int viewId}) async { - final LatLngBoundsDto bounds = await _viewApi.getVisibleRegion( - viewId, - ); - return LatLngBounds( - southwest: bounds.southwest.toLatLng(), - northeast: bounds.northeast.toLatLng(), - ); + try { + final LatLngBoundsDto bounds = await _viewApi.getVisibleRegion( + viewId, + ); + return LatLngBounds( + southwest: bounds.southwest.toLatLng(), + northeast: bounds.northeast.toLatLng(), + ); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Animates the movement of the camera. @@ -466,138 +573,238 @@ class MapViewAPIImpl { Future followMyLocation( {required int viewId, required CameraPerspective perspective, - required double? zoomLevel}) { - return _viewApi.followMyLocation(viewId, perspective.toDto(), zoomLevel); + required double? zoomLevel}) async { + try { + await _viewApi.followMyLocation(viewId, perspective.toDto(), zoomLevel); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Is the navigation trip progress bar enabled. - Future isNavigationTripProgressBarEnabled({required int viewId}) { - return _viewApi.isNavigationTripProgressBarEnabled(viewId); + Future isNavigationTripProgressBarEnabled({required int viewId}) async { + try { + return await _viewApi.isNavigationTripProgressBarEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enable navigation trip progress bar. Future setNavigationTripProgressBarEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setNavigationTripProgressBarEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setNavigationTripProgressBarEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Is the navigation header enabled. - Future isNavigationHeaderEnabled({required int viewId}) { - return _viewApi.isNavigationHeaderEnabled(viewId); + Future isNavigationHeaderEnabled({required int viewId}) async { + try { + return await _viewApi.isNavigationHeaderEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enable navigation header. Future setNavigationHeaderEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setNavigationHeaderEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + return await _viewApi.setNavigationHeaderEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Is the navigation footer enabled. - Future isNavigationFooterEnabled({required int viewId}) { - return _viewApi.isNavigationFooterEnabled(viewId); + Future isNavigationFooterEnabled({required int viewId}) async { + try { + return await _viewApi.isNavigationFooterEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enable the navigation footer. Future setNavigationFooterEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setNavigationFooterEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setNavigationFooterEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Is the recenter button enabled. - Future isRecenterButtonEnabled({required int viewId}) { - return _viewApi.isRecenterButtonEnabled(viewId); + Future isRecenterButtonEnabled({required int viewId}) async { + try { + return await _viewApi.isRecenterButtonEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enable the recenter button. Future setRecenterButtonEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setRecenterButtonEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setRecenterButtonEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Is the speed limit displayed. - Future isSpeedLimitIconEnabled({required int viewId}) { - return _viewApi.isSpeedLimitIconEnabled(viewId); + Future isSpeedLimitIconEnabled({required int viewId}) async { + try { + return await _viewApi.isSpeedLimitIconEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Should display speed limit. Future setSpeedLimitIconEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setSpeedLimitIconEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setSpeedLimitIconEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Is speedometer displayed. - Future isSpeedometerEnabled({required int viewId}) { - return _viewApi.isSpeedometerEnabled(viewId); + Future isSpeedometerEnabled({required int viewId}) async { + try { + return await _viewApi.isSpeedometerEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Should display speedometer. Future setSpeedometerEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setSpeedometerEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setSpeedometerEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Is incident cards displayed. - Future isTrafficIncidentCardsEnabled({required int viewId}) { - return _viewApi.isTrafficIncidentCardsEnabled(viewId); + Future isTrafficIncidentCardsEnabled({required int viewId}) async { + try { + return await _viewApi.isTrafficIncidentCardsEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Should display incident cards. Future setTrafficIncidentCardsEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setTrafficIncidentCardsEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setTrafficIncidentCardsEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Is the report incident button displayed. - Future isReportIncidentButtonEnabled({required int viewId}) { - return _viewApi.isReportIncidentButtonEnabled(viewId); + Future isReportIncidentButtonEnabled({required int viewId}) async { + try { + return await _viewApi.isReportIncidentButtonEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Should display the report incident button. Future setReportIncidentButtonEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setReportIncidentButtonEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setReportIncidentButtonEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Are the traffic prompts displayed. - Future isTrafficPromptsEnabled({required int viewId}) { - return _viewApi.isTrafficPromptsEnabled(viewId); + Future isTrafficPromptsEnabled({required int viewId}) async { + try { + return await _viewApi.isTrafficPromptsEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Should display the traffic prompts.. Future setTrafficPromptsEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setTrafficPromptsEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setTrafficPromptsEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Is navigation UI enabled. - Future isNavigationUIEnabled({required int viewId}) { - return _viewApi.isNavigationUIEnabled(viewId); + Future isNavigationUIEnabled({required int viewId}) async { + try { + return await _viewApi.isNavigationUIEnabled(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Enable navigation UI. Future setNavigationUIEnabled( - {required int viewId, required bool enabled}) { - return _viewApi.setNavigationUIEnabled(viewId, enabled); + {required int viewId, required bool enabled}) async { + try { + await _viewApi.setNavigationUIEnabled(viewId, enabled); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Show route overview. - Future showRouteOverview({required int viewId}) { - return _viewApi.showRouteOverview(viewId); + Future showRouteOverview({required int viewId}) async { + try { + await _viewApi.showRouteOverview(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Returns the minimum zoom level. - Future getMinZoomPreference({required int viewId}) { - return _viewApi.getMinZoomPreference(viewId); + Future getMinZoomPreference({required int viewId}) async { + try { + return await _viewApi.getMinZoomPreference(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Returns the maximum zoom level for the current camera position. - Future getMaxZoomPreference({required int viewId}) { - return _viewApi.getMaxZoomPreference(viewId); + Future getMaxZoomPreference({required int viewId}) async { + try { + return await _viewApi.getMaxZoomPreference(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Removes any previously specified upper and lower zoom bounds. - Future resetMinMaxZoomPreference({required int viewId}) { - return _viewApi.resetMinMaxZoomPreference(viewId); + Future resetMinMaxZoomPreference({required int viewId}) async { + try { + await _viewApi.resetMinMaxZoomPreference(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Sets a preferred lower bound for the camera zoom. @@ -605,12 +812,8 @@ class MapViewAPIImpl { {required int viewId, required double minZoomPreference}) async { try { return await _viewApi.setMinZoomPreference(viewId, minZoomPreference); - } on PlatformException catch (error) { - if (error.code == 'minZoomGreaterThanMaxZoom') { - throw const MinZoomRangeException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -619,12 +822,8 @@ class MapViewAPIImpl { {required int viewId, required double maxZoomPreference}) async { try { return await _viewApi.setMaxZoomPreference(viewId, maxZoomPreference); - } on PlatformException catch (error) { - if (error.code == 'maxZoomLessThanMinZoom') { - throw const MaxZoomRangeException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -637,38 +836,46 @@ class MapViewAPIImpl { /// Get all markers from map view. Future> getMarkers({required int viewId}) async { - final List markers = await _viewApi.getMarkers(viewId); - return markers - .whereType() - .map((MarkerDto e) => e.toMarker()) - .toList(); + try { + final List markers = await _viewApi.getMarkers(viewId); + return markers + .whereType() + .map((MarkerDto e) => e.toMarker()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Add markers to map view. Future> addMarkers( {required int viewId, required List markerOptions}) async { - // Convert options to pigeon format - final List options = - markerOptions.map((MarkerOptions opt) => opt.toDto()).toList(); + try { + // Convert options to pigeon format + final List options = + markerOptions.map((MarkerOptions opt) => opt.toDto()).toList(); + + // Create marker objects with new ID's + final List markersToAdd = options + .map((MarkerOptionsDto options) => + MarkerDto(markerId: _createMarkerId(), options: options)) + .toList(); - // Create marker objects with new ID's - final List markersToAdd = options - .map((MarkerOptionsDto options) => - MarkerDto(markerId: _createMarkerId(), options: options)) - .toList(); + // Add markers to map + final List markersAdded = + await _viewApi.addMarkers(viewId, markersToAdd); - // Add markers to map - final List markersAdded = - await _viewApi.addMarkers(viewId, markersToAdd); + if (markersToAdd.length != markersAdded.length) { + throw Exception('Could not add all markers to map view'); + } - if (markersToAdd.length != markersAdded.length) { - throw Exception('Could not add all markers to map view'); + return markersAdded + .whereType() + .map((MarkerDto markerDto) => markerDto.toMarker()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } - - return markersAdded - .whereType() - .map((MarkerDto markerDto) => markerDto.toMarker()) - .toList(); } /// Update markers on the map view. @@ -683,12 +890,8 @@ class MapViewAPIImpl { .whereType() .map((MarkerDto markerDto) => markerDto.toMarker()) .toList(); - } on PlatformException catch (error) { - if (error.code == 'markerNotFound') { - throw const MarkerNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -699,61 +902,73 @@ class MapViewAPIImpl { final List markerDtos = markers.map((Marker marker) => marker.toDto()).toList(); return await _viewApi.removeMarkers(viewId, markerDtos); - } on PlatformException catch (error) { - if (error.code == 'markerNotFound') { - throw const MarkerNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Remove all markers from map view. - Future clearMarkers({required int viewId}) { - return _viewApi.clearMarkers(viewId); + Future clearMarkers({required int viewId}) async { + try { + await _viewApi.clearMarkers(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Removes all markers, polylines, polygons, overlays, etc from the map. - Future clear({required int viewId}) { - return _viewApi.clear(viewId); + Future clear({required int viewId}) async { + try { + await _viewApi.clear(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get all polygons from map view. Future> getPolygons({required int viewId}) async { - final List polygons = await _viewApi.getPolygons(viewId); + try { + final List polygons = await _viewApi.getPolygons(viewId); - return polygons - .whereType() - .map((PolygonDto polygon) => polygon.toPolygon()) - .toList(); + return polygons + .whereType() + .map((PolygonDto polygon) => polygon.toPolygon()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Add polygons to map view. Future> addPolygons( {required int viewId, required List polygonOptions}) async { - // Convert options to pigeon format - final List options = - polygonOptions.map((PolygonOptions opt) => opt.toDto()).toList(); + try { + // Convert options to pigeon format + final List options = + polygonOptions.map((PolygonOptions opt) => opt.toDto()).toList(); + + // Create polygon objects with new ID's + final List polygonsToAdd = options + .map((PolygonOptionsDto options) => + PolygonDto(polygonId: _createPolygonId(), options: options)) + .toList(); - // Create polygon objects with new ID's - final List polygonsToAdd = options - .map((PolygonOptionsDto options) => - PolygonDto(polygonId: _createPolygonId(), options: options)) - .toList(); + // Add polygons to map + final List polygonsAdded = + await _viewApi.addPolygons(viewId, polygonsToAdd); - // Add polygons to map - final List polygonsAdded = - await _viewApi.addPolygons(viewId, polygonsToAdd); + if (polygonsToAdd.length != polygonsAdded.length) { + throw Exception('Could not add all polygons to map view'); + } - if (polygonsToAdd.length != polygonsAdded.length) { - throw Exception('Could not add all polygons to map view'); + return polygonsAdded + .whereType() + .map((PolygonDto polygon) => polygon.toPolygon()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } - - return polygonsAdded - .whereType() - .map((PolygonDto polygon) => polygon.toPolygon()) - .toList(); } /// Update polygons on the map view. @@ -768,12 +983,8 @@ class MapViewAPIImpl { .whereType() .map((PolygonDto polygon) => polygon.toPolygon()) .toList(); - } on PlatformException catch (error) { - if (error.code == 'polygonNotFound') { - throw const PolygonNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -784,56 +995,64 @@ class MapViewAPIImpl { final List navigationViewPolygons = polygons.map((Polygon polygon) => polygon.toDto()).toList(); return await _viewApi.removePolygons(viewId, navigationViewPolygons); - } on PlatformException catch (error) { - if (error.code == 'polygonNotFound') { - throw const PolygonNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Remove all polygons from map view. - Future clearPolygons({required int viewId}) { - return _viewApi.clearPolygons(viewId); + Future clearPolygons({required int viewId}) async { + try { + await _viewApi.clearPolygons(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get all polylines from map view. Future> getPolylines({required int viewId}) async { - final List polylines = await _viewApi.getPolylines(viewId); + try { + final List polylines = await _viewApi.getPolylines(viewId); - return polylines - .whereType() - .map((PolylineDto polyline) => polyline.toPolyline()) - .toList(); + return polylines + .whereType() + .map((PolylineDto polyline) => polyline.toPolyline()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Add polylines to map view. Future> addPolylines( {required int viewId, required List polylineOptions}) async { - // Convert options to pigeon format - final List options = - polylineOptions.map((PolylineOptions opt) => opt.toDto()).toList(); + try { + // Convert options to pigeon format + final List options = + polylineOptions.map((PolylineOptions opt) => opt.toDto()).toList(); + + // Create polyline objects with new ID's + final List polylinesToAdd = options + .map((PolylineOptionsDto options) => + PolylineDto(polylineId: _createPolylineId(), options: options)) + .toList(); - // Create polyline objects with new ID's - final List polylinesToAdd = options - .map((PolylineOptionsDto options) => - PolylineDto(polylineId: _createPolylineId(), options: options)) - .toList(); + // Add polylines to map + final List polylinesAdded = + await _viewApi.addPolylines(viewId, polylinesToAdd); - // Add polylines to map - final List polylinesAdded = - await _viewApi.addPolylines(viewId, polylinesToAdd); + if (polylinesToAdd.length != polylinesAdded.length) { + throw Exception('Could not add all polylines to map view'); + } - if (polylinesToAdd.length != polylinesAdded.length) { - throw Exception('Could not add all polylines to map view'); + return polylinesAdded + .whereType() + .map((PolylineDto polyline) => polyline.toPolyline()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } - - return polylinesAdded - .whereType() - .map((PolylineDto polyline) => polyline.toPolyline()) - .toList(); } /// Update polylines on the map view. @@ -849,12 +1068,8 @@ class MapViewAPIImpl { .whereType() .map((PolylineDto polyline) => polyline.toPolyline()) .toList(); - } on PlatformException catch (error) { - if (error.code == 'polylineNotFound') { - throw const PolylineNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -866,55 +1081,63 @@ class MapViewAPIImpl { .map((Polyline polyline) => polyline.toNavigationViewPolyline()) .toList(); return await _viewApi.removePolylines(viewId, navigationViewPolylines); - } on PlatformException catch (error) { - if (error.code == 'polylineNotFound') { - throw const PolylineNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Remove all polylines from map view. - Future clearPolylines({required int viewId}) { - return _viewApi.clearPolylines(viewId); + Future clearPolylines({required int viewId}) async { + try { + await _viewApi.clearPolylines(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Get all circles from map view. Future> getCircles({required int viewId}) async { - final List circles = await _viewApi.getCircles(viewId); + try { + final List circles = await _viewApi.getCircles(viewId); - return circles - .whereType() - .map((CircleDto circle) => circle.toCircle()) - .toList(); + return circles + .whereType() + .map((CircleDto circle) => circle.toCircle()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Add circles to map view. Future> addCircles( {required int viewId, required List options}) async { - // Convert options to pigeon format - final List optionsDto = - options.map((CircleOptions opt) => opt.toDto()).toList(); + try { + // Convert options to pigeon format + final List optionsDto = + options.map((CircleOptions opt) => opt.toDto()).toList(); + + // Create circle objects with new ID's + final List circlesToAdd = optionsDto + .map((CircleOptionsDto options) => + CircleDto(circleId: _createCircleId(), options: options)) + .toList(); - // Create circle objects with new ID's - final List circlesToAdd = optionsDto - .map((CircleOptionsDto options) => - CircleDto(circleId: _createCircleId(), options: options)) - .toList(); + // Add circles to map + final List circlesAdded = + await _viewApi.addCircles(viewId, circlesToAdd); - // Add circles to map - final List circlesAdded = - await _viewApi.addCircles(viewId, circlesToAdd); + if (circlesToAdd.length != circlesAdded.length) { + throw Exception('Could not add all circles to map view'); + } - if (circlesToAdd.length != circlesAdded.length) { - throw Exception('Could not add all circles to map view'); + return circlesAdded + .whereType() + .map((CircleDto circle) => circle.toCircle()) + .toList(); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } - - return circlesAdded - .whereType() - .map((CircleDto circle) => circle.toCircle()) - .toList(); } /// Update circles on the map view. @@ -930,12 +1153,8 @@ class MapViewAPIImpl { .whereType() .map((CircleDto circle) => circle.toCircle()) .toList(); - } on PlatformException catch (error) { - if (error.code == 'circleNotFound') { - throw const CircleNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } @@ -946,43 +1165,59 @@ class MapViewAPIImpl { final List navigationViewCircles = circles.map((Circle circle) => circle.toDto()).toList(); return await _viewApi.removeCircles(viewId, navigationViewCircles); - } on PlatformException catch (error) { - if (error.code == 'circleNotFound') { - throw const CircleNotFoundException(); - } else { - rethrow; - } + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); } } /// Remove all circles from map view. - Future clearCircles({required int viewId}) { - return _viewApi.clearCircles(viewId); + Future clearCircles({required int viewId}) async { + try { + await _viewApi.clearCircles(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } /// Register camera changed listeners. - Future enableOnCameraChangedEvents({required int viewId}) { - return _viewApi.enableOnCameraChangedEvents(viewId); + Future enableOnCameraChangedEvents({required int viewId}) async { + try { + await _viewApi.enableOnCameraChangedEvents(viewId); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } - Future setPadding({required int viewId, required EdgeInsets padding}) { - return _viewApi.setPadding( + Future setPadding( + {required int viewId, required EdgeInsets padding}) async { + try { + await _viewApi.setPadding( viewId, MapPaddingDto( - top: padding.top.toInt(), - left: padding.left.toInt(), - bottom: padding.bottom.toInt(), - right: padding.right.toInt())); + top: padding.top.toInt(), + left: padding.left.toInt(), + bottom: padding.bottom.toInt(), + right: padding.right.toInt(), + ), + ); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } // Gets the map padding from the map view. Future getPadding({required int viewId}) async { - final MapPaddingDto padding = await _viewApi.getPadding(viewId); - return EdgeInsets.only( + try { + final MapPaddingDto padding = await _viewApi.getPadding(viewId); + return EdgeInsets.only( top: padding.top.toDouble(), left: padding.left.toDouble(), bottom: padding.bottom.toDouble(), - right: padding.right.toDouble()); + right: padding.right.toDouble(), + ); + } catch (e, stackTrace) { + throw convertPlatformException(e, stackTrace); + } } Stream getMapClickEventStream({required int viewId}) {