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