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

Commit

Permalink
[google_maps_flutter] Widget based polyline support for google maps. (#…
Browse files Browse the repository at this point in the history
…1049)

- Adds supports for polylines.
  • Loading branch information
awazgyawali authored and iskakaushik committed Apr 10, 2019
1 parent d1ad723 commit af27685
Show file tree
Hide file tree
Showing 34 changed files with 1,831 additions and 23 deletions.
2 changes: 2 additions & 0 deletions AUTHORS
Expand Up @@ -27,6 +27,8 @@ Sarthak Verma <sarthak@artiosys.com>
Mike Diarmid <mike@invertase.io>
Invertase <oss@invertase.io>
Elliot Hesp <elliot@invertase.io>
Aawaz Gyawali <awazgyawali@gmail.com>
EUI Limited <ian.evans3@admiralgroup.co.uk>
Katarina Sheremet <katarina@sheremet.ch>
Thomas Stockx <thomas@stockxit.com>
Sarbagya Dhaubanjar <sarbagyastha@gmail.com>
4 changes: 4 additions & 0 deletions packages/google_maps_flutter/CHANGELOG.md
@@ -1,3 +1,7 @@
## 0.5.6

* Add support for Polylines on GoogleMap.

## 0.5.5

* Enable iOS accessibility.
Expand Down
Expand Up @@ -11,10 +11,20 @@
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.ButtCap;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.Cap;
import com.google.android.gms.maps.model.CustomCap;
import com.google.android.gms.maps.model.Dash;
import com.google.android.gms.maps.model.Dot;
import com.google.android.gms.maps.model.Gap;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.PatternItem;
import com.google.android.gms.maps.model.RoundCap;
import com.google.android.gms.maps.model.SquareCap;
import io.flutter.view.FlutterMain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -124,19 +134,19 @@ private static int toInt(Object o) {
return ((Number) o).intValue();
}

