Added aidl map layer api

This commit is contained in:
Alexey Kulish 2017-04-23 17:20:17 +03:00
parent df0908a46e
commit c7df23ba9d
12 changed files with 343 additions and 35 deletions

View file

@ -6,6 +6,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.view.View;
import net.osmand.aidl.maplayer.AMapLayer;
import net.osmand.aidl.maplayer.point.AMapPoint;
import net.osmand.aidl.mapmarker.AMapMarker;
import net.osmand.aidl.mapwidget.AMapWidget;
import net.osmand.data.LatLon;
@ -14,7 +16,9 @@ import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.views.AidlMapLayer;
import net.osmand.plus.views.MapInfoLayer;
import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.mapwidgets.MapWidgetRegistry.MapWidgetRegInfo;
import net.osmand.plus.views.mapwidgets.TextInfoWidget;
@ -27,17 +31,25 @@ import java.util.concurrent.ConcurrentHashMap;
public class OsmandAidlApi {
private static final String AIDL_REFRESH_MAP = "aidl_refresh_map";
private static final String AIDL_OBJECT_ID = "aidl_object_id";
private static final String AIDL_ADD_MAP_WIDGET = "aidl_add_map_widget";
private static final String AIDL_REMOVE_MAP_WIDGET = "aidl_remove_map_widget";
private static final String AIDL_MAP_WIDGET_ID = "aidl_map_widget_id";
private static final String AIDL_ADD_MAP_LAYER = "aidl_add_map_layer";
private static final String AIDL_REMOVE_MAP_LAYER = "aidl_remove_map_layer";
private OsmandApplication app;
private Map<String, AMapWidget> widgets = new ConcurrentHashMap<>();
private Map<String, TextInfoWidget> widgetControls = new ConcurrentHashMap<>();
private Map<String, AMapLayer> layers = new ConcurrentHashMap<>();
private Map<String, OsmandMapLayer> mapLayers = new ConcurrentHashMap<>();
private BroadcastReceiver refreshMapReceiver;
private BroadcastReceiver addMapWidgetReceiver;
private BroadcastReceiver removeMapWidgetReceiver;
private BroadcastReceiver addMapLayerReceiver;
private BroadcastReceiver removeMapLayerReceiver;
public OsmandAidlApi(OsmandApplication app) {
this.app = app;
@ -47,12 +59,15 @@ public class OsmandAidlApi {
registerRefreshMapReceiver(mapActivity);
registerAddMapWidgetReceiver(mapActivity);
registerRemoveMapWidgetReceiver(mapActivity);
registerAddMapLayerReceiver(mapActivity);
registerRemoveMapLayerReceiver(mapActivity);
}
public void onDestroyMapActivity(final MapActivity mapActivity) {
if (refreshMapReceiver != null) {
mapActivity.unregisterReceiver(refreshMapReceiver);
}
if (addMapWidgetReceiver != null) {
mapActivity.unregisterReceiver(addMapWidgetReceiver);
}
@ -60,6 +75,13 @@ public class OsmandAidlApi {
mapActivity.unregisterReceiver(removeMapWidgetReceiver);
}
widgetControls.clear();
if (addMapLayerReceiver != null) {
mapActivity.unregisterReceiver(addMapLayerReceiver);
}
if (removeMapLayerReceiver != null) {
mapActivity.unregisterReceiver(removeMapLayerReceiver);
}
}
private void registerRefreshMapReceiver(final MapActivity mapActivity) {
@ -84,7 +106,7 @@ public class OsmandAidlApi {
addMapWidgetReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String widgetId = intent.getStringExtra(AIDL_MAP_WIDGET_ID);
String widgetId = intent.getStringExtra(AIDL_OBJECT_ID);
if (widgetId != null) {
AMapWidget widget = widgets.get(widgetId);
if (widget != null) {
@ -112,7 +134,7 @@ public class OsmandAidlApi {
removeMapWidgetReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String widgetId = intent.getStringExtra(AIDL_MAP_WIDGET_ID);
String widgetId = intent.getStringExtra(AIDL_OBJECT_ID);
if (widgetId != null) {
MapInfoLayer layer = mapActivity.getMapLayers().getMapInfoLayer();
TextInfoWidget widgetControl = widgetControls.get(widgetId);
@ -144,13 +166,64 @@ public class OsmandAidlApi {
}
}
private void registerAddMapLayerReceiver(final MapActivity mapActivity) {
addMapLayerReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String layerId = intent.getStringExtra(AIDL_OBJECT_ID);
if (layerId != null) {
AMapLayer layer = layers.get(layerId);
if (layer != null) {
OsmandMapLayer mapLayer = mapLayers.get(layerId);
if (mapLayer != null) {
mapActivity.getMapView().removeLayer(mapLayer);
}
mapLayer = new AidlMapLayer(mapActivity, layer);
mapActivity.getMapView().addLayer(mapLayer, layer.getZOrder());
mapLayers.put(layerId, mapLayer);
}
}
}
};
mapActivity.registerReceiver(addMapLayerReceiver, new IntentFilter(AIDL_ADD_MAP_LAYER));
}
private void registerRemoveMapLayerReceiver(final MapActivity mapActivity) {
removeMapLayerReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String layerId = intent.getStringExtra(AIDL_OBJECT_ID);
if (layerId != null) {
OsmandMapLayer mapLayer = mapLayers.remove(layerId);
if (mapLayer != null) {
mapActivity.getMapView().removeLayer(mapLayer);
mapActivity.refreshMap();
}
}
}
};
mapActivity.registerReceiver(removeMapLayerReceiver, new IntentFilter(AIDL_REMOVE_MAP_LAYER));
}
public void registerMapLayers(MapActivity mapActivity) {
for (AMapLayer layer : layers.values()) {
OsmandMapLayer mapLayer = mapLayers.get(layer.getId());
if (mapLayer != null) {
mapActivity.getMapView().removeLayer(mapLayer);
}
mapLayer = new AidlMapLayer(mapActivity, layer);
mapActivity.getMapView().addLayer(mapLayer, layer.getZOrder());
mapLayers.put(layer.getId(), mapLayer);
}
}
private void refreshMap() {
Intent intent = new Intent();
intent.setAction(AIDL_REFRESH_MAP);
app.sendBroadcast(intent);
}
public TextInfoWidget createWidgetControl(final MapActivity mapActivity, final String widgetId) {
private TextInfoWidget createWidgetControl(final MapActivity mapActivity, final String widgetId) {
final TextInfoWidget control = new TextInfoWidget(mapActivity) {
@Override
@ -248,7 +321,7 @@ public class OsmandAidlApi {
widgets.put(widget.getId(), widget);
Intent intent = new Intent();
intent.setAction(AIDL_ADD_MAP_WIDGET);
intent.putExtra(AIDL_MAP_WIDGET_ID, widget.getId());
intent.putExtra(AIDL_OBJECT_ID, widget.getId());
app.sendBroadcast(intent);
}
refreshMap();
@ -263,7 +336,7 @@ public class OsmandAidlApi {
widgets.remove(widgetId);
Intent intent = new Intent();
intent.setAction(AIDL_REMOVE_MAP_WIDGET);
intent.putExtra(AIDL_MAP_WIDGET_ID, widgetId);
intent.putExtra(AIDL_OBJECT_ID, widgetId);
app.sendBroadcast(intent);
return true;
} else {
@ -280,4 +353,69 @@ public class OsmandAidlApi {
return false;
}
}
boolean addMapLayer(AMapLayer layer) {
if (layer != null) {
if (layers.containsKey(layer.getId())) {
updateMapLayer(layer);
} else {
layers.put(layer.getId(), layer);
Intent intent = new Intent();
intent.setAction(AIDL_ADD_MAP_LAYER);
intent.putExtra(AIDL_OBJECT_ID, layer.getId());
app.sendBroadcast(intent);
}
refreshMap();
return true;
} else {
return false;
}
}
boolean removeMapLayer(String layerId) {
if (!Algorithms.isEmpty(layerId) && layers.containsKey(layerId)) {
layers.remove(layerId);
Intent intent = new Intent();
intent.setAction(AIDL_REMOVE_MAP_LAYER);
intent.putExtra(AIDL_OBJECT_ID, layerId);
app.sendBroadcast(intent);
return true;
} else {
return false;
}
}
boolean updateMapLayer(AMapLayer layer) {
if (layer != null && layers.containsKey(layer.getId())) {
layers.put(layer.getId(), layer);
refreshMap();
return true;
} else {
return false;
}
}
boolean putMapPoint(String layerId, AMapPoint point) {
if (point != null) {
AMapLayer layer = layers.get(layerId);
if (layer != null) {
layer.putPoint(point);
refreshMap();
return true;
}
}
return false;
}
boolean removeMapPoint(String layerId, String pointId) {
if (pointId != null) {
AMapLayer layer = layers.get(layerId);
if (layer != null) {
layer.removePoint(pointId);
refreshMap();
return true;
}
}
return false;
}
}

View file

@ -94,33 +94,57 @@ public class OsmandAidlService extends Service {
@Override
public boolean addMapPoint(AddMapPointParams params) throws RemoteException {
try {
return params != null && getApi().putMapPoint(params.getLayerId(), params.getPoint());
} catch (Exception e) {
return false;
}
}
@Override
public boolean removeMapPoint(RemoveMapPointParams params) throws RemoteException {
try {
return params != null && getApi().removeMapPoint(params.getLayerId(), params.getPointId());
} catch (Exception e) {
return false;
}
}
@Override
public boolean updateMapPoint(UpdateMapPointParams params) throws RemoteException {
try {
return params != null && getApi().putMapPoint(params.getLayerId(), params.getPoint());
} catch (Exception e) {
return false;
}
}
@Override
public boolean addMapLayer(AddMapLayerParams params) throws RemoteException {
try {
return params != null && getApi().addMapLayer(params.getLayer());
} catch (Exception e) {
return false;
}
}
@Override
public boolean removeMapLayer(RemoveMapLayerParams params) throws RemoteException {
try {
return params != null && getApi().removeMapLayer(params.getId());
} catch (Exception e) {
return false;
}
}
@Override
public boolean updateMapLayer(UpdateMapLayerParams params) throws RemoteException {
try {
return params != null && getApi().updateMapLayer(params.getLayer());
} catch (Exception e) {
return false;
}
}
@Override
public boolean calculateRoute(CalculateRouteParams params) throws RemoteException {

View file

@ -5,17 +5,26 @@ import android.os.Parcelable;
import net.osmand.aidl.maplayer.point.AMapPoint;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class AMapLayer implements Parcelable {
private String id;
private String name;
private HashMap<String, AMapPoint> points = new HashMap<>();
private float zOrder = 5.5f;
private Map<String, AMapPoint> points = new ConcurrentHashMap<>();
public AMapLayer(String id, String name, HashMap<String, AMapPoint> points) {
public AMapLayer(String id, String name, float zOrder, List<AMapPoint> pointList) {
this.id = id;
this.name = name;
this.points = points;
this.zOrder = zOrder;
if (pointList != null) {
for (AMapPoint p : pointList) {
this.points.put(p.getId(), p);
}
}
}
public AMapLayer(Parcel in) {
@ -41,20 +50,42 @@ public class AMapLayer implements Parcelable {
return name;
}
public HashMap<String, AMapPoint> getPoints() {
return points;
public float getZOrder() {
return zOrder;
}
public List<AMapPoint> getPoints() {
return new ArrayList<>(points.values());
}
public boolean hasPoint(String pointId) {
return points.containsKey(pointId);
}
public void putPoint(AMapPoint point) {
points.put(point.getId(), point);
}
public void removePoint(String pointId) {
points.remove(pointId);
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(id);
out.writeString(name);
out.writeMap(points);
out.writeFloat(zOrder);
out.writeTypedList(new ArrayList<>(points.values()));
}
private void readFromParcel(Parcel in) {
id = in.readString();
name = in.readString();
in.readMap(points, HashMap.class.getClassLoader());
zOrder = in.readFloat();
List<AMapPoint> pointList = new ArrayList<>();
in.readTypedList(pointList, AMapPoint.CREATOR);
for (AMapPoint p : pointList) {
this.points.put(p.getId(), p);
}
}
public int describeContents() {

View file

@ -2,6 +2,7 @@ package net.osmand.aidl.maplayer;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;
public class AddMapLayerParams implements Parcelable {
private AMapLayer layer;
@ -14,8 +15,8 @@ public class AddMapLayerParams implements Parcelable {
readFromParcel(in);
}
public static final Parcelable.Creator<AddMapLayerParams> CREATOR = new
Parcelable.Creator<AddMapLayerParams>() {
public static final Creator<AddMapLayerParams> CREATOR = new
Creator<AddMapLayerParams>() {
public AddMapLayerParams createFromParcel(Parcel in) {
return new AddMapLayerParams(in);
}

View file

@ -2,6 +2,7 @@ package net.osmand.aidl.maplayer;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;
public class RemoveMapLayerParams implements Parcelable {
private String id;
@ -14,8 +15,8 @@ public class RemoveMapLayerParams implements Parcelable {
readFromParcel(in);
}
public static final Parcelable.Creator<RemoveMapLayerParams> CREATOR = new
Parcelable.Creator<RemoveMapLayerParams>() {
public static final Creator<RemoveMapLayerParams> CREATOR = new
Creator<RemoveMapLayerParams>() {
public RemoveMapLayerParams createFromParcel(Parcel in) {
return new RemoveMapLayerParams(in);
}

View file

@ -2,6 +2,7 @@ package net.osmand.aidl.maplayer;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable.Creator;
public class UpdateMapLayerParams implements Parcelable {
private AMapLayer layer;
@ -14,8 +15,8 @@ public class UpdateMapLayerParams implements Parcelable {
readFromParcel(in);
}
public static final Parcelable.Creator<UpdateMapLayerParams> CREATOR = new
Parcelable.Creator<UpdateMapLayerParams>() {
public static final Creator<UpdateMapLayerParams> CREATOR = new
Creator<UpdateMapLayerParams>() {
public UpdateMapLayerParams createFromParcel(Parcel in) {
return new UpdateMapLayerParams(in);
}

View file

@ -24,8 +24,8 @@ public class AMapPoint implements Parcelable {
readFromParcel(in);
}
public static final Parcelable.Creator<AMapPoint> CREATOR = new
Parcelable.Creator<AMapPoint>() {
public static final Creator<AMapPoint> CREATOR = new
Creator<AMapPoint>() {
public AMapPoint createFromParcel(Parcel in) {
return new AMapPoint(in);
}
@ -66,7 +66,7 @@ public class AMapPoint implements Parcelable {
private void readFromParcel(Parcel in) {
id = in.readString();
shortName = in.readString();
shortName = in.readString();
fullName = in.readString();
color = in.readInt();
location = in.readParcelable(ALatLon.class.getClassLoader());
}

View file

@ -16,8 +16,8 @@ public class AddMapPointParams implements Parcelable {
readFromParcel(in);
}
public static final Parcelable.Creator<AddMapPointParams> CREATOR = new
Parcelable.Creator<AddMapPointParams>() {
public static final Creator<AddMapPointParams> CREATOR = new
Creator<AddMapPointParams>() {
public AddMapPointParams createFromParcel(Parcel in) {
return new AddMapPointParams(in);
}

View file

@ -16,8 +16,8 @@ public class RemoveMapPointParams implements Parcelable {
readFromParcel(in);
}
public static final Parcelable.Creator<RemoveMapPointParams> CREATOR = new
Parcelable.Creator<RemoveMapPointParams>() {
public static final Creator<RemoveMapPointParams> CREATOR = new
Creator<RemoveMapPointParams>() {
public RemoveMapPointParams createFromParcel(Parcel in) {
return new RemoveMapPointParams(in);
}

View file

@ -16,8 +16,8 @@ public class UpdateMapPointParams implements Parcelable {
readFromParcel(in);
}
public static final Parcelable.Creator<UpdateMapPointParams> CREATOR = new
Parcelable.Creator<UpdateMapPointParams>() {
public static final Creator<UpdateMapPointParams> CREATOR = new
Creator<UpdateMapPointParams>() {
public UpdateMapPointParams createFromParcel(Parcel in) {
return new UpdateMapPointParams(in);
}

View file

@ -187,6 +187,7 @@ public class MapActivityLayers {
OsmandPlugin.createLayers(mapView, activity);
app.getAppCustomization().createLayers(mapView, activity);
app.getAidlApi().registerMapLayers(activity);
}

View file

@ -0,0 +1,111 @@
package net.osmand.plus.views;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import net.osmand.aidl.ALatLon;
import net.osmand.aidl.maplayer.AMapLayer;
import net.osmand.aidl.maplayer.point.AMapPoint;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import java.util.List;
public class AidlMapLayer extends OsmandMapLayer {
private static int POINT_OUTER_COLOR = 0x88555555;
private static int PAINT_TEXT_ICON_COLOR = Color.BLACK;
private final MapActivity map;
private AMapLayer aidlLayer;
private OsmandMapTileView view;
private Paint pointInnerCircle;
private Paint pointOuter;
private final static float startZoom = 7;
private Paint paintTextIcon;
public AidlMapLayer(MapActivity map, AMapLayer aidlLayer) {
this.map = map;
this.aidlLayer = aidlLayer;
}
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
DisplayMetrics dm = new DisplayMetrics();
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
wmgr.getDefaultDisplay().getMetrics(dm);
pointInnerCircle = new Paint();
pointInnerCircle.setColor(view.getApplication().getResources().getColor(R.color.poi_background));
pointInnerCircle.setStyle(Paint.Style.FILL);
pointInnerCircle.setAntiAlias(true);
paintTextIcon = new Paint();
paintTextIcon.setTextSize(10 * view.getDensity());
paintTextIcon.setTextAlign(Paint.Align.CENTER);
paintTextIcon.setFakeBoldText(true);
paintTextIcon.setColor(PAINT_TEXT_ICON_COLOR);
paintTextIcon.setAntiAlias(true);
pointOuter = new Paint();
pointOuter.setColor(POINT_OUTER_COLOR);
pointOuter.setAntiAlias(true);
pointOuter.setStyle(Paint.Style.FILL_AND_STROKE);
}
private int getRadiusPoi(RotatedTileBox tb) {
int r;
final double zoom = tb.getZoom();
if (zoom < startZoom) {
r = 0;
} else if (zoom <= 11) {
r = 10;
} else if (zoom <= 14) {
r = 12;
} else {
r = 14;
}
return (int) (r * tb.getDensity());
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings nightMode) {
final int r = getRadiusPoi(tileBox);
canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
List<AMapPoint> points = aidlLayer.getPoints();
for (AMapPoint point : points) {
ALatLon l = point.getLocation();
if (l != null) {
int x = (int) tileBox.getPixXFromLatLon(l.getLatitude(), l.getLongitude());
int y = (int) tileBox.getPixYFromLatLon(l.getLatitude(), l.getLongitude());
pointInnerCircle.setColor(point.getColor());
pointOuter.setColor(POINT_OUTER_COLOR);
paintTextIcon.setColor(PAINT_TEXT_ICON_COLOR);
canvas.drawCircle(x, y, r + (float)Math.ceil(tileBox.getDensity()), pointOuter);
canvas.drawCircle(x, y, r - (float)Math.ceil(tileBox.getDensity()), pointInnerCircle);
paintTextIcon.setTextSize(r * 3 / 2);
canvas.drawText(point.getShortName(), x, y + r / 2, paintTextIcon);
}
}
}
@Override
public void destroyLayer() {
}
@Override
public boolean drawInScreenPixels() {
return false;
}
public void refresh() {
if (view != null) {
view.refreshMap();
}
}
}