Extend Maps API implementation

+ Events
+ Enable/Disable gestures
This commit is contained in:
mar-v-in 2015-12-03 18:37:11 -08:00
parent 249c935f44
commit 93487b51ea
14 changed files with 275 additions and 33 deletions

2
extern/GmsApi vendored

@ -1 +1 @@
Subproject commit a55281ec5d48681e071b85290fc020ea56af482c
Subproject commit 609e53a7d363183de4494600d4141b7c7cf5a692

Binary file not shown.

View File

@ -54,7 +54,7 @@ public class CreatorImpl extends ICreator.Stub {
@Override
public ICameraUpdateFactoryDelegate newCameraUpdateFactoryDelegate() throws RemoteException {
return new CameraUpdateFactoryImpl();
return CameraUpdateFactoryImpl.get();
}
@Override

View File

@ -22,9 +22,10 @@ import android.util.Log;
import android.view.View;
import com.google.android.gms.R;
import com.google.android.gms.maps.model.CameraPosition;
import org.microg.gms.maps.data.SharedTileCache;
import org.microg.gms.maps.camera.CameraUpdate;
import org.microg.gms.maps.data.SharedTileCache;
import org.microg.gms.maps.markup.ClearableVectorLayer;
import org.microg.gms.maps.markup.DrawableMarkup;
import org.microg.gms.maps.markup.MarkerItemMarkup;
@ -32,6 +33,9 @@ import org.microg.gms.maps.markup.Markup;
import org.oscim.android.MapView;
import org.oscim.android.canvas.AndroidBitmap;
import org.oscim.core.MapPosition;
import org.oscim.core.Point;
import org.oscim.event.Event;
import org.oscim.event.MotionEvent;
import org.oscim.layers.marker.ItemizedLayer;
import org.oscim.layers.marker.MarkerItem;
import org.oscim.layers.marker.MarkerSymbol;
@ -53,7 +57,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerItem> {
public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerItem>, Map.InputListener {
private final static String TAG = "GmsMapBackend";
private final Context context;
@ -67,8 +71,11 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
private java.util.Map<String, Markup> markupMap = new HashMap<String, Markup>();
private List<DrawableMarkup> drawableMarkups = new ArrayList<DrawableMarkup>();
private ClearableVectorLayer drawables;
private MarkerItemMarkup currentlyDraggedItem;
private float dragLastX = -1;
private float dragLastY = -1;
public BackendMap(Context context) {
public BackendMap(Context context, final CameraUpdateListener cameraUpdateListener) {
this.context = context;
mapView = new MapView(new ContextContainer(context));
cache = new SharedTileCache(context);
@ -84,10 +91,14 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
.decodeResource(ResourcesContainer.get(), R.drawable.nop)), 0.5F, 1)));
items.setOnItemGestureListener(this);
mapView.map().setTheme(VtmThemes.DEFAULT);
}
mapView.map().input.bind(this);
mapView.map().events.bind(new Map.UpdateListener() {
public void setInputListener(Map.InputListener listener) {
mapView.map().input.bind(listener);
@Override
public void onMapEvent(Event event, MapPosition mapPosition) {
cameraUpdateListener.onCameraUpdate(GmsMapsTypeHelper.toCameraPosition(mapPosition));
}
});
}
public Viewport getViewport() {
@ -199,12 +210,12 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
if (markup instanceof MarkerItemMarkup) {
markupMap.remove(markup.getId());
items.removeItem(items.getByUid(markup.getId()));
redraw();
} else if (markup instanceof DrawableMarkup) {
drawableMarkups.remove(markup);
updateDrawableLayer();
redraw();
drawables.update();
}
redraw();
}
public synchronized void update(Markup markup) {
@ -214,6 +225,7 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
items.addItem(((MarkerItemMarkup) markup).getMarkerItem(context));
} else if (markup instanceof DrawableMarkup) {
updateDrawableLayer();
drawables.update();
}
redraw();
}
@ -229,8 +241,58 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
@Override
public boolean onItemLongPress(int index, MarkerItem item) {
// TODO: start drag+drop
Log.d(TAG, "onItemLongPress: " + markupMap.get(item.getUid()));
return false;
Markup markup = markupMap.get(item.getUid());
if (((MarkerItemMarkup) markup).isDraggable()) {
currentlyDraggedItem = (MarkerItemMarkup) markup;
currentlyDraggedItem.onDragStart();
return false;
} else {
Log.d(TAG, "onItemLongPress: " + markup);
return false;
}
}
@Override
public void onInputEvent(Event event, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL || motionEvent.getAction() == MotionEvent.ACTION_UP && currentlyDraggedItem != null) {
currentlyDraggedItem.onDragStop();
currentlyDraggedItem = null;
}
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
dragLastX = motionEvent.getX();
dragLastY = motionEvent.getY();
}
if (motionEvent.getAction() == MotionEvent.ACTION_MOVE && currentlyDraggedItem != null) {
Point out = new Point();
mapView.map().viewport().toScreenPoint(GmsMapsTypeHelper.fromLatLng(currentlyDraggedItem.getPosition()), out);
out.x += mapView.getWidth() / 2;
out.y += mapView.getHeight() / 2;
float mx = motionEvent.getX() - dragLastX;
float my = motionEvent.getY() - dragLastY;
currentlyDraggedItem.setPosition(GmsMapsTypeHelper.toLatLng(mapView.map().viewport().fromScreenPoint((float) out.getX() + mx, (float) out.getY() + my)));
currentlyDraggedItem.onDragProgress();
dragLastX += mx;
dragLastY += my;
}
}
public void setZoomGesturesEnabled(boolean enabled) {
mapView.map().getEventLayer().enableZoom(enabled);
}
public void setScrollGesturesEnabled(boolean enabled) {
mapView.map().getEventLayer().enableMove(enabled);
}
public void setRotateGesturesEnabled(boolean enabled) {
mapView.map().getEventLayer().enableRotation(enabled);
}
public void setTiltGesturesEnabled(boolean enabled) {
mapView.map().getEventLayer().enableTilt(enabled);
}
public interface CameraUpdateListener {
void onCameraUpdate(CameraPosition cameraPosition);
}
}

