Loading src/org/microg/gms/maps/BackendMap.java +41 −9 Original line number Diff line number Diff line Loading @@ -18,9 +18,11 @@ package org.microg.gms.maps; import android.content.Context; import android.graphics.BitmapFactory; import android.util.Log; import android.view.View; import com.google.android.gms.R; import org.microg.gms.maps.bitmap.DefaultBitmapDescriptor; import org.microg.gms.maps.camera.CameraUpdate; import org.microg.gms.maps.markup.Markup; import org.oscim.android.MapView; Loading @@ -40,6 +42,8 @@ import org.oscim.theme.VtmThemes; import org.oscim.tiling.source.oscimap4.OSciMap4TileSource; public class BackendMap { private final static String TAG = "GmsBackendMap"; private final Context context; private final MapView mapView; private final BuildingLayer buildings; Loading Loading @@ -135,8 +139,21 @@ public class BackendMap { } public <T extends Markup> T add(T markup) { switch (markup.getType()) { case MARKER: 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); } return markup; } Loading @@ -146,14 +163,29 @@ public class BackendMap { } public void remove(Markup markup) { switch (markup.getType()) { case MARKER: items.removeItem(items.getByUid(markup.getId())); redraw(); break; default: Log.d(TAG, "Unknown markup: " + markup); } } public void update(Markup markup) { switch (markup.getType()) { case MARKER: // TODO: keep order items.removeItem(items.getByUid(markup.getId())); items.addItem(markup.getMarkerItem(context)); redraw(); break; case LAYER: redraw(); break; default: Log.d(TAG, "Unknown markup: " + markup); } } } src/org/microg/gms/maps/GoogleMapImpl.java +46 −7 Original line number Diff line number Diff line Loading @@ -22,14 +22,48 @@ import android.os.RemoteException; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.dynamic.ObjectWrapper; import com.google.android.gms.maps.GoogleMapOptions; import com.google.android.gms.maps.internal.*; import com.google.android.gms.maps.model.*; import com.google.android.gms.maps.model.internal.*; import com.google.android.gms.maps.internal.ICancelableCallback; import com.google.android.gms.maps.internal.IGoogleMapDelegate; import com.google.android.gms.maps.internal.IInfoWindowAdapter; import com.google.android.gms.maps.internal.ILocationSourceDelegate; import com.google.android.gms.maps.internal.IOnCameraChangeListener; import com.google.android.gms.maps.internal.IOnInfoWindowClickListener; import com.google.android.gms.maps.internal.IOnMapClickListener; import com.google.android.gms.maps.internal.IOnMapLoadedCallback; import com.google.android.gms.maps.internal.IOnMapLongClickListener; import com.google.android.gms.maps.internal.IOnMarkerClickListener; import com.google.android.gms.maps.internal.IOnMarkerDragListener; import com.google.android.gms.maps.internal.IOnMyLocationButtonClickListener; import com.google.android.gms.maps.internal.IOnMyLocationChangeListener; import com.google.android.gms.maps.internal.IProjectionDelegate; import com.google.android.gms.maps.internal.ISnapshotReadyCallback; import com.google.android.gms.maps.internal.IUiSettingsDelegate; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.GroundOverlayOptions; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.PolygonOptions; import com.google.android.gms.maps.model.PolylineOptions; import com.google.android.gms.maps.model.TileOverlayOptions; import com.google.android.gms.maps.model.internal.ICircleDelegate; import com.google.android.gms.maps.model.internal.IGroundOverlayDelegate; import com.google.android.gms.maps.model.internal.IMarkerDelegate; import com.google.android.gms.maps.model.internal.IPolygonDelegate; 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.markup.*; import org.microg.gms.maps.markup.CircleImpl; import org.microg.gms.maps.markup.GroundOverlayImpl; import org.microg.gms.maps.markup.MarkerImpl; 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; Loading @@ -45,6 +79,7 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub private final ProjectionImpl projection; private int markerCounter = 0; private int circleCounter = 0; public GoogleMapImpl(LayoutInflater inflater, GoogleMapOptions options) { context = inflater.getContext(); Loading Loading @@ -75,6 +110,10 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub return "m" + markerCounter++; } private String getNextCircleId() { return "c" + circleCounter++; } /* Camera */ Loading Loading @@ -136,7 +175,7 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub @Override public ICircleDelegate addCircle(CircleOptions options) throws RemoteException { return new CircleImpl(options); // TODO return backendMap.add(new CircleImpl(getNextCircleId(), options, this)); } @Override Loading src/org/microg/gms/maps/markup/CircleImpl.java +205 −26 Original line number Diff line number Diff line Loading @@ -16,102 +16,136 @@ package org.microg.gms.maps.markup; import android.content.Context; import android.os.RemoteException; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.internal.ICircleDelegate; public class CircleImpl extends ICircleDelegate.Stub { private LatLng center; private double radius; private float zIndex; private boolean visible; private String id; private float strokeWidth; private int strokeColor; private int fillColor; 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.oscim.layers.Layer; import org.oscim.layers.marker.MarkerItem; 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; 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; public CircleImpl(CircleOptions options) { 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); } @Override public String getId() throws RemoteException { public String getId() { return id; } @Override public void setCenter(LatLng center) throws RemoteException { this.center = center; options.center(center); point = new Point(longitudeToX(center.longitude), latitudeToY(center.latitude)); drawRadius = (float) (options.getRadius() / groundResolution(center.latitude, 1)); } @Override public LatLng getCenter() throws RemoteException { return center; return options.getCenter(); } @Override public void setRadius(double radius) throws RemoteException { this.radius = radius; options.radius(radius); if (point != null) { this.drawRadius = (float) (options.getRadius() / groundResolution(options.getCenter().latitude, 1)); } } @Override public double getRadius() throws RemoteException { return radius; return options.getRadius(); } @Override public void setStrokeWidth(float width) throws RemoteException { this.strokeWidth = width; options.strokeWidth(width); } @Override public float getStrokeWidth() throws RemoteException { return strokeWidth; return options.getStrokeWidth(); } @Override public void setStrokeColor(int color) throws RemoteException { this.strokeColor = color; options.strokeColor(color); } @Override public int getStrokeColor() throws RemoteException { return strokeColor; return options.getStrokeColor(); } @Override public void setFillColor(int color) throws RemoteException { this.fillColor = color; options.fillColor(color); listener.update(this); } @Override public int getFillColor() throws RemoteException { return fillColor; return options.getFillColor(); } @Override public void setZIndex(float zIndex) throws RemoteException { this.zIndex = zIndex; options.zIndex(zIndex); } @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); } @Override public boolean isVisible() throws RemoteException { return visible; return options.isVisible(); } @Override Loading @@ -123,4 +157,149 @@ public class CircleImpl extends ICircleDelegate.Stub { public int hashCodeRemote() throws RemoteException { return id.hashCode(); } @Override public MarkerItem getMarkerItem(Context context) { return null; } @Override public Layer getLayer(Context context, Map map) { if (layer == null) { layer = new CircleLayer(map); } return layer; } @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 direction; private int color; @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); 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); GL.uniform2f(direction, 0, 0); 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); 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"); direction = GL.getUniformLocation(shader, "u_dir"); color = GL.getUniformLocation(shader, "u_color"); 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 float u_phase;" + "uniform vec2 u_dir;" + "uniform vec4 u_color;" + "void main() {" + " float len = 1.0 - length(v_tex);" + " float a = smoothstep(0.0, 2.0 / u_scale, len);" + " gl_FragColor = u_color * a;" + "}"; } src/org/microg/gms/maps/markup/MarkerImpl.java +15 −71 Original line number Diff line number Diff line Loading @@ -27,85 +27,19 @@ import com.google.android.gms.maps.model.internal.IMarkerDelegate; import org.microg.gms.maps.GmsMapsTypeHelper; import org.microg.gms.maps.bitmap.BitmapDescriptorImpl; import org.oscim.android.canvas.AndroidBitmap; import org.oscim.layers.Layer; import org.oscim.layers.marker.MarkerItem; import org.oscim.layers.marker.MarkerSymbol; import org.oscim.map.Map; public class MarkerImpl extends IMarkerDelegate.Stub implements Markup { private static final String TAG = MarkerImpl.class.getName(); private final String id; private MarkerOptions options; private final MarkerOptions options; private final MarkupListener listener; private BitmapDescriptorImpl icon; private MarkupListener listener; /*private Overlay overlay = new Overlay() { private Point point = new Point(); @Override public boolean onTap(GeoPoint p, MapView mapView) { Point touchPoint = mapView.getProjection().toPixels(p, null); Bitmap bitmap = icon.getBitmap(); if (bitmap == null) return false; //mapView.getProjection().toPixels(position.toGeoPoint(), point); float xTest = bitmap.getWidth() * anchorU + touchPoint.x - point.x; float yTest = bitmap.getHeight() * anchorV + touchPoint.y - point.y; if (0 < xTest && xTest < bitmap.getWidth() && 0 < yTest && yTest < bitmap.getHeight()) { Log.d(TAG, "touched " + title); IOnMarkerClickListener markerClickListener = map.getMarkerClickListener(); boolean result = false; if (markerClickListener != null) { try { result = markerClickListener.onMarkerClick(MarkerImpl.this); } catch (RemoteException e) { Log.w(TAG, e); } } if (!result) { mapView.getController().animateTo(position.toGeoPoint()); map.showInfoWindow(MarkerImpl.this); } return true; } return false; } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { if (shadow && flat) return; // shadows are broken right now, we skip them Bitmap bitmap = icon.getBitmap(); if (bitmap != null) { //mapView.getProjection().toPixels(position.toGeoPoint(), point); float x = point.x - bitmap.getWidth() * anchorU; float y = point.y - bitmap.getHeight() * anchorV; Paint paint = new Paint(); paint.setAlpha((int) (alpha * 255)); if (shadow) { paint.setColorFilter( new PorterDuffColorFilter(Color.argb((int) (128 * alpha), 0, 0, 0), PorterDuff.Mode.SRC_IN)); } Matrix matrix = new Matrix(); matrix.setRotate(rotation, bitmap.getWidth() / 2, bitmap.getHeight() / 2); if (shadow) { matrix.postSkew(-0.9F, 0); matrix.postScale(1, 0.5F); } matrix.postTranslate(x, y); canvas.drawBitmap(bitmap, matrix, paint); } else { icon.loadBitmapAsync(map.getContext(), new Runnable() { @Override public void run() { map.redraw(); } }); } } };*/ public MarkerImpl(String id, MarkerOptions options, MarkupListener listener) { this.id = id; this.listener = listener; Loading Loading @@ -274,7 +208,7 @@ public class MarkerImpl extends IMarkerDelegate.Stub implements Markup { if (icon.getBitmap() != null) { item.setMarker( new MarkerSymbol(new AndroidBitmap(icon.getBitmap()), options.getAnchorU(), options.getAnchorV(), isFlat())); options.getAnchorV(), !options.isFlat())); } else { icon.loadBitmapAsync(context, new Runnable() { @Override Loading @@ -286,4 +220,14 @@ public class MarkerImpl extends IMarkerDelegate.Stub implements Markup { } return item; } @Override public Layer getLayer(Context context, Map map) { return null; } @Override public Type getType() { return Type.MARKER; } } src/org/microg/gms/maps/markup/Markup.java +11 −0 Original line number Diff line number Diff line Loading @@ -17,13 +17,24 @@ package org.microg.gms.maps.markup; import android.content.Context; import org.oscim.layers.Layer; import org.oscim.layers.marker.MarkerItem; import org.oscim.map.Map; public interface Markup { public MarkerItem getMarkerItem(Context context); public Layer getLayer(Context context, Map map); public Type getType(); public String getId(); public static enum Type { MARKER, LAYER } public static interface MarkupListener { void update(Markup markup); Loading Loading
src/org/microg/gms/maps/BackendMap.java +41 −9 Original line number Diff line number Diff line Loading @@ -18,9 +18,11 @@ package org.microg.gms.maps; import android.content.Context; import android.graphics.BitmapFactory; import android.util.Log; import android.view.View; import com.google.android.gms.R; import org.microg.gms.maps.bitmap.DefaultBitmapDescriptor; import org.microg.gms.maps.camera.CameraUpdate; import org.microg.gms.maps.markup.Markup; import org.oscim.android.MapView; Loading @@ -40,6 +42,8 @@ import org.oscim.theme.VtmThemes; import org.oscim.tiling.source.oscimap4.OSciMap4TileSource; public class BackendMap { private final static String TAG = "GmsBackendMap"; private final Context context; private final MapView mapView; private final BuildingLayer buildings; Loading Loading @@ -135,8 +139,21 @@ public class BackendMap { } public <T extends Markup> T add(T markup) { switch (markup.getType()) { case MARKER: 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); } return markup; } Loading @@ -146,14 +163,29 @@ public class BackendMap { } public void remove(Markup markup) { switch (markup.getType()) { case MARKER: items.removeItem(items.getByUid(markup.getId())); redraw(); break; default: Log.d(TAG, "Unknown markup: " + markup); } } public void update(Markup markup) { switch (markup.getType()) { case MARKER: // TODO: keep order items.removeItem(items.getByUid(markup.getId())); items.addItem(markup.getMarkerItem(context)); redraw(); break; case LAYER: redraw(); break; default: Log.d(TAG, "Unknown markup: " + markup); } } }
src/org/microg/gms/maps/GoogleMapImpl.java +46 −7 Original line number Diff line number Diff line Loading @@ -22,14 +22,48 @@ import android.os.RemoteException; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import com.google.android.gms.dynamic.IObjectWrapper; import com.google.android.gms.dynamic.ObjectWrapper; import com.google.android.gms.maps.GoogleMapOptions; import com.google.android.gms.maps.internal.*; import com.google.android.gms.maps.model.*; import com.google.android.gms.maps.model.internal.*; import com.google.android.gms.maps.internal.ICancelableCallback; import com.google.android.gms.maps.internal.IGoogleMapDelegate; import com.google.android.gms.maps.internal.IInfoWindowAdapter; import com.google.android.gms.maps.internal.ILocationSourceDelegate; import com.google.android.gms.maps.internal.IOnCameraChangeListener; import com.google.android.gms.maps.internal.IOnInfoWindowClickListener; import com.google.android.gms.maps.internal.IOnMapClickListener; import com.google.android.gms.maps.internal.IOnMapLoadedCallback; import com.google.android.gms.maps.internal.IOnMapLongClickListener; import com.google.android.gms.maps.internal.IOnMarkerClickListener; import com.google.android.gms.maps.internal.IOnMarkerDragListener; import com.google.android.gms.maps.internal.IOnMyLocationButtonClickListener; import com.google.android.gms.maps.internal.IOnMyLocationChangeListener; import com.google.android.gms.maps.internal.IProjectionDelegate; import com.google.android.gms.maps.internal.ISnapshotReadyCallback; import com.google.android.gms.maps.internal.IUiSettingsDelegate; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.GroundOverlayOptions; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.PolygonOptions; import com.google.android.gms.maps.model.PolylineOptions; import com.google.android.gms.maps.model.TileOverlayOptions; import com.google.android.gms.maps.model.internal.ICircleDelegate; import com.google.android.gms.maps.model.internal.IGroundOverlayDelegate; import com.google.android.gms.maps.model.internal.IMarkerDelegate; import com.google.android.gms.maps.model.internal.IPolygonDelegate; 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.markup.*; import org.microg.gms.maps.markup.CircleImpl; import org.microg.gms.maps.markup.GroundOverlayImpl; import org.microg.gms.maps.markup.MarkerImpl; 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; Loading @@ -45,6 +79,7 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub private final ProjectionImpl projection; private int markerCounter = 0; private int circleCounter = 0; public GoogleMapImpl(LayoutInflater inflater, GoogleMapOptions options) { context = inflater.getContext(); Loading Loading @@ -75,6 +110,10 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub return "m" + markerCounter++; } private String getNextCircleId() { return "c" + circleCounter++; } /* Camera */ Loading Loading @@ -136,7 +175,7 @@ public class GoogleMapImpl extends IGoogleMapDelegate.Stub @Override public ICircleDelegate addCircle(CircleOptions options) throws RemoteException { return new CircleImpl(options); // TODO return backendMap.add(new CircleImpl(getNextCircleId(), options, this)); } @Override Loading
src/org/microg/gms/maps/markup/CircleImpl.java +205 −26 Original line number Diff line number Diff line Loading @@ -16,102 +16,136 @@ package org.microg.gms.maps.markup; import android.content.Context; import android.os.RemoteException; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.internal.ICircleDelegate; public class CircleImpl extends ICircleDelegate.Stub { private LatLng center; private double radius; private float zIndex; private boolean visible; private String id; private float strokeWidth; private int strokeColor; private int fillColor; 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.oscim.layers.Layer; import org.oscim.layers.marker.MarkerItem; 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; 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; public CircleImpl(CircleOptions options) { 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); } @Override public String getId() throws RemoteException { public String getId() { return id; } @Override public void setCenter(LatLng center) throws RemoteException { this.center = center; options.center(center); point = new Point(longitudeToX(center.longitude), latitudeToY(center.latitude)); drawRadius = (float) (options.getRadius() / groundResolution(center.latitude, 1)); } @Override public LatLng getCenter() throws RemoteException { return center; return options.getCenter(); } @Override public void setRadius(double radius) throws RemoteException { this.radius = radius; options.radius(radius); if (point != null) { this.drawRadius = (float) (options.getRadius() / groundResolution(options.getCenter().latitude, 1)); } } @Override public double getRadius() throws RemoteException { return radius; return options.getRadius(); } @Override public void setStrokeWidth(float width) throws RemoteException { this.strokeWidth = width; options.strokeWidth(width); } @Override public float getStrokeWidth() throws RemoteException { return strokeWidth; return options.getStrokeWidth(); } @Override public void setStrokeColor(int color) throws RemoteException { this.strokeColor = color; options.strokeColor(color); } @Override public int getStrokeColor() throws RemoteException { return strokeColor; return options.getStrokeColor(); } @Override public void setFillColor(int color) throws RemoteException { this.fillColor = color; options.fillColor(color); listener.update(this); } @Override public int getFillColor() throws RemoteException { return fillColor; return options.getFillColor(); } @Override public void setZIndex(float zIndex) throws RemoteException { this.zIndex = zIndex; options.zIndex(zIndex); } @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); } @Override public boolean isVisible() throws RemoteException { return visible; return options.isVisible(); } @Override Loading @@ -123,4 +157,149 @@ public class CircleImpl extends ICircleDelegate.Stub { public int hashCodeRemote() throws RemoteException { return id.hashCode(); } @Override public MarkerItem getMarkerItem(Context context) { return null; } @Override public Layer getLayer(Context context, Map map) { if (layer == null) { layer = new CircleLayer(map); } return layer; } @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 direction; private int color; @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); 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); GL.uniform2f(direction, 0, 0); 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); 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"); direction = GL.getUniformLocation(shader, "u_dir"); color = GL.getUniformLocation(shader, "u_color"); 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 float u_phase;" + "uniform vec2 u_dir;" + "uniform vec4 u_color;" + "void main() {" + " float len = 1.0 - length(v_tex);" + " float a = smoothstep(0.0, 2.0 / u_scale, len);" + " gl_FragColor = u_color * a;" + "}"; }
src/org/microg/gms/maps/markup/MarkerImpl.java +15 −71 Original line number Diff line number Diff line Loading @@ -27,85 +27,19 @@ import com.google.android.gms.maps.model.internal.IMarkerDelegate; import org.microg.gms.maps.GmsMapsTypeHelper; import org.microg.gms.maps.bitmap.BitmapDescriptorImpl; import org.oscim.android.canvas.AndroidBitmap; import org.oscim.layers.Layer; import org.oscim.layers.marker.MarkerItem; import org.oscim.layers.marker.MarkerSymbol; import org.oscim.map.Map; public class MarkerImpl extends IMarkerDelegate.Stub implements Markup { private static final String TAG = MarkerImpl.class.getName(); private final String id; private MarkerOptions options; private final MarkerOptions options; private final MarkupListener listener; private BitmapDescriptorImpl icon; private MarkupListener listener; /*private Overlay overlay = new Overlay() { private Point point = new Point(); @Override public boolean onTap(GeoPoint p, MapView mapView) { Point touchPoint = mapView.getProjection().toPixels(p, null); Bitmap bitmap = icon.getBitmap(); if (bitmap == null) return false; //mapView.getProjection().toPixels(position.toGeoPoint(), point); float xTest = bitmap.getWidth() * anchorU + touchPoint.x - point.x; float yTest = bitmap.getHeight() * anchorV + touchPoint.y - point.y; if (0 < xTest && xTest < bitmap.getWidth() && 0 < yTest && yTest < bitmap.getHeight()) { Log.d(TAG, "touched " + title); IOnMarkerClickListener markerClickListener = map.getMarkerClickListener(); boolean result = false; if (markerClickListener != null) { try { result = markerClickListener.onMarkerClick(MarkerImpl.this); } catch (RemoteException e) { Log.w(TAG, e); } } if (!result) { mapView.getController().animateTo(position.toGeoPoint()); map.showInfoWindow(MarkerImpl.this); } return true; } return false; } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { if (shadow && flat) return; // shadows are broken right now, we skip them Bitmap bitmap = icon.getBitmap(); if (bitmap != null) { //mapView.getProjection().toPixels(position.toGeoPoint(), point); float x = point.x - bitmap.getWidth() * anchorU; float y = point.y - bitmap.getHeight() * anchorV; Paint paint = new Paint(); paint.setAlpha((int) (alpha * 255)); if (shadow) { paint.setColorFilter( new PorterDuffColorFilter(Color.argb((int) (128 * alpha), 0, 0, 0), PorterDuff.Mode.SRC_IN)); } Matrix matrix = new Matrix(); matrix.setRotate(rotation, bitmap.getWidth() / 2, bitmap.getHeight() / 2); if (shadow) { matrix.postSkew(-0.9F, 0); matrix.postScale(1, 0.5F); } matrix.postTranslate(x, y); canvas.drawBitmap(bitmap, matrix, paint); } else { icon.loadBitmapAsync(map.getContext(), new Runnable() { @Override public void run() { map.redraw(); } }); } } };*/ public MarkerImpl(String id, MarkerOptions options, MarkupListener listener) { this.id = id; this.listener = listener; Loading Loading @@ -274,7 +208,7 @@ public class MarkerImpl extends IMarkerDelegate.Stub implements Markup { if (icon.getBitmap() != null) { item.setMarker( new MarkerSymbol(new AndroidBitmap(icon.getBitmap()), options.getAnchorU(), options.getAnchorV(), isFlat())); options.getAnchorV(), !options.isFlat())); } else { icon.loadBitmapAsync(context, new Runnable() { @Override Loading @@ -286,4 +220,14 @@ public class MarkerImpl extends IMarkerDelegate.Stub implements Markup { } return item; } @Override public Layer getLayer(Context context, Map map) { return null; } @Override public Type getType() { return Type.MARKER; } }
src/org/microg/gms/maps/markup/Markup.java +11 −0 Original line number Diff line number Diff line Loading @@ -17,13 +17,24 @@ package org.microg.gms.maps.markup; import android.content.Context; import org.oscim.layers.Layer; import org.oscim.layers.marker.MarkerItem; import org.oscim.map.Map; public interface Markup { public MarkerItem getMarkerItem(Context context); public Layer getLayer(Context context, Map map); public Type getType(); public String getId(); public static enum Type { MARKER, LAYER } public static interface MarkupListener { void update(Markup markup); Loading