Skip to content

Commit

Permalink
Add marker API (flutter#481)
Browse files Browse the repository at this point in the history
  • Loading branch information
mravn-google authored and slightfoot committed Jun 5, 2018
1 parent e4c2f5c commit 78174b9
Show file tree
Hide file tree
Showing 10 changed files with 674 additions and 207 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
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.MarkerOptions;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import io.flutter.view.FlutterMain;
import io.flutter.view.TextureRegistry;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -91,122 +95,129 @@ public void onMethodCall(MethodCall call, Result result) {
}
case "moveCamera":
{
final long id = ((Number) call.argument("id")).longValue();
final GoogleMapsEntry entry = mapsEntry(call);
final CameraUpdate cameraUpdate = toCameraUpdate(call.argument("cameraUpdate"));
final GoogleMapsEntry entry = googleMaps.get(id);
if (entry == null) {
result.error("unknown", "Unknown ID " + id, null);
} else {
entry.moveCamera(cameraUpdate);
result.success(null);
}
entry.moveCamera(cameraUpdate);
result.success(null);
break;
}
case "animateCamera":
{
final long id = ((Number) call.argument("id")).longValue();
final GoogleMapsEntry entry = mapsEntry(call);
final CameraUpdate cameraUpdate = toCameraUpdate(call.argument("cameraUpdate"));
final GoogleMapsEntry entry = googleMaps.get(id);
if (entry == null) {
result.error("unknown", "Unknown ID " + id, null);
} else {
entry.animateCamera(cameraUpdate);
result.success(null);
}
entry.animateCamera(cameraUpdate);
result.success(null);
break;
}
case "addMarker":
{
final long id = ((Number) call.argument("id")).longValue();
final GoogleMapsEntry entry = mapsEntry(call);
final MarkerOptions markerOptions = toMarkerOptions(call.argument("markerOptions"));
final GoogleMapsEntry entry = googleMaps.get(id);
if (entry == null) {
result.error("unknown", "Unknown ID " + id, null);
} else {
entry.addMarker(markerOptions);
result.success(null);
}
final String markerId = entry.addMarker(markerOptions);
result.success(markerId);
break;
}
case "marker#remove":
{
final GoogleMapsEntry entry = mapsEntry(call);
final String markerId = call.argument("marker");
entry.removeMarker(markerId);
result.success(null);
break;
}
case "marker#hideInfoWindow":
{
final GoogleMapsEntry entry = mapsEntry(call);
final String markerId = call.argument("marker");
entry.hideMarkerInfoWindow(markerId);
result.success(null);
break;
}
case "marker#showInfoWindow":
{
final GoogleMapsEntry entry = mapsEntry(call);
final String markerId = call.argument("marker");
entry.showMarkerInfoWindow(markerId);
result.success(null);
break;
}
case "marker#update":
{
final GoogleMapsEntry entry = mapsEntry(call);
final String markerId = call.argument("marker");
final MarkerOptions markerOptions = toMarkerOptions(call.argument("markerOptions"));
entry.updateMarker(markerId, markerOptions);
result.success(null);
break;
}
case "showMapOverlay":
{
final long id = ((Number) call.argument("id")).longValue();
final GoogleMapsEntry entry = mapsEntry(call);
final int x = ((Number) call.argument("x")).intValue();
final int y = ((Number) call.argument("y")).intValue();
final GoogleMapsEntry entry = googleMaps.get(id);
if (entry == null) {
result.error("unknown", "Unknown ID " + id, null);
} else {
entry.showOverlay(x, y);
result.success(null);
}
entry.showOverlay(x, y);
result.success(null);
break;
}
case "hideMapOverlay":
{
final long id = ((Number) call.argument("id")).longValue();
final GoogleMapsEntry entry = googleMaps.get(id);
if (entry == null) {
result.error("unknown", "Unknown ID " + id, null);
} else {
entry.hideOverlay();
result.success(null);
}
final GoogleMapsEntry entry = mapsEntry(call);
entry.hideOverlay();
result.success(null);
break;
}
case "disposeMap":
{
final long id = ((Number) call.argument("id")).longValue();
final GoogleMapsEntry entry = googleMaps.get(id);
if (entry == null) {
result.error("unknown", "Unknown ID " + id, null);
} else {
entry.dispose();
result.success(null);
}
final GoogleMapsEntry entry = mapsEntry(call);
entry.dispose();
result.success(null);
break;
}
default:
result.notImplemented();
}
}

