Update Maps API

This commit is contained in:
mar-v-in 2015-10-02 18:10:48 +02:00
parent 3519d33709
commit b0701625ad
35 changed files with 541 additions and 295 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,10 +23,13 @@ import android.view.View;
import com.google.android.gms.R;
import org.microg.gms.maps.data.SharedTileCache;
import org.microg.gms.maps.camera.CameraUpdate;
import org.microg.gms.maps.markup.ClearableVectorLayer;
import org.microg.gms.maps.markup.DrawableMarkup;
import org.microg.gms.maps.markup.MarkerItemMarkup;
import org.microg.gms.maps.markup.Markup;
import org.oscim.android.MapView;
import org.oscim.android.cache.TileCache;
import org.oscim.android.canvas.AndroidBitmap;
import org.oscim.core.MapPosition;
import org.oscim.layers.marker.ItemizedLayer;
@ -39,10 +42,15 @@ import org.oscim.map.Layers;
import org.oscim.map.Map;
import org.oscim.map.Viewport;
import org.oscim.theme.VtmThemes;
import org.oscim.tiling.ITileCache;
import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerItem> {
private final static String TAG = "GmsMapBackend";
@ -53,25 +61,26 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
private final BuildingLayer buildings;
private final VectorTileLayer baseLayer;
private final OSciMap4TileSource tileSource;
private final TileCache cache;
private final ITileCache cache;
private final ItemizedLayer<MarkerItem> items;
private java.util.Map<String, Markup> markupMap = new HashMap<String, Markup>();
private boolean redrawPosted = false;
private List<DrawableMarkup> drawableMarkups = new ArrayList<DrawableMarkup>();
private ClearableVectorLayer drawables;
public BackendMap(Context context) {
this.context = context;
mapView = new MapView(new ContextContainer(context));
// TODO: Use a shared tile cache (provider?)
cache = new TileCache(context, null, "tile.db");
cache = new SharedTileCache(context);
cache.setCacheSize(512 * (1 << 10));
tileSource = new OSciMap4TileSource();
tileSource.setCache(cache);
baseLayer = mapView.map().setBaseMap(tileSource);
Layers layers = mapView.map().layers();
layers.add(labels = new LabelLayer(mapView.map(), baseLayer));
layers.add(drawables = new ClearableVectorLayer(mapView.map()));
layers.add(buildings = new BuildingLayer(mapView.map(), baseLayer));
layers.add(items = new ItemizedLayer<MarkerItem>(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);
}
@ -130,7 +139,7 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
}
public void redraw() {
mapView.map().render();
mapView.map().updateMap(true);
}
public void applyCameraUpdate(CameraUpdate cameraUpdate) {
@ -145,70 +154,64 @@ public class BackendMap implements ItemizedLayer.OnItemGestureListener<MarkerIte
mapView.map().animator().cancel();
}
public synchronized <T extends Markup> T add(T 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);
public synchronized <T extends DrawableMarkup> T add(T markup) {
if (markup == null) return null;
drawableMarkups.add(markup);
Collections.sort(drawableMarkups, new Comparator<DrawableMarkup>() {
@Override
public int compare(DrawableMarkup lhs, DrawableMarkup rhs) {
return Float.compare(lhs.getZIndex(), rhs.getZIndex());
}
});
updateDrawableLayer();
redraw();
return markup;
}
private synchronized void updateDrawableLayer() {
drawables.clear();
for (DrawableMarkup markup : drawableMarkups) {
drawables.add(markup.getDrawable(mapView.map()));
}
}
public synchronized <T extends MarkerItemMarkup> T add(T markup) {
if (markup == null) return null;
markupMap.put(markup.getId(), markup);
items.addItem(markup.getMarkerItem(context));
redraw();
return markup;
}
public synchronized void clear() {
markupMap.clear();
items.removeAllItems();
drawableMarkups.clear();
drawables.clear();
redraw();
}
public synchronized void remove(Markup markup) {
switch (markup.getType()) {
case MARKER:
markupMap.remove(markup.getId());
items.removeItem(items.getByUid(markup.getId()));
redraw();
break;
default:
Log.d(TAG, "Unknown markup: " + markup);
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();
}
}
public synchronized void update(Markup markup) {
if (markup == null || !markup.isValid()) {
Log.d(TAG, "Tried to update() invalid markup!");
return;
}
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);
if (markup == null) return;
if (markup instanceof MarkerItemMarkup) {
items.removeItem(items.getByUid(markup.getId()));
items.addItem(((MarkerItemMarkup) markup).getMarkerItem(context));
} else if (markup instanceof DrawableMarkup) {
updateDrawableLayer();
}
redraw();
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,6 +28,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@ -286,6 +287,7 @@ public class ContextContainer extends Context {
original.startActivity(intent);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void startActivity(Intent intent, Bundle bundle) {
original.startActivity(intent, bundle);
@ -296,6 +298,7 @@ public class ContextContainer extends Context {
original.startActivities(intents);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void startActivities(Intent[] intents, Bundle bundle) {
original.startActivities(intents, bundle);
@ -307,6 +310,7 @@ public class ContextContainer extends Context {
original.startIntentSender(intentSender, intent, i, i1, i2);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void startIntentSender(IntentSender intentSender, Intent intent, int i, int i1, int i2,
Bundle bundle) throws IntentSender.SendIntentException {
@ -449,6 +453,12 @@ public class ContextContainer extends Context {
return original.getSystemService(s);
}
@TargetApi(23)
@Override
public String getSystemServiceName(Class<?> serviceClass) {
return original.getSystemServiceName(serviceClass);
}
@Override
public int checkPermission(String s, int i, int i1) {
return original.checkPermission(s, i, i1);
@ -464,6 +474,12 @@ public class ContextContainer extends Context {
return original.checkCallingOrSelfPermission(s);
}
@TargetApi(23)
@Override
public int checkSelfPermission(String permission) {
return original.checkSelfPermission(permission);
}
@Override
public void enforcePermission(String s, int i, int i1, String s1) {
original.enforcePermission(s, i, i1, s1);
@ -536,11 +552,13 @@ public class ContextContainer extends Context {
return original.createPackageContext(s, i);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public Context createConfigurationContext(Configuration configuration) {
return original.createConfigurationContext(configuration);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public Context createDisplayContext(Display display) {
return original.createDisplayContext(display);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -0,0 +1,139 @@
/*
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.data;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import org.oscim.core.Tile;
import org.oscim.tiling.ITileCache;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
public class SharedTileCache implements ITileCache {
private final ArrayList<ByteArrayOutputStream> cacheBuffers;
private final Context context;
public SharedTileCache(Context context) {
this.context = context;
this.cacheBuffers = new ArrayList<ByteArrayOutputStream>();
}
@Override
public TileWriter writeTile(Tile tile) {
ByteArrayOutputStream os;
synchronized (this.cacheBuffers) {
if (this.cacheBuffers.isEmpty()) {
os = new ByteArrayOutputStream('耀');
} else {
os = this.cacheBuffers.remove(this.cacheBuffers.size() - 1);
}
}
return new CacheTileWriter(tile, os);
}
public void saveTile(Tile tile, ByteArrayOutputStream data, boolean success) {
byte[] bytes = null;
if (success) {
bytes = data.toByteArray();
}
synchronized (this.cacheBuffers) {
data.reset();
this.cacheBuffers.add(data);
}
if (success) {
ContentValues values = new ContentValues();
values.put("x", tile.tileX);
values.put("y", tile.tileY);
values.put("z", tile.zoomLevel);
values.put("time", 0);
values.put("last_access", 0);
values.put("data", bytes);
context.getContentResolver().insert(SharedTileProvider.PROVIDER_URI, values);
}
}
@Override
public TileReader getTile(Tile tile) {
Cursor cursor = context.getContentResolver().query(SharedTileProvider.PROVIDER_URI, new String[]{"data"}, "z=? AND x=? AND y=?", new String[]{String.valueOf(tile.zoomLevel), String.valueOf(tile.tileX), String.valueOf(tile.tileY)}, null);
if (cursor != null) {
if (!cursor.moveToFirst()) {
cursor.close();
return null;
} else {
ByteArrayInputStream in = new ByteArrayInputStream(cursor.getBlob(0));
cursor.close();
return new CacheTileReader(tile, in);
}
}
return null;
}
@Override
public void setCacheSize(long l) {
}
class CacheTileWriter implements TileWriter {
final ByteArrayOutputStream os;
final Tile tile;
CacheTileWriter(Tile tile, ByteArrayOutputStream os) {
this.tile = tile;
this.os = os;
}
public Tile getTile() {
return tile;
}
public OutputStream getOutputStream() {
return os;
}
public void complete(boolean success) {
saveTile(tile, os, success);
}
}
class CacheTileReader implements TileReader {
final InputStream is;
final Tile tile;
public CacheTileReader(Tile tile, InputStream is) {
this.tile = tile;
this.is = is;
}
public Tile getTile() {
return tile;
}
public InputStream getInputStream() {
return is;
}
}
}

View File

@ -0,0 +1,94 @@
/*
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.data;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
/*
* TODO: Writing to cache should be protected, tiles should be downloaded by service instead of client app.
*/
public class SharedTileProvider extends ContentProvider {
private static final String DB_NAME = "tilecache.db";
public static final String PROVIDER_NAME = "org.microg.gms.map.tile";
public static final Uri PROVIDER_URI = Uri.parse("content://" + PROVIDER_NAME);
private SQLiteHelper sqLiteHelper;
public SharedTileProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
return "vnd.android.cursor.item/org.microg.gms.map.tile";
}
@Override
public Uri insert(Uri uri, ContentValues values) {
sqLiteHelper.getWritableDatabase().insert("tiles", null, values);
return PROVIDER_URI;
}
@Override
public boolean onCreate() {
sqLiteHelper = new SQLiteHelper(getContext(), DB_NAME);
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return sqLiteHelper.getReadableDatabase().query("tiles", projection, selection, selectionArgs, null, null, sortOrder);
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return sqLiteHelper.getWritableDatabase().update("tiles", values, selection, selectionArgs);
}
class SQLiteHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String TILE_SCHEMA = "CREATE TABLE tiles(x INTEGER NOT NULL,y INTEGER NOT NULL,z INTEGER NOT NULL,time LONG NOT NULL,last_access LONG NOT NULL,data BLOB,PRIMARY KEY(x,y,z));";
public SQLiteHelper(Context context, String dbName) {
super(context, dbName, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(TILE_SCHEMA);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS tiles");
this.onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
this.onUpgrade(db, oldVersion, newVersion);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,7 +16,6 @@
package org.microg.gms.maps.markup;
import android.content.Context;
import android.os.RemoteException;
import com.google.android.gms.maps.model.CircleOptions;
@ -24,22 +23,16 @@ import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.internal.ICircleDelegate;
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.Drawable;
import org.oscim.layers.vector.geometries.Style;
import org.oscim.map.Map;
//import org.oscim.backend.GL20;
public class CircleImpl extends ICircleDelegate.Stub implements Markup {
public class CircleImpl extends ICircleDelegate.Stub implements DrawableMarkup {
private final String id;
private final CircleOptions options;
private final MarkupListener listener;
private VectorLayer vectorLayer;
private CircleDrawable circleDrawable;
private boolean removed = false;
public CircleImpl(String id, CircleOptions options, MarkupListener listener) {
@ -62,7 +55,7 @@ public class CircleImpl extends ICircleDelegate.Stub implements Markup {
@Override
public void setCenter(LatLng center) throws RemoteException {
options.center(center);
if (vectorLayer != null) update();
listener.update(this);
}
@Override
@ -73,7 +66,7 @@ public class CircleImpl extends ICircleDelegate.Stub implements Markup {
@Override
public void setRadius(double radius) throws RemoteException {
options.radius(radius);
if (vectorLayer != null) update();
listener.update(this);
}
@Override
@ -84,7 +77,7 @@ public class CircleImpl extends ICircleDelegate.Stub implements Markup {
@Override
public void setStrokeWidth(float width) throws RemoteException {
options.strokeWidth(width);
if (vectorLayer != null) update();
listener.update(this);
}
@Override
@ -95,7 +88,7 @@ public class CircleImpl extends ICircleDelegate.Stub implements Markup {
@Override
public void setStrokeColor(int color) throws RemoteException {
options.strokeColor(color);
if (vectorLayer != null) update();
listener.update(this);
}
@Override
@ -106,7 +99,6 @@ public class CircleImpl extends ICircleDelegate.Stub implements Markup {
@Override
public void setFillColor(int color) throws RemoteException {
options.fillColor(color);
if (vectorLayer != null) update();
listener.update(this);
}
@ -118,21 +110,22 @@ public class CircleImpl extends ICircleDelegate.Stub implements Markup {
@Override
public void setZIndex(float zIndex) throws RemoteException {
options.zIndex(zIndex);
listener.update(this);
}
@Override
public float getZIndex() throws RemoteException {
public float getZIndex() {
return options.getZIndex();
}
@Override
public void setVisible(boolean visible) throws RemoteException {
options.visible(visible);
if (vectorLayer != null) update();
listener.update(this);
}
@Override
public boolean isVisible() throws RemoteException {
public boolean isVisible() {
return options.isVisible();
}
@ -148,45 +141,19 @@ public class CircleImpl extends ICircleDelegate.Stub implements Markup {
@Override
public boolean onClick() {
return false;
return listener.onClick(this);
}
@Override
public boolean isValid() {
return !removed;
}
@Override
public MarkerItem getMarkerItem(Context context) {
return null;
}
@Override
public Layer getLayer(Context context, Map 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);
}
vectorLayer.update();
}
@Override
public Type getType() {
return Type.LAYER;
public Drawable getDrawable(Map map) {
if (!isVisible() || removed) return null;
return new CircleDrawable(
GmsMapsTypeHelper.fromLatLng(options.getCenter()),
options.getRadius() / 1000.0,
Style.builder()
.strokeColor(options.getStrokeColor())
.fillAlpha(1)
.fillColor(options.getFillColor())
.strokeWidth(options.getStrokeWidth()).build());
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.markup;
import org.oscim.layers.vector.VectorLayer;
import org.oscim.map.Map;
public class ClearableVectorLayer extends VectorLayer {
public ClearableVectorLayer(Map map) {
super(map);
}
public void clear() {
mDrawables.clear();
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.markup;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.map.Map;
public interface DrawableMarkup extends Markup {
float getZIndex();
Drawable getDrawable(Map map);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,12 +30,10 @@ import org.microg.gms.maps.GmsMapsTypeHelper;
import org.microg.gms.maps.bitmap.BitmapDescriptorImpl;
import org.microg.gms.maps.bitmap.DefaultBitmapDescriptor;
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 {
public class MarkerImpl extends IMarkerDelegate.Stub implements MarkerItemMarkup {
private static final String TAG = "GmsMapMarkerImpl";
private final String id;
@ -213,13 +211,9 @@ public class MarkerImpl extends IMarkerDelegate.Stub implements Markup {
return listener.onClick(this);
}
@Override
public boolean isValid() {
return !removed;
}
@Override
public MarkerItem getMarkerItem(Context context) {
if (removed) return null;
MarkerItem item = new MarkerItem(getId(), getTitle(), getSnippet(),
GmsMapsTypeHelper.fromLatLng(getPosition()));
BitmapDescriptorImpl icon = this.icon;
@ -250,14 +244,4 @@ public class MarkerImpl extends IMarkerDelegate.Stub implements Markup {
private void prepareMarkerIcon(MarkerItem item) {
item.setMarker(new MarkerSymbol(oldBitmap, options.getAnchorU(), options.getAnchorV(), !options.isFlat()));
}
@Override
public Layer getLayer(Context context, Map map) {
return null;
}
@Override
public Type getType() {
return Type.MARKER;
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.microg.gms.maps.markup;
import android.content.Context;
import org.oscim.layers.marker.MarkerItem;
public interface MarkerItemMarkup extends Markup {
MarkerItem getMarkerItem(Context context);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,30 +16,12 @@
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);
String getId();
public Layer getLayer(Context context, Map map);
boolean onClick();
public Type getType();
public String getId();
public boolean onClick();
public boolean isValid();
public static enum Type {
MARKER, LAYER, DRAWABLE
}
public static interface MarkupListener {
interface MarkupListener {
void update(Markup markup);
void remove(Markup markup);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,53 +16,40 @@
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.microg.gms.maps.GmsMapsTypeHelper;
import org.oscim.core.GeoPoint;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.layers.vector.geometries.PolygonDrawable;
import org.oscim.layers.vector.geometries.Style;
import org.oscim.map.Map;
import java.util.ArrayList;
import java.util.List;
public class PolygonImpl extends IPolygonDelegate.Stub implements Markup {
private List<LatLng> points;
private List holes;
private float zIndex;
private boolean geodesic;
private boolean visible;
private String id;
private float strokeWidth;
private int strokeColor;
private int fillColor;
public class PolygonImpl extends IPolygonDelegate.Stub implements DrawableMarkup {
private static final String TAG = "GmsMapsPolygonImpl";
private final String id;
private final PolygonOptions options;
private final MarkupListener listener;
private boolean removed = false;
public PolygonImpl(String id, PolygonOptions options, MarkupListener listener) {
this.id = id;
this.options = options;
this.listener = listener;
}
@Override
public void remove() throws RemoteException {
}
@Override
public MarkerItem getMarkerItem(Context context) {
return null;
}
@Override
public Layer getLayer(Context context, Map map) {
return null;
}
@Override
public Type getType() {
return null;
listener.remove(this);
removed = true;
}
@Override
@ -72,92 +59,113 @@ public class PolygonImpl extends IPolygonDelegate.Stub implements Markup {
@Override
public boolean onClick() {
return false;
}
@Override
public boolean isValid() {
return false;
return listener.onClick(this);
}
@Override
public void setPoints(List<LatLng> points) throws RemoteException {
this.points = points;
options.getPoints().clear();
options.getPoints().addAll(points);
listener.update(this);
}
@Override
public List<LatLng> getPoints() throws RemoteException {
return points;
return options.getPoints();
}
@Override
public void setHoles(List holes) throws RemoteException {
this.holes = holes;
options.getHoles().clear();
options.getHoles().addAll(holes);
listener.update(this);
}
@Override
public List getHoles() throws RemoteException {
return holes;
return options.getHoles();
}
@Override
public void setStrokeWidth(float width) throws RemoteException {
this.strokeWidth = width;
options.strokeWidth(width);
listener.update(this);
}
@Override
public float getStrokeWidth() throws RemoteException {
return strokeWidth;
public float getStrokeWidth() {
return options.getStrokeWidth();
}
@Override
public void setStrokeColor(int color) throws RemoteException {
this.strokeColor = color;
options.strokeColor(color);
listener.update(this);
}
@Override
public int getStrokeColor() throws RemoteException {
return strokeColor;
public int getStrokeColor() {
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;
public int getFillColor() {
return options.getFillColor();
}
@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;
public float getZIndex() {
return options.getZIndex();
}
@Override
public Drawable getDrawable(Map map) {
if (!isVisible() || removed) return null;
List<GeoPoint> points = new ArrayList<GeoPoint>();
for (LatLng point : options.getPoints()) {
points.add(GmsMapsTypeHelper.fromLatLng(point));
}
// TODO: holes
return new PolygonDrawable(points, Style.builder()
.fillAlpha(1)
.strokeColor(getStrokeColor())
.strokeWidth(getStrokeWidth())
.fillColor(getFillColor())
.build());
}
@Override
public void setVisible(boolean visible) throws RemoteException {
this.visible = visible;
options.visible(visible);
listener.update(this);
}
@Override
public boolean isVisible() throws RemoteException {
return visible;
public boolean isVisible() {
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

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,7 +16,6 @@
package org.microg.gms.maps.markup;
import android.content.Context;
import android.os.RemoteException;
import android.util.Log;
@ -25,24 +24,25 @@ import com.google.android.gms.maps.model.PolylineOptions;
import com.google.android.gms.maps.model.internal.IPolylineDelegate;
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.core.GeoPoint;
import org.oscim.layers.vector.geometries.Drawable;
import org.oscim.layers.vector.geometries.LineDrawable;
import org.oscim.layers.vector.geometries.Style;
import org.oscim.map.Map;
import java.util.ArrayList;
import java.util.List;
/**
* TODO
*/
public class PolylineImpl extends IPolylineDelegate.Stub implements Markup {
public class PolylineImpl extends IPolylineDelegate.Stub implements DrawableMarkup {
private static final String TAG = "GmsMapsPolylineImpl";
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;
@ -51,30 +51,11 @@ public class PolylineImpl extends IPolylineDelegate.Stub implements Markup {
}
@Override
public void remove() throws RemoteException {
public void remove() {
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() {
return id;
@ -86,90 +67,69 @@ public class PolylineImpl extends IPolylineDelegate.Stub implements Markup {
}
@Override
public boolean isValid() {
return !removed;
}
@Override
public void setPoints(List<LatLng> points) throws RemoteException {
public void setPoints(List<LatLng> 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<LatLng> getPoints() throws RemoteException {
public List<LatLng> getPoints() {
return options.getPoints();
}
@Override
public void setWidth(float width) throws RemoteException {
public void setWidth(float width) {
options.width(width);
if (pathLayer != null) {
pathLayer.setStyle(options.getColor(), options.getWidth());
pathLayer.update();
}
listener.update(this);
}
@Override
public float getWidth() throws RemoteException {
public float getWidth() {
return options.getWidth();
}
@Override
public void setColor(int color) throws RemoteException {
public void setColor(int 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 {
public int getColor() {
return options.getColor();
}
@Override
public void setZIndex(float zIndex) throws RemoteException {
public void setZIndex(float zIndex) {
options.zIndex(zIndex);
listener.update(this);
}
@Override
public float getZIndex() throws RemoteException {
public float getZIndex() {
return options.getZIndex();
}
@Override
public void setVisible(boolean visible) throws RemoteException {
public void setVisible(boolean visible) {
options.visible(visible);
if (pathLayer != null) pathLayer.setEnabled(visible);
listener.update(this);
}
@Override
public boolean isVisible() throws RemoteException {
public boolean isVisible() {
return options.isVisible();
}
@Override
public void setGeodesic(boolean geod) throws RemoteException {
public void setGeodesic(boolean geod) {
options.geodesic(geod);
listener.update(this);
}
@Override
public boolean isGeodesic() throws RemoteException {
public boolean isGeodesic() {
return options.isGeodesic();
}
@ -180,8 +140,18 @@ public class PolylineImpl extends IPolylineDelegate.Stub implements Markup {
}
@Override
public int hashCodeRemote() throws RemoteException {
public int hashCodeRemote() {
Log.d(TAG, "hashcodeRemote");
return id.hashCode();
}
@Override
public Drawable getDrawable(Map map) {
if (!isVisible() || removed) return null;
List<GeoPoint> points = new ArrayList<GeoPoint>();
for (LatLng point : options.getPoints()) {
points.add(GmsMapsTypeHelper.fromLatLng(point));
}
return new LineDrawable(points, Style.builder().strokeColor(getColor()).strokeWidth(getWidth()).build());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 µg Project Team
* Copyright 2013-2015 microG Project Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.