static Object toJson(CameraPosition position) {
static Object latlngBoundsToJson(CameraPosition position) {
if (position == null) {
return null;
}
final Map<String, Object> data = new HashMap<>();
data.put("bearing", position.bearing);
data.put("target", toJson(position.target));
data.put("target", latLngToJson(position.target));
data.put("tilt", position.tilt);
data.put("zoom", position.zoom);
return data;
}

static Object toJson(String markerId) {
static Object markerIdToJson(String markerId) {
if (markerId == null) {
return null;
}
Expand All @@ -145,14 +155,23 @@ static Object toJson(String markerId) {
return data;
}

static Object toJson(LatLng latLng) {
static Object polylineIdToJson(String polylineId) {
if (polylineId == null) {
return null;
}
final Map<String, Object> data = new HashMap<>(1);
data.put("polylineId", polylineId);
return data;
}

static Object latLngToJson(LatLng latLng) {
return Arrays.asList(latLng.latitude, latLng.longitude);
}

public static Object toJson(LatLngBounds latLngBounds) {
public static Object latlngBoundsToJson(LatLngBounds latLngBounds) {
final Map<String, Object> arguments = new HashMap<>(2);
arguments.put("southwest", toJson(latLngBounds.southwest));
arguments.put("northeast", toJson(latLngBounds.northeast));
arguments.put("southwest", latLngToJson(latLngBounds.southwest));
arguments.put("northeast", latLngToJson(latLngBounds.northeast));
return arguments;
}

Expand Down Expand Up @@ -323,4 +342,118 @@ private static void interpretInfoWindowOptions(
sink.setInfoWindowAnchor(toFloat(anchorData.get(0)), toFloat(anchorData.get(1)));
}
}

static String interpretPolylineOptions(Object o, PolylineOptionsSink sink) {
final Map<?, ?> data = toMap(o);
final Object consumeTapEvents = data.get("consumeTapEvents");
if (consumeTapEvents != null) {
sink.setConsumeTapEvents(toBoolean(consumeTapEvents));
}
final Object color = data.get("color");
if (color != null) {
sink.setColor(toInt(color));
}
final Object endCap = data.get("endCap");
if (endCap != null) {
sink.setEndCap(toCap(endCap));
}
final Object geodesic = data.get("geodesic");
if (geodesic != null) {
sink.setGeodesic(toBoolean(geodesic));
}
final Object jointType = data.get("jointType");
if (jointType != null) {
sink.setJointType(toInt(jointType));
}
final Object startCap = data.get("startCap");
if (startCap != null) {
sink.setStartCap(toCap(startCap));
}
final Object visible = data.get("visible");
if (visible != null) {
sink.setVisible(toBoolean(visible));
}
final Object width = data.get("width");
if (width != null) {
sink.setWidth(toInt(width));
}
final Object zIndex = data.get("zIndex");
if (zIndex != null) {
sink.setZIndex(toFloat(zIndex));
}
final Object points = data.get("points");
if (points != null) {
sink.setPoints(toPoints(points));
}
final Object pattern = data.get("pattern");
if (pattern != null) {
sink.setPattern(toPattern(pattern));
}
final String polylineId = (String) data.get("polylineId");
if (polylineId == null) {
throw new IllegalArgumentException("polylineId was null");
} else {
return polylineId;
}
}

private static List<LatLng> toPoints(Object o) {
final List<?> data = toList(o);
final List<LatLng> points = new ArrayList<>(data.size());

for (Object ob : data) {
final List<?> point = toList(ob);
points.add(new LatLng(toFloat(point.get(0)), toFloat(point.get(1))));
}
return points;
}

private static List<PatternItem> toPattern(Object o) {
final List<?> data = toList(o);

if (data.isEmpty()) {
return null;
}

final List<PatternItem> pattern = new ArrayList<>(data.size());

for (Object ob : data) {
final List<?> patternItem = toList(ob);
switch (toString(patternItem.get(0))) {
case "dot":
pattern.add(new Dot());
break;
case "dash":
pattern.add(new Dash(toFloat(patternItem.get(1))));
break;
case "gap":
pattern.add(new Gap(toFloat(patternItem.get(1))));
break;
default:
throw new IllegalArgumentException("Cannot interpret " + pattern + " as PatternItem");
}
}

return pattern;
}

private static Cap toCap(Object o) {
final List<?> data = toList(o);
switch (toString(data.get(0))) {
case "buttCap":
return new ButtCap();
case "roundCap":
return new RoundCap();
case "squareCap":
return new SquareCap();
case "customCap":
if (data.size() == 2) {
return new CustomCap(toBitmapDescriptor(data.get(1)));
} else {
return new CustomCap(toBitmapDescriptor(data.get(1)), toFloat(data.get(2)));
}
default:
throw new IllegalArgumentException("Cannot interpret " + o + " as Cap");
}
}
}
Expand Up @@ -16,6 +16,7 @@ class GoogleMapBuilder implements GoogleMapOptionsSink {
private boolean trackCameraPosition = false;
private boolean myLocationEnabled = false;
private Object initialMarkers;
private Object initialPolylines;

GoogleMapController build(
int id, Context context, AtomicInteger state, PluginRegistry.Registrar registrar) {
Expand All @@ -25,6 +26,7 @@ GoogleMapController build(
controller.setMyLocationEnabled(myLocationEnabled);
controller.setTrackCameraPosition(trackCameraPosition);
controller.setInitialMarkers(initialMarkers);
controller.setInitialPolylines(initialPolylines);
return controller;
}

Expand Down Expand Up @@ -91,4 +93,9 @@ public void setMyLocationEnabled(boolean myLocationEnabled) {
public void setInitialMarkers(Object initialMarkers) {
this.initialMarkers = initialMarkers;
}

@Override
public void setInitialPolylines(Object initialPolylines) {
this.initialPolylines = initialPolylines;
}
}
Expand Up @@ -29,6 +29,7 @@
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.Polyline;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
Expand All @@ -48,6 +49,7 @@ final class GoogleMapController
GoogleMap.OnCameraMoveStartedListener,
GoogleMap.OnInfoWindowClickListener,
GoogleMap.OnMarkerClickListener,
GoogleMap.OnPolylineClickListener,
GoogleMapOptionsSink,
MethodChannel.MethodCallHandler,
OnMapReadyCallback,
Expand All @@ -60,6 +62,7 @@ final class GoogleMapController
private final MethodChannel methodChannel;
private final PluginRegistry.Registrar registrar;
private final MapView mapView;
private final Map<String, PolylineController> polylines;
private GoogleMap googleMap;
private boolean trackCameraPosition = false;
private boolean myLocationEnabled = false;
Expand All @@ -69,7 +72,9 @@ final class GoogleMapController
private final int registrarActivityHashCode;
private final Context context;
private final MarkersController markersController;
private final PolylinesController polylinesController;
private List<Object> initialMarkers;
private List<Object> initialPolylines;

GoogleMapController(
int id,
Expand All @@ -82,12 +87,14 @@ final class GoogleMapController
this.activityState = activityState;
this.registrar = registrar;
this.mapView = new MapView(context, options);
this.polylines = new HashMap<>();
this.density = context.getResources().getDisplayMetrics().density;
methodChannel =
new MethodChannel(registrar.messenger(), "plugins.flutter.io/google_maps_" + id);
methodChannel.setMethodCallHandler(this);
this.registrarActivityHashCode = registrar.activity().hashCode();
this.markersController = new MarkersController(methodChannel);
this.polylinesController = new PolylinesController(methodChannel);
}

@Override
Expand Down Expand Up @@ -157,10 +164,13 @@ public void onMapReady(GoogleMap googleMap) {
googleMap.setOnCameraMoveListener(this);
googleMap.setOnCameraIdleListener(this);
googleMap.setOnMarkerClickListener(this);
googleMap.setOnPolylineClickListener(this);
googleMap.setOnMapClickListener(this);
updateMyLocationEnabled();
markersController.setGoogleMap(googleMap);
polylinesController.setGoogleMap(googleMap);
updateInitialMarkers();
updateInitialPolylines();
}

@Override
Expand All @@ -176,14 +186,14 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) {
case "map#update":
{
Convert.interpretGoogleMapOptions(call.argument("options"), this);
result.success(Convert.toJson(getCameraPosition()));
result.success(Convert.latlngBoundsToJson(getCameraPosition()));
break;
}
case "map#getVisibleRegion":
{
if (googleMap != null) {
LatLngBounds latLngBounds = googleMap.getProjection().getVisibleRegion().latLngBounds;
result.success(Convert.toJson(latLngBounds));
result.success(Convert.latlngBoundsToJson(latLngBounds));
} else {
result.error(
"GoogleMap uninitialized",
Expand Down Expand Up @@ -219,6 +229,17 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) {
result.success(null);
break;
}
case "polylines#update":
{
Object polylinesToAdd = call.argument("polylinesToAdd");
polylinesController.addPolylines((List<Object>) polylinesToAdd);
Object polylinesToChange = call.argument("polylinesToChange");
polylinesController.changePolylines((List<Object>) polylinesToChange);
Object polylineIdsToRemove = call.argument("polylineIdsToRemove");
polylinesController.removePolylines((List<Object>) polylineIdsToRemove);
result.success(null);
break;
}
case "map#isCompassEnabled":
{
result.success(googleMap.getUiSettings().isCompassEnabled());
Expand Down Expand Up @@ -260,7 +281,7 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) {
@Override
public void onMapClick(LatLng latLng) {
final Map<String, Object> arguments = new HashMap<>(2);
arguments.put("position", Convert.toJson(latLng));
arguments.put("position", Convert.latLngToJson(latLng));
methodChannel.invokeMethod("map#onTap", arguments);
}

Expand All @@ -283,7 +304,7 @@ public void onCameraMove() {
return;
}
final Map<String, Object> arguments = new HashMap<>(2);
arguments.put("position", Convert.toJson(googleMap.getCameraPosition()));
arguments.put("position", Convert.latlngBoundsToJson(googleMap.getCameraPosition()));
methodChannel.invokeMethod("camera#onMove", arguments);
}

Expand All @@ -297,6 +318,11 @@ public boolean onMarkerClick(Marker marker) {
return markersController.onMarkerTap(marker.getId());
}

@Override
public void onPolylineClick(Polyline polyline) {
polylinesController.onPolylineTap(polyline.getId());
}

@Override
public void dispose() {
if (disposed) {
Expand Down Expand Up @@ -440,6 +466,18 @@ private void updateInitialMarkers() {
markersController.addMarkers(initialMarkers);
}

@Override
public void setInitialPolylines(Object initialPolylines) {
this.initialPolylines = (List<Object>) initialPolylines;
if (googleMap != null) {
updateInitialPolylines();
}
}

private void updateInitialPolylines() {
polylinesController.addPolylines(initialPolylines);
}

@SuppressLint("MissingPermission")
private void updateMyLocationEnabled() {
if (hasLocationPermission()) {
Expand Down
Expand Up @@ -35,6 +35,9 @@ public PlatformView create(Context context, int id, Object args) {
if (params.containsKey("markersToAdd")) {
builder.setInitialMarkers(params.get("markersToAdd"));
}
if (params.containsKey("polylinesToAdd")) {
builder.setInitialPolylines(params.get("polylinesToAdd"));
}
return builder.build(id, context, mActivityState, mPluginRegistrar);
}
}
Expand Up @@ -29,4 +29,6 @@ interface GoogleMapOptionsSink {
void setMyLocationEnabled(boolean myLocationEnabled);

void setInitialMarkers(Object initialMarkers);

void setInitialPolylines(Object initialPolylines);
}

0 comments on commit af27685

Please sign in to comment.