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

Commit 5a6e3b1

Browse files
author
Chris Yang
committed
tile overlay
format doc updates compelete tests
1 parent 5916f55 commit 5a6e3b1

File tree

13 files changed

+734
-3
lines changed

13 files changed

+734
-3
lines changed

packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.2.0
2+
3+
* Add TileOverlay support.
4+
15
## 1.1.0
26

37
* Add support for holes in Polygons.

packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/method_channel/method_channel_google_maps_flutter.dart

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform {
3333
return _channels[mapId];
3434
}
3535

36+
// Keep a collection of id -> GetTileCallback
37+
// Every method call passes the int mapId
38+
final Map<int, MapGetTileCallback> _getTileCallbacks = {};
39+
3640
/// Initializes the platform interface with [id].
3741
///
3842
/// This method is called when the plugin is first initialized.
@@ -184,6 +188,15 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform {
184188
LatLng.fromJson(call.arguments['position']),
185189
));
186190
break;
191+
case 'tileOverlay#getTile':
192+
final getTileCallback = _getTileCallbacks[mapId];
193+
final Tile tile = await getTileCallback(
194+
call.arguments['tileOverlayId'],
195+
call.arguments['x'],
196+
call.arguments['y'],
197+
call.arguments['zoom'],
198+
);
199+
return tile.toJson();
187200
default:
188201
throw MissingPluginException();
189202
}
@@ -281,6 +294,40 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform {
281294
);
282295
}
283296

297+
/// Updates tile overlay configuration.
298+
///
299+
/// Change listeners are notified once the update has been made on the
300+
/// platform side.
301+
///
302+
/// The returned [Future] completes after listeners have been notified.
303+
@override
304+
Future<void> updateTileOverlays(
305+
TileOverlayUpdates tileOverlayUpdates, {
306+
@required int mapId,
307+
}) {
308+
assert(tileOverlayUpdates != null);
309+
return channel(mapId).invokeMethod<void>(
310+
'tileOverlays#update',
311+
tileOverlayUpdates.toJson(),
312+
);
313+
}
314+
315+
/// Clears the tile cache so that all tiles will be requested again from the
316+
/// [TileProvider]. The current tiles from this tile overlay will also be
317+
/// cleared from the map after calling this method. The API maintains a small
318+
/// in-memory cache of tiles. If you want to cache tiles for longer, you
319+
/// should implement an on-disk cache.
320+
@override
321+
Future<void> clearTileCache(
322+
TileOverlayId tileOverlayId, {
323+
@required int mapId,
324+
}) {
325+
return channel(mapId)
326+
.invokeMethod<void>('tileOverlays#clearTileCache', <String, dynamic>{
327+
'tileOverlayId': tileOverlayId.value,
328+
});
329+
}
330+
284331
/// Starts an animated change of the map camera position.
285332
///
286333
/// The returned [Future] completes after the change has been started on the
@@ -451,6 +498,16 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform {
451498
return channel(mapId).invokeMethod<Uint8List>('map#takeSnapshot');
452499
}
453500

501+
/// Sets the `MapGetTileCallback` with mapId.
502+
///
503+
/// `mapId` and `callback` must not be null.
504+
@override
505+
void setGetTileCallback(
506+
{@required int mapId, @required MapGetTileCallback callback}) {
507+
assert(mapId != null && callback != null);
508+
_getTileCallbacks[mapId] = callback;
509+
}
510+
454511
/// This method builds the appropriate platform view where the map
455512
/// can be rendered.
456513
/// The `mapId` is passed as a parameter from the framework on the

packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/platform_interface/google_maps_flutter_platform.dart

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ import 'package:google_maps_flutter_platform_interface/src/method_channel/method
1515
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
1616
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
1717

18+
/// Callback method for when a [Tile] is requested from a [TileProvider].
19+
typedef Future<Tile> MapGetTileCallback(
20+
TileOverlayId tileOverlayId, int x, int y, int zoom);
21+
1822
/// The interface that platform-specific implementations of `google_maps_flutter` must extend.
1923
///
2024
/// Avoid `implements` of this interface. Using `implements` makes adding any new
@@ -115,6 +119,31 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface {
115119
throw UnimplementedError('updateCircles() has not been implemented.');
116120
}
117121

