From 44f4bdc6aca4cf1783cf8320124bc1955ed093af Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Thu, 6 Aug 2015 17:02:47 +0200 Subject: [PATCH] Update Maps API --- extern/GmsApi | 2 +- .../java/org/microg/gms/maps/BackendMap.java | 45 ++-- .../microg/gms/maps/GmsMapsTypeHelper.java | 12 +- .../org/microg/gms/maps/GoogleMapImpl.java | 22 +- .../org/microg/gms/maps/ProjectionImpl.java | 4 +- .../microg/gms/maps/markup/CircleImpl.java | 204 +++--------------- .../org/microg/gms/maps/markup/Markup.java | 2 +- .../microg/gms/maps/markup/PolygonImpl.java | 40 +++- .../microg/gms/maps/markup/PolylineImpl.java | 111 ++++++++-- 9 files changed, 214 insertions(+), 228 deletions(-) diff --git a/extern/GmsApi b/extern/GmsApi index 0890bf4546..28ff7f36f2 160000 --- a/extern/GmsApi +++ b/extern/GmsApi @@ -1 +1 @@ -Subproject commit 0890bf454651e90274949af9dca09fbcfbf50d36 +Subproject commit 28ff7f36f2b75a29cead8efc25fc0418065db601 diff --git a/play-services-core/src/main/java/org/microg/gms/maps/BackendMap.java b/play-services-core/src/main/java/org/microg/gms/maps/BackendMap.java index 9da8ccfe59..1b9c86a3e5 100644 --- a/play-services-core/src/main/java/org/microg/gms/maps/BackendMap.java +++ b/play-services-core/src/main/java/org/microg/gms/maps/BackendMap.java @@ -49,6 +49,7 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener(mapView.map(), new MarkerSymbol(new AndroidBitmap(BitmapFactory .decodeResource(ResourcesContainer.get(), R.drawable.nop)), 0.5F, 1))); + layers.add(buildings = new BuildingLayer(mapView.map(), baseLayer)); items.setOnItemGestureListener(this); mapView.map().setTheme(VtmThemes.DEFAULT); } @@ -145,22 +146,30 @@ public void stopAnimation() { } public synchronized T add(T markup) { - switch (markup.getType()) { - case MARKER: - markupMap.put(markup.getId(), markup); - items.addItem(markup.getMarkerItem(context)); - redraw(); - break; - case LAYER: - Layers layers = mapView.map().layers(); - layers.add(markup.getLayer(context, mapView.map())); - layers.remove(items); - layers.add(items); - redraw(); - break; - default: - Log.d(TAG, "Unknown markup: " + markup); - } + if (markup != null && markup.getType() != null) + switch (markup.getType()) { + case MARKER: + markupMap.put(markup.getId(), markup); + items.addItem(markup.getMarkerItem(context)); + redraw(); + break; + case LAYER: + Layers layers = mapView.map().layers(); + // TODO: better sorting code + layers.add(markup.getLayer(context, mapView.map())); + if (hasBuilding()) { + layers.remove(buildings); + layers.add(buildings); + } + layers.remove(items); + layers.add(items); + layers.remove(labels); + layers.add(labels); + redraw(); + break; + default: + Log.d(TAG, "Unknown markup: " + markup); + } return markup; } diff --git a/play-services-core/src/main/java/org/microg/gms/maps/GmsMapsTypeHelper.java b/play-services-core/src/main/java/org/microg/gms/maps/GmsMapsTypeHelper.java index df49858d0a..1d9b40b911 100644 --- a/play-services-core/src/main/java/org/microg/gms/maps/GmsMapsTypeHelper.java +++ b/play-services-core/src/main/java/org/microg/gms/maps/GmsMapsTypeHelper.java @@ -19,9 +19,12 @@ 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 org.oscim.core.BoundingBox; +import org.oscim.core.Box; import org.oscim.core.GeoPoint; import org.oscim.core.MapPosition; +import org.oscim.core.MercatorProjection; public class GmsMapsTypeHelper { public static android.graphics.Point toPoint(org.oscim.core.Point in) { @@ -36,9 +39,12 @@ public static LatLng toLatLng(GeoPoint geoPoint) { return new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude()); } - public static LatLngBounds toLatLngBounds(BoundingBox box) { - return new LatLngBounds(new LatLng(box.getMinLatitude(), box.getMinLongitude()), - new LatLng(box.getMaxLatitude(), box.getMaxLongitude())); + public static LatLngBounds toLatLngBounds(Box box) { + double minLon = MercatorProjection.toLongitude(box.xmin); + double maxLon = MercatorProjection.toLongitude(box.xmax); + double minLat = MercatorProjection.toLatitude(box.ymax); + double maxLat = MercatorProjection.toLatitude(box.ymin); + return new LatLngBounds(new LatLng(minLat, minLon), new LatLng(maxLat, maxLon)); } public static org.oscim.core.Point fromPoint(android.graphics.Point point) { diff --git a/play-services-core/src/main/java/org/microg/gms/maps/GoogleMapImpl.java b/play-services-core/src/main/java/org/microg/gms/maps/GoogleMapImpl.java index 5be0f08394..6b78a63833 100644 --- a/play-services-core/src/main/java/org/microg/gms/maps/GoogleMapImpl.java +++ b/play-services-core/src/main/java/org/microg/gms/maps/GoogleMapImpl.java @@ -81,6 +81,9 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub private int markerCounter = 0; private int circleCounter = 0; + private int polylineCounter = 0; + private int polygonCounter = 0; + private IOnMarkerClickListener onMarkerClickListener; public GoogleMapImpl(LayoutInflater inflater, GoogleMapOptions options) { @@ -115,6 +118,14 @@ private String getNextMarkerId() { private String getNextCircleId() { return "c" + circleCounter++; } + + private String getNextPolylineId() { + return "l" + polylineCounter++; + } + + private String getNextPolygonId() { + return "p" + polygonCounter++; + } /* Camera @@ -182,14 +193,13 @@ public ICircleDelegate addCircle(CircleOptions options) throws RemoteException { @Override public IPolylineDelegate addPolyline(PolylineOptions options) throws RemoteException { - Log.d(TAG, "not yet usable: addPolyline"); - return new PolylineImpl(options); // TODO + Log.d(TAG, "addPolyline"); + return backendMap.add(new PolylineImpl(getNextPolylineId(), options, this)); } @Override public IPolygonDelegate addPolygon(PolygonOptions options) throws RemoteException { - Log.d(TAG, "not yet usable: addPolygon"); - return new PolygonImpl(options); // TODO + return backendMap.add(new PolygonImpl(getNextPolygonId(), options, this)); } @Override @@ -218,8 +228,10 @@ public void setInfoWindowAdapter(IInfoWindowAdapter adapter) throws RemoteExcept @Override public void clear() throws RemoteException { backendMap.clear(); - circleCounter = 0; markerCounter = 0; + circleCounter = 0; + polylineCounter = 0; + polygonCounter = 0; } @Override diff --git a/play-services-core/src/main/java/org/microg/gms/maps/ProjectionImpl.java b/play-services-core/src/main/java/org/microg/gms/maps/ProjectionImpl.java index 7a16f9e71c..385bae6e53 100644 --- a/play-services-core/src/main/java/org/microg/gms/maps/ProjectionImpl.java +++ b/play-services-core/src/main/java/org/microg/gms/maps/ProjectionImpl.java @@ -17,11 +17,13 @@ package org.microg.gms.maps; import android.os.RemoteException; + import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.dynamic.ObjectWrapper; import com.google.android.gms.maps.internal.IProjectionDelegate; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.VisibleRegion; + import org.oscim.core.Point; import org.oscim.map.Viewport; @@ -49,6 +51,6 @@ public IObjectWrapper toScreenLocation(LatLng latLng) throws RemoteException { @Override public VisibleRegion getVisibleRegion() throws RemoteException { - return new VisibleRegion(GmsMapsTypeHelper.toLatLngBounds(viewport.getBBox())); + return new VisibleRegion(GmsMapsTypeHelper.toLatLngBounds(viewport.getBBox(null, 0))); } } diff --git a/play-services-core/src/main/java/org/microg/gms/maps/markup/CircleImpl.java b/play-services-core/src/main/java/org/microg/gms/maps/markup/CircleImpl.java index 853c486f02..027636359d 100644 --- a/play-services-core/src/main/java/org/microg/gms/maps/markup/CircleImpl.java +++ b/play-services-core/src/main/java/org/microg/gms/maps/markup/CircleImpl.java @@ -23,52 +23,35 @@ import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.internal.ICircleDelegate; -import org.oscim.android.gl.AndroidGL; -import org.oscim.backend.GL20; -import org.oscim.backend.canvas.Color; -import org.oscim.core.Box; -import org.oscim.core.Point; -import org.oscim.core.Tile; +import org.microg.gms.maps.GmsMapsTypeHelper; import org.oscim.layers.Layer; import org.oscim.layers.marker.MarkerItem; +import org.oscim.layers.vector.VectorLayer; +import org.oscim.layers.vector.geometries.CircleDrawable; +import org.oscim.layers.vector.geometries.Style; import org.oscim.map.Map; -import org.oscim.renderer.GLShader; -import org.oscim.renderer.GLState; -import org.oscim.renderer.GLViewport; -import org.oscim.renderer.LayerRenderer; -import org.oscim.renderer.MapRenderer; -import static org.oscim.core.MercatorProjection.groundResolution; -import static org.oscim.core.MercatorProjection.latitudeToY; -import static org.oscim.core.MercatorProjection.longitudeToX; +//import org.oscim.backend.GL20; public class CircleImpl extends ICircleDelegate.Stub implements Markup { private final String id; private final CircleOptions options; private final MarkupListener listener; - private CircleLayer layer; - private Point point; - private float drawRadius; + private VectorLayer vectorLayer; + private CircleDrawable circleDrawable; private boolean removed = false; public CircleImpl(String id, CircleOptions options, MarkupListener listener) { this.id = id; this.listener = listener; this.options = options == null ? new CircleOptions() : options; - LatLng center = this.options.getCenter(); - if (center != null) { - point = new Point(longitudeToX(center.longitude), latitudeToY(center.latitude)); - drawRadius = (float) (options.getRadius() / groundResolution(center.latitude, 1)); - } } @Override public void remove() throws RemoteException { listener.remove(this); removed = true; - layer.setEnabled(false); - layer = null; } @Override @@ -79,8 +62,7 @@ public String getId() { @Override public void setCenter(LatLng center) throws RemoteException { options.center(center); - point = new Point(longitudeToX(center.longitude), latitudeToY(center.latitude)); - drawRadius = (float) (options.getRadius() / groundResolution(center.latitude, 1)); + if (vectorLayer != null) update(); } @Override @@ -91,9 +73,7 @@ public LatLng getCenter() throws RemoteException { @Override public void setRadius(double radius) throws RemoteException { options.radius(radius); - if (point != null) { - this.drawRadius = (float) (options.getRadius() / groundResolution(options.getCenter().latitude, 1)); - } + if (vectorLayer != null) update(); } @Override @@ -104,6 +84,7 @@ public double getRadius() throws RemoteException { @Override public void setStrokeWidth(float width) throws RemoteException { options.strokeWidth(width); + if (vectorLayer != null) update(); } @Override @@ -114,6 +95,7 @@ public float getStrokeWidth() throws RemoteException { @Override public void setStrokeColor(int color) throws RemoteException { options.strokeColor(color); + if (vectorLayer != null) update(); } @Override @@ -124,6 +106,7 @@ public int getStrokeColor() throws RemoteException { @Override public void setFillColor(int color) throws RemoteException { options.fillColor(color); + if (vectorLayer != null) update(); listener.update(this); } @@ -145,6 +128,7 @@ public float getZIndex() throws RemoteException { @Override public void setVisible(boolean visible) throws RemoteException { options.visible(visible); + if (vectorLayer != null) update(); } @Override @@ -179,154 +163,30 @@ public MarkerItem getMarkerItem(Context context) { @Override public Layer getLayer(Context context, Map map) { - if (layer == null) { - layer = new CircleLayer(map); + vectorLayer = new VectorLayer(map); + update(); + return vectorLayer; + } + + private void update() { + if (circleDrawable != null) { + vectorLayer.remove(circleDrawable); + } + if (options.isVisible()) { + circleDrawable = new CircleDrawable( + GmsMapsTypeHelper.fromLatLng(options.getCenter()), + options.getRadius() / 1000.0, + Style.builder() + .strokeColor(options.getStrokeColor()) + .fillColor(options.getFillColor()) + .strokeWidth(options.getStrokeWidth()).build()); + vectorLayer.add(circleDrawable); } - return layer; + vectorLayer.update(); } @Override public Type getType() { return Type.LAYER; } - - private class CircleLayer extends Layer { - - public CircleLayer(Map map) { - super(map); - mRenderer = new CircleRenderer(); - } - - private class CircleRenderer extends LayerRenderer { - private final Box bBox = new Box(); - private final Point screenPoint = new Point(); - private final Point indicatorPosition = new Point(); - private AndroidGL GL = new AndroidGL(); - - private int shader; - private int vertexPosition; - private int matrixPosition; - private int phase; - private int scale; - private int color; - - private int borderColor; - private int borderWidth; - - @Override - public void update(GLViewport viewport) { - if (!isEnabled()) { - setReady(false); - return; - } - - if (!viewport.changed() && isReady()) return; - - setReady(true); - - int width = mMap.getWidth(); - int height = mMap.getHeight(); - - // clamp location to a position that can be - // savely translated to screen coordinates - viewport.getBBox(bBox, 0); - - double x = point.x; - double y = point.y; - - // get position of Location in pixel relative to - // screen center - viewport.toScreenPoint(x, y, screenPoint); - - x = screenPoint.x + width / 2; - y = screenPoint.y + height / 2; - - viewport.fromScreenPoint(x, y, indicatorPosition); - } - - @Override - public void render(GLViewport viewport) { - - GLState.useProgram(shader); - GLState.blend(true); - GLState.test(false, false); - - GLState.enableVertexArrays(vertexPosition, -1); - MapRenderer.bindQuadVertexVBO(vertexPosition); - - float radius = (float) (drawRadius * viewport.pos.scale); - GL.uniform1f(scale, radius); - GL.uniform1f(borderWidth, (float) (options.getStrokeWidth() / (viewport.pos.scale * 10))); - - double x = indicatorPosition.x - viewport.pos.x; - double y = indicatorPosition.y - viewport.pos.y; - double tileScale = Tile.SIZE * viewport.pos.scale; - - viewport.mvp.setTransScale((float) (x * tileScale), (float) (y * tileScale), 1); - viewport.mvp.multiplyMM(viewport.viewproj, viewport.mvp); - viewport.mvp.setAsUniform(matrixPosition); - GL.uniform1f(phase, 1); - float alpha = Color.aToFloat(options.getFillColor()); - GL.uniform4f(color, - Color.rToFloat(options.getFillColor()) * alpha, - Color.gToFloat(options.getFillColor()) * alpha, - Color.bToFloat(options.getFillColor()) * alpha, - alpha); - - alpha = Color.aToFloat(options.getStrokeColor()); - GL.uniform4f(borderColor, - Color.rToFloat(options.getStrokeColor()) * alpha, - Color.gToFloat(options.getStrokeColor()) * alpha, - Color.bToFloat(options.getStrokeColor()) * alpha, - alpha); - - GL.drawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4); - } - - @Override - public boolean setup() { - shader = GLShader.createProgram(vShaderStr, fShaderStr); - if (shader == 0) - return false; - vertexPosition = GL.getAttribLocation(shader, "a_pos"); - matrixPosition = GL.getUniformLocation(shader, "u_mvp"); - phase = GL.getUniformLocation(shader, "u_phase"); - scale = GL.getUniformLocation(shader, "u_scale"); - color = GL.getUniformLocation(shader, "u_color"); - - borderColor = GL.getUniformLocation(shader, "u_border_color"); - borderWidth = GL.getUniformLocation(shader, "u_border_width"); - return true; - } - } - } - - private final static String vShaderStr = "" - + "precision mediump float;" - + "uniform mat4 u_mvp;" - + "uniform float u_phase;" - + "uniform float u_scale;" - + "attribute vec2 a_pos;" - + "varying vec2 v_tex;" - + "void main() {" - + " gl_Position = u_mvp * vec4(a_pos * u_scale * u_phase, 0.0, 1.0);" - + " v_tex = a_pos;" - + "}"; - - private final static String fShaderStr = "" - + "precision mediump float;" - + "varying vec2 v_tex;" - + "uniform float u_scale;" - + "uniform vec4 u_color;" - + "uniform float u_border_width;" - + "uniform vec4 u_border_color;" - + "void main() {" - + " float len = 1.0 - length(v_tex);" - + " float a = smoothstep(0.0, 2.0 / u_scale, len);" - + " if ( len > u_border_width )" - + " gl_FragColor = u_color;" - + " else " - + " gl_FragColor = u_border_color;" - + " gl_FragColor = gl_FragColor * a;" - + "}"; } diff --git a/play-services-core/src/main/java/org/microg/gms/maps/markup/Markup.java b/play-services-core/src/main/java/org/microg/gms/maps/markup/Markup.java index 787fca4a7d..3c8aecdc89 100644 --- a/play-services-core/src/main/java/org/microg/gms/maps/markup/Markup.java +++ b/play-services-core/src/main/java/org/microg/gms/maps/markup/Markup.java @@ -36,7 +36,7 @@ public interface Markup { public boolean isValid(); public static enum Type { - MARKER, LAYER + MARKER, LAYER, DRAWABLE } public static interface MarkupListener { diff --git a/play-services-core/src/main/java/org/microg/gms/maps/markup/PolygonImpl.java b/play-services-core/src/main/java/org/microg/gms/maps/markup/PolygonImpl.java index dd8997e4f2..b82c319547 100644 --- a/play-services-core/src/main/java/org/microg/gms/maps/markup/PolygonImpl.java +++ b/play-services-core/src/main/java/org/microg/gms/maps/markup/PolygonImpl.java @@ -16,14 +16,21 @@ package org.microg.gms.maps.markup; +import android.content.Context; import android.os.RemoteException; + import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.PolygonOptions; import com.google.android.gms.maps.model.internal.IPolygonDelegate; +import org.microg.gms.maps.GoogleMapImpl; +import org.oscim.layers.Layer; +import org.oscim.layers.marker.MarkerItem; +import org.oscim.map.Map; + import java.util.List; -public class PolygonImpl extends IPolygonDelegate.Stub { +public class PolygonImpl extends IPolygonDelegate.Stub implements Markup { private List points; private List holes; private float zIndex; @@ -34,8 +41,8 @@ public class PolygonImpl extends IPolygonDelegate.Stub { private int strokeColor; private int fillColor; - public PolygonImpl(PolygonOptions options) { - + public PolygonImpl(String id, PolygonOptions options, MarkupListener listener) { + this.id = id; } @Override @@ -44,10 +51,35 @@ public void remove() throws RemoteException { } @Override - public String getId() throws RemoteException { + public MarkerItem getMarkerItem(Context context) { + return null; + } + + @Override + public Layer getLayer(Context context, Map map) { + return null; + } + + @Override + public Type getType() { + return null; + } + + @Override + public String getId() { return id; } + @Override + public boolean onClick() { + return false; + } + + @Override + public boolean isValid() { + return false; + } + @Override public void setPoints(List points) throws RemoteException { this.points = points; diff --git a/play-services-core/src/main/java/org/microg/gms/maps/markup/PolylineImpl.java b/play-services-core/src/main/java/org/microg/gms/maps/markup/PolylineImpl.java index 333ceef30e..e42db2d1e0 100644 --- a/play-services-core/src/main/java/org/microg/gms/maps/markup/PolylineImpl.java +++ b/play-services-core/src/main/java/org/microg/gms/maps/markup/PolylineImpl.java @@ -16,107 +16,172 @@ package org.microg.gms.maps.markup; +import android.content.Context; import android.os.RemoteException; +import android.util.Log; + import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.PolylineOptions; import com.google.android.gms.maps.model.internal.IPolylineDelegate; -import java.util.Collections; +import org.microg.gms.maps.GmsMapsTypeHelper; +import org.oscim.layers.Layer; +import org.oscim.layers.PathLayer; +import org.oscim.layers.marker.MarkerItem; +import org.oscim.map.Map; + import java.util.List; /** * TODO */ -public class PolylineImpl extends IPolylineDelegate.Stub { - private List points; - private float zIndex; - private boolean geodesic; - private boolean visible; - private String id; - private float width; - private int color; +public class PolylineImpl extends IPolylineDelegate.Stub implements Markup { + private static final String TAG = "GmsMapsPolylineImpl"; - public PolylineImpl(PolylineOptions options) { + private final String id; + private final PolylineOptions options; + private final MarkupListener listener; + private boolean removed = false; + private PathLayer pathLayer; + public PolylineImpl(String id, PolylineOptions options, MarkupListener listener) { + this.id = id; + this.options = options == null ? new PolylineOptions() : options; + this.listener = listener; } @Override public void remove() throws RemoteException { + listener.remove(this); + removed = true; + } + + @Override + public MarkerItem getMarkerItem(Context context) { + return null; + } + + @Override + public Layer getLayer(Context context, Map map) { + pathLayer = new PathLayer(map, options.getColor(), options.getWidth()); + for (LatLng point : options.getPoints()) { + pathLayer.addPoint(GmsMapsTypeHelper.fromLatLng(point)); + } + return pathLayer; + } + @Override + public Type getType() { + return Type.LAYER; } @Override - public String getId() throws RemoteException { + public String getId() { return id; } + @Override + public boolean onClick() { + return listener.onClick(this); + } + + @Override + public boolean isValid() { + return !removed; + } + @Override public void setPoints(List points) throws RemoteException { - this.points = points; + options.getPoints().clear(); + options.getPoints().addAll(points); + if (pathLayer != null) { + pathLayer.clearPath(); + for (LatLng point : points) { + pathLayer.addPoint(GmsMapsTypeHelper.fromLatLng(point)); + } + pathLayer.update(); + } + listener.update(this); } @Override public List getPoints() throws RemoteException { - return points == null ? Collections.emptyList() : points; + return options.getPoints(); } @Override public void setWidth(float width) throws RemoteException { - this.width = width; + options.width(width); + if (pathLayer != null) { + pathLayer.setStyle(options.getColor(), options.getWidth()); + pathLayer.update(); + } + listener.update(this); } @Override public float getWidth() throws RemoteException { - return width; + return options.getWidth(); } @Override public void setColor(int color) throws RemoteException { - this.color = color; + this.options.color(color); + if (pathLayer != null) { + pathLayer.setStyle(options.getColor(), options.getWidth()); + pathLayer.update(); + } + listener.update(this); } @Override public int getColor() throws RemoteException { - return color; + return options.getColor(); } @Override public void setZIndex(float zIndex) throws RemoteException { - this.zIndex = zIndex; + options.zIndex(zIndex); + listener.update(this); } @Override public float getZIndex() throws RemoteException { - return zIndex; + return options.getZIndex(); } @Override public void setVisible(boolean visible) throws RemoteException { - this.visible = visible; + options.visible(visible); + if (pathLayer != null) pathLayer.setEnabled(visible); + listener.update(this); } @Override public boolean isVisible() throws RemoteException { - return visible; + return options.isVisible(); } @Override public void setGeodesic(boolean geod) throws RemoteException { - this.geodesic = geod; + options.geodesic(geod); + listener.update(this); } @Override public boolean isGeodesic() throws RemoteException { - return geodesic; + return options.isGeodesic(); } @Override public boolean equalsRemote(IPolylineDelegate other) throws RemoteException { + Log.d(TAG, "equalsRemote"); return other != null && other.getId().equals(getId()); } @Override public int hashCodeRemote() throws RemoteException { + Log.d(TAG, "hashcodeRemote"); return id.hashCode(); } }