View File

@ -58,6 +58,7 @@ import com.google.android.gms.maps.model.internal.IPolylineDelegate;
import com.google.android.gms.maps.model.internal.ITileOverlayDelegate;
import org.microg.gms.maps.camera.CameraUpdate;
import org.microg.gms.maps.camera.MapPositionCameraUpdate;
import org.microg.gms.maps.markup.CircleImpl;
import org.microg.gms.maps.markup.GroundOverlayImpl;
import org.microg.gms.maps.markup.MarkerImpl;
@ -65,12 +66,9 @@ import org.microg.gms.maps.markup.Markup;
import org.microg.gms.maps.markup.PolygonImpl;
import org.microg.gms.maps.markup.PolylineImpl;
import org.microg.gms.maps.markup.TileOverlayImpl;
import org.oscim.event.Event;
import org.oscim.event.MotionEvent;
import org.oscim.map.Map;
public class GoogleMapImpl extends IGoogleMapDelegate.Stub
implements UiSettingsImpl.UiSettingsListener, Map.InputListener, Markup.MarkupListener {
implements UiSettingsImpl.UiSettingsListener, Markup.MarkupListener, BackendMap.CameraUpdateListener {
private static final String TAG = "GoogleMapImpl";
private final GoogleMapOptions options;
@ -85,14 +83,32 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
private int polygonCounter = 0;
private IOnMarkerClickListener onMarkerClickListener;
private IOnMarkerDragListener onMarkerDragListener;
private IOnCameraChangeListener onCameraChangeListener;
public GoogleMapImpl(LayoutInflater inflater, GoogleMapOptions options) {
context = inflater.getContext();
backendMap = new BackendMap(context);
backendMap.setInputListener(this);
backendMap = new BackendMap(context, this);
uiSettings = new UiSettingsImpl(this);
projection = new ProjectionImpl(backendMap.getViewport());
this.options = options;
if (options != null) initFromOptions();
}
private void initFromOptions() {
try {
uiSettings.setCompassEnabled(options.isCompassEnabled());
uiSettings.setRotateGesturesEnabled(options.isRotateGesturesEnabled());
uiSettings.setTiltGesturesEnabled(options.isTiltGesturesEnabled());
uiSettings.setScrollGesturesEnabled(options.isScrollGesturesEnabled());
uiSettings.setZoomControlsEnabled(options.isZoomControlsEnabled());
uiSettings.setZoomGesturesEnabled(options.isZoomGesturesEnabled());
if (options.getCamera() != null) {
backendMap.applyCameraUpdate(MapPositionCameraUpdate.directMapPosition(GmsMapsTypeHelper.fromCameraPosition(options.getCamera())));
}
} catch (RemoteException e) {
// Never happens: not remote
}
}
public void onDestroy() {
@ -138,12 +154,12 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
@Override
public float getMaxZoomLevel() throws RemoteException {
return 0;
return (float) backendMap.getViewport().limitScale(Double.MIN_VALUE);
}
@Override
public float getMinZoomLevel() throws RemoteException {
return 0;
return (float) backendMap.getViewport().limitScale(Double.MAX_VALUE);
}
@Override
@ -181,6 +197,17 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
public void stopAnimation() throws RemoteException {
backendMap.stopAnimation();
}
@Override
public void onCameraUpdate(CameraPosition cameraPosition) {
if (onCameraChangeListener != null) {
try {
onCameraChangeListener.onCameraChange(cameraPosition);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
/*
Markers, polylines, polygons, overlays, etc
@ -193,7 +220,6 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
@Override
public IPolylineDelegate addPolyline(PolylineOptions options) throws RemoteException {
Log.d(TAG, "addPolyline");
return backendMap.add(new PolylineImpl(getNextPolylineId(), options, this));
}
@ -259,6 +285,57 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
}
return false;
}
@Override
public void onDragStart(Markup markup) {
backendMap.setScrollGesturesEnabled(false);
backendMap.setRotateGesturesEnabled(false);
backendMap.setTiltGesturesEnabled(false);
backendMap.setZoomGesturesEnabled(false);
if (markup instanceof IMarkerDelegate) {
if (onMarkerDragListener != null) {
try {
onMarkerDragListener.onMarkerDragStart((IMarkerDelegate) markup);
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
}
}
@Override
public void onDragStop(Markup markup) {
try {
backendMap.setScrollGesturesEnabled(uiSettings.isScrollGesturesEnabled());
backendMap.setRotateGesturesEnabled(uiSettings.isRotateGesturesEnabled());
backendMap.setTiltGesturesEnabled(uiSettings.isTiltGesturesEnabled());
backendMap.setZoomGesturesEnabled(uiSettings.isZoomGesturesEnabled());
} catch (RemoteException e) {
// Never happens, is local.
}
if (markup instanceof IMarkerDelegate) {
if (onMarkerDragListener != null) {
try {
onMarkerDragListener.onMarkerDragEnd((IMarkerDelegate) markup);
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
}
}
@Override
public void onDragProgress(Markup markup) {
if (markup instanceof IMarkerDelegate) {
if (onMarkerDragListener != null) {
try {
onMarkerDragListener.onMarkerDrag((IMarkerDelegate) markup);
} catch (RemoteException e) {
Log.w(TAG, e);
}
}
}
}
/*
Map options
@ -334,6 +411,10 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
if (settings.isZoomControlsEnabled()) {
Log.w(TAG, "ZoomControls not yet supported");
}
backendMap.setScrollGesturesEnabled(settings.isScrollGesturesEnabled());
backendMap.setRotateGesturesEnabled(settings.isRotateGesturesEnabled());
backendMap.setTiltGesturesEnabled(settings.isTiltGesturesEnabled());
backendMap.setZoomGesturesEnabled(settings.isZoomGesturesEnabled());
}
/*
@ -342,7 +423,7 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
@Override
public void setOnCameraChangeListener(IOnCameraChangeListener listener) throws RemoteException {
this.onCameraChangeListener = listener;
}
@Override
@ -362,7 +443,7 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
@Override
public void setOnMarkerDragListener(IOnMarkerDragListener listener) throws RemoteException {
this.onMarkerDragListener = listener;
}
@Override
@ -418,11 +499,6 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
}
@Override
public void onInputEvent(Event event, MotionEvent motionEvent) {
Log.d(TAG, "onInputEvent(" + event + ", " + motionEvent + ")");
}
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
if (super.onTransact(code, data, reply, flags)) return true;

View File

@ -23,10 +23,10 @@ public class UiSettingsImpl extends IUiSettingsDelegate.Stub {
private boolean zoomControlsEnabled;
private boolean compassEnabled;
private boolean myLocationButtonEnabled;
private boolean scrollGesturesEnabled;
private boolean zoomGesturesEnabled;
private boolean tiltGesturesEnabled;
private boolean rotateGesturesEnabled;
private boolean scrollGesturesEnabled = true;
private boolean zoomGesturesEnabled = true;
private boolean tiltGesturesEnabled = true;
private boolean rotateGesturesEnabled = true;
private UiSettingsListener listener;

View File

@ -33,6 +33,18 @@ import org.oscim.map.Map;
public class CameraUpdateFactoryImpl extends ICameraUpdateFactoryDelegate.Stub {
private static final String TAG = "GmsMapCamUpdateFactory";
private CameraUpdateFactoryImpl() {
}
private static CameraUpdateFactoryImpl instance;
public static CameraUpdateFactoryImpl get() {
if (instance == null) {
instance = new CameraUpdateFactoryImpl();
}
return instance;
}
@Override
public IObjectWrapper zoomIn() throws RemoteException {
Log.d(TAG, "zoomIn");

View File

@ -32,4 +32,13 @@ public abstract class MapPositionCameraUpdate implements CameraUpdate {
public void applyAnimated(Map map, int duration) {
map.animator().animateTo(duration, getMapPosition(map));
}
public static CameraUpdate directMapPosition(final MapPosition position) {
return new MapPositionCameraUpdate() {
@Override
MapPosition getMapPosition(Map map) {
return position;
}
};
}
}

View File

@ -144,6 +144,21 @@ public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup {
return listener.onClick(this);
}
@Override
public void onDragStart() {
listener.onDragStart(this);
}
@Override
public void onDragStop() {
listener.onDragStop(this);
}
@Override
public void onDragProgress() {
listener.onDragProgress(this);
}
@Override
public Drawable getDrawable(Map map) {
if (!isVisible() || removed) return null;

View File

@ -145,6 +145,11 @@ public class MarkerImpl extends IMarkerDelegate.Stub implements MarkerItemMarkup
return hashCode();
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public void setIcon(IObjectWrapper obj) {
if (obj == null) {
@ -211,6 +216,21 @@ public class MarkerImpl extends IMarkerDelegate.Stub implements MarkerItemMarkup
return listener.onClick(this);
}
@Override
public void onDragStart() {
listener.onDragStart(this);
}
@Override
public void onDragStop() {
listener.onDragStop(this);
}
@Override
public void onDragProgress() {
listener.onDragProgress(this);
}
@Override
public MarkerItem getMarkerItem(Context context) {
if (removed) return null;

View File

@ -18,8 +18,16 @@ package org.microg.gms.maps.markup;
import android.content.Context;
import com.google.android.gms.maps.model.LatLng;
import org.oscim.layers.marker.MarkerItem;
public interface MarkerItemMarkup extends Markup {
MarkerItem getMarkerItem(Context context);
boolean isDraggable();
LatLng getPosition();
void setPosition(LatLng latLng);
}

View File

@ -21,11 +21,21 @@ public interface Markup {
boolean onClick();
void onDragStart();
void onDragStop();
void onDragProgress();
interface MarkupListener {
void update(Markup markup);
void remove(Markup markup);
boolean onClick(Markup markup);
void onDragStart(Markup markup);
void onDragStop(Markup markup);
void onDragProgress(Markup markup);
}
}

View File

@ -62,6 +62,21 @@ public class PolygonImpl extends IPolygonDelegate.Stub implements DrawableMarkup
return listener.onClick(this);
}
@Override
public void onDragStart() {
listener.onDragStart(this);
}
@Override
public void onDragStop() {
listener.onDragStop(this);
}
@Override
public void onDragProgress() {
listener.onDragProgress(this);
}
@Override
public void setPoints(List<LatLng> points) throws RemoteException {
options.getPoints().clear();

View File

@ -66,6 +66,21 @@ public class PolylineImpl extends IPolylineDelegate.Stub implements DrawableMark
return listener.onClick(this);
}
@Override
public void onDragStart() {
listener.onDragStart(this);
}
@Override
public void onDragStop() {
listener.onDragStop(this);
}
@Override
public void onDragProgress() {
listener.onDragProgress(this);
}
@Override
public void setPoints(List<LatLng> points) {
options.getPoints().clear();