Fix issue with POI labeling
This commit is contained in:
parent
81f58d03b0
commit
7c6a9a02bd
4 changed files with 109 additions and 56 deletions
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<resources>
|
||||
<string name="layer_poi_label">POI labels</string>
|
||||
<string name="auto_follow_route_navigation_descr">Enable auto follow position only in navigation mode.</string>
|
||||
<string name="auto_follow_route_navigation">Auto follow navigation</string>
|
||||
<string name="auto_follow_location_enabled">Auto follow settings are enabled.</string>
|
||||
|
|
|
@ -413,6 +413,9 @@ public class OsmandSettings {
|
|||
public final OsmandPreference<Boolean> SHOW_POI_OVER_MAP =
|
||||
new BooleanPreference("show_poi_over_map", false, true);
|
||||
|
||||
public final OsmandPreference<Boolean> SHOW_POI_LABEL =
|
||||
new BooleanPreference("show_poi_label", false, true);
|
||||
|
||||
// this value string is synchronized with settings_pref.xml preference name
|
||||
public final OsmandPreference<Boolean> SHOW_TRANSPORT_OVER_MAP =
|
||||
new BooleanPreference("show_transport_over_map", false, true);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package net.osmand.plus.activities;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -234,59 +236,70 @@ public class MapActivityLayers {
|
|||
}
|
||||
|
||||
public void openLayerSelectionDialog(final OsmandMapTileView mapView){
|
||||
List<String> layersList = new ArrayList<String>();
|
||||
|
||||
final TIntArrayList layers = new TIntArrayList();
|
||||
TIntArrayList selectedList = new TIntArrayList();
|
||||
final OsmandSettings settings = getApplication().getSettings();
|
||||
layersList.add(getString(R.string.layer_map));
|
||||
layersList.add(getString(R.string.layer_poi));
|
||||
layersList.add(getString(R.string.layer_favorites));
|
||||
layersList.add(getString(R.string.layer_overlay));
|
||||
layersList.add(getString(R.string.layer_underlay));
|
||||
layersList.add(getString(R.string.layer_gpx_layer));
|
||||
layersList.add(getString(R.string.layer_transport));
|
||||
layersList.add(getString(R.string.layer_osm_bugs));
|
||||
layers.add(R.string.layer_map);
|
||||
selectedList.add(1);
|
||||
layers.add(R.string.layer_poi);
|
||||
selectedList.add(settings.SHOW_POI_OVER_MAP.get() ? 1 : 0);
|
||||
if(settings.SHOW_POI_OVER_MAP.get()){
|
||||
layers.add(R.string.layer_poi_label);
|
||||
selectedList.add(settings.SHOW_POI_LABEL.get() ? 1 : 0);
|
||||
}
|
||||
layers.add(R.string.layer_favorites);
|
||||
selectedList.add(settings.SHOW_FAVORITES.get() ? 1 : 0);
|
||||
layers.add(R.string.layer_overlay);
|
||||
selectedList.add(overlayLayer.getMap() != null ? 1 : 0);
|
||||
layers.add(R.string.layer_underlay);
|
||||
selectedList.add(underlayLayer.getMap() != null ? 1 : 0);
|
||||
|
||||
|
||||
final int routeInfoInd = routeInfoLayer.couldBeVisible() ? layersList.size() : -1;
|
||||
layers.add(R.string.layer_gpx_layer);
|
||||
selectedList.add(gpxLayer.isVisible() ? 1 : 0);
|
||||
if(routeInfoLayer.couldBeVisible()){
|
||||
layersList.add(getString(R.string.layer_route));
|
||||
}
|
||||
final int transportRouteInfoInd = !TransportRouteHelper.getInstance().routeIsCalculated() ? - 1 : layersList.size();
|
||||
if(transportRouteInfoInd > -1){
|
||||
layersList.add(getString(R.string.layer_transport_route));
|
||||
layers.add(R.string.layer_route);
|
||||
selectedList.add(routeInfoLayer.isUserDefinedVisible() ? 1 : 0);
|
||||
}
|
||||
|
||||
final boolean[] selected = new boolean[layersList.size()];
|
||||
Arrays.fill(selected, true);
|
||||
selected[1] = settings.SHOW_POI_OVER_MAP.get();
|
||||
selected[2] = settings.SHOW_FAVORITES.get();
|
||||
selected[3] = overlayLayer.getMap() != null;
|
||||
selected[4] = underlayLayer.getMap() != null;
|
||||
selected[5] = gpxLayer.isVisible();
|
||||
selected[6] = settings.SHOW_TRANSPORT_OVER_MAP.get();
|
||||
selected[7] = settings.SHOW_OSM_BUGS.get();
|
||||
if(routeInfoInd != -1){
|
||||
selected[routeInfoInd] = routeInfoLayer.isUserDefinedVisible();
|
||||
layers.add(R.string.layer_transport);
|
||||
selectedList.add(settings.SHOW_TRANSPORT_OVER_MAP.get() ? 1 : 0);
|
||||
if(TransportRouteHelper.getInstance().routeIsCalculated()){
|
||||
layers.add(R.string.layer_transport_route);
|
||||
selectedList.add(routeInfoLayer.isUserDefinedVisible() ? 1 : 0);
|
||||
}
|
||||
if(transportRouteInfoInd != -1){
|
||||
selected[transportRouteInfoInd] = transportInfoLayer.isVisible();
|
||||
|
||||
layers.add(R.string.layer_osm_bugs);
|
||||
selectedList.add(settings.SHOW_OSM_BUGS.get() ? 1 : 0);
|
||||
|
||||
final boolean[] selected = new boolean[selectedList.size()];
|
||||
for (int i = 0; i < selected.length; i++) {
|
||||
selected[i] = selectedList.get(i) > 0;
|
||||
}
|
||||
|
||||
Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.setMultiChoiceItems(layersList.toArray(new String[layersList.size()]), selected, new DialogInterface.OnMultiChoiceClickListener() {
|
||||
String[] layersName = new String[layers.size()];
|
||||
for (int i = 0; i < layers.size(); i++) {
|
||||
layersName[i] = getString(layers.get(i));
|
||||
|
||||
}
|
||||
builder.setMultiChoiceItems(layersName, selected, new DialogInterface.OnMultiChoiceClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int item, boolean isChecked) {
|
||||
if (item == 0) {
|
||||
if (layers.get(item) == R.string.layer_map) {
|
||||
dialog.dismiss();
|
||||
selectMapLayer(mapView);
|
||||
} else if(item == 1){
|
||||
} else if(layers.get(item) == R.string.layer_poi){
|
||||
if(isChecked){
|
||||
selectPOIFilterLayer(mapView);
|
||||
}
|
||||
settings.SHOW_POI_OVER_MAP.set(isChecked);
|
||||
} else if(item == 2){
|
||||
} else if(layers.get(item) == R.string.layer_favorites){
|
||||
settings.SHOW_FAVORITES.set(isChecked);
|
||||
} else if(item == 3){
|
||||
} else if(layers.get(item) == R.string.layer_poi_label){
|
||||
settings.SHOW_POI_LABEL.set(isChecked);
|
||||
} else if(layers.get(item) == R.string.layer_overlay){
|
||||
if(overlayLayer.getMap() != null){
|
||||
settings.MAP_OVERLAY.set(null);
|
||||
updateMapSource(mapView, null);
|
||||
|
@ -295,7 +308,7 @@ public class MapActivityLayers {
|
|||
selectMapOverlayLayer(mapView, settings.MAP_OVERLAY, settings.MAP_OVERLAY_TRANSPARENCY,
|
||||
overlayLayer);
|
||||
}
|
||||
} else if(item == 4){
|
||||
} else if(layers.get(item) == R.string.layer_underlay){
|
||||
if(underlayLayer.getMap() != null){
|
||||
settings.MAP_UNDERLAY.set(null);
|
||||
updateMapSource(mapView, null);
|
||||
|
@ -304,7 +317,7 @@ public class MapActivityLayers {
|
|||
selectMapOverlayLayer(mapView, settings.MAP_UNDERLAY,settings.MAP_TRANSPARENCY,
|
||||
mapTileLayer, mapVectorLayer);
|
||||
}
|
||||
} else if(item == 5){
|
||||
} else if(layers.get(item) == R.string.layer_gpx_layer){
|
||||
if(gpxLayer.isVisible()){
|
||||
getApplication().setGpxFileToDisplay(null);
|
||||
gpxLayer.clearCurrentGPX();
|
||||
|
@ -312,13 +325,13 @@ public class MapActivityLayers {
|
|||
dialog.dismiss();
|
||||
showGPXFileLayer(mapView);
|
||||
}
|
||||
} else if(item == 6){
|
||||
} else if(layers.get(item) == R.string.layer_transport){
|
||||
settings.SHOW_TRANSPORT_OVER_MAP.set(isChecked);
|
||||
} else if(item == 7){
|
||||
} else if(layers.get(item) == R.string.layer_osm_bugs){
|
||||
settings.SHOW_OSM_BUGS.set(isChecked);
|
||||
} else if(item == routeInfoInd){
|
||||
} else if(layers.get(item) == R.string.layer_route){
|
||||
routeInfoLayer.setVisible(isChecked);
|
||||
} else if(item == transportRouteInfoInd){
|
||||
} else if(layers.get(item) == R.string.layer_transport_route){
|
||||
transportInfoLayer.setVisible(isChecked);
|
||||
}
|
||||
updateLayers(mapView);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package net.osmand.plus.views;
|
||||
|
||||
import gnu.trove.set.hash.TIntHashSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
@ -9,6 +11,7 @@ import net.osmand.LogUtil;
|
|||
import net.osmand.OsmAndFormatter;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import net.osmand.plus.PoiFilter;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.ResourceManager;
|
||||
|
@ -35,7 +38,8 @@ import android.widget.Toast;
|
|||
|
||||
public class POIMapLayer implements OsmandMapLayer, ContextMenuLayer.IContextMenuProvider {
|
||||
private static final int startZoom = 10;
|
||||
public static final int TEXT_WRAP = 30;
|
||||
public static final int TEXT_WRAP = 15;
|
||||
public static final int TEXT_LINES = 3;
|
||||
public static final org.apache.commons.logging.Log log = LogUtil.getLog(POIMapLayer.class);
|
||||
|
||||
|
||||
|
@ -174,8 +178,8 @@ public class POIMapLayer implements OsmandMapLayer, ContextMenuLayer.IContextMen
|
|||
resourceManager.searchAmenitiesAsync(latLonBounds.top, latLonBounds.left, latLonBounds.bottom, latLonBounds.right, view.getZoom(), filter, objects);
|
||||
int r = getRadiusPoi(view.getZoom());
|
||||
for (Amenity o : objects) {
|
||||
int x = view.getMapXForPoint(o.getLocation().getLongitude());
|
||||
int y = view.getMapYForPoint(o.getLocation().getLatitude());
|
||||
int x = view.getRotatedMapXForPoint(o.getLocation().getLatitude(), o.getLocation().getLongitude());
|
||||
int y = view.getRotatedMapYForPoint(o.getLocation().getLatitude(), o.getLocation().getLongitude());
|
||||
canvas.drawCircle(x, y, r, pointAltUI);
|
||||
canvas.drawCircle(x, y, r, point);
|
||||
String id = null;
|
||||
|
@ -190,25 +194,52 @@ public class POIMapLayer implements OsmandMapLayer, ContextMenuLayer.IContextMen
|
|||
if(bmp != null){
|
||||
canvas.drawBitmap(bmp, x - bmp.getWidth() / 2, y - bmp.getHeight() / 2, paintIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (view.getSettings().SHOW_POI_LABEL.get()) {
|
||||
TIntHashSet set = new TIntHashSet();
|
||||
for (Amenity o : objects) {
|
||||
int x = view.getRotatedMapXForPoint(o.getLocation().getLatitude(), o.getLocation().getLongitude());
|
||||
int y = view.getRotatedMapYForPoint(o.getLocation().getLatitude(), o.getLocation().getLongitude());
|
||||
int tx = view.getMapXForPoint(o.getLocation().getLongitude());
|
||||
int ty = view.getMapYForPoint(o.getLocation().getLatitude());
|
||||
String name = o.getName(view.getSettings().USE_ENGLISH_NAMES.get());
|
||||
if(name != null && name.length() > 0){
|
||||
// TODO cache list
|
||||
// 1. Draw over in 2 phases over all circles
|
||||
// 2. Draw without rotation and icons (!)
|
||||
// 3. Omit highdensity icons
|
||||
// drawWrappedText(canvas, name, paintTextIcon.getTextSize(),
|
||||
// x + bmp.getWidth() / 2, y + bmp.getHeight() / 2 +
|
||||
// paintTextIcon.getTextSize() / 2);
|
||||
|
||||
if (name != null && name.length() > 0) {
|
||||
int lines = 0;
|
||||
while (lines < TEXT_LINES) {
|
||||
if (set.contains(division(tx, ty, 0, lines)) ||
|
||||
set.contains(division(tx, ty, -1, lines)) || set.contains(division(tx, ty, +1, lines))) {
|
||||
break;
|
||||
}
|
||||
lines++;
|
||||
}
|
||||
if (lines == 0) {
|
||||
// drawWrappedText(canvas, "...", paintTextIcon.getTextSize(), x, y + r + 2 + paintTextIcon.getTextSize() / 2, 1);
|
||||
} else {
|
||||
drawWrappedText(canvas, name, paintTextIcon.getTextSize(), x, y + r + 2 + paintTextIcon.getTextSize() / 2,
|
||||
lines);
|
||||
while (lines > 0) {
|
||||
set.add(division(tx, ty, 1, lines - 1));
|
||||
set.add(division(tx, ty, -1, lines - 1));
|
||||
set.add(division(tx, ty, 0, lines - 1));
|
||||
lines--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void drawWrappedText(Canvas cv, String text, float textSize, float x, float y) {
|
||||
private int division(int x, int y, int sx, int sy) {
|
||||
// make numbers positive
|
||||
return ((((x + 10000) >> 4) + sx) << 16) | (((y + 10000) >> 4) + sy);
|
||||
}
|
||||
|
||||
private void drawWrappedText(Canvas cv, String text, float textSize, float x, float y, int lines) {
|
||||
if(text.length() > TEXT_WRAP){
|
||||
int start = 0;
|
||||
int end = text.length();
|
||||
|
@ -216,7 +247,7 @@ public class POIMapLayer implements OsmandMapLayer, ContextMenuLayer.IContextMen
|
|||
int line = 0;
|
||||
int pos = 0;
|
||||
int limit = 0;
|
||||
while(pos < end){
|
||||
while(pos < end && (line < lines)){
|
||||
lastSpace = -1;
|
||||
limit += TEXT_WRAP;
|
||||
while(pos < limit && pos < end){
|
||||
|
@ -230,13 +261,18 @@ public class POIMapLayer implements OsmandMapLayer, ContextMenuLayer.IContextMen
|
|||
start = pos;
|
||||
} else {
|
||||
String subtext = text.substring(start, lastSpace);
|
||||
if (line + 1 == lines) {
|
||||
subtext += "..";
|
||||
}
|
||||
drawShadowText(cv, subtext, x, y + line * (textSize + 2));
|
||||
|
||||
start = lastSpace + 1;
|
||||
limit += (start - pos) - 1;
|
||||
}
|
||||
|
||||
line++;
|
||||
|
||||
|
||||
}
|
||||
} else {
|
||||
drawShadowText(cv, text, x, y);
|
||||
|
@ -263,7 +299,7 @@ public class POIMapLayer implements OsmandMapLayer, ContextMenuLayer.IContextMen
|
|||
|
||||
@Override
|
||||
public boolean drawInScreenPixels() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue