commit
afb9f08e4b
28 changed files with 1215 additions and 559 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue