Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.2.0

* Make this plugin compatible with the rest of null-safe plugins.
* Noop tile overlays methods, so they don't crash on web.

**NOTE**: This plugin is **not** null-safe yet!

## 0.1.2

* Update min Flutter SDK to 1.20.0.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ final _nullLatLngBounds = LatLngBounds(
);

// Defaults taken from the Google Maps Platform SDK documentation.
final _defaultStrokeColor = Colors.black.value;
final _defaultFillColor = Colors.transparent.value;
final _defaultCssColor = '#000000';
final _defaultCssOpacity = 0.0;

Expand Down Expand Up @@ -59,41 +57,39 @@ double _getCssOpacity(Color color) {
// buildingsEnabled seems to not have an equivalent in web
// padding seems to behave differently in web than mobile. You can't move UI elements in web.
gmaps.MapOptions _rawOptionsToGmapsOptions(Map<String, dynamic> rawOptions) {
Map<String, dynamic> optionsUpdate = rawOptions['options'] ?? {};

gmaps.MapOptions options = gmaps.MapOptions();

if (_mapTypeToMapTypeId.containsKey(optionsUpdate['mapType'])) {
options.mapTypeId = _mapTypeToMapTypeId[optionsUpdate['mapType']];
if (_mapTypeToMapTypeId.containsKey(rawOptions['mapType'])) {
options.mapTypeId = _mapTypeToMapTypeId[rawOptions['mapType']];
}

if (optionsUpdate['minMaxZoomPreference'] != null) {
if (rawOptions['minMaxZoomPreference'] != null) {
options
..minZoom = optionsUpdate['minMaxZoomPreference'][0]
..maxZoom = optionsUpdate['minMaxZoomPreference'][1];
..minZoom = rawOptions['minMaxZoomPreference'][0]
..maxZoom = rawOptions['minMaxZoomPreference'][1];
}

if (optionsUpdate['cameraTargetBounds'] != null) {
if (rawOptions['cameraTargetBounds'] != null) {
// Needs gmaps.MapOptions.restriction and gmaps.MapRestriction
// see: https://developers.google.com/maps/documentation/javascript/reference/map#MapOptions.restriction
}

if (optionsUpdate['zoomControlsEnabled'] != null) {
options.zoomControl = optionsUpdate['zoomControlsEnabled'];
if (rawOptions['zoomControlsEnabled'] != null) {
options.zoomControl = rawOptions['zoomControlsEnabled'];
}

if (optionsUpdate['styles'] != null) {
options.styles = optionsUpdate['styles'];
if (rawOptions['styles'] != null) {
options.styles = rawOptions['styles'];
}

if (optionsUpdate['scrollGesturesEnabled'] == false ||
optionsUpdate['zoomGesturesEnabled'] == false) {
if (rawOptions['scrollGesturesEnabled'] == false ||
rawOptions['zoomGesturesEnabled'] == false) {
options.gestureHandling = 'none';
} else {
options.gestureHandling = 'auto';
}

// These don't have any optionUpdate entry, but they seem to be off in the native maps.
// These don't have any rawOptions entry, but they seem to be off in the native maps.
options.mapTypeControl = false;
options.fullscreenControl = false;
options.streetViewControl = false;
Expand All @@ -102,26 +98,21 @@ gmaps.MapOptions _rawOptionsToGmapsOptions(Map<String, dynamic> rawOptions) {
}

gmaps.MapOptions _applyInitialPosition(
Map<String, dynamic> rawOptions,
CameraPosition initialPosition,
gmaps.MapOptions options,
) {
// Adjust the initial position, if passed...
Map<String, dynamic> initialPosition = rawOptions['initialCameraPosition'];
if (initialPosition != null) {
final position = CameraPosition.fromMap(initialPosition);
options.zoom = position.zoom;
options.center =
gmaps.LatLng(position.target.latitude, position.target.longitude);
options.zoom = initialPosition.zoom;
options.center = gmaps.LatLng(
initialPosition.target.latitude, initialPosition.target.longitude);
}
return options;
}

// Extracts the status of the traffic layer from the rawOptions map.
bool _isTrafficLayerEnabled(Map<String, dynamic> rawOptions) {
if (rawOptions['options'] == null) {
return false;
}
return rawOptions['options']['trafficEnabled'] ?? false;
return rawOptions['trafficEnabled'] ?? false;
}

// Coverts the incoming JSON object into a List of MapTypeStyler objects.
Expand Down Expand Up @@ -257,126 +248,6 @@ CameraPosition _gmViewportToCameraPosition(gmaps.GMap map) {
);
}

Set<Marker> _rawOptionsToInitialMarkers(Map<String, dynamic> rawOptions) {
final List<Map<String, dynamic>> list = rawOptions['markersToAdd'];
Set<Marker> markers = {};
markers.addAll(list?.map((rawMarker) {
Offset offset;
LatLng position;
InfoWindow infoWindow;
BitmapDescriptor icon;
if (rawMarker['anchor'] != null) {
offset = Offset((rawMarker['anchor'][0]), (rawMarker['anchor'][1]));
}
if (rawMarker['position'] != null) {
position = LatLng.fromJson(rawMarker['position']);
}
if (rawMarker['infoWindow'] != null) {
final String title = rawMarker['infoWindow']['title'];
final String snippet = rawMarker['infoWindow']['snippet'];
if (title != null || snippet != null) {
infoWindow = InfoWindow(
title: title ?? '',
snippet: snippet ?? '',
);
}
}
if (rawMarker['icon'] != null) {
icon = BitmapDescriptor.fromJson(rawMarker['icon']);
}
return Marker(
markerId: MarkerId(rawMarker['markerId']),
alpha: rawMarker['alpha'],
anchor: offset,
consumeTapEvents: rawMarker['consumeTapEvents'],
draggable: rawMarker['draggable'],
flat: rawMarker['flat'],
icon: icon,
infoWindow: infoWindow,
position: position ?? _nullLatLng,
rotation: rawMarker['rotation'],
visible: rawMarker['visible'],
zIndex: rawMarker['zIndex'],
);
}) ??
[]);
return markers;
}

Set<Circle> _rawOptionsToInitialCircles(Map<String, dynamic> rawOptions) {
final List<Map<String, dynamic>> list = rawOptions['circlesToAdd'];
Set<Circle> circles = {};
circles.addAll(list?.map((rawCircle) {
LatLng center;
if (rawCircle['center'] != null) {
center = LatLng.fromJson(rawCircle['center']);
}
return Circle(
circleId: CircleId(rawCircle['circleId']),
consumeTapEvents: rawCircle['consumeTapEvents'],
fillColor: Color(rawCircle['fillColor'] ?? _defaultFillColor),
center: center ?? _nullLatLng,
radius: rawCircle['radius'],
strokeColor: Color(rawCircle['strokeColor'] ?? _defaultStrokeColor),
strokeWidth: rawCircle['strokeWidth'],
visible: rawCircle['visible'],
zIndex: rawCircle['zIndex'],
);
}) ??
[]);
return circles;
}

// Unsupported on the web: endCap, jointType, patterns and startCap.
Set<Polyline> _rawOptionsToInitialPolylines(Map<String, dynamic> rawOptions) {
final List<Map<String, dynamic>> list = rawOptions['polylinesToAdd'];
Set<Polyline> polylines = {};
polylines.addAll(list?.map((rawPolyline) {
return Polyline(
polylineId: PolylineId(rawPolyline['polylineId']),
consumeTapEvents: rawPolyline['consumeTapEvents'],
color: Color(rawPolyline['color'] ?? _defaultStrokeColor),
geodesic: rawPolyline['geodesic'],
visible: rawPolyline['visible'],
zIndex: rawPolyline['zIndex'],
width: rawPolyline['width'],
points: rawPolyline['points']
?.map<LatLng>((rawPoint) => LatLng.fromJson(rawPoint))
?.toList(),
);
}) ??
[]);
return polylines;
}

Set<Polygon> _rawOptionsToInitialPolygons(Map<String, dynamic> rawOptions) {
final List<Map<String, dynamic>> list = rawOptions['polygonsToAdd'];
Set<Polygon> polygons = {};

polygons.addAll(list?.map((rawPolygon) {
return Polygon(
polygonId: PolygonId(rawPolygon['polygonId']),
consumeTapEvents: rawPolygon['consumeTapEvents'],
fillColor: Color(rawPolygon['fillColor'] ?? _defaultFillColor),
geodesic: rawPolygon['geodesic'],
strokeColor: Color(rawPolygon['strokeColor'] ?? _defaultStrokeColor),
strokeWidth: rawPolygon['strokeWidth'],
visible: rawPolygon['visible'],
zIndex: rawPolygon['zIndex'],
points: rawPolygon['points']
?.map<LatLng>((rawPoint) => LatLng.fromJson(rawPoint))
?.toList(),
holes: rawPolygon['holes']
?.map<List<LatLng>>((List hole) => hole
?.map<LatLng>((rawPoint) => LatLng.fromJson(rawPoint))
?.toList())
?.toList(),
);
}) ??
[]);
return polygons;
}

// Convert plugin objects to gmaps.Options objects
// TODO: Move to their appropriate objects, maybe make these copy constructors:
// Marker.fromMarker(anotherMarker, moreOptions);
Expand Down Expand Up @@ -550,7 +421,7 @@ gmaps.PolylineOptions _polylineOptionsFromPolyline(

// Translates a [CameraUpdate] into operations on a [gmaps.GMap].
void _applyCameraUpdate(gmaps.GMap map, CameraUpdate update) {
final json = update.toJson();
final json = update.toJson() as List<dynamic>;
switch (json[0]) {
case 'newCameraPosition':
map.heading = json[1]['bearing'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ class GoogleMapController {
// The internal ID of the map. Used to broadcast events, DOM IDs and everything where a unique ID is needed.
final int _mapId;

final CameraPosition _initialCameraPosition;
final Set<Marker> _markers;
final Set<Polygon> _polygons;
final Set<Polyline> _polylines;
final Set<Circle> _circles;
// The raw options passed by the user, before converting to gmaps.
// Caching this allows us to re-create the map faithfully when needed.
Map<String, dynamic> _rawOptions = {
'options': {},
};
Map<String, dynamic> _rawMapOptions = <String, dynamic>{};

// Creates the 'viewType' for the _widget
String _getViewType(int mapId) => 'plugins.flutter.io/google_maps_$mapId';
Expand Down Expand Up @@ -68,10 +71,23 @@ class GoogleMapController {
GoogleMapController({
@required int mapId,
@required StreamController<MapEvent> streamController,
@required Map<String, dynamic> rawOptions,
}) : this._mapId = mapId,
this._streamController = streamController,
this._rawOptions = rawOptions {
@required CameraPosition initialCameraPosition,
Set<Marker> markers = const <Marker>{},
Set<Polygon> polygons = const <Polygon>{},
Set<Polyline> polylines = const <Polyline>{},
Set<Circle> circles = const <Circle>{},
Set<TileOverlay> tileOverlays = const <TileOverlay>{},
Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers =
const <Factory<OneSequenceGestureRecognizer>>{},
Map<String, dynamic> mapOptions = const <String, dynamic>{},
}) : _mapId = mapId,
_streamController = streamController,
_initialCameraPosition = initialCameraPosition,
_markers = markers,
_polygons = polygons,
_polylines = polylines,
_circles = circles,
_rawMapOptions = mapOptions {
_circlesController = CirclesController(stream: this._streamController);
_polygonsController = PolygonsController(stream: this._streamController);
_polylinesController = PolylinesController(stream: this._streamController);
Expand Down Expand Up @@ -121,9 +137,9 @@ class GoogleMapController {
/// Failure to call this method would result in the GMap not rendering at all,
/// and most of the public methods on this class no-op'ing.
void init() {
var options = _rawOptionsToGmapsOptions(_rawOptions);
var options = _rawOptionsToGmapsOptions(_rawMapOptions);
// Initial position can only to be set here!
options = _applyInitialPosition(_rawOptions, options);
options = _applyInitialPosition(_initialCameraPosition, options);

// Create the map...
_googleMap = _createMap(_div, options);
Expand All @@ -132,13 +148,13 @@ class GoogleMapController {
_attachGeometryControllers(_googleMap);

_renderInitialGeometry(
markers: _rawOptionsToInitialMarkers(_rawOptions),
circles: _rawOptionsToInitialCircles(_rawOptions),
polygons: _rawOptionsToInitialPolygons(_rawOptions),
polylines: _rawOptionsToInitialPolylines(_rawOptions),
markers: _markers,
circles: _circles,
polygons: _polygons,
polylines: _polylines,
);

_setTrafficLayer(_googleMap, _isTrafficLayerEnabled(_rawOptions));
_setTrafficLayer(_googleMap, _isTrafficLayerEnabled(_rawMapOptions));
}

// Funnels map gmap events into the plugin's stream controller.
Expand Down Expand Up @@ -196,20 +212,15 @@ class GoogleMapController {
_polylinesController.addPolylines(polylines);
}

// Merges new options coming from the plugin into the `key` entry of the _rawOptions map.
// Merges new options coming from the plugin into the _rawMapOptions map.
//
// By default: `key` is 'options'.
//
// Returns the updated _rawOptions object.
Map<String, dynamic> _mergeRawOptions(
Map<String, dynamic> newOptions, {
String key = 'options',
}) {
_rawOptions[key] = <String, dynamic>{
...(_rawOptions[key] ?? {}),
// Returns the updated _rawMapOptions object.
Map<String, dynamic> _mergeRawOptions(Map<String, dynamic> newOptions) {
_rawMapOptions = <String, dynamic>{
..._rawMapOptions,
...newOptions,
};
return _rawOptions;
return _rawMapOptions;
}

/// Updates the map options from a `Map<String, dynamic>`.
Expand Down
Loading