122+
/// Updates tile overlay configuration.
123+
///
124+
/// Change listeners are notified once the update has been made on the
125+
/// platform side.
126+
///
127+
/// The returned [Future] completes after listeners have been notified.
128+
Future<void> updateTileOverlays(
129+
TileOverlayUpdates tileOverlayUpdates, {
130+
@required int mapId,
131+
}) {
132+
throw UnimplementedError('updateTileOverlays() has not been implemented.');
133+
}
134+
135+
/// Clears the tile cache so that all tiles will be requested again from the
136+
/// [TileProvider]. The current tiles from this tile overlay will also be
137+
/// cleared from the map after calling this method. The API maintains a small
138+
/// in-memory cache of tiles. If you want to cache tiles for longer, you
139+
/// should implement an on-disk cache.
140+
Future<void> clearTileCache(
141+
TileOverlayId tileOverlayId, {
142+
@required int mapId,
143+
}) {
144+
throw UnimplementedError('clearTileCache() has not been implemented.');
145+
}
146+
118147
/// Starts an animated change of the map camera position.
119148
///
120149
/// The returned [Future] completes after the change has been started on the
@@ -246,6 +275,12 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface {
246275
throw UnimplementedError('takeSnapshot() has not been implemented.');
247276
}
248277

278+
/// Set the [MapGetTileCallback] for the map, which will be called
279+
/// when a [Tile] is requested for an added [TileProvider].
280+
void setGetTileCallback({@required int mapId, MapGetTileCallback callback}) {
281+
throw UnimplementedError('onGetTile() has not been implemented.');
282+
}
283+
249284
// The following are the 11 possible streams of data from the native side
250285
// into the plugin
251286

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2018 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:typed_data';
6+
import 'package:meta/meta.dart' show immutable;
7+
8+
/// Contains information about a Tile that is returned by a [TileProvider].
9+
@immutable
10+
class Tile {
11+
/// Creates an immutable representation of a [Tile] to draw by [TileProvider].
12+
const Tile(this.width, this.height, this.data);
13+
14+
/// The width of the image encoded by data in pixels.
15+
final int width;
16+
17+
/// The height of the image encoded by data in pixels.
18+
final int height;
19+
20+
/// A byte array containing the image data.
21+
final Uint8List data;
22+
23+
/// Converts this object to JSON.
24+
dynamic toJson() {
25+
final Map<String, dynamic> json = <String, dynamic>{};
26+
27+
void addIfPresent(String fieldName, dynamic value) {
28+
if (value != null) {
29+
json[fieldName] = value;
30+
}
31+
}
32+
33+
addIfPresent('width', width);
34+
addIfPresent('height', height);
35+
addIfPresent('data', data);
36+
37+
return json;
38+
}
39+
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// Copyright 2018 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'types.dart';
6+
import 'package:meta/meta.dart' show immutable, required;
7+
8+
/// Uniquely identifies a [TileOverlay] among [GoogleMap] tile overlays.
9+
///
10+
/// This does not have to be globally unique, only unique among the list.
11+
@immutable
12+
class TileOverlayId {
13+
/// Creates an immutable identifier for a [TileOverlay].
14+
TileOverlayId(this.value) : assert(value != null);
15+
16+
/// value of the [TileOverlayId].
17+
final String value;
18+
19+
@override
20+
bool operator ==(Object other) {
21+
if (identical(this, other)) return true;
22+
if (other.runtimeType != runtimeType) return false;
23+
final TileOverlayId typedOther = other;
24+
return value == typedOther.value;
25+
}
26+
27+
@override
28+
int get hashCode => value.hashCode;
29+
30+
@override
31+
String toString() {
32+
return 'TileOverlay{value: $value}';
33+
}
34+
}
35+
36+
/// A Tile Overlay is a set of images which are displayed on top of the base map tiles.
37+
/// These tiles may be transparent, allowing you to add features to existing maps.
38+
///
39+
/// Tile Coordinates
40+
///
41+
/// Note that the world is projected using the Mercator projection
42+
/// (see [Wikipedia](https://en.wikipedia.org/wiki/Mercator_projection)) with the left (west) side
43+
/// of the map corresponding to -180 degrees of longitude and the right (east) side of the map
44+
/// corresponding to 180 degrees of longitude. To make the map square, the top (north) side of the
45+
/// map corresponds to 85.0511 degrees of latitude and the bottom (south) side of the map
46+
/// corresponds to -85.0511 degrees of latitude. Areas outside this latitude range are not rendered.
47+
///
48+
/// At each zoom level, the map is divided into tiles and only the tiles that overlap the screen are
49+
/// downloaded and rendered. Each tile is square and the map is divided into tiles as follows:
50+
///
51+
/// * At zoom level 0, one tile represents the entire world. The coordinates of that tile are
52+
/// (x, y) = (0, 0).
53+
/// * At zoom level 1, the world is divided into 4 tiles arranged in a 2 x 2 grid.
54+
/// * ...
55+
/// * At zoom level N, the world is divided into 4N tiles arranged in a 2N x 2N grid.
56+
///
57+
/// Note that the minimum zoom level that the camera supports (which can depend on various factors)
58+
/// is GoogleMap.getMinZoomLevel and the maximum zoom level is GoogleMap.getMaxZoomLevel.
59+
///
60+
/// The coordinates of the tiles are measured from the top left (northwest) corner of the map.
61+
/// At zoom level N, the x values of the tile coordinates range from 0 to 2N - 1 and increase from
62+
/// west to east and the y values range from 0 to 2N - 1 and increase from north to south.
63+
///
64+
class TileOverlay {
65+
/// Creates an immutable representation of a [TileOverlay] to draw on [GoogleMap].
66+
const TileOverlay({
67+
@required this.tileOverlayId,
68+
this.fadeIn = true,
69+
this.tileProvider,
70+
this.transparency = 0.0,
71+
this.zIndex,
72+
this.visible = true,
73+
this.tileSize = 256,
74+
}) : assert(transparency >= 0.0 && transparency <= 1.0);
75+
76+
/// Uniquely identifies a [TileOverlay].
77+
final TileOverlayId tileOverlayId;
78+
79+
/// Whether the tiles should fade in. The default is true.
80+
final bool fadeIn;
81+
82+
/// The tile provider to use for this tile overlay.
83+
final TileProvider tileProvider;
84+
85+
/// The transparency of the tile overlay. The default transparency is 0 (opaque).
86+
final double transparency;
87+
88+
/// The tile overlay's zIndex, i.e., the order in which it will be drawn where
89+
/// overlays with larger values are drawn above those with lower values
90+
final int zIndex;
91+
92+
/// The visibility for the tile overlay. The default visibility is true.
93+
final bool visible;
94+
95+
/// Specifies the number of pixels (not points) that the returned tile images will prefer
96+
/// to display as. iOS only.
97+
///
98+
/// Defaults to 256, which is the traditional size of Google Maps tiles.
99+
/// As an example, an application developer may wish to provide retina tiles (512 pixel edge length)
100+
/// on retina devices, to keep the same number of tiles per view as the default value of 256
101+
/// would give on a non-retina device.
102+
final int tileSize;
103+
104+
/// Creates a new [Polygon] object whose values are the same as this instance,
105+
/// unless overwritten by the specified parameters.
106+
TileOverlay copyWith({
107+
TileOverlayId tileOverlayId,
108+
bool fadeInParam,
109+
double transparencyParam,
110+
int zIndexParam,
111+
bool visibleParam,
112+
int tileSizeParam,
113+
}) {
114+
return TileOverlay(
115+
tileOverlayId: tileOverlayId,
116+
fadeIn: fadeInParam ?? fadeIn,
117+
transparency: transparencyParam ?? transparency,
118+
zIndex: zIndexParam ?? zIndex,
119+
visible: visibleParam ?? visible,
120+
tileSize: tileSizeParam ?? tileSize,
121+
);
122+
}
123+
124+
/// Converts this object to JSON.
125+
dynamic toJson() {
126+
final Map<String, dynamic> json = <String, dynamic>{};
127+
128+
void addIfPresent(String fieldName, dynamic value) {
129+
if (value != null) {
130+
json[fieldName] = value;
131+
}
132+
}
133+
134+
addIfPresent('tileOverlayId', tileOverlayId.value);
135+
addIfPresent('fadeIn', fadeIn);
136+
addIfPresent('transparency', transparency);
137+
addIfPresent('zIndex', zIndex);
138+
addIfPresent('visible', visible);
139+
addIfPresent('tileSize', tileSize);
140+
141+
return json;
142+
}
143+
144+
@override
145+
bool operator ==(Object other) {
146+
if (identical(this, other)) return true;
147+
if (other.runtimeType != runtimeType) return false;
148+
final TileOverlay typedOther = other;
149+
return tileOverlayId == typedOther.tileOverlayId &&
150+
fadeIn == typedOther.fadeIn &&
151+
transparency == typedOther.transparency &&
152+
zIndex == typedOther.zIndex &&
153+
visible == typedOther.visible &&
154+
tileSize == typedOther.tileSize;
155+
}
156+
157+
@override
158+
int get hashCode => tileOverlayId.hashCode;
159+
}

0 commit comments

Comments
 (0)