Merge pull request #2593 from osmandapp/moving_marker

Moving marker
This commit is contained in:
vshcherb 2016-05-25 13:02:22 +02:00
commit afb9f08e4b
28 changed files with 1215 additions and 559 deletions

View file

@ -1,6 +1,5 @@
package net.osmand.util;
import net.osmand.IProgress;
import net.osmand.PlatformUtil;
@ -21,22 +20,23 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
/**
* Basic algorithms that are not in jdk
* Basic algorithms that are not in jdk
*/
public class Algorithms {
private static final int BUFFER_SIZE = 1024;
private static final Log log = PlatformUtil.getLog(Algorithms.class);
public static boolean isEmpty(String s){
public static boolean isEmpty(String s) {
return s == null || s.length() == 0;
}
public static boolean isBlank(String s){
public static boolean isBlank(String s) {
return s == null || s.trim().length() == 0;
}
@ -47,13 +47,12 @@ public class Algorithms {
return false;
} else if (s2 == null) {
return false;
} else {
return s2.equals(s1);
}
return s2.equals(s1);
}
public static long parseLongSilently(String input, long def) {
if(input != null && input.length() > 0) {
if (input != null && input.length() > 0) {
try {
return Long.parseLong(input);
} catch (NumberFormatException e) {
@ -62,20 +61,24 @@ public class Algorithms {
}
return def;
}
public static String getFileNameWithoutExtension(File f) {
String name = f.getName();
int i = name.indexOf('.');
if(i >= 0) {
if (i >= 0) {
name = name.substring(0, i);
}
return name;
}
public static File[] getSortedFilesVersions(File dir){
public static String getFileExtension(File f) {
String name = f.getName();
int i = name.lastIndexOf(".");
return name.substring(i + 1);
}
public static File[] getSortedFilesVersions(File dir) {
File[] listFiles = dir.listFiles();
if (listFiles != null) {
Arrays.sort(listFiles, getFileVersionComparator());
@ -89,37 +92,37 @@ public class Algorithms {
public int compare(File o1, File o2) {
return -simplifyFileName(o1.getName()).compareTo(simplifyFileName(o2.getName()));
}
public String simplifyFileName(String fn) {
String lc = fn.toLowerCase();
if (lc.indexOf(".") != -1) {
if (lc.contains(".")) {
lc = lc.substring(0, lc.indexOf("."));
}
if (lc.endsWith("_2")) {
lc = lc.substring(0, lc.length() - "_2".length());
}
boolean hasTimestampEnd = false;
for(int i = 0; i < lc.length(); i++) {
if(lc.charAt(i) >= '0' && lc.charAt(i) <= '9') {
for (int i = 0; i < lc.length(); i++) {
if (lc.charAt(i) >= '0' && lc.charAt(i) <= '9') {
hasTimestampEnd = true;
break;
}
}
if(!hasTimestampEnd) {
if (!hasTimestampEnd) {
lc += "_00_00_00";
}
return lc;
}
};
}
private static final char CHAR_TOSPLIT = 0x01;
public static Map<String, String> decodeMap(String s) {
if (isEmpty(s)) {
return Collections.emptyMap();
}
Map<String, String> names = new HashMap<String, String>();
Map<String, String> names = new HashMap<>();
String[] split = s.split(CHAR_TOSPLIT + "");
// last split is an empty string
for (int i = 1; i < split.length; i += 2) {
@ -127,7 +130,7 @@ public class Algorithms {
}
return names;
}
public static String encodeMap(Map<String, String> names) {
if (names != null) {
Iterator<Entry<String, String>> it = names.entrySet().iterator();
@ -135,14 +138,14 @@ public class Algorithms {
while (it.hasNext()) {
Entry<String, String> e = it.next();
bld.append(e.getKey()).append(CHAR_TOSPLIT)
.append(e.getValue().replace(CHAR_TOSPLIT, (char)(CHAR_TOSPLIT + 1)));
.append(e.getValue().replace(CHAR_TOSPLIT, (char) (CHAR_TOSPLIT + 1)));
bld.append(CHAR_TOSPLIT);
}
return bld.toString();
}
return "";
}
public static int findFirstNumberEndIndex(String value) {
int i = 0;
boolean valid = false;
@ -159,7 +162,7 @@ public class Algorithms {
return -1;
}
}
public static boolean isDigit(char charAt) {
return charAt >= '0' && charAt <= '9';
}
@ -182,17 +185,17 @@ public class Algorithms {
in.close();
return test == 0x504b0304;
}
private static final int readInt(InputStream in) throws IOException {
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
}
private static int readInt(InputStream in) throws IOException {
int ch1 = in.read();
int ch2 = in.read();
int ch3 = in.read();
int ch4 = in.read();
if ((ch1 | ch2 | ch3 | ch4) < 0)
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
}
public static String capitalizeFirstLetterAndLowercase(String s) {
if (s != null && s.length() > 1) {
// not very efficient algorithm
@ -201,48 +204,48 @@ public class Algorithms {
return s;
}
}
public static boolean objectEquals(Object a, Object b){
if(a == null){
public static boolean objectEquals(Object a, Object b) {
if (a == null) {
return b == null;
} else {
return a.equals(b);
}
}
/**
* Parse the color string, and return the corresponding color-int.
* If the string cannot be parsed, throws an IllegalArgumentException
* exception. Supported formats are:
* #RRGGBB
* #AARRGGBB
* 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta',
* 'yellow', 'lightgray', 'darkgray'
*/
public static int parseColor(String colorString) {
if (colorString.charAt(0) == '#') {
// Use a long to avoid rollovers on #ffXXXXXX
if (colorString.length() == 4) {
colorString = "#" +
colorString.charAt(1) + colorString.charAt(1) +
colorString.charAt(2) + colorString.charAt(2) +
colorString.charAt(3) + colorString.charAt(3);
}
long color = Long.parseLong(colorString.substring(1), 16);
if (colorString.length() == 7) {
// Set the alpha value
color |= 0x00000000ff000000;
} else if (colorString.length() != 9) {
throw new IllegalArgumentException("Unknown color " + colorString); //$NON-NLS-1$
}
return (int)color;
}
throw new IllegalArgumentException("Unknown color " + colorString); //$NON-NLS-1$
}
* Parse the color string, and return the corresponding color-int.
* If the string cannot be parsed, throws an IllegalArgumentException
* exception. Supported formats are:
* #RRGGBB
* #AARRGGBB
* 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta',
* 'yellow', 'lightgray', 'darkgray'
*/
public static int parseColor(String colorString) {
if (colorString.charAt(0) == '#') {
// Use a long to avoid rollovers on #ffXXXXXX
if (colorString.length() == 4) {
colorString = "#" +
colorString.charAt(1) + colorString.charAt(1) +
colorString.charAt(2) + colorString.charAt(2) +
colorString.charAt(3) + colorString.charAt(3);
}
long color = Long.parseLong(colorString.substring(1), 16);
if (colorString.length() == 7) {
// Set the alpha value
color |= 0x00000000ff000000;
} else if (colorString.length() != 9) {
throw new IllegalArgumentException("Unknown color " + colorString); //$NON-NLS-1$
}
return (int) color;
}
throw new IllegalArgumentException("Unknown color " + colorString); //$NON-NLS-1$
}
public static int extractFirstIntegerNumber(String s) {
int i = 0;
for (int k = 0; k < s.length(); k++) {
@ -254,10 +257,10 @@ public class Algorithms {
}
return i;
}
public static int extractIntegerNumber(String s) {
int i = 0;
int k = 0;
int k;
for (k = 0; k < s.length(); k++) {
if (isDigit(s.charAt(k))) {
break;
@ -272,7 +275,7 @@ public class Algorithms {
}
return i;
}
public static String extractIntegerPrefix(String s) {
int k = 0;
for (; k < s.length(); k++) {
@ -282,7 +285,7 @@ public class Algorithms {
}
return "";
}
public static String extractOnlyIntegerSuffix(String s) {
int k = 0;
for (; k < s.length(); k++) {
@ -292,7 +295,7 @@ public class Algorithms {
}
return "";
}
public static String extractIntegerSuffix(String s) {
int k = 0;
for (; k < s.length(); k++) {
@ -302,8 +305,9 @@ public class Algorithms {
}
return "";
}
@SuppressWarnings("TryFinallyCanBeTryWithResources")
public static void fileCopy(File src, File dst) throws IOException {
FileOutputStream fout = new FileOutputStream(dst);
try {
@ -317,59 +321,61 @@ public class Algorithms {
fout.close();
}
}
public static void streamCopy(InputStream in, OutputStream out) throws IOException{
public static void streamCopy(InputStream in, OutputStream out) throws IOException {
byte[] b = new byte[BUFFER_SIZE];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
}
public static void streamCopy(InputStream in, OutputStream out, IProgress pg, int bytesDivisor) throws IOException{
public static void streamCopy(InputStream in, OutputStream out, IProgress pg, int bytesDivisor) throws IOException {
byte[] b = new byte[BUFFER_SIZE];
int read;
int cp = 0;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
cp += read;
if(pg != null && cp > bytesDivisor) {
if (pg != null && cp > bytesDivisor) {
pg.progress(cp / bytesDivisor);
cp = cp % bytesDivisor;
cp = cp % bytesDivisor;
}
}
}
public static void oneByteStreamCopy(InputStream in, OutputStream out) throws IOException{
public static void oneByteStreamCopy(InputStream in, OutputStream out) throws IOException {
int read;
while ((read = in.read()) != -1) {
out.write(read);
}
}
public static void closeStream(Closeable stream){
public static void closeStream(Closeable stream) {
try {
if(stream != null){
if (stream != null) {
stream.close();
}
} catch(IOException e){
} catch (IOException e) {
log.warn("Closing stream warn", e); //$NON-NLS-1$
}
}
public static void updateAllExistingImgTilesToOsmandFormat(File f){
if(f.isDirectory()){
for(File c : f.listFiles()){
@SuppressWarnings("ResultOfMethodCallIgnored")
public static void updateAllExistingImgTilesToOsmandFormat(File f) {
if (f.isDirectory()) {
for (File c : f.listFiles()) {
updateAllExistingImgTilesToOsmandFormat(c);
}
} else if(f.getName().endsWith(".png") || f.getName().endsWith(".jpg")){ //$NON-NLS-1$ //$NON-NLS-2$
} else if (f.getName().endsWith(".png") || f.getName().endsWith(".jpg")) { //$NON-NLS-1$ //$NON-NLS-2$
f.renameTo(new File(f.getAbsolutePath() + ".tile")); //$NON-NLS-1$
} else if(f.getName().endsWith(".andnav2")) { //$NON-NLS-1$
} else if (f.getName().endsWith(".andnav2")) { //$NON-NLS-1$
f.renameTo(new File(f.getAbsolutePath().substring(0, f.getAbsolutePath().length() - ".andnav2".length()) + ".tile")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
public static StringBuilder readFromInputStream(InputStream i) throws IOException {
StringBuilder responseBody = new StringBuilder();
responseBody.setLength(0);
@ -388,27 +394,27 @@ public class Algorithms {
}
return responseBody;
}
public static boolean removeAllFiles(File f) {
if (f == null) {
return false;
}
if (f.isDirectory()) {
File[] fs = f.listFiles();
if(fs != null) {
for (File c : fs) {
removeAllFiles(c);
}
if (fs != null) {
for (File c : fs) {
removeAllFiles(c);
}
}
return f.delete();
} else {
return f.delete();
}
}
public static long parseLongFromBytes(byte[] bytes, int offset) {
long o= 0xff & bytes[offset + 7];
long o = 0xff & bytes[offset + 7];
o = o << 8 | (0xff & bytes[offset + 6]);
o = o << 8 | (0xff & bytes[offset + 5]);
o = o << 8 | (0xff & bytes[offset + 4]);
@ -418,10 +424,9 @@ public class Algorithms {
o = o << 8 | (0xff & bytes[offset]);
return o;
}
public static void putLongToBytes(byte[] bytes, int offset, long l){
public static void putLongToBytes(byte[] bytes, int offset, long l) {
bytes[offset] = (byte) (l & 0xff);
l >>= 8;
bytes[offset + 1] = (byte) (l & 0xff);
@ -438,8 +443,8 @@ public class Algorithms {
l >>= 8;
bytes[offset + 7] = (byte) (l & 0xff);
}
public static int parseIntFromBytes(byte[] bytes, int offset) {
int o = (0xff & bytes[offset + 3]) << 24;
o |= (0xff & bytes[offset + 2]) << 16;
@ -447,8 +452,8 @@ public class Algorithms {
o |= (0xff & bytes[offset]);
return o;
}
public static void putIntToBytes(byte[] bytes, int offset, int l){
public static void putIntToBytes(byte[] bytes, int offset, int l) {
bytes[offset] = (byte) (l & 0xff);
l >>= 8;
bytes[offset + 1] = (byte) (l & 0xff);
@ -457,8 +462,8 @@ public class Algorithms {
l >>= 8;
bytes[offset + 3] = (byte) (l & 0xff);
}
public static void writeLongInt(OutputStream stream, long l) throws IOException {
stream.write((int) (l & 0xff));
l >>= 8;
@ -476,7 +481,7 @@ public class Algorithms {
l >>= 8;
stream.write((int) (l & 0xff));
}
public static void writeInt(OutputStream stream, int l) throws IOException {
stream.write(l & 0xff);
l >>= 8;
@ -486,26 +491,24 @@ public class Algorithms {
l >>= 8;
stream.write(l & 0xff);
}
public static void writeSmallInt(OutputStream stream, int l) throws IOException {
stream.write(l & 0xff);
l >>= 8;
stream.write(l & 0xff);
l >>= 8;
}
public static int parseSmallIntFromBytes(byte[] bytes, int offset) {
int s = (0xff & bytes[offset + 1]) << 8;
s |= (0xff & bytes[offset]);
return s;
}
public static void putSmallIntBytes(byte[] bytes, int offset, int s){
public static void putSmallIntBytes(byte[] bytes, int offset, int s) {
bytes[offset] = (byte) (s & 0xff);
s >>= 8;
bytes[offset + 1] = (byte) (s & 0xff);
s >>= 8;
}
public static boolean containsDigit(String name) {
@ -516,7 +519,7 @@ public class Algorithms {
}
return false;
}
public static String formatDuration(int seconds, boolean fullForm) {
String sec;
@ -546,14 +549,14 @@ public class Algorithms {
} else {
int min = minutes % 60;
int hours = minutes / 60;
return String.format("%02d:%02d", hours, min);
return String.format(Locale.UK, "%02d:%02d", hours, min);
}
}
public static <T extends Enum<T> > T parseEnumValue(T[] cl, String val, T defaultValue){
for(int i = 0; i< cl.length; i++) {
if(cl[i].name().equalsIgnoreCase(val)) {
return cl[i];
public static <T extends Enum<T>> T parseEnumValue(T[] cl, String val, T defaultValue) {
for (T aCl : cl) {
if (aCl.name().equalsIgnoreCase(val)) {
return aCl;
}
}
return defaultValue;
@ -568,7 +571,7 @@ public class Algorithms {
}
private static String format(int i, String hexString) {
while(hexString.length() < i) {
while (hexString.length() < i) {
hexString = "0" + hexString;
}
return hexString;
@ -580,16 +583,16 @@ public class Algorithms {
// from purple (low) to red(high). This is useful for producing value-based colourations (e.g., altitude)
double a = (1. - percent) * 5.;
int X = (int)Math.floor(a);
int Y = (int)(Math.floor(255 * (a - X)));
int X = (int) Math.floor(a);
int Y = (int) (Math.floor(255 * (a - X)));
switch (X) {
case 0: return 0xFFFF0000 + (Y<<8);
case 1: return 0xFF00FF00 + ((255-Y)<<16);
case 0: return 0xFFFF0000 + (Y << 8);
case 1: return 0xFF00FF00 + ((255 - Y) << 16);
case 2: return 0xFF00FF00 + Y;
case 3: return 0xFF0000FF + ((255-Y)<<8);
case 3: return 0xFF0000FF + ((255 - Y) << 8);
case 4: return 0xFF0000FF + (Y << 16);
}
return 0xFFFF00FF;
}
}
}

View file

@ -2164,4 +2164,4 @@ Für Hilfe mit der OsmAnd-App kontaktieren Sie bitte unser Support-Team unter su
<string name="access_direction_audio_feedback_descr">Zeige Richtung des Zielpunkt durch Ton</string>
<string name="access_direction_haptic_feedback">Richtung haptisches Feedback</string>
<string name="access_direction_haptic_feedback_descr">Zeige Richtung des Zielpunkt durch Vibration</string>
</resources>
</resources>

View file

@ -11,6 +11,7 @@
-->
<string name="map_widget_battery">Battery level</string>
<string name="change_markers_position">Change marker\'s position</string>
<string name="move_marker_bottom_sheet_title">Move the map to change marker\'s position</string>
<string name="lat_lon_pattern">Lat: %1$.6f Lon: %2$.6f</string>
<string name="follow_us">Follow us</string>

View file

@ -5,6 +5,7 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.ColorInt;
import net.osmand.Location;
import net.osmand.PlatformUtil;
@ -64,8 +65,9 @@ public class GPXUtilities {
}
return extensions;
}
public int getColor(int defColor) {
@ColorInt
public int getColor(@ColorInt int defColor) {
if(extensions != null && extensions.containsKey("color")) {
try {
return Color.parseColor(extensions.get("color").toUpperCase());
@ -665,7 +667,7 @@ public class GPXUtilities {
return points.size() > 0;
}
public boolean hasTrkpt() {
public boolean hasTrkPt() {
for(Track t : tracks) {
for (TrkSegment ts : t.segments) {
if (ts.points.size() > 0) {
@ -1224,7 +1226,5 @@ public class GPXUtilities {
if (from.warning != null) {
to.warning = from.warning;
}
}
}
}

View file

@ -1,6 +1,7 @@
package net.osmand.plus;
import android.content.Context;
import android.support.annotation.Nullable;
import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint;
@ -80,6 +81,37 @@ public class MapMarkersHelper {
return false;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MapMarker mapMarker = (MapMarker) o;
if (colorIndex != mapMarker.colorIndex) return false;
if (pos != mapMarker.pos) return false;
if (index != mapMarker.index) return false;
if (history != mapMarker.history) return false;
if (selected != mapMarker.selected) return false;
if (dist != mapMarker.dist) return false;
//noinspection SimplifiableIfStatement
if (!point.equals(mapMarker.point)) return false;
return pointDescription != null ? pointDescription.equals(mapMarker.pointDescription) : mapMarker.pointDescription == null;
}
@Override
public int hashCode() {
int result = point.hashCode();
result = 31 * result + (pointDescription != null ? pointDescription.hashCode() : 0);
result = 31 * result + colorIndex;
result = 31 * result + pos;
result = 31 * result + index;
result = 31 * result + (history ? 1 : 0);
result = 31 * result + (selected ? 1 : 0);
result = 31 * result + dist;
return result;
}
}
public MapMarkersHelper(OsmandApplication ctx) {
@ -363,6 +395,15 @@ public class MapMarkersHelper {
}
}
public void moveMapMarker(@Nullable MapMarker marker, LatLon latLon) {
if (marker != null) {
settings.moveMapMarker(new LatLon(marker.getLatitude(), marker.getLongitude()), latLon,
marker.pointDescription, marker.colorIndex, marker.pos, marker.selected);
readFromSettings();
refresh();
}
}
public void removeMapMarker(MapMarker marker) {
if (marker != null) {
settings.deleteMapMarker(marker.index);

View file

@ -40,7 +40,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -50,7 +49,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
public class OsmandSettings {
@ -1859,20 +1857,61 @@ public class OsmandSettings {
List<Integer> ns = getPositions(ps.size());
List<Boolean> bs = getSelections(ps.size());
int index = ps.indexOf(new LatLon(latitude, longitude));
ds.set(index, PointDescription.serializeToString(historyDescription));
if (cs.size() > index) {
cs.set(index, colorIndex);
if (index != -1) {
ds.set(index, PointDescription.serializeToString(historyDescription));
if (cs.size() > index) {
cs.set(index, colorIndex);
}
if (ns.size() > index) {
ns.set(index, pos);
}
if (bs.size() > index) {
bs.set(index, selected);
}
if (historyDescription != null && !historyDescription.isSearchingAddress(ctx)) {
SearchHistoryHelper.getInstance(ctx).addNewItemToHistory(latitude, longitude, historyDescription);
}
return savePoints(ps, ds, cs, ns, bs);
} else {
return false;
}
if (ns.size() > index) {
ns.set(index, pos);
}
public boolean movePoint(LatLon latLonEx,
LatLon latLonNew,
PointDescription historyDescription,
int colorIndex,
int pos,
boolean selected) {
List<LatLon> ps = getPoints();
List<String> ds = getPointDescriptions(ps.size());
List<Integer> cs = getColors(ps.size());
List<Integer> ns = getPositions(ps.size());
List<Boolean> bs = getSelections(ps.size());
int index = ps.indexOf(latLonEx);
if (index != -1) {
if (ps.size() > index) {
ps.set(index, latLonNew);
}
ds.set(index, PointDescription.serializeToString(historyDescription));
if (cs.size() > index) {
cs.set(index, colorIndex);
}
if (ns.size() > index) {
ns.set(index, pos);
}
if (bs.size() > index) {
bs.set(index, selected);
}
if (historyDescription != null && !historyDescription.isSearchingAddress(ctx)) {
double lat = latLonNew.getLatitude();
double lon = latLonNew.getLongitude();
SearchHistoryHelper.getInstance(ctx).addNewItemToHistory(lat, lon, historyDescription);
}
return savePoints(ps, ds, cs, ns, bs);
} else {
return false;
}
if (bs.size() > index) {
bs.set(index, selected);
}
if (historyDescription != null && !historyDescription.isSearchingAddress(ctx)) {
SearchHistoryHelper.getInstance(ctx).addNewItemToHistory(latitude, longitude, historyDescription);
}
return savePoints(ps, ds, cs, ns, bs);
}
@Override
@ -2137,6 +2176,16 @@ public class OsmandSettings {
pos, selected);
}
public boolean moveMapMarker(LatLon latLonEx,
LatLon latLonNew,
PointDescription historyDescription,
int colorIndex,
int pos,
boolean selected) {
return mapMarkersStorage.movePoint(latLonEx, latLonNew, historyDescription, colorIndex,
pos, selected);
}
public boolean deleteMapMarker(int index) {
return mapMarkersStorage.deletePoint(index);
}

View file

@ -1,6 +1,7 @@
package net.osmand.plus;
import android.annotation.SuppressLint;
import android.content.Context;
import net.osmand.Location;
@ -19,12 +20,12 @@ import java.util.List;
public class TargetPointsHelper {
private List<TargetPoint> intermediatePoints = new ArrayList<TargetPoint>();
private List<TargetPoint> intermediatePoints = new ArrayList<>();
private TargetPoint pointToNavigate = null;
private TargetPoint pointToStart = null;
private OsmandSettings settings;
private RoutingHelper routingHelper;
private List<StateChangedListener<Void>> listeners = new ArrayList<StateChangedListener<Void>>();
private List<StateChangedListener<Void>> listeners = new ArrayList<>();
private OsmandApplication ctx;
private AddressLookupRequest startPointRequest;
@ -49,6 +50,7 @@ public class TargetPointsHelper {
this.intermediate = true;
}
@SuppressLint("StringFormatInvalid")
public PointDescription getPointDescription(Context ctx) {
if (!intermediate) {
return new PointDescription(PointDescription.POINT_TYPE_TARGET, ctx.getString(R.string.destination_point, ""),
@ -61,7 +63,7 @@ public class TargetPointsHelper {
public PointDescription getOriginalPointDescription() {
return pointDescription;
};
}
public String getOnlyName() {
return pointDescription == null ? "" : pointDescription.getName();
@ -229,7 +231,7 @@ public class TargetPointsHelper {
}
public List<LatLon> getIntermediatePointsLatLon() {
List<LatLon> intermediatePointsLatLon = new ArrayList<LatLon>();
List<LatLon> intermediatePointsLatLon = new ArrayList<>();
for (TargetPoint t : this.intermediatePoints) {
intermediatePointsLatLon.add(t.point);
}
@ -237,7 +239,7 @@ public class TargetPointsHelper {
}
public List<LatLon> getIntermediatePointsLatLonNavigation() {
List<LatLon> intermediatePointsLatLon = new ArrayList<LatLon>();
List<LatLon> intermediatePointsLatLon = new ArrayList<>();
if (settings.USE_INTERMEDIATE_POINTS_NAVIGATION.get()) {
for (TargetPoint t : this.intermediatePoints) {
intermediatePointsLatLon.add(t.point);
@ -247,7 +249,7 @@ public class TargetPointsHelper {
}
public List<TargetPoint> getAllPoints() {
List<TargetPoint> res = new ArrayList<TargetPoint>();
List<TargetPoint> res = new ArrayList<>();
if(pointToStart != null) {
res.add(pointToStart);
}
@ -259,7 +261,7 @@ public class TargetPointsHelper {
}
public List<TargetPoint> getIntermediatePointsWithTarget() {
List<TargetPoint> res = new ArrayList<TargetPoint>();
List<TargetPoint> res = new ArrayList<>();
res.addAll(this.intermediatePoints);
if(pointToNavigate != null) {
res.add(pointToNavigate);
@ -423,8 +425,8 @@ public class TargetPointsHelper {
settings.clearPointToNavigate();
if (point.size() > 0) {
List<TargetPoint> subList = point.subList(0, point.size() - 1);
ArrayList<String> names = new ArrayList<String>(subList.size());
ArrayList<LatLon> ls = new ArrayList<LatLon>(subList.size());
ArrayList<String> names = new ArrayList<>(subList.size());
ArrayList<LatLon> ls = new ArrayList<>(subList.size());
for(int i = 0; i < subList.size(); i++) {
names.add(PointDescription.serializeToString(subList.get(i).pointDescription));
ls.add(subList.get(i).point);

View file

@ -320,7 +320,7 @@ public class MapActivityActions implements DialogProvider {
} else {
GPXRouteParamsBuilder params = new GPXRouteParamsBuilder(result, mapActivity.getMyApplication()
.getSettings());
if (result.hasRtePt() && !result.hasTrkpt()) {
if (result.hasRtePt() && !result.hasTrkPt()) {
settings.GPX_CALCULATE_RTEPT.set(true);
} else {
settings.GPX_CALCULATE_RTEPT.set(false);
@ -350,7 +350,7 @@ public class MapActivityActions implements DialogProvider {
final List<GPXFile> gpxFiles = new ArrayList<>();
for (SelectedGpxFile gs : selectedGPXFiles) {
if (!gs.isShowCurrentTrack() && !gs.notShowNavigationDialog) {
if (gs.getGpxFile().hasRtePt() || gs.getGpxFile().hasTrkpt()) {
if (gs.getGpxFile().hasRtePt() || gs.getGpxFile().hasTrkPt()) {
gpxFiles.add(gs.getGpxFile());
}
}

View file

@ -37,7 +37,7 @@ import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.views.ContextMenuLayer;
import net.osmand.plus.views.DownloadedRegionsLayer;
import net.osmand.plus.views.FavoritesLayer;
import net.osmand.plus.views.FavouritesLayer;
import net.osmand.plus.views.GPXLayer;
import net.osmand.plus.views.ImpassableRoadsLayer;
import net.osmand.plus.views.MapControlsLayer;
@ -72,7 +72,7 @@ public class MapActivityLayers {
private GPXLayer gpxLayer;
private RouteLayer routeLayer;
private POIMapLayer poiMapLayer;
private FavoritesLayer favoritesLayer;
private FavouritesLayer mFavouritesLayer;
private TransportStopsLayer transportStopsLayer;
private TransportInfoLayer transportInfoLayer;
private PointLocationLayer locationLayer;
@ -138,8 +138,8 @@ public class MapActivityLayers {
poiMapLayer = new POIMapLayer(activity);
mapView.addLayer(poiMapLayer, 3);
// 4. favorites layer
favoritesLayer = new FavoritesLayer();
mapView.addLayer(favoritesLayer, 4);
mFavouritesLayer = new FavouritesLayer();
mapView.addLayer(mFavouritesLayer, 4);
// 5. transport layer
transportStopsLayer = new TransportStopsLayer();
// 5.5 transport info layer
@ -565,8 +565,8 @@ public class MapActivityLayers {
return contextMenuLayer;
}
public FavoritesLayer getFavoritesLayer() {
return favoritesLayer;
public FavouritesLayer getFavouritesLayer() {
return mFavouritesLayer;
}
public MapTextLayer getMapTextLayer() {

View file

@ -7,6 +7,9 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import net.osmand.data.DataTileManager;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
@ -16,6 +19,7 @@ import net.osmand.data.RotatedTileBox;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin.Recording;
import net.osmand.plus.views.ContextMenuLayer;
import net.osmand.plus.views.ContextMenuLayer.IContextMenuProvider;
import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapTileView;
@ -24,20 +28,22 @@ import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.List;
public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvider {
public class AudioNotesLayer extends OsmandMapLayer implements
IContextMenuProvider, ContextMenuLayer.IMoveObjectProvider {
private static final int startZoom = 10;
private MapActivity activity;
private AudioVideoNotesPlugin plugin;
private Paint pointAltUI;
private Paint paintIcon;
private Paint point;
private OsmandMapTileView view;
private Bitmap audio;
private Bitmap video;
private Bitmap photo;
private Bitmap pointSmall;
private ContextMenuLayer contextMenuLayer;
public AudioNotesLayer(MapActivity activity, AudioVideoNotesPlugin plugin) {
this.activity = activity;
this.plugin = plugin;
@ -50,7 +56,7 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
pointAltUI = new Paint();
pointAltUI.setColor(0xa0FF3344);
pointAltUI.setStyle(Style.FILL);
audio = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_note_audio);
video = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_note_video);
photo = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_note_photo);
@ -59,15 +65,17 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
paintIcon = new Paint();
point = new Paint();
Paint point = new Paint();
point.setColor(Color.GRAY);
point.setAntiAlias(true);
point.setStyle(Style.STROKE);
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
}
public int getRadiusPoi(RotatedTileBox tb){
public int getRadiusPoi(RotatedTileBox tb) {
int r = 0;
if(tb.getZoom() < startZoom){
if (tb.getZoom() < startZoom) {
r = 0;
} else {
r = 15;
@ -77,8 +85,13 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
@Override
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (contextMenuLayer.getMoveableObject() instanceof Recording) {
Recording objectInMotion = (Recording) contextMenuLayer.getMoveableObject();
PointF pf = contextMenuLayer.getMoveableCenterPoint(tileBox);
drawRecording(canvas, objectInMotion, pf.x, pf.y);
}
}
@Override
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (tileBox.getZoom() >= startZoom) {
@ -92,35 +105,41 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
List<LatLon> fullObjectsLatLon = new ArrayList<>();
List<LatLon> smallObjectsLatLon = new ArrayList<>();
for (Recording o : objects) {
float x = tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude());
float y = tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude());
if (o != contextMenuLayer.getMoveableObject()) {
float x = tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude());
float y = tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude());
if (intersects(boundIntersections, x, y, iconSize, iconSize)) {
canvas.drawBitmap(pointSmall, x - pointSmall.getWidth() / 2, y - pointSmall.getHeight() / 2, paintIcon);
smallObjectsLatLon.add(new LatLon(o.getLatitude(), o.getLongitude()));
} else {
fullObjects.add(o);
fullObjectsLatLon.add(new LatLon(o.getLatitude(), o.getLongitude()));
if (intersects(boundIntersections, x, y, iconSize, iconSize)) {
canvas.drawBitmap(pointSmall, x - pointSmall.getWidth() / 2, y - pointSmall.getHeight() / 2, paintIcon);
smallObjectsLatLon.add(new LatLon(o.getLatitude(), o.getLongitude()));
} else {
fullObjects.add(o);
fullObjectsLatLon.add(new LatLon(o.getLatitude(), o.getLongitude()));
}
}
}
for (Recording o : fullObjects) {
float x = tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude());
float y = tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude());
Bitmap b;
if (o.isPhoto()) {
b = photo;
} else if (o.isAudio()) {
b = audio;
} else {
b = video;
}
canvas.drawBitmap(b, x - b.getWidth() / 2, y - b.getHeight() / 2, paintIcon);
drawRecording(canvas, o, x, y);
}
this.fullObjectsLatLon = fullObjectsLatLon;
this.smallObjectsLatLon = smallObjectsLatLon;
}
}
private void drawRecording(Canvas canvas, Recording o, float x, float y) {
Bitmap b;
if (o.isPhoto()) {
b = photo;
} else if (o.isAudio()) {
b = audio;
} else {
b = video;
}
canvas.drawBitmap(b, x - b.getWidth() / 2, y - b.getHeight() / 2, paintIcon);
}
@Override
public void destroyLayer() {
}
@ -130,13 +149,13 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
return true;
}
@Override
public PointDescription getObjectName(Object o) {
if(o instanceof Recording){
if (o instanceof Recording) {
Recording rec = (Recording) o;
String recName = rec.getName(activity, true);
if(Algorithms.isEmpty(recName)) {
if (Algorithms.isEmpty(recName)) {
return new PointDescription(rec.getSearchHistoryType(), view.getResources().getString(R.string.recording_default_name));
}
return new PointDescription(rec.getSearchHistoryType(), recName);
@ -165,7 +184,7 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
getRecordingsFromPoint(point, tileBox, objects);
}
}
public void getRecordingsFromPoint(PointF point, RotatedTileBox tileBox, List<? super Recording> am) {
int ex = (int) point.x;
int ey = (int) point.y;
@ -182,17 +201,31 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
}
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius ;
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius;
}
@Override
public LatLon getObjectLocation(Object o) {
if(o instanceof Recording){
return new LatLon(((Recording)o).getLatitude(), ((Recording)o).getLongitude());
if (o instanceof Recording) {
return new LatLon(((Recording) o).getLatitude(), ((Recording) o).getLongitude());
}
return null;
}
@Override
public boolean isObjectMovable(Object o) {
return o instanceof Recording;
}
@Override
public void applyNewObjectPosition(@NonNull Object o, @NonNull LatLon position, @Nullable ContextMenuLayer.ApplyMovedObjectCallback callback) {
boolean result = false;
if (o instanceof Recording) {
result = ((Recording) o).setLocation(position);
}
if (callback != null) {
callback.onApplyMovedObject(result, o);
}
}
}

View file

@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.StatFs;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.view.Display;
@ -254,6 +255,18 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
return false;
}
public boolean setLocation(LatLon latLon) {
File directory = file.getParentFile();
lat = latLon.getLatitude();
lon = latLon.getLongitude();
File to = getBaseFileName(lat, lon, directory, Algorithms.getFileExtension(file));
if (file.renameTo(to)) {
file = to;
return true;
}
return false;
}
public String getFileName() {
return file.getName();
}
@ -764,14 +777,18 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
}
}
private File getBaseFileName(double lat, double lon, OsmandApplication app, String ext) {
private static File getBaseFileName(double lat, double lon, OsmandApplication app, String ext) {
File baseDir = app.getAppPath(IndexConstants.AV_INDEX_DIR);
return getBaseFileName(lat, lon, baseDir, ext);
}
private static File getBaseFileName(double lat, double lon, @NonNull File baseDir, @NonNull String ext) {
String basename = MapUtils.createShortLinkString(lat, lon, 15);
int k = 1;
File f = app.getAppPath(IndexConstants.AV_INDEX_DIR);
f.mkdirs();
baseDir.mkdirs();
File fl;
do {
fl = new File(f, basename + "." + (k++) + "." + ext);
fl = new File(baseDir, basename + "." + (k++) + "." + ext);
} while (fl.exists());
return fl;
}

View file

@ -24,6 +24,7 @@ import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import net.osmand.CallbackWithObject;
import net.osmand.IndexConstants;
import net.osmand.data.LatLon;
@ -55,7 +56,6 @@ import net.osmand.util.MapUtils;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@ -68,7 +68,7 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
private DistanceCalculatorLayer distanceCalculatorLayer;
private TextInfoWidget distanceControl;
private List<LinkedList<WptPt>> measurementPoints = new ArrayList<LinkedList<WptPt>>();
private List<LinkedList<WptPt>> measurementPoints = new ArrayList<>();
private GPXFile originalGPX;
private String distance = null;
@ -320,7 +320,8 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
b.show();
}
private void saveGpx(final MapActivity activity, final String fileNameSave) {
private void saveGpx(final MapActivity activity,
final String fileNameSave) {
final AsyncTask<Void, Void, String> exportTask = new AsyncTask<Void, Void, String>() {
private ProgressDialog dlg;
private File toSave;
@ -383,9 +384,7 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
}
};
};
exportTask.execute(new Void[0]);
exportTask.execute();
}
private void startEditingHelp(MapActivity ctx) {
final CommonPreference<Boolean> pref = app.getSettings().registerBooleanPreference("show_measurement_help_first_time", true);
@ -643,9 +642,8 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
final WptPt p = (WptPt) o;
boolean containsPoint = false;
for (int i = 0; i < measurementPoints.size(); i++) {
Iterator<WptPt> it = measurementPoints.get(i).iterator();
while (it.hasNext()) {
if (it.next() == p) {
for (WptPt wptPt : measurementPoints.get(i)) {
if (wptPt == p) {
containsPoint = true;
break;
}

View file

@ -138,14 +138,15 @@ public class AvoidSpecificRoads {
@Override
public boolean processResult(LatLon result) {
addImpassableRoad(mapActivity, result, true);
addImpassableRoad(mapActivity, result, true, null);
return true;
}
});
}
public void addImpassableRoad(final MapActivity activity, final LatLon loc, final boolean showDialog) {
public void addImpassableRoad(final MapActivity activity, final LatLon loc,
final boolean showDialog, final AvoidSpecificRoadsCallback callback) {
final Location ll = new Location("");
ll.setLatitude(loc.getLatitude());
ll.setLongitude(loc.getLongitude());
@ -153,34 +154,85 @@ public class AvoidSpecificRoads {
@Override
public boolean publish(RouteDataObject object) {
if(object == null) {
if (object == null) {
Toast.makeText(activity, R.string.error_avoid_specific_road, Toast.LENGTH_LONG).show();
if (callback != null) {
callback.onAddImpassableRoad(false, null);
}
} else {
getBuilder().addImpassableRoad(object, ll);
RoutingHelper rh = app.getRoutingHelper();
if(rh.isRouteCalculated() || rh.isRouteBeingCalculated()) {
rh.recalculateRouteDueToSettingsChange();
addImpassableRoadInternal(object, ll, showDialog, activity, loc);
if (callback != null) {
callback.onAddImpassableRoad(true, object);
}
if (showDialog) {
showDialog(activity);
}
MapContextMenu menu = activity.getContextMenu();
if (menu.isActive() && menu.getLatLon().equals(loc)) {
menu.close();
}
activity.refreshMap();
}
return true;
}
@Override
public boolean isCancelled() {
if (callback != null) {
return callback.isCancelled();
}
return false;
}
});
}
public void replaceImpassableRoad(final MapActivity activity, final RouteDataObject currentObject,
final LatLon loc, final boolean showDialog,
final AvoidSpecificRoadsCallback callback) {
final Location ll = new Location("");
ll.setLatitude(loc.getLatitude());
ll.setLongitude(loc.getLongitude());
app.getLocationProvider().getRouteSegment(ll, new ResultMatcher<RouteDataObject>() {
@Override
public boolean publish(RouteDataObject object) {
if (object == null) {
Toast.makeText(activity, R.string.error_avoid_specific_road, Toast.LENGTH_LONG).show();
if (callback != null) {
callback.onAddImpassableRoad(false, null);
}
} else {
getBuilder().removeImpassableRoad(currentObject);
addImpassableRoadInternal(object, ll, showDialog, activity, loc);
if (callback != null) {
callback.onAddImpassableRoad(true, object);
}
}
return true;
}
@Override
public boolean isCancelled() {
if (callback != null) {
return callback.isCancelled();
}
return false;
}
});
}
private void addImpassableRoadInternal(RouteDataObject object, Location ll, boolean showDialog, MapActivity activity, LatLon loc) {
getBuilder().addImpassableRoad(object, ll);
RoutingHelper rh = app.getRoutingHelper();
if(rh.isRouteCalculated() || rh.isRouteBeingCalculated()) {
rh.recalculateRouteDueToSettingsChange();
}
if (showDialog) {
showDialog(activity);
}
MapContextMenu menu = activity.getContextMenu();
if (menu.isActive() && menu.getLatLon().equals(loc)) {
menu.close();
}
activity.refreshMap();
}
private void showOnMap(MapActivity ctx, double lat, double lon, String name,
DialogInterface dialog) {
AnimateDraggingMapThread thread = ctx.getMapView().getAnimatedDraggingThread();
@ -195,4 +247,10 @@ public class AvoidSpecificRoads {
dialog.dismiss();
}
public interface AvoidSpecificRoadsCallback {
void onAddImpassableRoad(boolean success, RouteDataObject newObject);
boolean isCancelled();
}
}

View file

@ -363,7 +363,7 @@ public class ExternalApiHelper {
FavouritesDbHelper helper = app.getFavorites();
helper.addFavourite(fav);
showOnMap(lat, lon, fav, mapActivity.getMapLayers().getFavoritesLayer().getObjectName(fav));
showOnMap(lat, lon, fav, mapActivity.getMapLayers().getFavouritesLayer().getObjectName(fav));
resultCode = Activity.RESULT_OK;
} else if (API_CMD_ADD_MAP_MARKER.equals(cmd)) {

View file

@ -3,6 +3,7 @@ package net.osmand.plus.mapcontextmenu;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AlertDialog.Builder;
@ -214,7 +215,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
public MapContextMenu() {
}
public boolean init(LatLon latLon, PointDescription pointDescription, Object object) {
public boolean init(LatLon latLon, PointDescription pointDescription, @Nullable Object object) {
return init(latLon, pointDescription, object, false);
}
@ -295,7 +296,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
}
}
public void show(LatLon latLon, PointDescription pointDescription, Object object) {
public void show(LatLon latLon, PointDescription pointDescription, @Nullable Object object) {
if (init(latLon, pointDescription, object)) {
if (!MapContextMenuFragment.showInstance(this, mapActivity, centerMarker)) {
active = false;
@ -406,7 +407,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
}
}
private void setSelectedObject(Object object) {
private void setSelectedObject(@Nullable Object object) {
if (object != null) {
for (OsmandMapLayer l : mapActivity.getMapView().getLayers()) {
if (l instanceof ContextMenuLayer.IContextMenuProvider) {

View file

@ -1,6 +1,7 @@
package net.osmand.plus.mapcontextmenu.controllers;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.PointDescription;
@ -47,6 +48,6 @@ public class ImpassibleRoadsMenuController extends MenuController {
@Override
public Drawable getLeftIcon() {
return getMapActivity().getResources().getDrawable(R.drawable.map_pin_avoid_road);
return ContextCompat.getDrawable(getMapActivity(), R.drawable.map_pin_avoid_road);
}
}

View file

@ -455,7 +455,7 @@ public class EditPoiDialogFragment extends BaseOsmAndDialogFragment {
}
public static void commitNode(final OsmPoint.Action action,
final Node n,
final Node node,
final EntityInfo info,
final String comment,
final boolean closeChangeSet,
@ -477,7 +477,7 @@ public class EditPoiDialogFragment extends BaseOsmAndDialogFragment {
@Override
protected Node doInBackground(Void... params) {
return openstreetmapUtil.commitNodeImpl(action, n, info, comment, closeChangeSet);
return openstreetmapUtil.commitNodeImpl(action, node, info, comment, closeChangeSet);
}
@Override

View file

@ -1,6 +1,7 @@
package net.osmand.plus.osmedit;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@ -8,13 +9,13 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.util.Xml;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.data.LatLon;
@ -61,11 +62,6 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
private Bitmap resolvedNoteSmall;
private final MapActivity activity;
protected static final String KEY_BUG = "bug";
protected static final String KEY_TEXT = "text";
protected static final String KEY_ACTION = "action";
private static final int DIALOG_BUG = 305;
private static Bundle dialogBundle = new Bundle();
private OsmBugsLocalUtil local;
private MapLayerData<List<OpenStreetNote>> data;
@ -400,6 +396,7 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
OsmBugsUtil util = getOsmbugsUtil(bug);
final boolean offline = util instanceof OsmBugsLocalUtil;
@SuppressLint("InflateParams")
final View view = LayoutInflater.from(activity).inflate(R.layout.open_bug, null);
if (offline) {
view.findViewById(R.id.user_name_field).setVisibility(View.GONE);

View file

@ -5,9 +5,15 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.widget.Toast;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.data.RotatedTileBox;
import net.osmand.osm.edit.Node;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.views.ContextMenuLayer;
@ -17,25 +23,25 @@ import net.osmand.plus.views.OsmandMapTileView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Denis on
* 20.03.2015.
*/
public class OsmEditsLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider {
public class OsmEditsLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider,
ContextMenuLayer.IMoveObjectProvider {
private static final int startZoom = 10;
private final OsmEditingPlugin plugin;
private final MapActivity activity;
private final OpenstreetmapLocalUtil mOsmChangeUtil;
private final OsmBugsLocalUtil mOsmBugsUtil;
private Bitmap poi;
private Bitmap bug;
private OsmandMapTileView view;
private Paint paintIcon;
private ContextMenuLayer contextMenuLayer;
public OsmEditsLayer(MapActivity activity, OsmEditingPlugin plugin) {
this.activity = activity;
this.plugin = plugin;
mOsmChangeUtil = plugin.getPoiModificationLocalUtil();
mOsmBugsUtil = plugin.getOsmNotesLocalUtil();
}
@Override
@ -43,13 +49,19 @@ public class OsmEditsLayer extends OsmandMapLayer implements ContextMenuLayer.IC
this.view = view;
poi = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pin_poi);
bug = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pin_poi);
bug = poi;
paintIcon = new Paint();
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (contextMenuLayer.getMoveableObject() instanceof OsmPoint) {
OsmPoint objectInMotion = (OsmPoint) contextMenuLayer.getMoveableObject();
PointF pf = contextMenuLayer.getMoveableCenterPoint(tileBox);
drawPoint(canvas, objectInMotion, pf.x, pf.y);
}
}
@Override
@ -65,21 +77,27 @@ public class OsmEditsLayer extends OsmandMapLayer implements ContextMenuLayer.IC
private void drawPoints(Canvas canvas, RotatedTileBox tileBox, List<? extends OsmPoint> objects,
List<LatLon> fullObjectsLatLon) {
for (OsmPoint o : objects) {
float x = tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude());
float y = tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude());
Bitmap b;
if (o.getGroup() == OsmPoint.Group.POI) {
b = poi;
} else if (o.getGroup() == OsmPoint.Group.BUG) {
b = bug;
} else {
b = poi;
if (contextMenuLayer.getMoveableObject() != o) {
float x = tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude());
float y = tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude());
drawPoint(canvas, o, x, y);
fullObjectsLatLon.add(new LatLon(o.getLatitude(), o.getLongitude()));
}
canvas.drawBitmap(b, x - b.getWidth() / 2, y - b.getHeight() / 2, paintIcon);
fullObjectsLatLon.add(new LatLon(o.getLatitude(), o.getLongitude()));
}
}
private void drawPoint(Canvas canvas, OsmPoint o, float x, float y) {
Bitmap b;
if (o.getGroup() == OsmPoint.Group.POI) {
b = poi;
} else if (o.getGroup() == OsmPoint.Group.BUG) {
b = bug;
} else {
b = poi;
}
canvas.drawBitmap(b, x - b.getWidth() / 2, y - b.getHeight() / 2, paintIcon);
}
@Override
public void destroyLayer() {
@ -97,11 +115,11 @@ public class OsmEditsLayer extends OsmandMapLayer implements ContextMenuLayer.IC
int compare = getRadiusPoi(tileBox);
int radius = compare * 3 / 2;
compare = getFromPoint(tileBox, am, ex, ey, compare, radius, plugin.getDBBug().getOsmbugsPoints());
compare = getFromPoint(tileBox, am, ex, ey, compare, radius, plugin.getDBPOI().getOpenstreetmapPoints());
getFromPoint(tileBox, am, ex, ey, compare, radius, plugin.getDBPOI().getOpenstreetmapPoints());
}
private int getFromPoint(RotatedTileBox tileBox, List<? super OsmPoint> am, int ex, int ey, int compare,
int radius, List<? extends OsmPoint> pnts) {
int radius, List<? extends OsmPoint> pnts) {
for (OsmPoint n : pnts) {
int x = (int) tileBox.getPixXFromLatLon(n.getLatitude(), n.getLongitude());
int y = (int) tileBox.getPixYFromLatLon(n.getLatitude(), n.getLongitude());
@ -114,12 +132,12 @@ public class OsmEditsLayer extends OsmandMapLayer implements ContextMenuLayer.IC
}
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius ;
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius;
}
public int getRadiusPoi(RotatedTileBox tb){
int r = 0;
if(tb.getZoom() < startZoom){
public int getRadiusPoi(RotatedTileBox tb) {
int r;
if (tb.getZoom() < startZoom) {
r = 0;
} else {
r = 15;
@ -152,7 +170,7 @@ public class OsmEditsLayer extends OsmandMapLayer implements ContextMenuLayer.IC
@Override
public LatLon getObjectLocation(Object o) {
if (o instanceof OsmPoint) {
return new LatLon(((OsmPoint)o).getLatitude(),((OsmPoint)o).getLongitude());
return new LatLon(((OsmPoint) o).getLatitude(), ((OsmPoint) o).getLongitude());
}
return null;
}
@ -160,11 +178,11 @@ public class OsmEditsLayer extends OsmandMapLayer implements ContextMenuLayer.IC
@Override
public PointDescription getObjectName(Object o) {
if(o instanceof OsmPoint) {
OsmPoint point = (OsmPoint) o;
if (o instanceof OsmPoint) {
OsmPoint point = (OsmPoint) o;
String name = "";
String type = "";
if (point.getGroup() == OsmPoint.Group.POI){
if (point.getGroup() == OsmPoint.Group.POI) {
name = ((OpenstreetmapPoint) point).getName();
type = PointDescription.POINT_TYPE_OSM_NOTE;
} else if (point.getGroup() == OsmPoint.Group.BUG) {
@ -176,4 +194,100 @@ public class OsmEditsLayer extends OsmandMapLayer implements ContextMenuLayer.IC
return null;
}
@Override
public boolean isObjectMovable(Object o) {
return o instanceof OsmPoint;
}
@Override
public void applyNewObjectPosition(@NonNull Object o, @NonNull LatLon position, @Nullable ContextMenuLayer.ApplyMovedObjectCallback callback) {
if (o instanceof OsmPoint) {
if (o instanceof OpenstreetmapPoint) {
OpenstreetmapPoint objectInMotion = (OpenstreetmapPoint) o;
Node node = objectInMotion.getEntity();
node.setLatitude(position.getLatitude());
node.setLongitude(position.getLongitude());
new SaveOsmChangeAsyncTask(mOsmChangeUtil, callback).execute(node);
} else if (o instanceof OsmNotesPoint) {
OsmNotesPoint objectInMotion = (OsmNotesPoint) o;
objectInMotion.setLatitude(position.getLatitude());
objectInMotion.setLongitude(position.getLongitude());
new SaveOsmNoteAsyncTask(objectInMotion.getText(), activity, callback, plugin, mOsmBugsUtil)
.execute(objectInMotion);
}
} else if (callback != null) {
callback.onApplyMovedObject(false, o);
}
}
static class SaveOsmChangeAsyncTask extends AsyncTask<Node, Void, Node> {
private final OpenstreetmapLocalUtil mOpenstreetmapUtil;
@Nullable
private final ContextMenuLayer.ApplyMovedObjectCallback mCallback;
SaveOsmChangeAsyncTask(OpenstreetmapLocalUtil openstreetmapUtil,
@Nullable ContextMenuLayer.ApplyMovedObjectCallback callback) {
this.mOpenstreetmapUtil = openstreetmapUtil;
this.mCallback = callback;
}
@Override
protected Node doInBackground(Node... params) {
Node node = params[0];
return mOpenstreetmapUtil.commitNodeImpl(OsmPoint.Action.MODIFY, node,
mOpenstreetmapUtil.getEntityInfo(node.getId()), "", false);
}
@Override
protected void onPostExecute(Node newNode) {
if (mCallback != null) {
mCallback.onApplyMovedObject(true, newNode);
}
}
}
private static class SaveOsmNoteAsyncTask extends AsyncTask<OsmNotesPoint, Void, Boolean> {
private final String mText;
private final MapActivity mActivity;
@Nullable
private final ContextMenuLayer.ApplyMovedObjectCallback mCallback;
private final OsmEditingPlugin plugin;
private OsmBugsUtil mOsmbugsUtil;
private OsmNotesPoint mOsmNotesPoint;
public SaveOsmNoteAsyncTask(String text,
MapActivity activity,
@Nullable ContextMenuLayer.ApplyMovedObjectCallback callback,
OsmEditingPlugin plugin, OsmBugsUtil osmbugsUtil) {
mText = text;
mActivity = activity;
mCallback = callback;
this.plugin = plugin;
mOsmbugsUtil = osmbugsUtil;
}
@Override
protected Boolean doInBackground(OsmNotesPoint... params) {
mOsmNotesPoint = params[0];
OsmPoint.Action action = mOsmNotesPoint.getAction();
boolean isSuccess = plugin.getDBBug().deleteAllBugModifications(mOsmNotesPoint);
OsmBugsUtil.OsmBugResult result = mOsmbugsUtil.commit(mOsmNotesPoint, mText, action);
isSuccess &= isOperationSuccessfull(result);
return isSuccess;
}
private boolean isOperationSuccessfull(OsmBugsUtil.OsmBugResult result) {
return result != null && result.warning == null;
}
@Override
protected void onPostExecute(Boolean isSuccess) {
if (isSuccess) {
Toast.makeText(mActivity, R.string.osm_changes_added_to_local_edits, Toast.LENGTH_LONG).show();
}
if (mCallback != null) {
mCallback.onApplyMovedObject(isSuccess, mOsmNotesPoint);
}
}
}
}

View file

@ -1,6 +1,15 @@
package net.osmand.plus.parkingpoint;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
@ -10,14 +19,8 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.views.ContextMenuLayer;
import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapTileView;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import java.util.List;
/**
* Class represents a layer which depicts the position of the parked car
@ -25,7 +28,8 @@ import android.view.WindowManager;
* @see ParkingPositionPlugin
*
*/
public class ParkingPositionLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider {
public class ParkingPositionLayer extends OsmandMapLayer implements
ContextMenuLayer.IContextMenuProvider, ContextMenuLayer.IMoveObjectProvider {
/**
* magic number so far
*/
@ -45,6 +49,8 @@ public class ParkingPositionLayer extends OsmandMapLayer implements ContextMenuL
private ParkingPositionPlugin plugin;
private ContextMenuLayer contextMenuLayer;
public ParkingPositionLayer(MapActivity map, ParkingPositionPlugin plugin) {
this.map = map;
this.plugin = plugin;
@ -68,11 +74,14 @@ public class ParkingPositionLayer extends OsmandMapLayer implements ContextMenuL
parkingNoLimitIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_poi_parking_pos_no_limit);
parkingLimitIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_poi_parking_pos_limit);
timeLimit = plugin.getParkingType();
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings nightMode) {
LatLon parkingPoint = getParkingPoint();
boolean inMotion = parkingPoint == contextMenuLayer.getMoveableObject();
if (parkingPoint == null)
return;
@ -84,11 +93,19 @@ public class ParkingPositionLayer extends OsmandMapLayer implements ContextMenuL
}
double latitude = parkingPoint.getLatitude();
double longitude = parkingPoint.getLongitude();
if (isLocationVisible(tb, latitude, longitude)) {
if (isLocationVisible(tileBox, latitude, longitude) || inMotion) {
int marginX = parkingNoLimitIcon.getWidth() / 2;
int marginY = parkingNoLimitIcon.getHeight() / 2;
int locationX = tb.getPixXFromLonNoRot(longitude);
int locationY = tb.getPixYFromLatNoRot(latitude);
float locationX;
float locationY;
if (inMotion) {
PointF pf = contextMenuLayer.getMoveableCenterPoint(tileBox);
locationX = pf.x;
locationY = pf.y;
} else {
locationX = tileBox.getPixXFromLonNoRot(longitude);
locationY = tileBox.getPixYFromLatNoRot(latitude);
}
canvas.rotate(-view.getRotate(), locationX, locationY);
canvas.drawBitmap(parkingIcon, locationX - marginX, locationY - marginY, bitmapPaint);
}
@ -183,5 +200,22 @@ public class ParkingPositionLayer extends OsmandMapLayer implements ContextMenuL
}
}
@Override
public boolean isObjectMovable(Object o) {
return o == getParkingPoint();
}
@Override
public void applyNewObjectPosition(@NonNull Object o, @NonNull LatLon position,
@Nullable ContextMenuLayer.ApplyMovedObjectCallback callback) {
boolean result = false;
if (o == getParkingPoint()) {
plugin.setParkingPosition(position.getLatitude(), position.getLongitude());
result = true;
}
if (callback != null) {
callback.onApplyMovedObject(result, getParkingPoint());
}
}
}

View file

@ -10,6 +10,7 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresPermission;
import android.support.v4.content.ContextCompat;
import android.view.GestureDetector;
@ -58,6 +59,8 @@ public class ContextMenuLayer extends OsmandMapLayer {
private final MoveMarkerBottomSheetHelper mMoveMarkerBottomSheetHelper;
private boolean mInChangeMarkerPositionMode;
private IContextMenuProvider selectedObjectContextMenuProvider;
private boolean cancelApplyingNewMarkerPosition;
private LatLon applyingMarkerLatLon;
public ContextMenuLayer(MapActivity activity) {
this.activity = activity;
@ -133,14 +136,25 @@ public class ContextMenuLayer extends OsmandMapLayer {
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked) {
if (itemId == R.string.shared_string_show_description) {
menu.openMenuFullScreen();
} else if (itemId == R.string.change_markers_position) {
RotatedTileBox tileBox = activity.getMapView().getCurrentRotatedTileBox();
enterMovingMode(tileBox);
}
return true;
}
};
adapter.addItem(new ContextMenuItem.ItemBuilder()
.setTitleId(R.string.shared_string_show_description, activity)
.setIcon(R.drawable.ic_action_note_dark).setListener(listener)
.setIcon(R.drawable.ic_action_note_dark)
.setListener(listener)
.createItem());
if (isObjectMoveable(o)) {
adapter.addItem(new ContextMenuItem.ItemBuilder()
.setTitleId(R.string.change_markers_position, activity)
.setIcon(R.drawable.ic_show_on_map)
.setListener(listener)
.createItem());
}
}
}
@ -153,22 +167,7 @@ public class ContextMenuLayer extends OsmandMapLayer {
if (pressedContextMarker(tileBox, point.x, point.y)) {
Object obj = menu.getObject();
if (isObjectMoveable(obj)) {
Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_SHORT);
menu.updateMapCenter(null);
menu.hide();
LatLon ll = menu.getLatLon();
RotatedTileBox rb = new RotatedTileBox(tileBox);
rb.setCenterLocation(0.5f, 0.5f);
rb.setLatLonCenter(ll.getLatitude(), ll.getLongitude());
double lat = rb.getLatFromPixel(tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
double lon = rb.getLonFromPixel(tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
view.setLatLon(lat, lon);
enterMovingMode();
view.refreshMap();
enterMovingMode(tileBox);
return true;
}
return false;
@ -181,7 +180,13 @@ public class ContextMenuLayer extends OsmandMapLayer {
public PointF getMoveableCenterPoint(RotatedTileBox tb) {
return new PointF(tb.getPixWidth() / 2, tb.getPixHeight() / 2);
if (applyingMarkerLatLon != null) {
float x = tb.getPixXFromLatLon(applyingMarkerLatLon.getLatitude(), applyingMarkerLatLon.getLongitude());
float y = tb.getPixYFromLatLon(applyingMarkerLatLon.getLatitude(), applyingMarkerLatLon.getLongitude());
return new PointF(x, y);
} else {
return new PointF(tb.getPixWidth() / 2, tb.getPixHeight() / 2);
}
}
public Object getMoveableObject() {
@ -198,20 +203,23 @@ public class ContextMenuLayer extends OsmandMapLayer {
} else if (selectedObjectContextMenuProvider != null
&& selectedObjectContextMenuProvider instanceof ContextMenuLayer.IMoveObjectProvider) {
final IMoveObjectProvider l = (ContextMenuLayer.IMoveObjectProvider) selectedObjectContextMenuProvider;
if (l.isObjectMoveable(o)) {
if (l.isObjectMovable(o)) {
return true;
}
}
return false;
}
public void applyMovedObject(Object o, LatLon position) {
if (selectedObjectContextMenuProvider != null
&& selectedObjectContextMenuProvider instanceof ContextMenuLayer.IMoveObjectProvider) {
final IMoveObjectProvider l = (ContextMenuLayer.IMoveObjectProvider) selectedObjectContextMenuProvider;
if (l.isObjectMoveable(o)) {
l.applyNewObjectPosition(o, position);
public void applyMovedObject(Object o, LatLon position, ApplyMovedObjectCallback callback) {
if (selectedObjectContextMenuProvider != null) {
if (selectedObjectContextMenuProvider instanceof IMoveObjectProvider) {
final IMoveObjectProvider l = (IMoveObjectProvider) selectedObjectContextMenuProvider;
if (l.isObjectMovable(o)) {
l.applyNewObjectPosition(o, position, callback);
}
}
} else if (mInChangeMarkerPositionMode) {
callback.onApplyMovedObject(true, null);
}
}
@ -222,18 +230,35 @@ public class ContextMenuLayer extends OsmandMapLayer {
RotatedTileBox tileBox = activity.getMapView().getCurrentRotatedTileBox();
PointF newMarkerPosition = getMoveableCenterPoint(tileBox);
LatLon ll = tileBox.getLatLonFromPixel(newMarkerPosition.x, newMarkerPosition.y);
final LatLon ll = tileBox.getLatLonFromPixel(newMarkerPosition.x, newMarkerPosition.y);
applyingMarkerLatLon = ll;
Object obj = getMoveableObject();
applyMovedObject(obj, ll);
quitMovingMarker();
cancelApplyingNewMarkerPosition = false;
mMoveMarkerBottomSheetHelper.enterApplyPositionMode();
applyMovedObject(obj, ll, new ApplyMovedObjectCallback() {
@Override
public void onApplyMovedObject(boolean success, @Nullable Object newObject) {
mMoveMarkerBottomSheetHelper.exitApplyPositionMode();
if (success && !cancelApplyingNewMarkerPosition) {
mMoveMarkerBottomSheetHelper.hide();
quitMovingMarker();
PointDescription pointDescription = null;
if (selectedObjectContextMenuProvider != null) {
pointDescription = selectedObjectContextMenuProvider.getObjectName(obj);
}
menu.show(ll, pointDescription, obj);
view.refreshMap();
PointDescription pointDescription = null;
if (selectedObjectContextMenuProvider != null) {
pointDescription = selectedObjectContextMenuProvider.getObjectName(newObject);
}
menu.show(ll, pointDescription, newObject);
view.refreshMap();
}
applyingMarkerLatLon = null;
}
@Override
public boolean isCancelled() {
return cancelApplyingNewMarkerPosition;
}
});
}
private void quitMovingMarker() {
@ -242,11 +267,27 @@ public class ContextMenuLayer extends OsmandMapLayer {
R.id.map_left_widgets_panel, R.id.map_right_widgets_panel, R.id.map_center_info);
}
private void enterMovingMode() {
private void enterMovingMode(RotatedTileBox tileBox) {
Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_SHORT);
menu.updateMapCenter(null);
menu.hide();
LatLon ll = menu.getLatLon();
RotatedTileBox rb = new RotatedTileBox(tileBox);
rb.setCenterLocation(0.5f, 0.5f);
rb.setLatLonCenter(ll.getLatitude(), ll.getLongitude());
double lat = rb.getLatFromPixel(tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
double lon = rb.getLonFromPixel(tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
view.setLatLon(lat, lon);
mInChangeMarkerPositionMode = true;
mMoveMarkerBottomSheetHelper.show(menu.getLeftIcon());
mark(View.INVISIBLE, R.id.map_ruler_layout,
R.id.map_left_widgets_panel, R.id.map_right_widgets_panel, R.id.map_center_info);
view.refreshMap();
}
private void mark(int status, int... widgets) {
@ -259,8 +300,10 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
public void cancelMovingMarker() {
cancelApplyingNewMarkerPosition = true;
quitMovingMarker();
activity.getContextMenu().show();
applyingMarkerLatLon = null;
}
public boolean showContextMenu(double latitude, double longitude, boolean showUnknownLocation) {
@ -492,12 +535,19 @@ public class ContextMenuLayer extends OsmandMapLayer {
public interface IMoveObjectProvider {
boolean isObjectMoveable(Object o);
boolean applyNewObjectPosition(Object o, LatLon position);
boolean isObjectMovable(Object o);
void applyNewObjectPosition(@NonNull Object o,
@NonNull LatLon position,
@Nullable ApplyMovedObjectCallback callback);
}
public interface ApplyMovedObjectCallback {
void onApplyMovedObject(boolean success, @Nullable Object newObject);
boolean isCancelled();
}
public interface IContextMenuProviderSelection {

View file

@ -9,6 +9,8 @@ import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import net.osmand.data.FavouritePoint;
@ -21,12 +23,13 @@ import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.base.FavoriteImageDrawable;
import net.osmand.plus.views.ContextMenuLayer.ApplyMovedObjectCallback;
import net.osmand.plus.views.MapTextLayer.MapTextProvider;
import java.util.ArrayList;
import java.util.List;
public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider,
public class FavouritesLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider,
ContextMenuLayer.IMoveObjectProvider, MapTextProvider<FavouritePoint> {
protected int startZoom = 6;
@ -36,14 +39,13 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.
private FavouritesDbHelper favorites;
protected List<FavouritePoint> cache = new ArrayList<>();
private MapTextLayer textLayer;
private ContextMenuLayer contextMenuLayer;
private Paint paintIcon;
private Bitmap pointSmall;
private int defaultColor;
private OsmandSettings settings;
private ContextMenuLayer contextMenuLayer;
protected String getObjName() {
return view.getContext().getString(R.string.favorite);
@ -63,10 +65,10 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.
settings = view.getApplication().getSettings();
favorites = view.getApplication().getFavorites();
textLayer = view.getLayerByClass(MapTextLayer.class);
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
paintIcon = new Paint();
pointSmall = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_white_shield_small);
defaultColor = ContextCompat.getColor(view.getContext(), R.color.color_favorite);
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
}
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
@ -90,8 +92,9 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.
@Override
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (contextMenuLayer.getMoveableObject() instanceof FavouritePoint) {
FavouritePoint fp = (FavouritePoint) contextMenuLayer.getMoveableObject();
FavoriteImageDrawable fid = FavoriteImageDrawable.getOrCreate(view.getContext(), fp.getColor(), true);
FavouritePoint objectInMotion = (FavouritePoint) contextMenuLayer.getMoveableObject();
FavoriteImageDrawable fid = FavoriteImageDrawable.getOrCreate(view.getContext(),
objectInMotion.getColor(), true);
PointF pf = contextMenuLayer.getMoveableCenterPoint(tileBox);
fid.drawBitmapInCenter(canvas, pf.x, pf.y);
}
@ -238,17 +241,22 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.
@Override
public boolean isObjectMoveable(Object o) {
public boolean isObjectMovable(Object o) {
return o instanceof FavouritePoint;
}
@Override
public boolean applyNewObjectPosition(Object o, LatLon position) {
if(o instanceof FavouritePoint) {
favorites.editFavourite((FavouritePoint) o, position.getLatitude(), position.getLongitude());
return true;
public void applyNewObjectPosition(@NonNull Object o,
@NonNull LatLon position,
@Nullable ApplyMovedObjectCallback callback) {
boolean result = false;
if (o instanceof FavouritePoint) {
favorites.editFavourite((FavouritePoint) o, position.getLatitude(), position.getLongitude());
result = true;
}
if (callback != null) {
callback.onApplyMovedObject(result, o);
}
return false;
}
}

View file

@ -12,11 +12,18 @@ import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffColorFilter;
import android.os.AsyncTask;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect;
import net.osmand.data.QuadTree;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.GPXUtilities;
import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.TrkSegment;
import net.osmand.plus.GPXUtilities.WptPt;
@ -24,6 +31,7 @@ import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings.CommonPreference;
import net.osmand.plus.R;
import net.osmand.plus.base.FavoriteImageDrawable;
@ -34,15 +42,18 @@ import net.osmand.render.RenderingRuleProperty;
import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider,
ContextMenuLayer.IMoveObjectProvider, MapTextProvider<WptPt> {
public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider,
MapTextProvider<WptPt> {
private OsmandMapTileView view;
private Paint paint;
private Paint paint2;
private boolean isPaint2;
@ -57,10 +68,11 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
private static final int startZoom = 7;
private GpxSelectionHelper selectedGpxHelper;
private Paint paintBmp;
private List<WptPt> cache = new ArrayList<WptPt>();
private List<WptPt> cache = new ArrayList<>();
private Map<WptPt, SelectedGpxFile> pointFileMap = new HashMap<>();
private MapTextLayer textLayer;
@ -75,7 +87,20 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
private List<TrkSegment> points;
private GPXFile gpx;
private ContextMenuLayer contextMenuLayer;
@ColorInt
private int visitedColor;
@ColorInt
private int defPointColor;
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
selectedGpxHelper = view.getApplication().getSelectedGpxHelper();
osmandRenderer = view.getApplication().getResourceManager().getRenderer().getRenderer();
initUI();
}
private void initUI() {
paint = new Paint();
paint.setStyle(Style.STROKE);
@ -89,21 +114,19 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
paint_1 = new Paint();
paint_1.setStyle(Style.STROKE);
paint_1.setAntiAlias(true);
paintBmp = new Paint();
paintBmp.setAntiAlias(true);
paintBmp.setFilterBitmap(true);
paintBmp.setDither(true);
paintTextIcon = new Paint();
paintTextIcon.setTextSize(10 * view.getDensity());
paintTextIcon.setTextAlign(Align.CENTER);
paintTextIcon.setFakeBoldText(true);
paintTextIcon.setColor(Color.BLACK);
paintTextIcon.setAntiAlias(true);
textLayer = view.getLayerByClass(MapTextLayer.class);
paintOuter = new Paint();
@ -117,43 +140,71 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
paintIcon = new Paint();
pointSmall = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_white_shield_small);
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
visitedColor = ContextCompat.getColor(view.getApplication(), R.color.color_ok);
defPointColor = ContextCompat.getColor(view.getApplication(), R.color.gpx_color_point);
}
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
selectedGpxHelper = view.getApplication().getSelectedGpxHelper();
osmandRenderer = view.getApplication().getResourceManager().getRenderer().getRenderer();
initUI();
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (contextMenuLayer.getMoveableObject() instanceof WptPt) {
WptPt objectInMotion = (WptPt) contextMenuLayer.getMoveableObject();
PointF pf = contextMenuLayer.getMoveableCenterPoint(tileBox);
SelectedGpxFile gpxFile = pointFileMap.get(objectInMotion);
if (gpxFile != null) {
drawBigPoint(canvas, objectInMotion, getFileColor(gpxFile), pf.x, pf.y);
}
}
}
@Override
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (points != null) {
updatePaints(0, false, false, settings, tileBox);
for (TrkSegment ts : points)
ts.drawRenderers(view.getZoom(), paint, canvas, tileBox);
} else {
List<SelectedGpxFile> selectedGPXFiles = selectedGpxHelper.getSelectedGPXFiles();
cache.clear();
if (!selectedGPXFiles.isEmpty()) {
drawSelectedFilesSegments(canvas, tileBox, selectedGPXFiles, settings);
canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
drawSelectedFilesSplits(canvas, tileBox, selectedGPXFiles, settings);
drawSelectedFilesPoints(canvas, tileBox, selectedGPXFiles);
}
if (textLayer != null && textLayer.isVisible()) {
textLayer.putData(this, cache);
}
}
}
public void updateLayerStyle() {
cachedHash = -1;
}
private int updatePaints(int color, boolean routePoints, boolean currentTrack, DrawSettings nightMode, RotatedTileBox tileBox){
private int updatePaints(int color, boolean routePoints, boolean currentTrack, DrawSettings nightMode, RotatedTileBox tileBox) {
RenderingRulesStorage rrs = view.getApplication().getRendererRegistry().getCurrentSelectedRenderer();
final boolean isNight = nightMode != null && nightMode.isNightMode();
int hsh = calculateHash(rrs, routePoints, isNight, tileBox.getMapDensity(), tileBox.getZoom());
if (hsh != cachedHash) {
cachedHash = hsh;
cachedColor = view.getResources().getColor(R.color.gpx_track);
cachedColor = ContextCompat.getColor(view.getApplication(), R.color.gpx_track);
if (rrs != null) {
RenderingRuleSearchRequest req = new RenderingRuleSearchRequest(rrs);
req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, isNight);
CommonPreference<String> p = view.getSettings().getCustomRenderProperty("currentTrackColor");
if(p != null && p.isSet()) {
if (p != null && p.isSet()) {
RenderingRuleProperty ctColor = rrs.PROPS.get("currentTrackColor");
if(ctColor != null) {
if (ctColor != null) {
req.setStringFilter(ctColor, p.get());
}
}
CommonPreference<String> p2 = view.getSettings().getCustomRenderProperty("currentTrackWidth");
if(p2 != null && p2.isSet()) {
if (p2 != null && p2.isSet()) {
RenderingRuleProperty ctWidth = rrs.PROPS.get("currentTrackWidth");
if(ctWidth != null) {
if (ctWidth != null) {
req.setStringFilter(ctWidth, p2.get());
}
}
@ -193,35 +244,13 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
paint.setColor(color == 0 ? cachedColor : color);
return cachedColor;
}
private int calculateHash(Object... o) {
return Arrays.hashCode(o);
}
@Override
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if(points != null) {
updatePaints(0, false, false, settings, tileBox);
for (TrkSegment ts : points)
ts.drawRenderers(view.getZoom(), paint, canvas, tileBox);
} else {
List<SelectedGpxFile> selectedGPXFiles = selectedGpxHelper.getSelectedGPXFiles();
cache.clear();
if (!selectedGPXFiles.isEmpty()) {
drawSelectedFilesSegments(canvas, tileBox, selectedGPXFiles, settings);
canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
drawSelectedFilesSplits(canvas, tileBox, selectedGPXFiles, settings);
drawSelectedFilesPoints(canvas, tileBox, selectedGPXFiles);
}
if (textLayer != null && textLayer.isVisible()) {
textLayer.putData(this, cache);
}
}
}
private void drawSelectedFilesSplits(Canvas canvas, RotatedTileBox tileBox, List<SelectedGpxFile> selectedGPXFiles,
DrawSettings settings) {
private void drawSelectedFilesSplits(Canvas canvas, RotatedTileBox tileBox, List<SelectedGpxFile> selectedGPXFiles,
DrawSettings settings) {
if (tileBox.getZoom() >= startZoom) {
// request to load
for (SelectedGpxFile g : selectedGPXFiles) {
@ -239,10 +268,10 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
private void drawSplitItems(Canvas canvas, RotatedTileBox tileBox, List<GpxDisplayItem> items, DrawSettings settings) {
final QuadRect latLonBounds = tileBox.getLatLonBounds();
int r = (int) (12 * tileBox.getDensity());
int dr = r * 3 / 2;
int dr = r * 3 / 2;
int px = -1;
int py = -1;
for(int k = 0; k < items.size(); k++) {
for (int k = 0; k < items.size(); k++) {
GpxDisplayItem i = items.get(k);
WptPt o = i.locationEnd;
if (o != null && o.lat >= latLonBounds.bottom && o.lat <= latLonBounds.top && o.lon >= latLonBounds.left
@ -272,8 +301,6 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
}
private void drawSelectedFilesPoints(Canvas canvas, RotatedTileBox tileBox, List<SelectedGpxFile> selectedGPXFiles) {
int defPointColor = view.getResources().getColor(R.color.gpx_color_point);
int visitedColor = view.getContext().getResources().getColor(R.color.color_ok);
if (tileBox.getZoom() >= startZoom) {
float iconSize = FavoriteImageDrawable.getOrCreate(view.getContext(), 0,
true).getIntrinsicWidth() * 3 / 2.5f;
@ -286,18 +313,20 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
for (SelectedGpxFile g : selectedGPXFiles) {
List<WptPt> pts = getListStarPoints(g);
List<WptPt> fullObjects = new ArrayList<>();
int fcolor = g.getColor() == 0 ? defPointColor : g.getColor();
@ColorInt
int fileColor = getFileColor(g);
for (WptPt o : pts) {
if (o.lat >= latLonBounds.bottom && o.lat <= latLonBounds.top
&& o.lon >= latLonBounds.left && o.lon <= latLonBounds.right) {
&& o.lon >= latLonBounds.left && o.lon <= latLonBounds.right
&& o != contextMenuLayer.getMoveableObject()) {
cache.add(o);
float x = tileBox.getPixXFromLatLon(o.lat, o.lon);
float y = tileBox.getPixYFromLatLon(o.lat, o.lon);
if (intersects(boundIntersections, x, y, iconSize, iconSize)) {
boolean visit = isPointVisited(o);
int col = visit ? visitedColor : o.getColor(fcolor);
paintIcon.setColorFilter(new PorterDuffColorFilter(col, PorterDuff.Mode.MULTIPLY));
@ColorInt
int pointColor = getPointColor(o, fileColor);
paintIcon.setColorFilter(new PorterDuffColorFilter(pointColor, PorterDuff.Mode.MULTIPLY));
canvas.drawBitmap(pointSmall, x - pointSmall.getWidth() / 2, y - pointSmall.getHeight() / 2, paintIcon);
smallObjectsLatLon.add(new LatLon(o.lat, o.lon));
} else {
@ -305,14 +334,12 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
fullObjectsLatLon.add(new LatLon(o.lat, o.lon));
}
}
pointFileMap.put(o, g);
}
for (WptPt o : fullObjects) {
float x = tileBox.getPixXFromLatLon(o.lat, o.lon);
float y = tileBox.getPixYFromLatLon(o.lat, o.lon);
boolean visit = isPointVisited(o);
int pointColor = visit ? visitedColor : o.getColor(fcolor);
FavoriteImageDrawable fid = FavoriteImageDrawable.getOrCreate(view.getContext(), pointColor, true);
fid.drawBitmapInCenter(canvas, x, y);
drawBigPoint(canvas, o, fileColor, x, y);
}
}
this.fullObjectsLatLon = fullObjectsLatLon;
@ -320,15 +347,31 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
}
}
private int getFileColor(@NonNull SelectedGpxFile g) {
return g.getColor() == 0 ? defPointColor : g.getColor();
}
private void drawBigPoint(Canvas canvas, WptPt o, int fileColor, float x, float y) {
int pointColor = getPointColor(o, fileColor);
FavoriteImageDrawable fid = FavoriteImageDrawable.getOrCreate(view.getContext(), pointColor, true);
fid.drawBitmapInCenter(canvas, x, y);
}
@ColorInt
private int getPointColor(WptPt o, @ColorInt int fileColor) {
boolean visit = isPointVisited(o);
return visit ? visitedColor : o.getColor(fileColor);
}
private void drawSelectedFilesSegments(Canvas canvas, RotatedTileBox tileBox,
List<SelectedGpxFile> selectedGPXFiles, DrawSettings settings) {
List<SelectedGpxFile> selectedGPXFiles, DrawSettings settings) {
for (SelectedGpxFile g : selectedGPXFiles) {
List<TrkSegment> segments = g.getPointsToDisplay();
for (TrkSegment ts : segments) {
if (ts.renders.isEmpty() // only do once (CODE HERE NEEDS TO BE UI INSTEAD)
&& !ts.points.isEmpty()) { // hmmm. 0-point tracks happen, but.... how?
if (ts.renders.isEmpty() // only do once (CODE HERE NEEDS TO BE UI INSTEAD)
&& !ts.points.isEmpty()) { // hmmm. 0-point tracks happen, but.... how?
if (g.isShowCurrentTrack()) {
ts.renders.add(new Renderable.CurrentTrack(ts.points));
@ -343,32 +386,22 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
}
}
private boolean isPointVisited(WptPt o) {
boolean visit = false;
String visited = o.getExtensionsToRead().get("VISITED_KEY");
if(visited != null && !visited.equals("0")) {
if (visited != null && !visited.equals("0")) {
visit = true;
}
return visit;
}
private List<WptPt> getListStarPoints(SelectedGpxFile g) {
List<WptPt> pts = g.getGpxFile().points;
// don't display points here
// if(pts.isEmpty() & !g.getGpxFile().routes.isEmpty()) {
// pts = g.getGpxFile().routes.get(0).points;
// }
return pts;
return g.getGpxFile().points;
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
}
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
return (Math.abs(objx - ex) <= radius * 2 && Math.abs(objy - ey) <= radius * 2) ;
return (Math.abs(objx - ex) <= radius * 2 && Math.abs(objy - ey) <= radius * 2);
// return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius ;
}
@ -391,8 +424,8 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
@Override
public PointDescription getObjectName(Object o) {
if(o instanceof WptPt){
return new PointDescription(PointDescription.POINT_TYPE_WPT, ((WptPt)o).name); //$NON-NLS-1$
if (o instanceof WptPt) {
return new PointDescription(PointDescription.POINT_TYPE_WPT, ((WptPt) o).name); //$NON-NLS-1$
}
return null;
}
@ -421,17 +454,18 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
@Override
public LatLon getObjectLocation(Object o) {
if(o instanceof WptPt){
return new LatLon(((WptPt)o).lat, ((WptPt)o).lon);
if (o instanceof WptPt) {
return new LatLon(((WptPt) o).lat, ((WptPt) o).lon);
}
return null;
}
@Override
public void destroyLayer() {
}
@Override
public boolean drawInScreenPixels() {
return false;
@ -444,7 +478,7 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
@Override
public LatLon getTextLocation(WptPt o) {
return new LatLon(((WptPt)o).lat, ((WptPt)o).lon);
return new LatLon(o.lat, o.lon);
}
@Override
@ -460,8 +494,58 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
public void setGivenGpx(GPXFile gpx) {
this.gpx = gpx;
this.points = (gpx == null ? null : gpx.proccessPoints());
this.points = (gpx == null ? null : gpx.proccessPoints());
}
@Override
public boolean isObjectMovable(Object o) {
return o instanceof WptPt;
}
@Override
public void applyNewObjectPosition(@NonNull Object o,
@NonNull LatLon position,
@Nullable ContextMenuLayer.ApplyMovedObjectCallback callback) {
if (o instanceof WptPt) {
WptPt objectInMotion = (WptPt) o;
GPXFile gpxFile = pointFileMap.get(objectInMotion).getGpxFile();
gpxFile.updateWptPt(objectInMotion, position.getLatitude(),
position.getLongitude(), System.currentTimeMillis(), objectInMotion.desc,
objectInMotion.name, objectInMotion.category, objectInMotion.getColor());
new SaveGpxFileAsyncTask(view.getApplication(), callback, objectInMotion).execute(gpxFile);
} else if (callback != null) {
callback.onApplyMovedObject(false, o);
}
}
static class SaveGpxFileAsyncTask extends AsyncTask<GPXFile, Void, String> {
private final OsmandApplication app;
@Nullable
private final ContextMenuLayer.ApplyMovedObjectCallback callback;
@Nullable
private final WptPt point;
SaveGpxFileAsyncTask(OsmandApplication app,
@Nullable ContextMenuLayer.ApplyMovedObjectCallback callback,
@Nullable WptPt point) {
this.app = app;
this.callback = callback;
this.point = point;
}
@Override
protected String doInBackground(GPXFile... params) {
GPXFile gpxFile = params[0];
return GPXUtilities.writeGpxFile(new File(gpxFile.path), gpxFile, app);
}
@Override
protected void onPostExecute(String errorMessage) {
if (callback != null) {
callback.onApplyMovedObject(errorMessage == null, point);
}
}
}
}

View file

@ -5,7 +5,10 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.widget.ArrayAdapter;
import net.osmand.Location;
import net.osmand.binary.RouteDataObject;
import net.osmand.data.LatLon;
@ -13,14 +16,18 @@ import net.osmand.data.PointDescription;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidSpecificRoadsCallback;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.views.ContextMenuLayer.ApplyMovedObjectCallback;
import java.util.List;
import java.util.Map;
public class ImpassableRoadsLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider {
public class ImpassableRoadsLayer extends OsmandMapLayer implements
ContextMenuLayer.IContextMenuProvider, ContextMenuLayer.IMoveObjectProvider {
private static final int startZoom = 10;
private final MapActivity activity;
@ -31,6 +38,8 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements ContextMenuL
private List<RouteDataObject> missingRoads;
private RoutingHelper routingHelper;
private ContextMenuLayer contextMenuLayer;
public ImpassableRoadsLayer(MapActivity activity) {
this.activity = activity;
}
@ -41,17 +50,30 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements ContextMenuL
roadWorkIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pin_avoid_road);
paint = new Paint();
routingHelper = activity.getRoutingHelper();
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (contextMenuLayer.getMoveableObject() instanceof RouteDataObject) {
PointF pf = contextMenuLayer.getMoveableCenterPoint(tileBox);
float left = pf.x - roadWorkIcon.getWidth() / 2;
float top = pf.y - roadWorkIcon.getHeight();
canvas.drawBitmap(roadWorkIcon, left, top, paint);
}
}
@Override
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (tileBox.getZoom() >= startZoom) {
for (long id : getMissingRoadLocations().keySet()) {
if(contextMenuLayer.getMoveableObject() instanceof RouteDataObject) {
RouteDataObject object = (RouteDataObject) contextMenuLayer.getMoveableObject();
if (object.id == id) {
continue;
}
}
Location location = getMissingRoadLocations().get(id);
float x = tileBox.getPixXFromLatLon(location.getLatitude(), location.getLongitude());
float y = tileBox.getPixYFromLatLon(location.getLatitude(), location.getLongitude());
@ -87,7 +109,7 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements ContextMenuL
}
public int getRadiusPoi(RotatedTileBox tb) {
int r = 0;
int r;
if (tb.getZoom() < startZoom) {
r = 0;
} else {
@ -164,7 +186,7 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements ContextMenuL
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked) {
if (itemId == R.string.avoid_road) {
activity.getMyApplication().getAvoidSpecificRoads().addImpassableRoad(
activity, latLon, false);
activity, latLon, false, null);
}
return true;
}
@ -176,4 +198,32 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements ContextMenuL
.createItem());
}
}
@Override
public boolean isObjectMovable(Object o) {
return o instanceof RouteDataObject;
}
@Override
public void applyNewObjectPosition(@NonNull Object o,
@NonNull LatLon position,
@Nullable final ApplyMovedObjectCallback callback) {
if (o instanceof RouteDataObject) {
final RouteDataObject object = (RouteDataObject) o;
final OsmandApplication application = activity.getMyApplication();
application.getAvoidSpecificRoads().replaceImpassableRoad(activity, object, position, false, new AvoidSpecificRoadsCallback() {
@Override
public void onAddImpassableRoad(boolean success, RouteDataObject newObject) {
if (callback != null) {
callback.onApplyMovedObject(success, newObject);
}
}
@Override
public boolean isCancelled() {
return callback != null && callback.isCancelled();
}
});
}
}
}

View file

@ -10,8 +10,12 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
@ -24,6 +28,7 @@ import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.views.ContextMenuLayer.ApplyMovedObjectCallback;
import net.osmand.plus.views.ContextMenuLayer.IContextMenuProvider;
import net.osmand.plus.views.ContextMenuLayer.IContextMenuProviderSelection;
import net.osmand.plus.views.mapwidgets.MapMarkersWidgetsFactory;
@ -31,7 +36,8 @@ import net.osmand.plus.views.mapwidgets.MapMarkersWidgetsFactory;
import java.util.ArrayList;
import java.util.List;
public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvider, IContextMenuProviderSelection {
public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvider,
IContextMenuProviderSelection, ContextMenuLayer.IMoveObjectProvider {
protected static final int DIST_TO_SHOW = 80;
protected static final long USE_FINGER_LOCATION_DELAY = 1000;
private static final int MAP_REFRESH_MESSAGE = OsmAndConstants.UI_HANDLER_MAP_VIEW + 6;
@ -71,6 +77,8 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
private GestureDetector longTapDetector;
private Handler handler;
private ContextMenuLayer contextMenuLayer;
public MapMarkersLayer(MapActivity map) {
this.map = map;
}
@ -108,10 +116,12 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setColor(map.getResources().getColor(R.color.marker_red));
paint.setColor(ContextCompat.getColor(map, R.color.marker_red));
paint.setAlpha(200);
widgetsFactory = new MapMarkersWidgetsFactory(map);
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
}
private Paint createPaintDest(int colorId) {
@ -119,7 +129,7 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
paint.setDither(true);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
int color = map.getResources().getColor(colorId);
int color = ContextCompat.getColor(map, colorId);
paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
return paint;
}
@ -216,11 +226,11 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings nightMode) {
widgetsFactory.updateInfo(useFingerLocation ? fingerLocation : null, tb.getZoom());
widgetsFactory.updateInfo(useFingerLocation ? fingerLocation : null, tileBox.getZoom());
if (tb.getZoom() < 3 || !map.getMyApplication().getSettings().USE_MAP_MARKERS.get()) {
if (tileBox.getZoom() < 3 || !map.getMyApplication().getSettings().USE_MAP_MARKERS.get()) {
return;
}
@ -230,14 +240,14 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
boolean first = true;
Location myLocation = map.getMapViewTrackingUtilities().getMyLocation();
if (markersHelper.isStartFromMyLocation() && myLocation != null) {
int locationX = tb.getPixXFromLonNoRot(myLocation.getLongitude());
int locationY = tb.getPixYFromLatNoRot(myLocation.getLatitude());
int locationX = tileBox.getPixXFromLonNoRot(myLocation.getLongitude());
int locationY = tileBox.getPixYFromLatNoRot(myLocation.getLatitude());
path.moveTo(locationX, locationY);
first = false;
}
for (LatLon point : route) {
int locationX = tb.getPixXFromLonNoRot(point.getLongitude());
int locationY = tb.getPixYFromLatNoRot(point.getLatitude());
int locationX = tileBox.getPixXFromLonNoRot(point.getLongitude());
int locationY = tileBox.getPixYFromLatNoRot(point.getLatitude());
if (first) {
path.moveTo(locationX, locationY);
first = false;
@ -249,17 +259,17 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
}
List<MapMarker> activeMapMarkers = markersHelper.getActiveMapMarkers();
for (int i = 0; i < activeMapMarkers.size(); i++) {
MapMarker marker = activeMapMarkers.get(i);
if (isLocationVisible(tb, marker) && !overlappedByWaypoint(marker)) {
for (MapMarker marker : activeMapMarkers) {
if (isLocationVisible(tileBox, marker) && !overlappedByWaypoint(marker)
&& !isInMotion(marker)) {
Bitmap bmp = getMapMarkerBitmap(marker.colorIndex);
int marginX = bmp.getWidth() / 6;
int marginY = bmp.getHeight();
int locationX = tb.getPixXFromLonNoRot(marker.getLongitude());
int locationY = tb.getPixYFromLatNoRot(marker.getLatitude());
canvas.rotate(-tb.getRotate(), locationX, locationY);
int locationX = tileBox.getPixXFromLonNoRot(marker.getLongitude());
int locationY = tileBox.getPixYFromLatNoRot(marker.getLatitude());
canvas.rotate(-tileBox.getRotate(), locationX, locationY);
canvas.drawBitmap(bmp, locationX - marginX, locationY - marginY, bitmapPaint);
canvas.rotate(tb.getRotate(), locationX, locationY);
canvas.rotate(tileBox.getRotate(), locationX, locationY);
}
}
@ -269,21 +279,21 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
if (show) {
LatLon loc = fingerLocation;
if (!useFingerLocation) {
loc = tb.getCenterLatLon();
loc = tileBox.getCenterLatLon();
}
if (loc != null) {
List<MapMarker> sortedMapMarkers = markersHelper.getSortedMapMarkers();
int i = 0;
for (MapMarker marker : sortedMapMarkers) {
if (!isLocationVisible(tb, marker)) {
if (!isLocationVisible(tileBox, marker) && !isInMotion(marker)) {
canvas.save();
net.osmand.Location.distanceBetween(loc.getLatitude(), loc.getLongitude(),
marker.getLatitude(), marker.getLongitude(), calculations);
float bearing = calculations[1] - 90;
float radiusBearing = DIST_TO_SHOW * tb.getDensity();
final QuadPoint cp = tb.getCenterPixelPoint();
float radiusBearing = DIST_TO_SHOW * tileBox.getDensity();
final QuadPoint cp = tileBox.getCenterPixelPoint();
canvas.rotate(bearing, cp.x, cp.y);
canvas.translate(-24 * tb.getDensity() + radiusBearing, -22 * tb.getDensity());
canvas.translate(-24 * tileBox.getDensity() + radiusBearing, -22 * tileBox.getDensity());
canvas.drawBitmap(arrowToDestination, cp.x, cp.y, getMarkerDestPaint(marker.colorIndex));
canvas.restore();
}
@ -294,9 +304,26 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
}
}
}
if (contextMenuLayer.getMoveableObject() instanceof MapMarker) {
MapMarker objectInMotion = (MapMarker) contextMenuLayer.getMoveableObject();
Bitmap bitmap = getMapMarkerBitmap(objectInMotion.colorIndex);
PointF pf = contextMenuLayer.getMoveableCenterPoint(tileBox);
int marginX = bitmap.getWidth() / 6;
int marginY = bitmap.getHeight();
float locationX = pf.x;
float locationY = pf.y;
canvas.rotate(-tileBox.getRotate(), locationX, locationY);
canvas.drawBitmap(bitmap, locationX - marginX, locationY - marginY, bitmapPaint);
}
}
private boolean isInMotion(@NonNull MapMarker marker) {
return marker.equals(contextMenuLayer.getMoveableObject());
}
public boolean isLocationVisible(RotatedTileBox tb, MapMarker marker) {
//noinspection SimplifiableIfStatement
if (marker == null || tb == null) {
return false;
}
@ -482,4 +509,30 @@ public class MapMarkersLayer extends OsmandMapLayer implements IContextMenuProvi
public void clearSelectedObject() {
}
@Override
public boolean isObjectMovable(Object o) {
return o instanceof MapMarker;
}
@Override
public void applyNewObjectPosition(@NonNull Object o, @NonNull LatLon position,
@Nullable ApplyMovedObjectCallback callback) {
boolean result = false;
MapMarker newObject = null;
if (o instanceof MapMarker) {
MapMarkersHelper markersHelper = map.getMyApplication().getMapMarkersHelper();
MapMarker marker = (MapMarker) o;
marker.getOriginalPointDescription().setName(PointDescription.getSearchAddressStr(map));
markersHelper.moveMapMarker(marker, position);
int index = markersHelper.getActiveMapMarkers().indexOf(marker);
if (index != -1) {
newObject = markersHelper.getActiveMapMarkers().get(index);
}
result = true;
}
if (callback != null) {
callback.onApplyMovedObject(result, newObject == null ? o : newObject);
}
}
}

View file

@ -1,25 +1,26 @@
package net.osmand.plus.views;
import gnu.trove.set.hash.TIntHashSet;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import gnu.trove.set.hash.TIntHashSet;
public class MapTextLayer extends OsmandMapLayer {
private Map<OsmandMapLayer,
List<?>> textObjects = new LinkedHashMap<OsmandMapLayer, List<?>>();
private Map<OsmandMapLayer,
Collection<?>> textObjects = new LinkedHashMap<>();
public static final int TEXT_WRAP = 15;
public static final int TEXT_LINES = 3;
private Paint paintTextIcon;
@ -37,7 +38,7 @@ public class MapTextLayer extends OsmandMapLayer {
String getText(T o);
}
public void putData(OsmandMapLayer ml, List<?> objects) {
public void putData(OsmandMapLayer ml, Collection<?> objects) {
if(objects == null || objects.isEmpty()) {
textObjects.remove(ml);
} else {
@ -173,7 +174,7 @@ public class MapTextLayer extends OsmandMapLayer {
paintTextIcon.setTextSize(13 * v.getDensity());
paintTextIcon.setTextAlign(Align.CENTER);
paintTextIcon.setAntiAlias(true);
Map<OsmandMapLayer, List<?>> textObjectsLoc = new TreeMap<OsmandMapLayer, List<?>>(new Comparator<OsmandMapLayer>() {
Map<OsmandMapLayer, Collection<?>> textObjectsLoc = new TreeMap<OsmandMapLayer, Collection<?>>(new Comparator<OsmandMapLayer>() {
@Override
public int compare(OsmandMapLayer lhs, OsmandMapLayer rhs) {

View file

@ -1,10 +1,12 @@
package net.osmand.plus.views;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.IconsCache;
import net.osmand.plus.R;
@ -15,6 +17,7 @@ public class MoveMarkerBottomSheetHelper {
private final TextView mDescription;
private final Context mContext;
private final ContextMenuLayer mContextMenuLayer;
private boolean applyingPositionMode;
public MoveMarkerBottomSheetHelper(MapActivity activity, ContextMenuLayer contextMenuLayer) {
mContextMenuLayer = contextMenuLayer;
@ -28,7 +31,6 @@ public class MoveMarkerBottomSheetHelper {
mView.findViewById(R.id.apply_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
hide();
mContextMenuLayer.applyNewMarkerPosition();
}
});
@ -42,8 +44,9 @@ public class MoveMarkerBottomSheetHelper {
}
public void onDraw(RotatedTileBox rt) {
double lat = rt.getLatFromPixel(rt.getPixWidth() / 2, rt.getPixHeight() / 2);
double lon = rt.getLonFromPixel(rt.getPixWidth() / 2, rt.getPixHeight() / 2);
PointF point = mContextMenuLayer.getMoveableCenterPoint(rt);
double lat = rt.getLatFromPixel(point.x, point.y);
double lon = rt.getLonFromPixel(point.x, point.y);
mDescription.setText(mContext.getString(R.string.lat_lon_pattern, lat, lon));
}
@ -52,11 +55,27 @@ public class MoveMarkerBottomSheetHelper {
}
public void show(Drawable drawable) {
exitApplyPositionMode();
mView.setVisibility(View.VISIBLE);
((ImageView) mView.findViewById(R.id.icon)).setImageDrawable(drawable);
}
public void hide() {
exitApplyPositionMode();
mView.setVisibility(View.GONE);
}
public void enterApplyPositionMode() {
if (!applyingPositionMode) {
applyingPositionMode = true;
mView.findViewById(R.id.apply_button).setEnabled(false);
}
}
public void exitApplyPositionMode() {
if (applyingPositionMode) {
applyingPositionMode = false;
mView.findViewById(R.id.apply_button).setEnabled(true);
}
}
}

View file

@ -8,6 +8,10 @@ import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.data.QuadPoint;
@ -21,61 +25,60 @@ import net.osmand.plus.views.ContextMenuLayer.IContextMenuProvider;
import java.util.Iterator;
import java.util.List;
public class PointNavigationLayer extends OsmandMapLayer implements IContextMenuProvider {
public class PointNavigationLayer extends OsmandMapLayer implements
IContextMenuProvider, ContextMenuLayer.IMoveObjectProvider {
protected final static int DIST_TO_SHOW = 80;
private Paint point;
private Paint bitmapPaint;
private OsmandMapTileView view;
private float[] calculations = new float[2];
private Paint mPoint;
private Paint mBitmapPaint;
private Bitmap startPoint;
private Bitmap targetPoint;
private Bitmap intermediatePoint;
private Bitmap arrowToDestination;
private OsmandMapTileView mView;
private float[] mCalculations = new float[2];
private Paint textPaint;
private Bitmap mStartPoint;
private Bitmap mTargetPoint;
private Bitmap mIntermediatePoint;
private Bitmap mArrowToDestination;
private Paint mTextPaint;
private final MapActivity map;
private ContextMenuLayer contextMenuLayer;
public PointNavigationLayer(MapActivity map) {
this.map = map;
}
private void initUI() {
point = new Paint();
point.setColor(view.getResources().getColor(R.color.nav_point));
point.setAntiAlias(true);
point.setStyle(Style.FILL);
mPoint = new Paint();
mPoint.setColor(ContextCompat.getColor(map, R.color.nav_point));
mPoint.setAntiAlias(true);
mPoint.setStyle(Style.FILL);
bitmapPaint = new Paint();
bitmapPaint.setDither(true);
bitmapPaint.setAntiAlias(true);
bitmapPaint.setFilterBitmap(true);
textPaint = new Paint();
mBitmapPaint = new Paint();
mBitmapPaint.setDither(true);
mBitmapPaint.setAntiAlias(true);
mBitmapPaint.setFilterBitmap(true);
mTextPaint = new Paint();
float sp = Resources.getSystem().getDisplayMetrics().scaledDensity;
textPaint.setTextSize(sp * 18);
textPaint.setTextAlign(Align.CENTER);
textPaint.setAntiAlias(true);
startPoint = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_start_point);
targetPoint = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_target_point);
intermediatePoint = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_intermediate_point);
arrowToDestination = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_arrow_to_destination);
mTextPaint.setTextSize(sp * 18);
mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setAntiAlias(true);
mStartPoint = BitmapFactory.decodeResource(mView.getResources(), R.drawable.map_start_point);
mTargetPoint = BitmapFactory.decodeResource(mView.getResources(), R.drawable.map_target_point);
mIntermediatePoint = BitmapFactory.decodeResource(mView.getResources(), R.drawable.map_intermediate_point);
mArrowToDestination = BitmapFactory.decodeResource(mView.getResources(), R.drawable.map_arrow_to_destination);
}
@Override
public void initLayer(OsmandMapTileView view) {
this.view = view;
this.mView = view;
initUI();
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
}
@Override
public void onDraw(Canvas canvas, RotatedTileBox tb, DrawSettings nightMode) {
if (tb.getZoom() < 3) {
@ -86,75 +89,96 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu
TargetPoint pointToStart = targetPoints.getPointToStart();
if (pointToStart != null) {
if (isLocationVisible(tb, pointToStart)) {
int marginX = startPoint.getWidth() / 6;
int marginY = startPoint.getHeight();
int locationX = tb.getPixXFromLonNoRot(pointToStart.getLongitude());
int locationY = tb.getPixYFromLatNoRot(pointToStart.getLatitude());
int marginX = mStartPoint.getWidth() / 6;
int marginY = mStartPoint.getHeight();
float locationX = getPointX(tb, pointToStart);
float locationY = getPointY(tb, pointToStart);
canvas.rotate(-tb.getRotate(), locationX, locationY);
canvas.drawBitmap(startPoint, locationX - marginX, locationY - marginY, bitmapPaint);
canvas.drawBitmap(mStartPoint, locationX - marginX, locationY - marginY, mBitmapPaint);
}
}
int index = 0;
for (TargetPoint ip : targetPoints.getIntermediatePoints()) {
index ++;
index++;
if (isLocationVisible(tb, ip)) {
int marginX = intermediatePoint.getWidth() / 6;
int marginY = intermediatePoint.getHeight();
int locationX = tb.getPixXFromLonNoRot(ip.getLongitude());
int locationY = tb.getPixYFromLatNoRot(ip.getLatitude());
int marginX = mIntermediatePoint.getWidth() / 6;
int marginY = mIntermediatePoint.getHeight();
float locationX = getPointX(tb, ip);
float locationY = getPointY(tb, ip);
canvas.rotate(-tb.getRotate(), locationX, locationY);
canvas.drawBitmap(intermediatePoint, locationX - marginX, locationY - marginY, bitmapPaint);
marginX = intermediatePoint.getWidth() / 3;
canvas.drawText(index + "", locationX + marginX, locationY - 3 * marginY / 5, textPaint);
canvas.drawBitmap(mIntermediatePoint, locationX - marginX, locationY - marginY, mBitmapPaint);
marginX = mIntermediatePoint.getWidth() / 3;
canvas.drawText(index + "", locationX + marginX, locationY - 3 * marginY / 5, mTextPaint);
canvas.rotate(tb.getRotate(), locationX, locationY);
}
}
TargetPoint pointToNavigate = targetPoints.getPointToNavigate();
if (isLocationVisible(tb, pointToNavigate)) {
int marginX = targetPoint.getWidth() / 6;
int marginY = targetPoint.getHeight();
int locationX = tb.getPixXFromLonNoRot(pointToNavigate.getLongitude());
int locationY = tb.getPixYFromLatNoRot(pointToNavigate.getLatitude());
int marginX = mTargetPoint.getWidth() / 6;
int marginY = mTargetPoint.getHeight();
float locationX = getPointX(tb, pointToNavigate);
float locationY = getPointY(tb, pointToNavigate);
canvas.rotate(-tb.getRotate(), locationX, locationY);
canvas.drawBitmap(targetPoint, locationX - marginX, locationY - marginY, bitmapPaint);
}
canvas.drawBitmap(mTargetPoint, locationX - marginX, locationY - marginY, mBitmapPaint);
}
Iterator<TargetPoint> it = targetPoints.getIntermediatePoints().iterator();
if(it.hasNext()) {
if (it.hasNext()) {
pointToNavigate = it.next();
}
if (pointToNavigate != null && !isLocationVisible(tb, pointToNavigate)) {
boolean show = !view.getApplication().getRoutingHelper().isRouteCalculated();
if(view.getSettings().SHOW_DESTINATION_ARROW.isSet()) {
show = view.getSettings().SHOW_DESTINATION_ARROW.get();
boolean show = !mView.getApplication().getRoutingHelper().isRouteCalculated();
if (mView.getSettings().SHOW_DESTINATION_ARROW.isSet()) {
show = mView.getSettings().SHOW_DESTINATION_ARROW.get();
}
if (show) {
net.osmand.Location.distanceBetween(view.getLatitude(), view.getLongitude(),
pointToNavigate.getLatitude(), pointToNavigate.getLongitude(), calculations);
float bearing = calculations[1] - 90;
net.osmand.Location.distanceBetween(mView.getLatitude(), mView.getLongitude(),
pointToNavigate.getLatitude(), pointToNavigate.getLongitude(), mCalculations);
float bearing = mCalculations[1] - 90;
float radiusBearing = DIST_TO_SHOW * tb.getDensity();
final QuadPoint cp = tb.getCenterPixelPoint();
canvas.rotate(bearing, cp.x, cp.y);
canvas.translate(-24 * tb.getDensity() + radiusBearing, -22 * tb.getDensity());
canvas.drawBitmap(arrowToDestination, cp.x, cp.y, bitmapPaint);
canvas.drawBitmap(mArrowToDestination, cp.x, cp.y, mBitmapPaint);
}
}
}
public boolean isLocationVisible(RotatedTileBox tb, TargetPoint p){
if(p == null || tb == null){
private float getPointX(RotatedTileBox tileBox, TargetPoint point) {
if (contextMenuLayer.getMoveableObject() != null
&& point == contextMenuLayer.getMoveableObject()) {
return contextMenuLayer.getMoveableCenterPoint(tileBox).x;
} else {
return tileBox.getPixXFromLonNoRot(point.getLongitude());
}
}
private float getPointY(RotatedTileBox tileBox, TargetPoint point) {
if (contextMenuLayer.getMoveableObject() != null
&& point == contextMenuLayer.getMoveableObject()) {
return contextMenuLayer.getMoveableCenterPoint(tileBox).y;
} else {
return tileBox.getPixYFromLatNoRot(point.getLatitude());
}
}
public boolean isLocationVisible(RotatedTileBox tb, TargetPoint p) {
if (contextMenuLayer.getMoveableObject() != null
&& p == contextMenuLayer.getMoveableObject()) {
return true;
} else if (p == null || tb == null) {
return false;
}
return tb.containsLatLon(p.getLatitude(), p.getLongitude());
}
@Override
public void destroyLayer() {
}
@Override
@ -198,19 +222,19 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu
}
}
}
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius && (objy - ey) <= 2.5 * radius ;
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius && (objy - ey) <= 2.5 * radius;
}
public int getRadiusPoi(RotatedTileBox tb){
int r = 0;
public int getRadiusPoi(RotatedTileBox tb) {
int r;
final double zoom = tb.getZoom();
if(zoom <= 15){
if (zoom <= 15) {
r = 10;
} else if(zoom <= 16){
} else if (zoom <= 16) {
r = 14;
} else if(zoom <= 17){
} else if (zoom <= 17) {
r = 16;
} else {
r = 18;
@ -226,14 +250,32 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu
return null;
}
@Override
public PointDescription getObjectName(Object o) {
if (o instanceof TargetPoint) {
return ((TargetPoint) o).getPointDescription(view.getContext());
return ((TargetPoint) o).getPointDescription(mView.getContext());
}
return null;
}
@Override
public boolean isObjectMovable(Object o) {
TargetPointsHelper targetPoints = map.getMyApplication().getTargetPointsHelper();
return o == targetPoints.getPointToNavigate();
}
@Override
public void applyNewObjectPosition(@NonNull Object o, @NonNull LatLon position,
@Nullable ContextMenuLayer.ApplyMovedObjectCallback callback) {
boolean result = false;
if (o instanceof TargetPoint) {
TargetPoint point = (TargetPoint) o;
TargetPointsHelper tph = map.getMyApplication().getTargetPointsHelper();
tph.navigateToPoint(position, true, -1, point.getPointDescription(map));
result = true;
}
if (callback != null) {
callback.onApplyMovedObject(result, o);
}
}
}