Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit e0ff184

Browse files
committed
Add tests for google_maps_controller.dart
* Add a few changes to the controller to allow for overrides when testing. * Make some conversion functions more null-resilient. * Fix some inconsistencies in some conversion function naming.
1 parent 0a2d3a4 commit e0ff184

File tree

6 files changed

+669
-55
lines changed

6 files changed

+669
-55
lines changed

packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart

Lines changed: 79 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ final _nullLatLngBounds = LatLngBounds(
66
southwest: _nullLatLng,
77
);
88

9+
// Defaults taken from the Google Maps Platform SDK documentation.
10+
final _defaultStrokeColor = Colors.black.value;
11+
final _defaultFillColor = Colors.transparent.value;
12+
913
// Indices in the plugin side don't match with the ones
1014
// in the gmaps lib. This translates from plugin -> gmaps.
1115
final _mapTypeToMapTypeId = {
@@ -75,7 +79,10 @@ gmaps.MapOptions _rawOptionsToGmapsOptions(Map<String, dynamic> rawOptions) {
7579
return options;
7680
}
7781

78-
gmaps.MapOptions _setInitialPosition(Map<String, dynamic> rawOptions, gmaps.MapOptions options) {
82+
gmaps.MapOptions _applyInitialPosition(
83+
Map<String, dynamic> rawOptions,
84+
gmaps.MapOptions options,
85+
) {
7986
// Adjust the initial position, if passed...
8087
Map<String, dynamic> initialPosition = rawOptions['initialCameraPosition'];
8188
if (initialPosition != null) {
@@ -198,11 +205,13 @@ List<gmaps.MapTypeStyle> _mapStyles(String mapStyleJson) {
198205
return styles;
199206
}
200207

201-
gmaps.LatLng _latlngToGmLatlng(LatLng latLng) {
208+
gmaps.LatLng _latLngToGmLatLng(LatLng latLng) {
209+
if (latLng == null) return null;
202210
return gmaps.LatLng(latLng.latitude, latLng.longitude);
203211
}
204212

205-
LatLng _gmLatlngToLatlng(gmaps.LatLng latLng) {
213+
LatLng _gmLatLngToLatLng(gmaps.LatLng latLng) {
214+
if (latLng == null) return _nullLatLng;
206215
return LatLng(latLng.lat, latLng.lng);
207216
}
208217

@@ -212,41 +221,53 @@ LatLngBounds _gmLatLngBoundsTolatLngBounds(gmaps.LatLngBounds latLngBounds) {
212221
}
213222

214223
return LatLngBounds(
215-
southwest: _gmLatlngToLatlng(latLngBounds.southWest),
216-
northeast: _gmLatlngToLatlng(latLngBounds.northEast),
224+
southwest: _gmLatLngToLatLng(latLngBounds.southWest),
225+
northeast: _gmLatLngToLatLng(latLngBounds.northEast),
217226
);
218227
}
219228

220229
CameraPosition _gmViewportToCameraPosition(gmaps.GMap map) {
221230
return CameraPosition(
222-
target: _gmLatlngToLatlng(map.center),
231+
target: _gmLatLngToLatLng(map.center),
223232
bearing: map.heading ?? 0,
224-
tilt: map.tilt,
225-
zoom: map.zoom.toDouble(),
233+
tilt: map.tilt ?? 0,
234+
zoom: map.zoom?.toDouble() ?? 10,
226235
);
227236
}
228237

229238
Set<Marker> _rawOptionsToInitialMarkers(Map<String, dynamic> rawOptions) {
230239
final List<Map<String, dynamic>> list = rawOptions['markersToAdd'];
231240
Set<Marker> markers = {};
232241
markers.addAll(list?.map((rawMarker) {
233-
Offset offset =
234-
Offset((rawMarker['anchor'][0]), (rawMarker['anchor'][1]));
242+
Offset offset;
243+
LatLng position;
244+
InfoWindow infoWindow;
245+
if (rawMarker['anchor'] != null) {
246+
offset = Offset((rawMarker['anchor'][0]), (rawMarker['anchor'][1]));
247+
}
248+
if (rawMarker['position'] != null) {
249+
position = LatLng.fromJson(rawMarker['position']);
250+
}
251+
if (rawMarker['infoWindow'] != null || rawMarker['snippet'] != null) {
252+
String title = rawMarker['infoWindow'] != null
253+
? rawMarker['infoWindow']['title']
254+
: null;
255+
infoWindow = InfoWindow(
256+
title: title ?? '',
257+
snippet: rawMarker['snippet'] ?? '',
258+
);
259+
}
235260
return Marker(
236261
markerId: MarkerId(rawMarker['markerId']),
237262
alpha: rawMarker['alpha'],
238263
anchor: offset,
239264
consumeTapEvents: rawMarker['consumeTapEvents'],
240265
draggable: rawMarker['draggable'],
241266
flat: rawMarker['flat'],
242-
icon: BitmapDescriptor
243-
.defaultMarker, // TODO: Doesn't this support custom icons?
244-
infoWindow: InfoWindow(
245-
title: rawMarker['infoWindow']['title'] ?? '',
246-
snippet: rawMarker['snippet'],
247-
anchor: offset, // TODO: Check this value. Is it correct?
248-
),
249-
position: LatLng.fromJson(rawMarker['position']),
267+
// TODO: Doesn't this support custom icons?
268+
icon: BitmapDescriptor.defaultMarker,
269+
infoWindow: infoWindow,
270+
position: position ?? _nullLatLng,
250271
rotation: rawMarker['rotation'],
251272
visible: rawMarker['visible'],
252273
zIndex: rawMarker['zIndex'],
@@ -260,13 +281,17 @@ Set<Circle> _rawOptionsToInitialCircles(Map<String, dynamic> rawOptions) {
260281
final List<Map<String, dynamic>> list = rawOptions['circlesToAdd'];
261282
Set<Circle> circles = {};
262283
circles.addAll(list?.map((rawCircle) {
284+
LatLng center;
285+
if (rawCircle['center'] != null) {
286+
center = LatLng.fromJson(rawCircle['center']);
287+
}
263288
return Circle(
264289
circleId: CircleId(rawCircle['circleId']),
265290
consumeTapEvents: rawCircle['consumeTapEvents'],
266-
fillColor: Color(rawCircle['fillColor']),
267-
center: LatLng.fromJson(rawCircle['center']),
291+
fillColor: Color(rawCircle['fillColor'] ?? _defaultFillColor),
292+
center: center ?? _nullLatLng,
268293
radius: rawCircle['radius'],
269-
strokeColor: Color(rawCircle['strokeColor']),
294+
strokeColor: Color(rawCircle['strokeColor'] ?? _defaultStrokeColor),
270295
strokeWidth: rawCircle['strokeWidth'],
271296
visible: rawCircle['visible'],
272297
zIndex: rawCircle['zIndex'],
@@ -284,7 +309,7 @@ Set<Polyline> _rawOptionsToInitialPolylines(Map<String, dynamic> rawOptions) {
284309
return Polyline(
285310
polylineId: PolylineId(rawPolyline['polylineId']),
286311
consumeTapEvents: rawPolyline['consumeTapEvents'],
287-
color: Color(rawPolyline['color']),
312+
color: Color(rawPolyline['color'] ?? _defaultStrokeColor),
288313
geodesic: rawPolyline['geodesic'],
289314
visible: rawPolyline['visible'],
290315
zIndex: rawPolyline['zIndex'],
@@ -306,9 +331,9 @@ Set<Polygon> _rawOptionsToInitialPolygons(Map<String, dynamic> rawOptions) {
306331
return Polygon(
307332
polygonId: PolygonId(rawPolygon['polygonId']),
308333
consumeTapEvents: rawPolygon['consumeTapEvents'],
309-
fillColor: Color(rawPolygon['fillColor']),
334+
fillColor: Color(rawPolygon['fillColor'] ?? _defaultFillColor),
310335
geodesic: rawPolygon['geodesic'],
311-
strokeColor: Color(rawPolygon['strokeColor']),
336+
strokeColor: Color(rawPolygon['strokeColor'] ?? _defaultStrokeColor),
312337
strokeWidth: rawPolygon['strokeWidth'],
313338
visible: rawPolygon['visible'],
314339
zIndex: rawPolygon['zIndex'],
@@ -403,7 +428,7 @@ gmaps.PolygonOptions _polygonOptionsFromPolygon(
403428
gmaps.GMap googleMap, Polygon polygon) {
404429
List<gmaps.LatLng> paths = [];
405430
polygon.points.forEach((point) {
406-
paths.add(_latlngToGmLatlng(point));
431+
paths.add(_latLngToGmLatLng(point));
407432
});
408433
return gmaps.PolygonOptions()
409434
..paths = paths
@@ -421,7 +446,7 @@ gmaps.PolylineOptions _polylineOptionsFromPolyline(
421446
gmaps.GMap googleMap, Polyline polyline) {
422447
List<gmaps.LatLng> paths = [];
423448
polyline.points.forEach((point) {
424-
paths.add(_latlngToGmLatlng(point));
449+
paths.add(_latLngToGmLatLng(point));
425450
});
426451

427452
return gmaps.PolylineOptions()
@@ -467,13 +492,22 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) {
467492
map.panBy(json[1], json[2]);
468493
break;
469494
case 'zoomBy':
495+
gmaps.LatLng focusLatLng;
470496
double zoomDelta = json[1] ?? 0;
471497
// Web only supports integer changes...
472498
int newZoomDelta = zoomDelta < 0 ? zoomDelta.floor() : zoomDelta.ceil();
473-
map.zoom = map.zoom + newZoomDelta;
474499
if (json.length == 3) {
475500
// With focus
476-
map.panTo(gmaps.LatLng(json[2][0], json[2][1]));
501+
try {
502+
focusLatLng = _pixelToLatLng(map, json[2][0], json[2][1]);
503+
} catch (e) {
504+
// https://github.com/a14n/dart-google-maps/issues/87
505+
// print('Error computing new focus LatLng. JS Error: ' + e.toString());
506+
}
507+
}
508+
map.zoom = map.zoom + newZoomDelta;
509+
if (focusLatLng != null) {
510+
map.panTo(focusLatLng);
477511
}
478512
break;
479513
case 'zoomIn':
@@ -489,3 +523,20 @@ void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) {
489523
throw UnimplementedError('Unimplemented CameraMove: ${json[0]}.');
490524
}
491525
}
526+
527+
// original JS by: Byron Singh (https://stackoverflow.com/a/30541162)
528+
gmaps.LatLng _pixelToLatLng(gmaps.GMap map, int x, int y) {
529+
final ne = map.bounds.northEast;
530+
final sw = map.bounds.southWest;
531+
final projection = map.projection;
532+
533+
final topRight = projection.fromLatLngToPoint(ne);
534+
final bottomLeft = projection.fromLatLngToPoint(sw);
535+
536+
final scale = 1 << map.zoom; // 2 ^ zoom
537+
538+
final point =
539+
gmaps.Point((x / scale) + bottomLeft.x, (y / scale) + topRight.y);
540+
541+
return projection.fromPointToLatLng(point);
542+
}

0 commit comments

Comments
 (0)