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 @Override
public ICameraUpdateFactoryDelegate newCameraUpdateFactoryDelegate() throws RemoteException { public ICameraUpdateFactoryDelegate newCameraUpdateFactoryDelegate() throws RemoteException {
return new CameraUpdateFactoryImpl(); return CameraUpdateFactoryImpl.get();
} }
@Override @Override

View File

@ -22,9 +22,10 @@ import android.util.Log;
import android.view.View; import android.view.View;
import com.google.android.gms.R; 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.camera.CameraUpdate;
import org.microg.gms.maps.data.SharedTileCache;
import org.microg.gms.maps.markup.ClearableVectorLayer; import org.microg.gms.maps.markup.ClearableVectorLayer;
import org.microg.gms.maps.markup.DrawableMarkup; import org.microg.gms.maps.markup.DrawableMarkup;
import org.microg.gms.maps.markup.MarkerItemMarkup; 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.MapView;
import org.oscim.android.canvas.AndroidBitmap; import org.oscim.android.canvas.AndroidBitmap;
import org.oscim.core.MapPosition; 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.ItemizedLayer;
import org.oscim.layers.marker.MarkerItem; import org.oscim.layers.marker.MarkerItem;
import org.oscim.layers.marker.MarkerSymbol; import org.oscim.layers.marker.MarkerSymbol;
@ -53,7 +57,7 @@ import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; 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 static String TAG = "GmsMapBackend";
private final Context context; 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 java.util.Map<String, Markup> markupMap = new HashMap<String, Markup>();
private List<DrawableMarkup> drawableMarkups = new ArrayList<DrawableMarkup>(); private List<DrawableMarkup> drawableMarkups = new ArrayList<DrawableMarkup>();
private ClearableVectorLayer drawables; 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; this.context = context;
mapView = new MapView(new ContextContainer(context)); mapView = new MapView(new ContextContainer(context));
cache = new SharedTileCache(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))); .decodeResource(ResourcesContainer.get(), R.drawable.nop)), 0.5F, 1)));
items.setOnItemGestureListener(this); items.setOnItemGestureListener(this);
mapView.map().setTheme(VtmThemes.DEFAULT); mapView.map().setTheme(VtmThemes.DEFAULT);
} mapView.map().input.bind(this);
mapView.map().events.bind(new Map.UpdateListener() {
public void setInputListener(Map.InputListener listener) { @Override
mapView.map().input.bind(listener); public void onMapEvent(Event event, MapPosition mapPosition) {
cameraUpdateListener.onCameraUpdate(GmsMapsTypeHelper.toCameraPosition(mapPosition));
}
});
} }
public Viewport getViewport() { public Viewport getViewport() {
@ -199,12 +210,12 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
if (markup instanceof MarkerItemMarkup) { if (markup instanceof MarkerItemMarkup) {
markupMap.remove(markup.getId()); markupMap.remove(markup.getId());
items.removeItem(items.getByUid(markup.getId())); items.removeItem(items.getByUid(markup.getId()));
redraw();
} else if (markup instanceof DrawableMarkup) { } else if (markup instanceof DrawableMarkup) {
drawableMarkups.remove(markup); drawableMarkups.remove(markup);
updateDrawableLayer(); updateDrawableLayer();
redraw(); drawables.update();
} }
redraw();
} }
public synchronized void update(Markup markup) { public synchronized void update(Markup markup) {
@ -214,6 +225,7 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
items.addItem(((MarkerItemMarkup) markup).getMarkerItem(context)); items.addItem(((MarkerItemMarkup) markup).getMarkerItem(context));
} else if (markup instanceof DrawableMarkup) { } else if (markup instanceof DrawableMarkup) {
updateDrawableLayer(); updateDrawableLayer();
drawables.update();
} }
redraw(); redraw();
} }
@ -229,8 +241,58 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
@Override @Override
public boolean onItemLongPress(int index, MarkerItem item) { public boolean onItemLongPress(int index, MarkerItem item) {
// TODO: start drag+drop Markup markup = markupMap.get(item.getUid());
Log.d(TAG, "onItemLongPress: " + markupMap.get(item.getUid())); if (((MarkerItemMarkup) markup).isDraggable()) {
currentlyDraggedItem = (MarkerItemMarkup) markup;
currentlyDraggedItem.onDragStart();
return false;
} else {
Log.d(TAG, "onItemLongPress: " + markup);
return false; 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 com.google.android.gms.maps.model.internal.ITileOverlayDelegate;
import org.microg.gms.maps.camera.CameraUpdate; 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.CircleImpl;
import org.microg.gms.maps.markup.GroundOverlayImpl; import org.microg.gms.maps.markup.GroundOverlayImpl;
import org.microg.gms.maps.markup.MarkerImpl; 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.PolygonImpl;
import org.microg.gms.maps.markup.PolylineImpl; import org.microg.gms.maps.markup.PolylineImpl;
import org.microg.gms.maps.markup.TileOverlayImpl; 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 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 static final String TAG = "GoogleMapImpl";
private final GoogleMapOptions options; private final GoogleMapOptions options;
@ -85,14 +83,32 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
private int polygonCounter = 0; private int polygonCounter = 0;
private IOnMarkerClickListener onMarkerClickListener; private IOnMarkerClickListener onMarkerClickListener;
private IOnMarkerDragListener onMarkerDragListener;
private IOnCameraChangeListener onCameraChangeListener;
public GoogleMapImpl(LayoutInflater inflater, GoogleMapOptions options) { public GoogleMapImpl(LayoutInflater inflater, GoogleMapOptions options) {
context = inflater.getContext(); context = inflater.getContext();
backendMap = new BackendMap(context); backendMap = new BackendMap(context, this);
backendMap.setInputListener(this);
uiSettings = new UiSettingsImpl(this); uiSettings = new UiSettingsImpl(this);
projection = new ProjectionImpl(backendMap.getViewport()); projection = new ProjectionImpl(backendMap.getViewport());
this.options = options; 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() { public void onDestroy() {
@ -138,12 +154,12 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
@Override @Override
public float getMaxZoomLevel() throws RemoteException { public float getMaxZoomLevel() throws RemoteException {
return 0; return (float) backendMap.getViewport().limitScale(Double.MIN_VALUE);
} }
@Override @Override
public float getMinZoomLevel() throws RemoteException { public float getMinZoomLevel() throws RemoteException {
return 0; return (float) backendMap.getViewport().limitScale(Double.MAX_VALUE);
} }
@Override @Override
@ -182,6 +198,17 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
backendMap.stopAnimation(); 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 Markers, polylines, polygons, overlays, etc
*/ */
@ -193,7 +220,6 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
@Override @Override
public IPolylineDelegate addPolyline(PolylineOptions options) throws RemoteException { public IPolylineDelegate addPolyline(PolylineOptions options) throws RemoteException {
Log.d(TAG, "addPolyline");
return backendMap.add(new PolylineImpl(getNextPolylineId(), options, this)); return backendMap.add(new PolylineImpl(getNextPolylineId(), options, this));
} }
@ -260,6 +286,57 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
return false; 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 Map options
*/ */
@ -334,6 +411,10 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
if (settings.isZoomControlsEnabled()) { if (settings.isZoomControlsEnabled()) {
Log.w(TAG, "ZoomControls not yet supported"); 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 @Override
public void setOnCameraChangeListener(IOnCameraChangeListener listener) throws RemoteException { public void setOnCameraChangeListener(IOnCameraChangeListener listener) throws RemoteException {
this.onCameraChangeListener = listener;
} }
@Override @Override
@ -362,7 +443,7 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub
@Override @Override
public void setOnMarkerDragListener(IOnMarkerDragListener listener) throws RemoteException { public void setOnMarkerDragListener(IOnMarkerDragListener listener) throws RemoteException {
this.onMarkerDragListener = listener;
} }
@Override @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 @Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
if (super.onTransact(code, data, reply, flags)) return true; 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 zoomControlsEnabled;
private boolean compassEnabled; private boolean compassEnabled;
private boolean myLocationButtonEnabled; private boolean myLocationButtonEnabled;
private boolean scrollGesturesEnabled; private boolean scrollGesturesEnabled = true;
private boolean zoomGesturesEnabled; private boolean zoomGesturesEnabled = true;
private boolean tiltGesturesEnabled; private boolean tiltGesturesEnabled = true;
private boolean rotateGesturesEnabled; private boolean rotateGesturesEnabled = true;
private UiSettingsListener listener; private UiSettingsListener listener;

View File

@ -33,6 +33,18 @@ import org.oscim.map.Map;
public class CameraUpdateFactoryImpl extends ICameraUpdateFactoryDelegate.Stub { public class CameraUpdateFactoryImpl extends ICameraUpdateFactoryDelegate.Stub {
private static final String TAG = "GmsMapCamUpdateFactory"; 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 @Override
public IObjectWrapper zoomIn() throws RemoteException { public IObjectWrapper zoomIn() throws RemoteException {
Log.d(TAG, "zoomIn"); Log.d(TAG, "zoomIn");

View File

@ -32,4 +32,13 @@ public abstract class MapPositionCameraUpdate implements CameraUpdate {
public void applyAnimated(Map map, int duration) { public void applyAnimated(Map map, int duration) {
map.animator().animateTo(duration, getMapPosition(map)); 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); 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 @Override
public Drawable getDrawable(Map map) { public Drawable getDrawable(Map map) {
if (!isVisible() || removed) return null; if (!isVisible() || removed) return null;

View File

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

View File

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

View File

@ -21,11 +21,21 @@ public interface Markup {
boolean onClick(); boolean onClick();
void onDragStart();
void onDragStop();
void onDragProgress();
interface MarkupListener { interface MarkupListener {
void update(Markup markup); void update(Markup markup);
void remove(Markup markup); void remove(Markup markup);
boolean onClick(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); 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 @Override
public void setPoints(List<LatLng> points) throws RemoteException { public void setPoints(List<LatLng> points) throws RemoteException {
options.getPoints().clear(); options.getPoints().clear();

View File

@ -66,6 +66,21 @@ public class PolylineImpl extends IPolylineDelegate.Stub implements DrawableMark
return listener.onClick(this); 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 @Override
public void setPoints(List<LatLng> points) { public void setPoints(List<LatLng> points) {
options.getPoints().clear(); options.getPoints().clear();