private static LatLng toLatLng(Object o) {
@SuppressWarnings("unchecked")
final List<Double> coordinates = (List<Double>) o;
return new LatLng(coordinates.get(0), coordinates.get(1));
}

private static LatLngBounds toLatLngBounds(Object o) {
final List<?> data = (List<?>) o;
return new LatLngBounds(toLatLng(data.get(0)), toLatLng(data.get(1)));
}

private static float toFloat(Object o) {
return ((Number) o).floatValue();
}

private static int toInt(Object o) {
return ((Number) o).intValue();
private GoogleMapsEntry mapsEntry(MethodCall call) {
final long id = toLong(call.argument("map"));
final GoogleMapsEntry entry = googleMaps.get(id);
if (entry == null) {
throw new IllegalArgumentException("Unknown map: " + id);
}
return entry;
}

private static Point toPoint(Object o) {
@SuppressWarnings("unchecked")
final List<Object> data = (List<Object>) o;
return new Point(toInt(data.get(0)), toInt(data.get(1)));
private static BitmapDescriptor toBitmapDescriptor(Object o) {
final List<?> data = toList(o);
switch (toString(data.get(0))) {
case "defaultMarker":
if (data.size() == 1) {
return BitmapDescriptorFactory.defaultMarker();
} else {
return BitmapDescriptorFactory.defaultMarker(toFloat(data.get(1)));
}
case "fromAsset":
if (data.size() == 2) {
return BitmapDescriptorFactory.fromAsset(
FlutterMain.getLookupKeyForAsset(toString(data.get(1))));
} else {
return BitmapDescriptorFactory.fromAsset(
FlutterMain.getLookupKeyForAsset(toString(data.get(1)), toString(data.get(2))));
}
case "fromFile":
return BitmapDescriptorFactory.fromFile(toString(data.get(1)));
case "fromPath":
return BitmapDescriptorFactory.fromPath(toString(data.get(1)));
}
throw new IllegalArgumentException("Cannot interpret " + o + " as BitmapDescriptor");
}

private static MarkerOptions toMarkerOptions(Object o) {
@SuppressWarnings("unchecked")
final Map<String, Object> data = (Map<String, Object>) o;
final MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(toLatLng(data.get("position")));
return markerOptions;
private static boolean toBoolean(Object o) {
return (Boolean) o;
}

private static CameraPosition toCameraPosition(Object o) {
@SuppressWarnings("unchecked")
final Map<String, Object> data = (Map<String, Object>) o;
final Map<?, ?> data = toMap(o);
final CameraPosition.Builder builder = CameraPosition.builder();
builder.bearing(toFloat(data.get("bearing")));
builder.target(toLatLng(data.get("target")));
Expand All @@ -216,9 +227,8 @@ private static CameraPosition toCameraPosition(Object o) {
}

private static CameraUpdate toCameraUpdate(Object o) {
@SuppressWarnings("unchecked")
final List<Object> data = (List<Object>) o;
switch ((String) data.get(0)) {
final List<?> data = toList(o);
switch (toString(data.get(0))) {
case "newCameraPosition":
return CameraUpdateFactory.newCameraPosition(toCameraPosition(data.get(1)));
case "newLatLng":
Expand All @@ -245,6 +255,68 @@ private static CameraUpdate toCameraUpdate(Object o) {
throw new IllegalArgumentException("Cannot interpret " + o + " as CameraUpdate");
}

private static double toDouble(Object o) {
return ((Number) o).doubleValue();
}

private static float toFloat(Object o) {
return ((Number) o).floatValue();
}

private static int toInt(Object o) {
return ((Number) o).intValue();
}

private static LatLng toLatLng(Object o) {
final List<?> data = toList(o);
return new LatLng(toDouble(data.get(0)), toDouble(data.get(1)));
}

private static LatLngBounds toLatLngBounds(Object o) {
final List<?> data = toList(o);
return new LatLngBounds(toLatLng(data.get(0)), toLatLng(data.get(1)));
}

private static List<?> toList(Object o) {
return (List<?>) o;
}

private static long toLong(Object o) {
return ((Number) o).longValue();
}

private static Map<?, ?> toMap(Object o) {
return (Map<?, ?>) o;
}

private static MarkerOptions toMarkerOptions(Object o) {
final Map<?, ?> data = toMap(o);
final List<?> anchor = toList(data.get("anchor"));
final List<?> infoWindowAnchor = toList(data.get("infoWindowAnchor"));
return new MarkerOptions()
.position(toLatLng(data.get("position")))
.alpha(toFloat(data.get("alpha")))
.anchor(toFloat(anchor.get(0)), toFloat(anchor.get(1)))
.draggable(toBoolean(data.get("draggable")))
.flat(toBoolean(data.get("flat")))
.icon(toBitmapDescriptor(data.get("icon")))
.infoWindowAnchor(toFloat(infoWindowAnchor.get(0)), toFloat(infoWindowAnchor.get(1)))
.rotation(toFloat(data.get("rotation")))
.snippet(toString(data.get("snippet")))
.title(toString(data.get("title")))
.visible(toBoolean(data.get("visible")))
.zIndex(toFloat(data.get("zIndex")));
}

private static Point toPoint(Object o) {
final List<?> data = toList(o);
return new Point(toInt(data.get(0)), toInt(data.get(1)));
}

private static String toString(Object o) {
return (String) o;
}

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
state.set(CREATED);
Expand Down Expand Up @@ -295,6 +367,7 @@ final class GoogleMapsEntry
private final int height;
private final Result result;
private final Timer timer;
private final Map<String, Marker> markers;
private GoogleMap googleMap;
private Surface surface;
private boolean disposed = false;
Expand All @@ -313,6 +386,7 @@ final class GoogleMapsEntry
textureEntry.surfaceTexture().setDefaultBufferSize(width, height);
this.mapView = new MapView(registrar.activity());
this.timer = new Timer();
this.markers = new HashMap<>();
}

void init() {
Expand Down Expand Up @@ -373,16 +447,59 @@ void hideOverlay() {
parent.addView(mapView, 0);
}

void moveCamera(final CameraUpdate cameraUpdate) {
void moveCamera(CameraUpdate cameraUpdate) {
googleMap.moveCamera(cameraUpdate);
}

void animateCamera(final CameraUpdate cameraUpdate) {
void animateCamera(CameraUpdate cameraUpdate) {
googleMap.animateCamera(cameraUpdate);
}

void addMarker(final MarkerOptions options) {
googleMap.addMarker(options);
String addMarker(MarkerOptions options) {
final Marker marker = googleMap.addMarker(options);
markers.put(marker.getId(), marker);
return marker.getId();
}

void removeMarker(String markerId) {
final Marker marker = markers.remove(markerId);
if (marker != null) {
marker.remove();
}
}

void showMarkerInfoWindow(String markerId) {
final Marker marker = marker(markerId);
marker.showInfoWindow();
}

void hideMarkerInfoWindow(String markerId) {
final Marker marker = marker(markerId);
marker.hideInfoWindow();
}

void updateMarker(String markerId, MarkerOptions options) {
final Marker marker = marker(markerId);
marker.setPosition(options.getPosition());
marker.setAlpha(options.getAlpha());
marker.setAnchor(options.getAnchorU(), options.getAnchorV());
marker.setDraggable(options.isDraggable());
marker.setFlat(options.isFlat());
marker.setIcon(options.getIcon());
marker.setInfoWindowAnchor(options.getInfoWindowAnchorU(), options.getInfoWindowAnchorV());
marker.setRotation(options.getRotation());
marker.setSnippet(options.getSnippet());
marker.setTitle(options.getTitle());
marker.setVisible(options.isVisible());
marker.setZIndex(options.getZIndex());
}

private Marker marker(String markerId) {
final Marker marker = markers.get(markerId);
if (marker == null) {
throw new IllegalArgumentException("Unknown marker: " + markerId);
}
return marker;
}

private void updateTexture() {
Expand Down
Loading

0 comments on commit 78174b9

Please sign in to comment.