diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index df4d9162be7e..881f21be3df9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.5.28 + +* Support projection method pointForMeters to get the distance in meters to content size + from the specified LatLng in the map. + ## 0.5.27+3 * iOS: Update the gesture recognizer blocking policy to "WaitUntilTouchesEnded", which fixes the camera idle callback not triggered issue. diff --git a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart index 9620d6067c65..72965f5ac4e3 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart +++ b/packages/google_maps_flutter/google_maps_flutter/example/test_driver/google_maps_e2e.dart @@ -4,6 +4,7 @@ import 'dart:async'; import 'dart:io'; +import 'dart:math'; import 'dart:typed_data'; import 'package:e2e/e2e.dart'; @@ -832,6 +833,39 @@ void main() { expect(topLeft, const ScreenCoordinate(x: 0, y: 0)); }); + testWidgets('testGetPointsForMeters', (WidgetTester tester) async { + final Key key = GlobalKey(); + final Completer controllerCompleter = + Completer(); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: GoogleMap( + key: key, + initialCameraPosition: _kInitialCameraPosition, + onMapCreated: (GoogleMapController controller) { + controllerCompleter.complete(controller); + }, + ), + )); + final GoogleMapController controller = await controllerCompleter.future; + + await tester.pumpAndSettle(); + // TODO(cyanglaz): Remove this after we added `mapRendered` callback, and `mapControllerCompleter.complete(controller)` above should happen + // in `mapRendered`. + // https://github.com/flutter/flutter/issues/54758 + await Future.delayed(Duration(seconds: 1)); + + final double points = + await controller.getPointsForMeters(1, _kInitialCameraPosition.target); + // Formula is from Chris Broadfoot's comment : https://groups.google.com/d/msg/google-maps-js-api-v3/hDRO4oHVSeM/osOYQYXg2oUJ + final double meters_per_pixel = 156543.03392 * + cos(_kInitialCameraPosition.target.latitude * pi / 180) / + pow(2, _kInitialZoomLevel); + final double points_per_meter = 1 / meters_per_pixel; + expect(points, moreOrLessEquals(points_per_meter, epsilon: 1e-5)); + }, skip: !Platform.isIOS); + testWidgets('testResizeWidget', (WidgetTester tester) async { final Completer controllerCompleter = Completer(); diff --git a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m index 321ddd318536..5acb9ad2f81b 100644 --- a/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m +++ b/packages/google_maps_flutter/google_maps_flutter/ios/Classes/GoogleMapController.m @@ -192,6 +192,18 @@ - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { message:@"getLatLng called prior to map initialization" details:nil]); } + } else if ([call.method isEqualToString:@"projection#getPointsForMeters"]) { + if (_mapView != nil) { + CLLocationDistance meter = ToDouble(call.arguments[@"meter"]); + CLLocationCoordinate2D location = + [FLTGoogleMapJsonConversions toLocation:call.arguments[@"location"]]; + CGFloat points = [_mapView.projection pointsForMeters:meter atCoordinate:location]; + result(@(points)); + } else { + result([FlutterError errorWithCode:@"GoogleMap uninitialized" + message:@"getPointsForMeters called prior to map initialization" + details:nil]); + } } else if ([call.method isEqualToString:@"map#waitForMap"]) { result(nil); } else if ([call.method isEqualToString:@"map#takeSnapshot"]) { diff --git a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart index f5ee180ab1fd..732eea186fe1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart +++ b/packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart @@ -254,6 +254,12 @@ class GoogleMapController { return _googleMapsFlutterPlatform.getZoomLevel(mapId: mapId); } + /// Converts a distance in meters to content size. + Future getPointsForMeters(double meters, LatLng latLng) { + return _googleMapsFlutterPlatform.getPointsForMeters(meters, latLng, + mapId: mapId); + } + /// Returns the image bytes of the map Future takeSnapshot() { return _googleMapsFlutterPlatform.takeSnapshot(mapId: mapId); diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index cf4b869c1a96..37ef54db0a80 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,13 +1,14 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 0.5.27+3 +version: 0.5.28 dependencies: flutter: sdk: flutter flutter_plugin_android_lifecycle: ^1.0.0 - google_maps_flutter_platform_interface: ^1.0.1 + google_maps_flutter_platform_interface: + path: ../google_maps_flutter_platform_interface dev_dependencies: flutter_test: diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index eca5c914a603..ba44556d8d9f 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.1.0 + +* Support projection method pointForMeters, to get the distance in meters to content size from the specified LatLng in the map for iOS. + ## 1.0.2 * Update lower bound of dart dependency to 2.1.0. diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart index edbc51ab5afd..db0cd38d1c1b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart @@ -437,6 +437,14 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform { return channel(mapId).invokeMethod('map#getZoomLevel'); } + /// Converts a distance in meters to content size. + Future getPointsForMeters(double meters, LatLng latLng, + {@required int mapId}) { + assert(meters != null && latLng != null); + return channel(mapId).invokeMethod('projection#getPointsForMeters', + {"meter": meters, "location": latLng.toJson()}); + } + /// Returns the image bytes of the map @override Future takeSnapshot({ diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart index b89d3420c68e..f2c7c07b62cb 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart @@ -239,6 +239,12 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface { throw UnimplementedError('getZoomLevel() has not been implemented.'); } + /// Converts a distance in meters to content size. + Future getPointsForMeters(double meters, LatLng latLng, + {@required int mapId}) { + throw UnimplementedError('getPointsForMeters() has not been implemented.'); + } + /// Returns the image bytes of the map Future takeSnapshot({ @required int mapId, diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index b28b7f47652d..920701f6f409 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -3,7 +3,7 @@ description: A common platform interface for the google_maps_flutter plugin. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter_platform_interface # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 1.0.2 +version: 1.1.0 dependencies: flutter: