Compare commits

..

8 commits

Author SHA1 Message Date
Vitaliy
a259064d29 Add MarkersDbHelperLegacy 2021-04-22 19:16:23 +03:00
Vitaliy
0256796d23 Fix saving id with alias 2021-04-22 17:58:27 +03:00
Vitaliy
c1e6654319 Merge branch 'master' into markers_refactor 2021-04-22 17:54:17 +03:00
Vitaliy
a2b6faf94a Revert renaming 2021-04-22 12:47:26 +03:00
Vitaliy
ec03c40c1b Remove group alias 2021-04-22 11:27:26 +03:00
Vitaliy
311771f03c Save itinerary.gpx 2021-04-22 05:09:03 +03:00
Vitaliy
4cc970c0d2 Add itineraryType 2021-04-22 05:06:45 +03:00
Vitaliy
256d634cdb Rename markersHelper and move fragments to separate packages 2021-04-22 05:01:58 +03:00
90 changed files with 1117 additions and 1587 deletions

View file

@ -112,7 +112,7 @@ public class GPXUtilities {
}
public interface GPXExtensionsReader {
public boolean readExtensions(GPXFile res, XmlPullParser parser) throws Exception;
public boolean readExtensions(GPXFile res, XmlPullParser parser) throws IOException, XmlPullParserException;
}
public static class GPXExtensions {
@ -1965,7 +1965,7 @@ public class GPXUtilities {
}
}
private static void writeNotNullText(XmlSerializer serializer, String tag, String value) throws IOException {
public static void writeNotNullText(XmlSerializer serializer, String tag, String value) throws IOException {
if (value != null) {
serializer.startTag(null, tag);
serializer.text(value);
@ -2085,7 +2085,7 @@ public class GPXUtilities {
}
}
private static String readText(XmlPullParser parser, String key) throws XmlPullParserException, IOException {
public static String readText(XmlPullParser parser, String key) throws XmlPullParserException, IOException {
int tok;
StringBuilder text = null;
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
@ -2146,36 +2146,36 @@ public class GPXUtilities {
return time;
}
public static GPXFile loadGPXFile(File f) {
public static GPXFile loadGPXFile(File file) {
return loadGPXFile(file, null);
}
public static GPXFile loadGPXFile(File file, GPXExtensionsReader extensionsReader) {
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
GPXFile file = loadGPXFile(fis);
file.path = f.getAbsolutePath();
file.modifiedTime = f.lastModified();
fis = new FileInputStream(file);
GPXFile gpxFile = loadGPXFile(fis, extensionsReader);
gpxFile.path = file.getAbsolutePath();
gpxFile.modifiedTime = file.lastModified();
try {
fis.close();
} catch (IOException e) {
}
return file;
Algorithms.closeStream(fis);
return gpxFile;
} catch (IOException e) {
GPXFile res = new GPXFile(null);
res.path = f.getAbsolutePath();
log.error("Error reading gpx " + res.path, e); //$NON-NLS-1$
res.error = e;
return res;
GPXFile gpxFile = new GPXFile(null);
gpxFile.path = file.getAbsolutePath();
log.error("Error reading gpx " + gpxFile.path, e); //$NON-NLS-1$
gpxFile.error = e;
return gpxFile;
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ignore) {
// ignore
}
Algorithms.closeStream(fis);
}
}
public static GPXFile loadGPXFile(InputStream f) {
public static GPXFile loadGPXFile(InputStream stream) {
return loadGPXFile(stream, null);
}
public static GPXFile loadGPXFile(InputStream stream, GPXExtensionsReader extensionsReader) {
GPXFile gpxFile = new GPXFile(null);
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT, Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
@ -2183,7 +2183,7 @@ public class GPXUtilities {
formatMillis.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
XmlPullParser parser = PlatformUtil.newXMLPullParser();
parser.setInput(getUTF8Reader(f));
parser.setInput(getUTF8Reader(stream));
Track routeTrack = new Track();
TrkSegment routeTrackSegment = new TrkSegment();
routeTrack.segments.add(routeTrackSegment);
@ -2231,17 +2231,19 @@ public class GPXUtilities {
break;
default:
Map<String, String> values = readTextMap(parser, tag);
if (values.size() > 0) {
for (Entry<String, String> entry : values.entrySet()) {
String t = entry.getKey().toLowerCase();
String value = entry.getValue();
parse.getExtensionsToWrite().put(t, value);
if (tag.equals("speed") && parse instanceof WptPt) {
try {
((WptPt) parse).speed = Float.parseFloat(value);
} catch (NumberFormatException e) {
log.debug(e.getMessage(), e);
if (extensionsReader == null || !extensionsReader.readExtensions(gpxFile, parser)) {
Map<String, String> values = readTextMap(parser, tag);
if (values.size() > 0) {
for (Entry<String, String> entry : values.entrySet()) {
String t = entry.getKey().toLowerCase();
String value = entry.getValue();
parse.getExtensionsToWrite().put(t, value);
if (tag.equals("speed") && parse instanceof WptPt) {
try {
((WptPt) parse).speed = Float.parseFloat(value);
} catch (NumberFormatException e) {
log.debug(e.getMessage(), e);
}
}
}
}

View file

@ -186,7 +186,7 @@ public class RouteColorize {
public List<RouteColorizationPoint> getResult(boolean simplify) {
List<RouteColorizationPoint> result = new ArrayList<>();
if (simplify) {
result = simplify(zoom);
result = simplify();
} else {
for (int i = 0; i < latitudes.length; i++) {
result.add(new RouteColorizationPoint(i, latitudes[i], longitudes[i], values[i]));
@ -200,7 +200,7 @@ public class RouteColorize {
public int getColorByValue(double value) {
if (Double.isNaN(value)) {
value = colorizationType == ColorizationType.SLOPE ? minValue : (minValue + maxValue) / 2;
value = (minValue + maxValue) / 2;
}
for (int i = 0; i < palette.length - 1; i++) {
if (value == palette[i][VALUE_INDEX])
@ -242,7 +242,7 @@ public class RouteColorize {
return rgbaToDecimal(0, 0, 0, 0);
}
public List<RouteColorizationPoint> simplify(int zoom) {
private List<RouteColorizationPoint> simplify() {
if (dataList == null) {
dataList = new ArrayList<>();
for (int i = 0; i < latitudes.length; i++) {
@ -266,8 +266,6 @@ public class RouteColorize {
List<RouteColorizationPoint> sublist = dataList.subList(prevId, currentId);
simplified.addAll(getExtremums(sublist));
}
Node lastSurvivedPoint = result.get(result.size() - 1);
simplified.add(dataList.get((int) lastSurvivedPoint.getId()));
return simplified;
}

View file

@ -2,8 +2,8 @@ package net.osmand.util;
import net.osmand.IProgress;
import net.osmand.PlatformUtil;
import net.osmand.router.RouteColorize;
import net.osmand.data.LatLon;
import net.osmand.router.RouteColorize;
import org.apache.commons.logging.Log;
import org.xmlpull.v1.XmlPullParser;
@ -26,8 +26,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -298,17 +298,25 @@ public class Algorithms {
}
public static Set<String> decodeStringSet(String s) {
if (isEmpty(s)) {
return Collections.emptySet();
}
return new HashSet<>(Arrays.asList(s.split(CHAR_TOSPLIT + "")));
return decodeStringSet(s, String.valueOf(CHAR_TOSPLIT));
}
public static String encodeStringSet(Set<String> set) {
return encodeStringSet(set, String.valueOf(CHAR_TOSPLIT));
}
public static Set<String> decodeStringSet(String s, String split) {
if (isEmpty(s)) {
return Collections.emptySet();
}
return new LinkedHashSet<>(Arrays.asList(s.split(split)));
}
public static String encodeStringSet(Set<String> set, String split) {
if (set != null) {
StringBuilder sb = new StringBuilder();
for (String s : set) {
sb.append(s).append(CHAR_TOSPLIT);
sb.append(s).append(split);
}
return sb.toString();
}

View file

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,22C17.5228,22 22,17.5228 22,12C22,6.4771 17.5228,2 12,2C6.4771,2 2,6.4771 2,12C2,17.5228 6.4771,22 12,22ZM11,14V7H13V14H11ZM11,18V16H13V18H11Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

View file

@ -1,18 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M20,12C20,15.4738 17.7859,18.4304 14.692,19.5358L14.9449,21.5593C19.0304,20.3022 22,16.4979 22,12C22,6.4771 17.5228,2 12,2C6.4771,2 2,6.4771 2,12C2,16.4979 4.9696,20.3022 9.0551,21.5593L9.308,19.5358C6.2141,18.4304 4,15.4738 4,12C4,7.5817 7.5817,4 12,4C16.4183,4 20,7.5817 20,12Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M18,12C18,14.4466 16.5357,16.5511 14.4356,17.485L14.1701,15.3607C15.2713,14.6482 16,13.4092 16,12C16,9.7909 14.2091,8 12,8C9.7909,8 8,9.7909 8,12C8,13.4092 8.7287,14.6482 9.8299,15.3607L9.5644,17.485C7.4643,16.5511 6,14.4466 6,12C6,8.6863 8.6863,6 12,6C15.3137,6 18,8.6863 18,12Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M14,12C14,13.1046 13.1046,14 12,14C10.8954,14 10,13.1046 10,12C10,10.8954 10.8954,10 12,10C13.1046,10 14,10.8954 14,12Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M11,15V22H13V15H11Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -1,15 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M22.0001,12C22.0001,13.9623 21.4349,15.7926 20.4583,17.337L18.9991,15.8777C19.6369,14.7291 20.0001,13.407 20.0001,12C20.0001,7.5817 16.4183,4 12.0001,4C10.5931,4 9.271,4.3632 8.1223,5.0009L6.6631,3.5417C8.2075,2.5652 10.0378,2 12.0001,2C17.5229,2 22.0001,6.4771 22.0001,12Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M18.0001,12C18.0001,12.8478 17.8242,13.6545 17.507,14.3857L15.9203,12.7989C15.9726,12.5407 16.0001,12.2736 16.0001,12C16.0001,9.7909 14.2092,8 12.0001,8C11.7265,8 11.4593,8.0275 11.2012,8.0798L9.6144,6.493C10.3456,6.1758 11.1523,6 12.0001,6C15.3138,6 18.0001,8.6863 18.0001,12Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M14.3449,16.759L14.4357,17.485C14.5806,17.4206 14.7225,17.3506 14.8611,17.2752L16.3203,18.7344C15.8138,19.0599 15.2682,19.33 14.692,19.5358L14.945,21.5593C15.9623,21.2463 16.9105,20.7753 17.7609,20.1749L21.293,23.7071L22.7072,22.2928L2.7072,2.2929L1.293,3.7071L3.8251,6.2392C2.6754,7.8677 2.0001,9.855 2.0001,12C2.0001,16.4979 4.9696,20.3022 9.0552,21.5593L9.3081,19.5358C6.2141,18.4304 4.0001,15.4738 4.0001,12C4.0001,10.4087 4.4647,8.9258 5.2657,7.6798L6.7248,9.1389C6.2626,9.9894 6.0001,10.964 6.0001,12C6.0001,14.4466 7.4644,16.5511 9.5644,17.485L9.83,15.3607C8.7288,14.6482 8.0001,13.4092 8.0001,12C8.0001,11.5256 8.0826,11.0705 8.2342,10.6483L10.0555,12.4696C10.2305,13.197 10.8031,13.7695 11.5305,13.9446L12.5859,15H11.0001V22H13.0001V15.4142L14.3449,16.759Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,18V17.9725C3.75,17.7238 2,15.8163 2,13.5C2,11.0147 4.0147,9 6.5,9C6.5998,9 6.6989,9.0033 6.7971,9.0097C7.8332,7.2109 9.7752,6 12,6C15.3137,6 18,8.6863 18,12C18,12.0574 17.9992,12.1146 17.9976,12.1716C18.3111,12.0605 18.6485,12 19,12C20.6569,12 22,13.3431 22,15C22,16.6569 20.6569,18 19,18H6Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,17.9725V18H19C20.6569,18 22,16.6569 22,15C22,13.3431 20.6569,12 19,12C18.6485,12 18.3111,12.0605 17.9976,12.1716C17.9992,12.1146 18,12.0574 18,12C18,8.6863 15.3137,6 12,6C9.7752,6 7.8332,7.2109 6.7971,9.0097C6.6989,9.0033 6.5998,9 6.5,9C4.0147,9 2,11.0147 2,13.5C2,15.8163 3.75,17.7238 6,17.9725ZM11,13V8H13V13H11ZM11,17V15H13V17H11Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M14,18V15H16.5L12.5,10L8.5,15H11V18H6V17.9725C3.75,17.7238 2,15.8163 2,13.5C2,11.0147 4.0147,9 6.5,9C6.5998,9 6.6989,9.0033 6.7971,9.0097C7.8332,7.2109 9.7752,6 12,6C15.3137,6 18,8.6863 18,12C18,12.0574 17.9992,12.1146 17.9976,12.1716C18.3111,12.0605 18.6485,12 19,12C20.6569,12 22,13.3431 22,15C22,16.6569 20.6569,18 19,18H14Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,18V17.9725C3.75,17.7238 2,15.8163 2,13.5C2,11.0147 4.0147,9 6.5,9C6.5998,9 6.6989,9.0033 6.7971,9.0097C7.8332,7.2109 9.7752,6 12,6C15.3137,6 18,8.6863 18,12C18,12.0574 17.9992,12.1146 17.9976,12.1716C18.3111,12.0605 18.6485,12 19,12C20.6569,12 22,13.3431 22,15C22,16.6569 20.6569,18 19,18H6Z"
android:fillColor="#6C19FF"/>
<path
android:pathData="M11,15H8.5L12.5,9.5L16.5,15H14V20H11V15Z"
android:fillColor="#FFC30D"/>
</vector>

View file

@ -1,15 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M14,2L20,8H16C14.8954,8 14,7.1046 14,6V2Z"
android:strokeAlpha="0.5"
android:fillColor="#ffffff"
android:fillAlpha="0.5"/>
<path
android:pathData="M4,4C4,2.8954 4.8954,2 6,2H14V6C14,7.1046 14.8954,8 16,8H20V20C20,21.1046 19.1046,22 18,22H6C4.8954,22 4,21.1046 4,20V4ZM11,18H13V13H15L12,9L9,13H11V18Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

View file

@ -1,37 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,5C12.5523,5 13,4.5523 13,4H17V8.0549C16.6717,8.0186 16.338,8 16,8C11.0294,8 7,12.0294 7,17V4H11C11,4.5523 11.4477,5 12,5Z"
android:strokeAlpha="0.3"
android:fillColor="#ffffff"
android:fillAlpha="0.3"/>
<path
android:pathData="M7,17C7,18.0519 7.1805,19.0617 7.5121,20H7V17Z"
android:strokeAlpha="0.3"
android:fillColor="#ffffff"
android:fillAlpha="0.3"/>
<path
android:pathData="M17,2.01L7,2C5.9,2 5,2.9 5,4V20C5,21.1 5.9,22 7,22H8.5155C8.1025,21.383 7.7638,20.7121 7.5121,20H7V4H11C11,4.5523 11.4477,5 12,5C12.5523,5 13,4.5523 13,4H17V8.0549C17.6935,8.1316 18.3632,8.287 19,8.5121V4C19,2.9 18.1,2.01 17,2.01Z"
android:strokeAlpha="0.7"
android:fillColor="#ffffff"
android:fillAlpha="0.7"/>
<path
android:pathData="M16,21C18.2091,21 20,19.2091 20,17C20,14.7909 18.2091,13 16,13C13.7909,13 12,14.7909 12,17H14L11,20L8,17H10C10,13.6863 12.6863,11 16,11C19.3137,11 22,13.6863 22,17C22,20.3137 19.3137,23 16,23C14.598,23 13.3082,22.5191 12.2868,21.7132L13.7159,20.2841C14.3635,20.7354 15.1508,21 16,21Z"
android:fillType="evenOdd">
<aapt:attr name="android:fillColor">
<gradient
android:gradientRadius="6.36396"
android:centerX="16"
android:centerY="17"
android:type="radial">
<item android:offset="0" android:color="#FFFFFFFF"/>
<item android:offset="0.8125" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#00FFFFFF"/>
</gradient>
</aapt:attr>
</path>
</vector>

View file

@ -1,15 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M6,3C4.8954,3 4,3.8954 4,5V7H20C20,5.8954 19.1046,5 18,5H13L11.4,3H6Z"
android:strokeAlpha="0.5"
android:fillColor="#ffffff"
android:fillAlpha="0.5"/>
<path
android:pathData="M2,7C2,5.8954 2.8954,5 4,5H10L12,7H20C21.1046,7 22,7.8954 22,9V19C22,20.1046 21.1046,21 20,21H4C2.8954,21 2,20.1046 2,19V7ZM17,12C17,13.1046 16.1046,14 15,14C13.8954,14 13,13.1046 13,12C13,10.8954 13.8954,10 15,10C16.1046,10 17,10.8954 17,12ZM10,17.5V19H20V17.5C20,15.5 17,15 15,15C13,15 10,15.5 10,17.5Z"
android:fillColor="#ffffff"
android:fillType="evenOdd"/>
</vector>

View file

@ -5,10 +5,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/content_padding"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingTop="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding">
<View
@ -45,9 +43,4 @@
</LinearLayout>
<View
android:id="@+id/space"
android:layout_width="match_parent"
android:layout_height="@dimen/content_padding" />
</LinearLayout>

View file

@ -1088,7 +1088,7 @@
<string name="lang_ja">Японская</string>
<string name="lang_ko">Карэйская</string>
<string name="lang_lv">Латышская</string>
<string name="lang_lt">Летувіская</string>
<string name="lang_lt">Летувісская</string>
<string name="lang_mr">Маратхі</string>
<string name="lang_no">Нарвежская (Bokmål)</string>
<string name="lang_pl">Польская</string>

View file

@ -3843,7 +3843,7 @@ POIの更新は利用できません</string>
<string name="subscription_expired_title">OsmAndLiveサブスクリプションの有効期限が切れました</string>
<string name="subscription_paused_title">OsmAndLiveサブスクリプションが一時停止されました</string>
<string name="subscription_on_hold_title">OsmAndLiveサブスクリプションは保留中です</string>
<string name="markers_history">マーカー履歴</string>
<string name="markers_history">マーカー履歴</string>
<string name="send_files_to_openstreetmap">GPXファイルをOpenStreetMapに送信</string>
<string name="enter_text_separated">タグはカンマで区切って入力してください。</string>
<string name="gpx_upload_public_visibility_descr">\"公開 \"状態は、追跡機能にてユーザーのGPS追跡、公開GPS追跡リスト、および生データのタイムスタンプ付き公開追跡リストに公開されることを意味します。APIを介して提供されるデータはユーザーの追跡ページを参照しません。追跡ポイントのタイムスタンプはパブリックGPS APIでは利用できず、また追跡ポイントは時系列に並んでいません。</string>

View file

@ -3927,5 +3927,4 @@
<string name="poi_cliff_diving">Mergulho de falésia</string>
<string name="poi_zurkhaneh_sport">Zurkhaneh</string>
<string name="poi_bay_filter">Tipo de baía</string>
<string name="poi_ultimate">Ultimate</string>
</resources>

View file

@ -4049,19 +4049,15 @@
<string name="shared_string_route_line">Linha de rota</string>
<string name="route_line_use_map_style_appearance">A linha de rota seria usada %1$s especificado no estilo de mapa selecionado: %2$s.</string>
<string name="specify_color_for_map_mode">Especifique a cor para o modo de mapa: %1$s.</string>
<string name="release_4_0_beta">"• Adicionada opção para baixar curvas de nível em pés
<string name="release_4_0_beta">• As atualizações do OsmAnd Live foram movidas para \"Downloads &gt; Atualizações\"
\n
\n • Plano de paisagem da rota: guias adicionadas para alternar entre pontos ou gráficos
\n• As trilhas agora podem ser coloridas por altitude, velocidade ou inclinação.
\n
\n • As atualizações do OsmAnd Live foram movidas para \"Downloads&gt; Atualizações\"
\n• Adicionada opção para alterar a aparência da linha da rota de navegação
\n
\n • As trilhas agora podem ser coloridas por altitude, velocidade ou inclinação.
\n• Caixa de diálogo \"Gravação de viagem\" atualizada
\n
\n • Adicionada opção para alterar a aparência da linha da rota de navegação
\n
\n • Caixa de diálogo \"Gravação de viagem\" atualizada
\n
\n"</string>
\n</string>
<string name="no_purchases">Você não tem nenhuma compra</string>
<string name="new_device_account">Novo dispositivo / nova conta</string>
<string name="contact_support_description">Se você tiver alguma dúvida, entre em contato conosco em %1$s.</string>
@ -4085,8 +4081,4 @@
<string name="user_points">Pontos do usuário</string>
<string name="output">Saída</string>
<string name="map_quick_action_pattern">%1$s → …</string>
<string name="shared_string_feet">pés</string>
<string name="srtm_unit_format">Formato da unidade de curvas de nível</string>
<string name="srtm_download_list_help_message">OsmAnd fornece dados de linhas de contorno em metros e pés. Você precisará baixar novamente o arquivo para alterar o formato.</string>
<string name="srtm_download_single_help_message">Selecione o formato necessário. Você precisará baixar novamente o arquivo para alterar o formato.</string>
</resources>

View file

@ -193,7 +193,7 @@
<string name="poi_ford_stepping_stones">Ponte pedonal em pedras separadas</string>
<string name="poi_mountain_pass">Passo de montanha</string>
<string name="poi_gate">Portão</string>
<string name="poi_city_wall">Muralha/cerca de cidade</string>
<string name="poi_city_wall">Muralha de cidade</string>
<string name="poi_lift_gate">Cancela elevatória</string>
<string name="poi_toll_booth">Cabine de portagem</string>
<string name="poi_border_control">Controlo aduaneiro</string>
@ -637,13 +637,13 @@
<string name="poi_australian_football">Futebol australiano</string>
<string name="poi_base">Base jumping</string>
<string name="poi_baseball">Beisebol</string>
<string name="poi_basketball">Basquetebol</string>
<string name="poi_basketball">Basquete</string>
<string name="poi_beachvolleyball">Voleibol de praia</string>
<string name="poi_bmx">BMX</string>
<string name="poi_boules">Bocha</string>
<string name="poi_bowls">Lawn bowls</string>
<string name="poi_canadian_football">Futebol canadiano</string>
<string name="poi_canoe">Canoagem</string>
<string name="poi_canoe">Canoa</string>
<string name="poi_chess">Xadrez</string>
<string name="poi_climbing">Escalada</string>
<string name="poi_cricket">Críquete</string>
@ -694,7 +694,7 @@
<string name="poi_boundary_stone">Marco de fronteira</string>
<string name="poi_historic_cannon">Canhão histórico</string>
<string name="poi_castle">Castelo</string>
<string name="poi_city_gate">Portão/porta/arco de cidade</string>
<string name="poi_city_gate">Portão/arco de cidade</string>
<string name="poi_fort">Forte</string>
<string name="poi_fountain">Chafariz</string>
<string name="poi_historic_ruins">Ruínas históricas</string>
@ -707,7 +707,7 @@
<string name="poi_aquarium">Aquário</string>
<string name="poi_theme_park">Parque de diversões</string>
<string name="poi_attraction">Atração turística</string>
<string name="poi_tourism_yes">Elemento turístico</string>
<string name="poi_tourism_yes">Objeto turístico</string>
<string name="poi_attraction_amusement_ride">Atracão de feira</string>
<string name="poi_attraction_animal">Animal (atração)</string>
<string name="poi_attraction_big_wheel">Roda gigante</string>
@ -2866,9 +2866,9 @@
<string name="poi_aquaculture_mussels">Aquicultura: mexilhões</string>
<string name="poi_mdf">Rede de distribuição principal (MDF)</string>
<string name="poi_min_age">Idade mínima</string>
<string name="poi_organic_yes">Produtos orgânicos: sim</string>
<string name="poi_organic_no">Produtos orgânicos: não</string>
<string name="poi_organic_only">Produtos orgânicos: unicamente</string>
<string name="poi_organic_yes">Sim</string>
<string name="poi_organic_no">Não</string>
<string name="poi_organic_only">Unicamente</string>
<string name="poi_traffic_mirror">Espelho de tráfego</string>
<string name="poi_diplomatic_consulate">Consulado</string>
<string name="poi_diplomatic_consulate_general">Consulado geral</string>
@ -3746,7 +3746,7 @@
<string name="poi_community_gender_male">Sexo comunitário: masculino</string>
<string name="poi_community_gender_mixed">Sexo comunitário: misto</string>
<string name="poi_grave">Sepultura</string>
<string name="poi_parking_space">Lugar de estacionamento (1 veículo)</string>
<string name="poi_parking_space">Espaço de estacionamento</string>
<string name="poi_url">URL</string>
<string name="poi_volcano_type">Tipo</string>
<string name="poi_volcano_status">Estado</string>

View file

@ -2013,7 +2013,7 @@
<string name="routing_attr_height_obstacles_name">Utilizar dados de elevação</string>
<string name="rendering_attr_depthContours_description">Mostrar pontos e contornos de profundidade.</string>
<string name="rendering_attr_depthContours_name">Contornos de profundidade náuticos</string>
<string name="show_transparency_seekbar">Mostrar barra deslizante de transparência</string>
<string name="show_transparency_seekbar">Mostra a transparência da barra de navegação</string>
<string name="shared_string_widgets">Widgets</string>
<string name="rendering_attr_hideUnderground_name">Objetos subterrâneos</string>
<string name="auto_split_recording_title">Dividir automaticamente as gravações após quebras</string>

View file

@ -2872,7 +2872,7 @@
<string name="sit_on_the_stop">Посадка на остановке</string>
<string name="use_osm_live_public_transport_description">Включить общественный транспорт с учётом автообновлений OsmAnd Live.</string>
<string name="use_osm_live_public_transport">Общественный транспорт OsmAnd Live</string>
<string name="transfers_size">пересадки: %1$d</string>
<string name="transfers_size">%1$d пересадки</string>
<string name="rendering_attr_surface_unpaved_name">Грунтовая</string>
<string name="rendering_attr_surface_sand_name">Песок</string>
<string name="rendering_attr_surface_grass_name">Трава</string>
@ -3263,7 +3263,7 @@
<string name="selected_profile">Выбранный профиль</string>
<string name="personal_category_name">Персональный</string>
<string name="shared_string_downloading_formatted">Скачивание %s</string>
<string name="rendering_value_thick_name">Толстая</string>
<string name="rendering_value_thick_name">Толсто</string>
<string name="default_speed_dialog_msg">Используется для оценки времени прибытия для неизвестного типа дорог и ограничения скорости для всех дорог (может изменить маршрут)</string>
<string name="routing_attr_allow_intermediate_name">Разрешить промежуточные маршруты</string>
<string name="routing_attr_allow_advanced_name">Разрешить расширенные маршруты</string>
@ -3302,7 +3302,7 @@
<string name="rendering_attr_piste_difficulty_connection_name">Соединение</string>
<string name="simulate_your_location_gpx_descr">Симулировать свою позицию используя записанный GPX трек.</string>
<string name="route_start_point">Начало маршрута</string>
<string name="shared_string_revert">Сброс</string>
<string name="shared_string_revert">Вернуться</string>
<string name="suggested_maps_descr">Эти карты необходимо использовать с плагином.</string>
<string name="added_profiles">Добавленные профили</string>
<string name="added_profiles_descr">Профили, добавленные плагином</string>
@ -4056,11 +4056,7 @@
<string name="next_billing_date">Следующая дата оплаты: %1$s</string>
<string name="osmand_live">OsmAnd Live</string>
<string name="annual_subscription">Годовая подписка</string>
<string name="release_4_0_beta">• Добавлена возможность скачать контурные линии в футах.
\n
\n• Планирование маршрута: добавлены вкладки для переключения между точками и графиками.
\n
\n• Обновления OsmAnd Live перемещены в «Загрузка карт» → «Обновления».
<string name="release_4_0_beta">• Обновления OsmAnd Live перемещены в «Загрузка карт» → «Обновления».
\n
\n• Теперь треки можно раскрашивать по высоте, скорости или уклону.
\n
@ -4091,8 +4087,4 @@
<string name="output">Вывод</string>
<string name="map_quick_action_pattern">%1$s → …</string>
<string name="exit_number">Номер съезда</string>
<string name="srtm_unit_format">Формат единиц на контурных линиях</string>
<string name="srtm_download_single_help_message">Выберите необходимый формат. Для изменения формата потребуется повторно загрузить файл.</string>
<string name="shared_string_feet">футы</string>
<string name="srtm_download_list_help_message">OsmAnd предоставляет данные изолиний в метрах и футах. Вам нужно будет повторно загрузить файл, чтобы изменить формат.</string>
</resources>

View file

@ -4045,11 +4045,7 @@
<string name="lost_data_warning">Všetky neuložené údaje budú stratené.</string>
<string name="show_start_dialog">Zobraziť úvodné okno</string>
<string name="trip_recording_show_start_dialog_setting">Ak je vypnuté, záznam začne hneď po stlačení nástroja alebo položky v menu a preskočí okno nastavenia.</string>
<string name="release_4_0_beta">• Pridaná možnosť stiahnutia Vrstevníc v stopách
\n
\n• Plánovať trasy: pridané prepínače medzi bodmi a grafmi
\n
\n• Aktualizácie OsmAnd Live presunuté do \"Sťahovania &gt; Aktualizácie\"
<string name="release_4_0_beta">• Aktualizácie OsmAnd Live presunuté do \"Sťahovania &gt; Aktualizácie\"
\n
\n • Stopy je teraz možné vyfarbiť podľa nadmorskej výšky, rýchlosti alebo sklonu svahu.
\n
@ -4085,8 +4081,4 @@
<string name="user_points">Body používateľa</string>
<string name="output">Výstup</string>
<string name="map_quick_action_pattern">%1$s → …</string>
<string name="shared_string_feet">stopy</string>
<string name="srtm_unit_format">Formát jednotiek vrstevníc</string>
<string name="srtm_download_list_help_message">OsmAnd poskytuje údaje vrstevníc v metroch a stopách. Budete musieť znovu stiahnuť súbor pre zmenu formátu.</string>
<string name="srtm_download_single_help_message">Prosím zvoľte požadovaný formát. Budete musieť znovu stiahnuť súbor pre zmenu formátu.</string>
</resources>

View file

@ -12,9 +12,6 @@
-->
<string name="shared_string_max_height">Max. height</string>
<string name="shared_string_min_height">Min. height</string>
<string name="route_line_use_gradient_coloring">Route line will be colorized depending on the elevation profile of the route.</string>
<string name="output">Output</string>
<string name="user_points">User points</string>
<string name="announce_when_exceeded">Announce when exceeded</string>

View file

@ -38,7 +38,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executor;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
@ -48,14 +47,13 @@ public class AndroidNetworkUtils {
private static final Log LOG = PlatformUtil.getLog(AndroidNetworkUtils.class);
public interface OnRequestResultListener {
void onResult(@Nullable String result, @Nullable String error);
void onResult(String result);
}
public interface OnFilesUploadCallback {
@Nullable
Map<String, String> getAdditionalParams(@NonNull File file);
void onFileUploadProgress(@NonNull File file, int percent);
void onFileUploadDone(@NonNull File file);
void onFilesUploadDone(@NonNull Map<File, String> errors);
}
@ -65,26 +63,16 @@ public class AndroidNetworkUtils {
void onFileDownloadProgress(@NonNull File file, int percent);
@WorkerThread
void onFileDownloadedAsync(@NonNull File file);
void onFileDownloadDone(@NonNull File file);
void onFilesDownloadDone(@NonNull Map<File, String> errors);
}
public static class RequestResponse {
private final Request request;
private final String response;
private final String error;
private Request request;
private String response;
RequestResponse(@NonNull Request request, @Nullable String response) {
this.request = request;
this.response = response;
this.error = null;
}
RequestResponse(@NonNull Request request, @Nullable String response, @Nullable String error) {
this.request = request;
this.response = response;
this.error = error;
}
public Request getRequest() {
@ -94,10 +82,6 @@ public class AndroidNetworkUtils {
public String getResponse() {
return response;
}
public String getError() {
return error;
}
}
public interface OnSendRequestsListener {
@ -108,13 +92,6 @@ public class AndroidNetworkUtils {
public static void sendRequestsAsync(@Nullable final OsmandApplication ctx,
@NonNull final List<Request> requests,
@Nullable final OnSendRequestsListener listener) {
sendRequestsAsync(ctx, requests, listener, AsyncTask.THREAD_POOL_EXECUTOR);
}
public static void sendRequestsAsync(@Nullable final OsmandApplication ctx,
@NonNull final List<Request> requests,
@Nullable final OnSendRequestsListener listener,
final Executor executor) {
new AsyncTask<Void, RequestResponse, List<RequestResponse>>() {
@ -124,18 +101,11 @@ public class AndroidNetworkUtils {
for (Request request : requests) {
RequestResponse requestResponse;
try {
final String[] response = {null, null};
sendRequest(ctx, request.getUrl(), request.getParameters(),
request.getUserOperation(), request.isToastAllowed(), request.isPost(), new OnRequestResultListener() {
@Override
public void onResult(@Nullable String result, @Nullable String error) {
response[0] = result;
response[1] = error;
}
});
requestResponse = new RequestResponse(request, response[0], response[1]);
String response = sendRequest(ctx, request.getUrl(), request.getParameters(),
request.getUserOperation(), request.isToastAllowed(), request.isPost());
requestResponse = new RequestResponse(request, response);
} catch (Exception e) {
requestResponse = new RequestResponse(request, null, "Unexpected error");
requestResponse = new RequestResponse(request, null);
}
responses.add(requestResponse);
publishProgress(requestResponse);
@ -157,7 +127,7 @@ public class AndroidNetworkUtils {
}
}
}.executeOnExecutor(executor, (Void) null);
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
public static void sendRequestAsync(final OsmandApplication ctx,
@ -167,45 +137,26 @@ public class AndroidNetworkUtils {
final boolean toastAllowed,
final boolean post,
final OnRequestResultListener listener) {
sendRequestAsync(ctx, url, parameters, userOperation, toastAllowed, post, listener,
AsyncTask.THREAD_POOL_EXECUTOR);
}
public static void sendRequestAsync(final OsmandApplication ctx,
final String url,
final Map<String, String> parameters,
final String userOperation,
final boolean toastAllowed,
final boolean post,
final OnRequestResultListener listener,
final Executor executor) {
new AsyncTask<Void, Void, String[]>() {
new AsyncTask<Void, Void, String>() {
@Override
protected String[] doInBackground(Void... params) {
final String[] res = {null, null};
protected String doInBackground(Void... params) {
try {
sendRequest(ctx, url, parameters, userOperation, toastAllowed, post, new OnRequestResultListener() {
@Override
public void onResult(@Nullable String result, @Nullable String error) {
res[0] = result;
res[1] = error;
}
});
return sendRequest(ctx, url, parameters, userOperation, toastAllowed, post);
} catch (Exception e) {
// ignore
return null;
}
return res;
}
@Override
protected void onPostExecute(String[] response) {
protected void onPostExecute(String response) {
if (listener != null) {
listener.onResult(response[0], response[1]);
listener.onResult(response);
}
}
}.executeOnExecutor(executor, (Void) null);
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
public static void downloadFileAsync(final String url,
@ -232,14 +183,6 @@ public class AndroidNetworkUtils {
final @NonNull List<File> files,
final @NonNull Map<String, String> parameters,
final @Nullable OnFilesDownloadCallback callback) {
downloadFilesAsync(url, files, parameters, callback, AsyncTask.THREAD_POOL_EXECUTOR);
}
public static void downloadFilesAsync(final @NonNull String url,
final @NonNull List<File> files,
final @NonNull Map<String, String> parameters,
final @Nullable OnFilesDownloadCallback callback,
final Executor executor) {
new AsyncTask<Void, Object, Map<File, String>>() {
@ -285,7 +228,7 @@ public class AndroidNetworkUtils {
} catch (Exception e) {
errors.put(file, e.getMessage());
}
publishProgress(file, -1);
publishProgress(file, Integer.MAX_VALUE);
}
return errors;
}
@ -293,13 +236,7 @@ public class AndroidNetworkUtils {
@Override
protected void onProgressUpdate(Object... objects) {
if (callback != null) {
File file = (File) objects[0];
Integer progress = (Integer) objects[1];
if (progress >= 0) {
callback.onFileDownloadProgress(file, progress);
} else {
callback.onFileDownloadDone(file);
}
callback.onFileDownloadProgress((File) objects[0], (Integer) objects[1]);
}
}
@ -310,23 +247,15 @@ public class AndroidNetworkUtils {
}
}
}.executeOnExecutor(executor, (Void) null);
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
public static String sendRequest(@Nullable OsmandApplication ctx, @NonNull String url,
@Nullable Map<String, String> parameters,
@Nullable String userOperation, boolean toastAllowed, boolean post) {
return sendRequest(ctx, url, parameters, userOperation, toastAllowed, post, null);
}
public static String sendRequest(@Nullable OsmandApplication ctx, @NonNull String url,
@Nullable Map<String, String> parameters,
@Nullable String userOperation, boolean toastAllowed, boolean post,
@Nullable OnRequestResultListener listener) {
String result = null;
String error = null;
HttpURLConnection connection = null;
try {
String params = null;
if (parameters != null && parameters.size() > 0) {
StringBuilder sb = new StringBuilder();
@ -356,66 +285,68 @@ public class AndroidNetworkUtils {
output.write(params.getBytes("UTF-8"));
output.flush();
output.close();
} else {
connection.setRequestMethod("GET");
connection.connect();
}
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
if (ctx != null) {
error = (!Algorithms.isEmpty(userOperation) ? userOperation + " " : "")
+ ctx.getString(R.string.failed_op) + ": " + connection.getResponseMessage();
} else {
error = (!Algorithms.isEmpty(userOperation) ? userOperation + " " : "")
+ "failed: " + connection.getResponseMessage();
}
if (toastAllowed && ctx != null) {
showToast(ctx, error);
}
InputStream errorStream = connection.getErrorStream();
if (errorStream != null) {
error = streamToString(errorStream);
String msg = (!Algorithms.isEmpty(userOperation) ? userOperation + " " : "")
+ ctx.getString(R.string.failed_op) + ": "
+ connection.getResponseMessage();
showToast(ctx, msg);
}
} else {
result = streamToString(connection.getInputStream());
StringBuilder responseBody = new StringBuilder();
responseBody.setLength(0);
InputStream i = connection.getInputStream();
if (i != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256);
String s;
boolean f = true;
while ((s = in.readLine()) != null) {
if (!f) {
responseBody.append("\n");
} else {
f = false;
}
responseBody.append(s);
}
try {
in.close();
i.close();
} catch (Exception e) {
// ignore exception
}
}
return responseBody.toString();
}
} catch (NullPointerException e) {
// that's tricky case why NPE is thrown to fix that problem httpClient could be used
if (ctx != null) {
error = ctx.getString(R.string.auth_failed);
} else {
error = "Authorization failed";
}
if (toastAllowed && ctx != null) {
showToast(ctx, error);
String msg = ctx.getString(R.string.auth_failed);
showToast(ctx, msg);
}
} catch (MalformedURLException e) {
if (ctx != null) {
error = MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation);
} else {
error = "Action " + userOperation + ": Unexpected error";
}
if (toastAllowed && ctx != null) {
showToast(ctx, error);
showToast(ctx, MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation));
}
} catch (IOException e) {
if (ctx != null) {
error = MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation);
} else {
error = "Action " + userOperation + ": I/O error";
}
if (toastAllowed && ctx != null) {
showToast(ctx, error);
showToast(ctx, MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
+ ": " + ctx.getResources().getString(R.string.shared_string_io_error), userOperation));
}
} finally {
if (connection != null) {
connection.disconnect();
}
}
if (listener != null) {
listener.onResult(result, error);
}
return null;
}
@ -443,64 +374,35 @@ public class AndroidNetworkUtils {
public static String downloadFile(@NonNull String url, @NonNull File fileToSave, boolean gzip, @Nullable IProgress progress) {
String error = null;
try {
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
URLConnection connection = NetworkUtils.getHttpURLConnection(url);
connection.setConnectTimeout(CONNECTION_TIMEOUT);
connection.setReadTimeout(CONNECTION_TIMEOUT);
if (gzip) {
connection.setRequestProperty("Accept-Encoding", "deflate, gzip");
}
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
return streamToString(connection.getErrorStream());
} else {
InputStream inputStream = gzip
? new GZIPInputStream(connection.getInputStream())
: new BufferedInputStream(connection.getInputStream(), 8 * 1024);
fileToSave.getParentFile().mkdirs();
OutputStream stream = null;
try {
stream = new FileOutputStream(fileToSave);
Algorithms.streamCopy(inputStream, stream, progress, 1024);
stream.flush();
} finally {
Algorithms.closeStream(inputStream);
Algorithms.closeStream(stream);
}
InputStream inputStream = gzip
? new GZIPInputStream(connection.getInputStream())
: new BufferedInputStream(connection.getInputStream(), 8 * 1024);
fileToSave.getParentFile().mkdirs();
OutputStream stream = null;
try {
stream = new FileOutputStream(fileToSave);
Algorithms.streamCopy(inputStream, stream, progress, 1024);
stream.flush();
} finally {
Algorithms.closeStream(inputStream);
Algorithms.closeStream(stream);
}
} catch (UnknownHostException e) {
error = e.getMessage();
LOG.error("UnknownHostException, cannot download file " + url + " " + error);
} catch (Exception e) {
error = e.getMessage();
LOG.warn("Cannot download file: " + url, e);
LOG.warn("Cannot download file : " + url, e);
}
return error;
}
private static String streamToString(InputStream inputStream) throws IOException {
StringBuilder result = new StringBuilder();
if (inputStream != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 256);
String buffer;
boolean f = true;
while ((buffer = in.readLine()) != null) {
if (!f) {
result.append("\n");
} else {
f = false;
}
result.append(buffer);
}
try {
in.close();
inputStream.close();
} catch (Exception e) {
// ignore exception
}
}
return result.toString();
}
private static final String BOUNDARY = "CowMooCowMooCowCowCow";
public static String uploadFile(@NonNull String urlText, @NonNull File file, boolean gzip,
@ -515,6 +417,7 @@ public class AndroidNetworkUtils {
@NonNull Map<String, String> additionalParams,
@Nullable Map<String, String> headers,
@Nullable IProgress progress) {
URL url;
try {
boolean firstPrm = !urlText.contains("?");
StringBuilder sb = new StringBuilder(urlText);
@ -525,7 +428,7 @@ public class AndroidNetworkUtils {
urlText = sb.toString();
LOG.info("Start uploading file to " + urlText + " " + fileName);
URL url = new URL(urlText);
url = new URL(urlText);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
@ -566,10 +469,6 @@ public class AndroidNetworkUtils {
LOG.info("Finish uploading file " + fileName);
LOG.info("Response code and message : " + conn.getResponseCode() + " " + conn.getResponseMessage());
if (conn.getResponseCode() != 200) {
InputStream errorStream = conn.getErrorStream();
if (errorStream != null) {
return streamToString(errorStream);
}
return conn.getResponseMessage();
}
InputStream is = conn.getInputStream();
@ -604,16 +503,6 @@ public class AndroidNetworkUtils {
final @NonNull Map<String, String> parameters,
final @Nullable Map<String, String> headers,
final OnFilesUploadCallback callback) {
uploadFilesAsync(url, files, gzip, parameters, headers, callback, AsyncTask.THREAD_POOL_EXECUTOR);
}
public static void uploadFilesAsync(final @NonNull String url,
final @NonNull List<File> files,
final boolean gzip,
final @NonNull Map<String, String> parameters,
final @Nullable Map<String, String> headers,
final OnFilesUploadCallback callback,
final Executor executor) {
new AsyncTask<Void, Object, Map<File, String>>() {
@ -649,7 +538,7 @@ public class AndroidNetworkUtils {
} catch (Exception e) {
errors.put(file, e.getMessage());
}
publishProgress(file, -1);
publishProgress(file, Integer.MAX_VALUE);
}
return errors;
}
@ -657,13 +546,7 @@ public class AndroidNetworkUtils {
@Override
protected void onProgressUpdate(Object... objects) {
if (callback != null) {
File file = (File) objects[0];
Integer progress = (Integer) objects[1];
if (progress >= 0) {
callback.onFileUploadProgress(file, progress);
} else {
callback.onFileUploadDone(file);
}
callback.onFileUploadProgress((File) objects[0], (Integer) objects[1]);
}
}
@ -674,7 +557,7 @@ public class AndroidNetworkUtils {
}
}
}.executeOnExecutor(executor, (Void) null);
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
private static void showToast(OsmandApplication ctx, String message) {
@ -682,11 +565,11 @@ public class AndroidNetworkUtils {
}
public static class Request {
private final String url;
private final Map<String, String> parameters;
private final String userOperation;
private final boolean toastAllowed;
private final boolean post;
private String url;
private Map<String, String> parameters;
private String userOperation;
private boolean toastAllowed;
private boolean post;
public Request(String url, Map<String, String> parameters, String userOperation, boolean toastAllowed, boolean post) {
this.url = url;

View file

@ -16,10 +16,10 @@ import net.osmand.ResultMatcher;
import net.osmand.binary.RouteDataObject;
import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.BooleanPreference;
import net.osmand.plus.settings.backend.OsmandPreference;
import net.osmand.plus.R;
import net.osmand.plus.parkingpoint.ParkingPositionPlugin;
import net.osmand.plus.settings.backend.BooleanPreference;
import net.osmand.plus.settings.backend.OsmandPreference;
import net.osmand.util.Algorithms;
import java.io.Serializable;
@ -333,7 +333,7 @@ public class FavouritePoint implements Serializable, LocationPoint {
result = prime * result + (int) Math.floor(latitude * 10000);
result = prime * result + (int) Math.floor(longitude * 10000);
result = prime * result + (int) Math.floor(altitude * 10000);
result = prime * result + (int) Math.floor(timestamp * 10000);
result = prime * result + (int) (timestamp ^ (timestamp >>> 32));
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((category == null) ? 0 : category.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
@ -454,8 +454,7 @@ public class FavouritePoint implements Serializable, LocationPoint {
if (name == null) {
name = "";
}
FavouritePoint fp;
fp = new FavouritePoint(pt.lat, pt.lon, name, categoryName, pt.ele, pt.time);
FavouritePoint fp = new FavouritePoint(pt.lat, pt.lon, name, categoryName, pt.ele, pt.time);
fp.setDescription(pt.desc);
if (pt.comment != null) {
fp.setOriginObjectName(pt.comment);

View file

@ -225,7 +225,7 @@ public class CustomRegion extends WorldRegion {
&& app.getSettings().isInternetConnectionAvailable()) {
OnRequestResultListener resultListener = new OnRequestResultListener() {
@Override
public void onResult(@Nullable String result, @Nullable String error) {
public void onResult(String result) {
if (!Algorithms.isEmpty(result)) {
if ("json".equalsIgnoreCase(dynamicDownloadItems.format)) {
dynamicItemsJson = mapJsonItems(result);

View file

@ -14,12 +14,13 @@ import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.PlatformUtil;
import net.osmand.data.FavouritePoint;
import net.osmand.data.FavouritePoint.SpecialPointType;
import net.osmand.data.LatLon;
import net.osmand.plus.GeocodingLookupService.AddressLookupRequest;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.util.Algorithms;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
@ -246,7 +247,7 @@ public class FavouritesDbHelper {
});
}
public FavouritePoint getSpecialPoint(FavouritePoint.SpecialPointType pointType) {
public FavouritePoint getSpecialPoint(SpecialPointType pointType) {
for (FavouritePoint fp : cachedFavoritePoints) {
if (fp.getSpecialPointType() == pointType) {
return fp;
@ -580,7 +581,7 @@ public class FavouritesDbHelper {
}
}
private void backup(File backupFile, File externalFile) {
public static void backup(File backupFile, File externalFile) {
try {
File f = new File(backupFile.getParentFile(), backupFile.getName());
BZip2CompressorOutputStream out = new BZip2CompressorOutputStream(new FileOutputStream(f));
@ -635,7 +636,11 @@ public class FavouritesDbHelper {
}
public File getBackupFile() {
File fld = new File(context.getAppPath(null), BACKUP_FOLDER);
return getBackupFile(context, "favourites_bak_");
}
public static File getBackupFile(OsmandApplication app, String fileName) {
File fld = new File(app.getAppPath(null), BACKUP_FOLDER);
if (!fld.exists()) {
fld.mkdirs();
}
@ -648,7 +653,7 @@ public class FavouritesDbHelper {
if (back < 10) {
backPrefix = "0" + backPrefix;
}
File bak = new File(fld, "favourites_bak_" + backPrefix + ".gpx.bz2");
File bak = new File(fld, fileName + backPrefix + ".gpx.bz2");
if (!bak.exists()) {
return bak;
} else if (bak.lastModified() < firstModifiedMin) {
@ -845,9 +850,7 @@ public class FavouritesDbHelper {
}
for (WptPt p : res.getPoints()) {
FavouritePoint fp = FavouritePoint.fromWpt(p, context);
if (fp != null) {
points.put(getKey(fp), fp);
}
points.put(getKey(fp), fp);
}
return true;
}
@ -959,7 +962,7 @@ public class FavouritesDbHelper {
public void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) {
if (oldVersion == 1) {
db.execSQL("ALTER TABLE " + FAVOURITE_TABLE_NAME + " ADD " + FAVOURITE_COL_CATEGORY + " text");
db.execSQL("UPDATE " + FAVOURITE_TABLE_NAME + " SET category = ?", new Object[]{""}); //$NON-NLS-1$ //$NON-NLS-2$
db.execSQL("UPDATE " + FAVOURITE_TABLE_NAME + " SET category = ?", new Object[] {""}); //$NON-NLS-1$ //$NON-NLS-2$
}
}

View file

@ -112,7 +112,7 @@ import net.osmand.plus.mapcontextmenu.other.DestinationReachedMenu;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenu;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersHelper.MapMarkerChangedListener;
import net.osmand.plus.mapmarkers.PlanRouteFragment;
import net.osmand.plus.mapmarkers.fragments.PlanRouteFragment;
import net.osmand.plus.measurementtool.GpxApproximationFragment;
import net.osmand.plus.measurementtool.GpxData;
import net.osmand.plus.measurementtool.LoginBottomSheetFragment;

View file

@ -46,17 +46,15 @@ import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.Version;
import net.osmand.plus.activities.actions.OsmAndDialogs;
import net.osmand.plus.dashboard.DashboardOnMap.DashboardType;
import net.osmand.plus.dialogs.FavoriteDialogs;
import net.osmand.plus.dialogs.SpeedCamerasBottomSheet;
import net.osmand.plus.download.IndexItem;
import net.osmand.plus.liveupdates.OsmLiveActivity;
import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment;
import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment.ContextMenuItemClickListener;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.fragments.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.MarkersPlanRouteContext;
import net.osmand.plus.measurementtool.MeasurementToolFragment;
@ -107,7 +105,6 @@ import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_HELP_ID;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_MAP_MARKERS_ID;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_MEASURE_DISTANCE_ID;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_MY_PLACES_ID;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_OSMAND_LIVE_ID;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_PLUGINS_ID;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SEARCH_ID;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_SETTINGS_ID;

View file

@ -34,7 +34,7 @@ import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.LockableViewPager;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment;
import net.osmand.plus.mapmarkers.fragments.CoordinateInputDialogFragment;
import net.osmand.plus.measurementtool.GpxData;
import net.osmand.plus.myplaces.FavoritesActivity;
import net.osmand.plus.myplaces.SplitSegmentDialogFragment;

View file

@ -37,10 +37,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class BackupHelper {
@ -49,9 +45,6 @@ public class BackupHelper {
private final FavouritesDbHelper favouritesHelper;
private final GpxDbHelper gpxHelper;
private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(1, 1, 0L,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
private static final String SERVER_URL = "https://osmand.net";
private static final String USER_REGISTER_URL = SERVER_URL + "/userdata/user-register";
@ -66,6 +59,10 @@ public class BackupHelper {
public final static int STATUS_EMPTY_RESPONSE_ERROR = 2;
public final static int STATUS_SERVER_ERROR = 3;
public interface OnResultListener {
void onResult(int status, @Nullable String message, @Nullable JSONObject json);
}
public interface OnRegisterUserListener {
void onRegisterUser(int status, @Nullable String message);
}
@ -80,6 +77,7 @@ public class BackupHelper {
public interface OnCollectLocalFilesListener {
void onFileCollected(@NonNull GpxFileInfo fileInfo);
void onFilesCollected(@NonNull List<GpxFileInfo> fileInfos);
}
@ -89,21 +87,20 @@ public class BackupHelper {
public interface OnUploadFilesListener {
void onFileUploadProgress(@NonNull File file, int progress);
void onFileUploadDone(@NonNull File file);
void onFilesUploadDone(@NonNull Map<File, String> errors);
}
public interface OnDeleteFilesListener {
void onFileDeleteProgress(@NonNull UserFile file);
void onFilesDeleteDone(@NonNull Map<UserFile, String> errors);
}
public interface OnDownloadFileListener {
void onFileDownloadProgress(@NonNull UserFile userFile, int progress);
@WorkerThread
void onFileDownloadedAsync(@NonNull File file);
void onFileDownloaded(@NonNull File file);
void onFilesDownloadDone(@NonNull Map<File, String> errors);
}
@ -171,22 +168,20 @@ public class BackupHelper {
params.put("orderid", orderId);
}
params.put("deviceid", app.getUserAndroidId());
AndroidNetworkUtils.sendRequestAsync(app, USER_REGISTER_URL, params, "Register user", false, true, new OnRequestResultListener() {
AndroidNetworkUtils.sendRequestAsync(app, USER_REGISTER_URL, params, "Register user", true, true, new OnRequestResultListener() {
@Override
public void onResult(@Nullable String resultJson, @Nullable String error) {
public void onResult(String resultJson) {
int status;
String message;
if (!Algorithms.isEmpty(error)) {
message = "User registration error: " + parseServerError(error);
status = STATUS_SERVER_ERROR;
} else if (!Algorithms.isEmpty(resultJson)) {
if (!Algorithms.isEmpty(resultJson)) {
try {
JSONObject result = new JSONObject(resultJson);
if (result.has("status") && "ok".equals(result.getString("status"))) {
String statusStr = result.getString("status");
if (statusStr.equals("ok")) {
message = "You have been registered successfully. Please check for email with activation code.";
status = STATUS_SUCCESS;
} else {
message = "User registration error: unknown";
message = "User registration error: " + statusStr;
status = STATUS_SERVER_ERROR;
}
} catch (JSONException e) {
@ -201,7 +196,7 @@ public class BackupHelper {
listener.onRegisterUser(status, message);
}
}
}, EXECUTOR);
});
}
public void registerDevice(String token, @Nullable final OnRegisterDeviceListener listener) {
@ -216,15 +211,12 @@ public class BackupHelper {
params.put("deviceid", androidId);
}
params.put("token", token);
AndroidNetworkUtils.sendRequestAsync(app, DEVICE_REGISTER_URL, params, "Register device", false, true, new OnRequestResultListener() {
AndroidNetworkUtils.sendRequestAsync(app, DEVICE_REGISTER_URL, params, "Register device", true, true, new OnRequestResultListener() {
@Override
public void onResult(@Nullable String resultJson, @Nullable String error) {
public void onResult(String resultJson) {
int status;
String message;
if (!Algorithms.isEmpty(error)) {
message = "Device registration error: " + parseServerError(error);
status = STATUS_SERVER_ERROR;
} else if (!Algorithms.isEmpty(resultJson)) {
if (!Algorithms.isEmpty(resultJson)) {
try {
JSONObject result = new JSONObject(resultJson);
settings.BACKUP_DEVICE_ID.set(result.getString("id"));
@ -232,9 +224,8 @@ public class BackupHelper {
settings.BACKUP_NATIVE_DEVICE_ID.set(result.getString("deviceid"));
settings.BACKUP_ACCESS_TOKEN.set(result.getString("accesstoken"));
settings.BACKUP_ACCESS_TOKEN_UPDATE_TIME.set(result.getString("udpatetime"));
message = "Device have been registered successfully";
status = STATUS_SUCCESS;
message = "Device have been registered successfully";
} catch (JSONException e) {
message = "Device registration error: json parsing";
status = STATUS_PARSE_JSON_ERROR;
@ -247,7 +238,7 @@ public class BackupHelper {
listener.onRegisterDevice(status, message);
}
}
}, EXECUTOR);
});
}
public void uploadFiles(@NonNull List<GpxFileInfo> gpxFiles, @Nullable final OnUploadFilesListener listener) throws UserNotRegisteredException {
@ -274,6 +265,14 @@ public class BackupHelper {
additionaParams.put("name", gpxFileInfo.getFileName(true));
additionaParams.put("type", Algorithms.getFileExtension(file));
gpxFileInfo.uploadTime = System.currentTimeMillis();
if (file.equals(favoritesFile)) {
favouritesHelper.setLastUploadedTime(gpxFileInfo.uploadTime);
} else {
GpxDataItem gpxItem = gpxHelper.getItem(file);
if (gpxItem != null) {
gpxHelper.updateLastUploadedTime(gpxItem, gpxFileInfo.uploadTime);
}
}
additionaParams.put("clienttime", String.valueOf(gpxFileInfo.uploadTime));
}
return additionaParams;
@ -286,34 +285,16 @@ public class BackupHelper {
}
}
@Override
public void onFileUploadDone(@NonNull File file) {
if (listener != null) {
GpxFileInfo gpxFileInfo = gpxInfos.get(file);
if (gpxFileInfo != null) {
if (file.equals(favoritesFile)) {
favouritesHelper.setLastUploadedTime(gpxFileInfo.uploadTime);
} else {
GpxDataItem gpxItem = gpxHelper.getItem(file);
if (gpxItem != null) {
gpxHelper.updateLastUploadedTime(gpxItem, gpxFileInfo.uploadTime);
}
}
}
listener.onFileUploadDone(file);
}
}
@Override
public void onFilesUploadDone(@NonNull Map<File, String> errors) {
if (errors.isEmpty()) {
settings.BACKUP_LAST_UPLOADED_TIME.set(System.currentTimeMillis() + 1);
}
if (listener != null) {
listener.onFilesUploadDone(resolveServerErrors(errors));
listener.onFilesUploadDone(errors);
}
}
}, EXECUTOR);
});
}
public void deleteFiles(@NonNull List<UserFile> userFiles, @Nullable final OnDeleteFilesListener listener) throws UserNotRegisteredException {
@ -351,36 +332,24 @@ public class BackupHelper {
for (RequestResponse response : results) {
UserFile userFile = filesMap.get(response.getRequest());
if (userFile != null) {
String responseStr = response.getResponse();
boolean success;
String message = null;
String errorStr = response.getError();
if (!Algorithms.isEmpty(errorStr)) {
message = parseServerError(errorStr);
try {
JSONObject json = new JSONObject(responseStr);
String status = json.getString("status");
success = status.equalsIgnoreCase("ok");
} catch (JSONException e) {
success = false;
} else {
String responseStr = response.getResponse();
try {
JSONObject result = new JSONObject(responseStr);
if (result.has("status") && "ok".equals(result.getString("status"))) {
success = true;
} else {
message = "Unknown error";
success = false;
}
} catch (JSONException e) {
message = "Json parsing error";
success = false;
}
}
if (!success) {
errors.put(userFile, message);
errors.put(userFile, responseStr);
}
}
}
listener.onFilesDeleteDone(errors);
}
}
}, EXECUTOR);
});
}
public void downloadFileList(@Nullable final OnDownloadFileListListener listener) throws UserNotRegisteredException {
@ -389,16 +358,13 @@ public class BackupHelper {
Map<String, String> params = new HashMap<>();
params.put("deviceid", getDeviceId());
params.put("accessToken", getAccessToken());
AndroidNetworkUtils.sendRequestAsync(app, LIST_FILES_URL, params, "Download file list", false, false, new OnRequestResultListener() {
AndroidNetworkUtils.sendRequestAsync(app, LIST_FILES_URL, params, "Download file list", true, false, new OnRequestResultListener() {
@Override
public void onResult(@Nullable String resultJson, @Nullable String error) {
public void onResult(String resultJson) {
int status;
String message;
List<UserFile> userFiles = new ArrayList<>();
if (!Algorithms.isEmpty(error)) {
status = STATUS_SERVER_ERROR;
message = "Download file list error: " + parseServerError(error);
} else if (!Algorithms.isEmpty(resultJson)) {
if (!Algorithms.isEmpty(resultJson)) {
try {
JSONObject result = new JSONObject(resultJson);
String totalZipSize = result.getString("totalZipSize");
@ -425,7 +391,7 @@ public class BackupHelper {
listener.onDownloadFileList(status, message, userFiles);
}
}
}, EXECUTOR);
});
}
public void downloadFiles(@NonNull final Map<File, UserFile> filesMap, @Nullable final OnDownloadFileListener listener) throws UserNotRegisteredException {
@ -453,13 +419,6 @@ public class BackupHelper {
}
}
@Override
public void onFileDownloadDone(@NonNull File file) {
if (listener != null) {
listener.onFileDownloaded(file);
}
}
@Override
public void onFileDownloadedAsync(@NonNull File file) {
if (listener != null) {
@ -470,10 +429,10 @@ public class BackupHelper {
@Override
public void onFilesDownloadDone(@NonNull Map<File, String> errors) {
if (listener != null) {
listener.onFilesDownloadDone(resolveServerErrors(errors));
listener.onFilesDownloadDone(errors);
}
}
}, EXECUTOR);
});
}
@SuppressLint("StaticFieldLeak")
@ -555,37 +514,7 @@ public class BackupHelper {
}
}
};
task.executeOnExecutor(EXECUTOR);
}
private Map<File, String> resolveServerErrors(@NonNull Map<File, String> errors) {
Map<File, String> resolvedErrors = new HashMap<>();
for (Entry<File, String> fileError : errors.entrySet()) {
File file = fileError.getKey();
String errorStr = fileError.getValue();
try {
JSONObject errorJson = new JSONObject(errorStr);
JSONObject error = errorJson.getJSONObject("error");
errorStr = "Error " + error.getInt("errorCode") + " (" + error.getString("message") + ")";
} catch (JSONException e) {
// ignore
}
resolvedErrors.put(file, errorStr);
}
return resolvedErrors;
}
private String parseServerError(@NonNull String error) {
try {
JSONObject resultError = new JSONObject(error);
if (resultError.has("error")) {
JSONObject errorObj = resultError.getJSONObject("error");
return errorObj.getInt("errorCode") + " (" + errorObj.getString("message") + ")";
}
} catch (JSONException e) {
// ignore
}
return error;
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@SuppressLint("StaticFieldLeak")
@ -646,6 +575,6 @@ public class BackupHelper {
}
}
};
task.executeOnExecutor(EXECUTOR);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}

View file

@ -11,6 +11,7 @@ import net.osmand.AndroidUtils;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GpxDbHelper;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.ProgressImplementation;
import net.osmand.plus.backup.BackupHelper.BackupInfo;
@ -112,7 +113,7 @@ public class BackupTask {
tasks.push(backupTasks[i]);
}
this.runningTasks = tasks;
onBackupTasksInit();
onTasksInit();
}
private void initRestoreTasks() {
@ -122,7 +123,7 @@ public class BackupTask {
tasks.push(restoreTasks[i]);
}
this.runningTasks = tasks;
onRestoreTasksInit();
onTasksInit();
}
private void initData() {
@ -179,11 +180,6 @@ public class BackupTask {
}
}
@Override
public void onFileUploadDone(@NonNull File file) {
onTaskProgressDone();
}
@Override
public void onFilesUploadDone(@NonNull Map<File, String> errors) {
uploadErrors = errors;
@ -228,11 +224,6 @@ public class BackupTask {
}
}
@Override
public void onFileDownloaded(@NonNull File file) {
onTaskProgressDone();
}
@Override
public void onFileDownloadedAsync(@NonNull File file) {
UserFile userFile = filesMap.get(file);
@ -284,22 +275,14 @@ public class BackupTask {
}
}
private void onBackupTasksInit() {
private void onTasksInit() {
Context ctx = contextRef.get();
if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx)) {
if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx) && progress != null) {
progress = ProgressImplementation.createProgressDialog(ctx,
"Backup data", "Initializing...", ProgressDialog.STYLE_HORIZONTAL);
}
}
private void onRestoreTasksInit() {
Context ctx = contextRef.get();
if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx)) {
progress = ProgressImplementation.createProgressDialog(ctx,
"Restore data", "Initializing...", ProgressDialog.STYLE_HORIZONTAL);
}
}
private void onTaskProgressUpdate(Object... objects) {
Context ctx = contextRef.get();
if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx) && progress != null) {
@ -309,7 +292,7 @@ public class BackupTask {
progress.startTask((String) objects[0], -1);
} else if (objects[0] instanceof Integer) {
int progressValue = (Integer) objects[0];
if (progressValue >= 0) {
if (progressValue < Integer.MAX_VALUE) {
progress.progress(progressValue);
} else {
progress.finishTask();
@ -322,13 +305,6 @@ public class BackupTask {
}
}
private void onTaskProgressDone() {
Context ctx = contextRef.get();
if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx) && progress != null) {
progress.finishTask();
}
}
private void onError(@NonNull String message) {
this.error = message;
runningTasks.clear();

View file

@ -137,7 +137,6 @@ public class TestBackupActivity extends OsmandActionBarActivity {
a.buttonVerify.setVisibility(View.VISIBLE);
a.buttonVerify.setEnabled(status == BackupHelper.STATUS_SUCCESS);
a.tokenEditText.requestFocus();
a.infoView.setText(message);
}
}
});
@ -163,11 +162,10 @@ public class TestBackupActivity extends OsmandActionBarActivity {
a.progressBar.setVisibility(View.GONE);
a.buttonVerify.setEnabled(status != BackupHelper.STATUS_SUCCESS);
if (status == BackupHelper.STATUS_SUCCESS) {
a.tokenEdit.setVisibility(View.GONE);
a.buttonVerify.setVisibility(View.GONE);
a.prepareBackup();
tokenEdit.setVisibility(View.GONE);
buttonVerify.setVisibility(View.GONE);
}
a.infoView.setText(message);
a.prepareBackup();
}
}
});
@ -188,41 +186,6 @@ public class TestBackupActivity extends OsmandActionBarActivity {
@Override
public void onClick(View v) {
if (backupInfo != null) {
buttonBackup.setEnabled(false);
BackupTask task = new BackupTask(backupInfo, TestBackupActivity.this, new OnBackupListener() {
@Override
public void onBackupDone(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors,
@Nullable Map<UserFile, String> deleteErrors, @Nullable String error) {
TestBackupActivity a = activityRef.get();
if (AndroidUtils.isActivityNotDestroyed(a)) {
String description;
if (error != null) {
description = error;
} else if (uploadErrors == null && deleteErrors == null) {
description = "No data";
} else {
description = getBackupErrorsDescription(uploadErrors, downloadErrors, deleteErrors, error);
}
a.infoView.setText(description);
a.infoView.requestFocus();
a.buttonBackup.setEnabled(true);
if (Algorithms.isEmpty(description)) {
a.prepareBackup();
} else {
a.backupInfo = null;
}
}
}
});
task.runBackup();
}
}
});
buttonRestore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (backupInfo != null) {
buttonRestore.setEnabled(false);
BackupTask task = new BackupTask(backupInfo, TestBackupActivity.this, new OnBackupListener() {
@Override
public void onBackupDone(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors,
@ -239,12 +202,35 @@ public class TestBackupActivity extends OsmandActionBarActivity {
}
a.infoView.setText(description);
a.infoView.requestFocus();
a.buttonRestore.setEnabled(true);
if (Algorithms.isEmpty(description)) {
a.prepareBackup();
a.prepareBackup();
}
}
});
task.runBackup();
}
}
});
buttonRestore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (backupInfo != null) {
BackupTask task = new BackupTask(backupInfo, TestBackupActivity.this, new OnBackupListener() {
@Override
public void onBackupDone(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors,
@Nullable Map<UserFile, String> deleteErrors, @Nullable String error) {
TestBackupActivity a = activityRef.get();
if (AndroidUtils.isActivityNotDestroyed(a)) {
String description;
if (error != null) {
description = error;
} else if (uploadErrors == null && downloadErrors == null) {
description = "No data";
} else {
a.backupInfo = null;
description = getBackupErrorsDescription(uploadErrors, downloadErrors, deleteErrors, error);
}
a.infoView.setText(description);
a.infoView.requestFocus();
a.prepareBackup();
}
}
});
@ -259,21 +245,21 @@ public class TestBackupActivity extends OsmandActionBarActivity {
private String getBackupErrorsDescription(@Nullable Map<File, String> uploadErrors, @Nullable Map<File, String> downloadErrors, @Nullable Map<UserFile, String> deleteErrors, @Nullable String error) {
StringBuilder sb = new StringBuilder();
if (!Algorithms.isEmpty(uploadErrors)) {
sb.append("--- Upload errors ---").append("\n\n");
sb.append("--- Upload errors ---").append("\n");
for (Entry<File, String> uploadEntry : uploadErrors.entrySet()) {
sb.append(uploadEntry.getKey().getName()).append(": ").append(uploadEntry.getValue()).append("\n\n");
sb.append(uploadEntry.getKey().getName()).append(": ").append(uploadEntry.getValue()).append("\n");
}
}
if (!Algorithms.isEmpty(downloadErrors)) {
sb.append("--- Download errors ---").append("\n\n");
sb.append("--- Download errors ---").append("\n");
for (Entry<File, String> downloadEntry : downloadErrors.entrySet()) {
sb.append(downloadEntry.getKey().getName()).append(": ").append(downloadEntry.getValue()).append("\n\n");
sb.append(downloadEntry.getKey().getName()).append(": ").append(downloadEntry.getValue()).append("\n");
}
}
if (!Algorithms.isEmpty(deleteErrors)) {
sb.append("--- Delete errors ---").append("\n\n");
sb.append("--- Delete errors ---").append("\n");
for (Entry<UserFile, String> deleteEntry : deleteErrors.entrySet()) {
sb.append(deleteEntry.getKey().getName()).append(": ").append(deleteEntry.getValue()).append("\n\n");
sb.append(deleteEntry.getKey().getName()).append(": ").append(deleteEntry.getValue()).append("\n");
}
}
return sb.length() == 0 ? "OK" : sb.toString();
@ -282,32 +268,32 @@ public class TestBackupActivity extends OsmandActionBarActivity {
private String getBackupDescription(@NonNull BackupInfo backupInfo) {
StringBuilder sb = new StringBuilder();
if (!Algorithms.isEmpty(backupInfo.filesToUpload)) {
sb.append("\n").append("--- Upload ---").append("\n\n");
sb.append("\n").append("--- Upload ---").append("\n");
for (GpxFileInfo info : backupInfo.filesToUpload) {
sb.append(info.getFileName(true))
.append(" L: ").append(DF.format(new Date(info.getFileDate())))
.append(" U: ").append(DF.format(new Date(info.uploadTime)))
.append("\n\n");
.append("\n");
}
}
if (!Algorithms.isEmpty(backupInfo.filesToDownload)) {
sb.append("\n").append("--- Download ---").append("\n\n");
sb.append("\n").append("--- Download ---").append("\n");
for (UserFile userFile : backupInfo.filesToDownload) {
sb.append(userFile.getName())
.append(" R: ").append(DF.format(new Date(userFile.getClienttimems())))
.append("\n\n");
.append("\n");
}
}
if (!Algorithms.isEmpty(backupInfo.filesToDelete)) {
sb.append("\n").append("--- Delete ---").append("\n\n");
sb.append("\n").append("--- Delete ---").append("\n");
for (UserFile userFile : backupInfo.filesToDelete) {
sb.append(userFile.getName())
.append(" R: ").append(DF.format(new Date(userFile.getClienttimems())))
.append("\n\n");
.append("\n");
}
}
if (!Algorithms.isEmpty(backupInfo.filesToMerge)) {
sb.append("\n").append("--- Conflicts ---").append("\n\n");
sb.append("\n").append("--- Conflicts ---").append("\n");
for (Pair<GpxFileInfo, UserFile> localRemote : backupInfo.filesToMerge) {
GpxFileInfo local = localRemote.first;
UserFile remote = localRemote.second;
@ -315,7 +301,7 @@ public class TestBackupActivity extends OsmandActionBarActivity {
.append(" L: ").append(DF.format(new Date(local.getFileDate())))
.append(" U: ").append(DF.format(new Date(local.uploadTime)))
.append(" R: ").append(DF.format(new Date(remote.getClienttimems())))
.append("\n\n");
.append("\n");
}
}
return sb.toString();
@ -323,7 +309,6 @@ public class TestBackupActivity extends OsmandActionBarActivity {
private void prepareBackup() {
final WeakReference<TestBackupActivity> activityRef = new WeakReference<>(this);
buttonRefresh.setEnabled(false);
PrepareBackupTask prepareBackupTask = new PrepareBackupTask(this, new OnPrepareBackupListener() {
@Override
public void onBackupPrepared(@Nullable BackupInfo backupInfo, @Nullable String error) {
@ -344,7 +329,6 @@ public class TestBackupActivity extends OsmandActionBarActivity {
}
a.infoView.setText(description);
a.infoView.requestFocus();
a.buttonRefresh.setEnabled(true);
}
}
});

View file

@ -2125,12 +2125,9 @@ public class GpxUiHelper {
public static GPXFile makeGpxFromRoute(RouteCalculationResult route, OsmandApplication app) {
return makeGpxFromLocations(route.getRouteLocations(), app);
}
public static GPXFile makeGpxFromLocations(List<Location> locations, OsmandApplication app) {
double lastHeight = HEIGHT_UNDEFINED;
GPXFile gpx = new GPXUtilities.GPXFile(Version.getFullVersion(app));
List<Location> locations = route.getRouteLocations();
if (locations != null) {
GPXUtilities.Track track = new GPXUtilities.Track();
GPXUtilities.TrkSegment seg = new GPXUtilities.TrkSegment();
@ -2150,8 +2147,6 @@ public class GpxUiHelper {
}
}
lastHeight = h;
} else {
lastHeight = HEIGHT_UNDEFINED;
}
seg.points.add(point);
}

View file

@ -18,7 +18,7 @@ import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.PluginsFragment;
import net.osmand.plus.dashboard.DashboardOnMap.DashboardType;
import net.osmand.plus.mapmarkers.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.fragments.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapsource.EditMapSourceDialogFragment;
import net.osmand.plus.openplacereviews.OPRConstants;

View file

@ -8,9 +8,6 @@ import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
import net.osmand.AndroidNetworkUtils.OnSendRequestsListener;
@ -44,6 +41,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public abstract class InAppPurchaseHelper {
// Debug tag, for logging
protected static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(InAppPurchaseHelper.class);
@ -466,7 +466,7 @@ public abstract class InAppPurchaseHelper {
protected void onSkuDetailsResponseDone(List<PurchaseInfo> purchaseInfoList) {
final AndroidNetworkUtils.OnRequestResultListener listener = new AndroidNetworkUtils.OnRequestResultListener() {
@Override
public void onResult(@Nullable String result, @Nullable String error) {
public void onResult(String result) {
notifyDismissProgress(InAppPurchaseTaskType.REQUEST_INVENTORY);
notifyGetItems();
stop(true);
@ -477,7 +477,7 @@ public abstract class InAppPurchaseHelper {
if (purchaseInfoList.size() > 0) {
sendTokens(purchaseInfoList, listener);
} else {
listener.onResult("OK", null);
listener.onResult("OK");
}
}
@ -503,7 +503,7 @@ public abstract class InAppPurchaseHelper {
liveUpdatesPurchase.setState(ctx, SubscriptionState.UNDEFINED);
sendTokens(Collections.singletonList(info), new OnRequestResultListener() {
@Override
public void onResult(@Nullable String result, @Nullable String error) {
public void onResult(String result) {
boolean active = ctx.getSettings().LIVE_UPDATES_PURCHASED.get();
ctx.getSettings().LIVE_UPDATES_PURCHASED.set(true);
ctx.getSettings().getCustomRenderBooleanProperty("depthContours").set(true);
@ -642,7 +642,7 @@ public abstract class InAppPurchaseHelper {
}
}
if (listener != null) {
listener.onResult("OK", null);
listener.onResult("OK");
}
}
@ -695,7 +695,7 @@ public abstract class InAppPurchaseHelper {
} catch (Exception e) {
logError("SendToken Error", e);
if (listener != null) {
listener.onResult("Error", null);
listener.onResult("Error");
}
}
}

View file

@ -6,7 +6,6 @@ import android.content.Context;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidNetworkUtils.OnRequestResultListener;
@ -195,7 +194,7 @@ public class PerformLiveUpdateAsyncTask
AndroidNetworkUtils.sendRequestAsync(
app, LiveUpdatesFragment.URL, null, "Requesting map updates info...", false, false, new OnRequestResultListener() {
@Override
public void onResult(@Nullable String result, @Nullable String error) {
public void onResult(String result) {
if (!Algorithms.isEmpty(result)) {
SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
source.setTimeZone(TimeZone.getTimeZone("UTC"));

View file

@ -208,7 +208,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In
"https://osmand.net/subscription/update",
parameters, "Sending data...", true, true, new AndroidNetworkUtils.OnRequestResultListener() {
@Override
public void onResult(@Nullable String result, @Nullable String error) {
public void onResult(String result) {
dismissProgress(null);
OsmandApplication app = getMyApplication();
if (result != null) {

View file

@ -1,4 +0,0 @@
package net.osmand.plus.mapmarkers;
import androidx.annotation.DrawableRes;

View file

@ -0,0 +1,266 @@
package net.osmand.plus.mapmarkers;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import net.osmand.FileUtils;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXExtensionsWriter;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.Version;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import org.xmlpull.v1.XmlSerializer;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import static net.osmand.GPXUtilities.writeNotNullText;
import static net.osmand.plus.FavouritesDbHelper.backup;
import static net.osmand.util.MapUtils.createShortLinkString;
public class ItineraryDataHelper {
private static final Log log = PlatformUtil.getLog(ItineraryDataHelper.class);
private static final String VISITED_DATE = "visited_date";
private static final String CREATION_DATE = "creation_date";
private static final String CATEGORIES_SPLIT = ",";
private static final String FILE_TO_SAVE = "itinerary.gpx";
private static final String FILE_TO_BACKUP = "itinerary_bak.gpx";
private static final String ITINERARY_ID = "itinerary_id";
private static final String ITINERARY_GROUP = "itinerary_group";
private static final String GPX_KEY = "gpx";
private static final String FAVOURITES_KEY = "favourites_group";
private static final SimpleDateFormat GPX_TIME_FORMAT = new SimpleDateFormat(GPXUtilities.GPX_TIME_FORMAT, Locale.US);
static {
GPX_TIME_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
}
private OsmandApplication app;
private MapMarkersHelper mapMarkersHelper;
public ItineraryDataHelper(OsmandApplication app, MapMarkersHelper mapMarkersHelper) {
this.app = app;
this.mapMarkersHelper = mapMarkersHelper;
}
private File getInternalFile() {
return app.getFileStreamPath(FILE_TO_BACKUP);
}
public File getExternalFile() {
return new File(app.getAppPath(null), FILE_TO_SAVE);
}
public File getBackupFile() {
return FavouritesDbHelper.getBackupFile(app, "itinerary_bak_");
}
public void saveGroups() {
try {
saveFile(getInternalFile());
saveFile(getExternalFile());
backup(getBackupFile(), getExternalFile());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
public Exception saveFile(File file) {
List<MapMarkersGroup> groups = mapMarkersHelper.getMapMarkersGroups();
GPXFile gpxFile = generateGpx(groups);
return GPXUtilities.writeGpxFile(file, gpxFile);
}
private void assignRouteExtensionWriter(GPXFile gpxFile, final List<ItineraryGroupInfo> groups) {
if (gpxFile.getExtensionsWriter() == null) {
gpxFile.setExtensionsWriter(new GPXExtensionsWriter() {
@Override
public void writeExtensions(XmlSerializer serializer) {
for (ItineraryGroupInfo group : groups) {
try {
serializer.startTag(null, "osmand:" + ITINERARY_GROUP);
writeNotNullText(serializer, "osmand:name", group.name);
writeNotNullText(serializer, "osmand:type", group.type);
writeNotNullText(serializer, "osmand:path", group.path);
writeNotNullText(serializer, "osmand:alias", group.alias);
writeNotNullText(serializer, "osmand:categories", group.categories);
serializer.endTag(null, "osmand:" + ITINERARY_GROUP);
} catch (IOException e) {
log.error(e);
}
}
}
});
}
}
public String saveMarkersToFile(String fileName) {
GPXFile gpxFile = generateGpx();
String dirName = IndexConstants.GPX_INDEX_DIR + IndexConstants.MAP_MARKERS_INDEX_DIR;
File dir = app.getAppPath(dirName);
if (!dir.exists()) {
dir.mkdirs();
}
String uniqueFileName = FileUtils.createUniqueFileName(app, fileName, dirName, IndexConstants.GPX_FILE_EXT);
File fout = new File(dir, uniqueFileName + IndexConstants.GPX_FILE_EXT);
GPXUtilities.writeGpxFile(fout, gpxFile);
return fout.getAbsolutePath();
}
public GPXFile generateGpx() {
return generateGpx(mapMarkersHelper.getMapMarkers(), false);
}
public GPXFile generateGpx(List<MapMarker> markers, boolean completeBackup) {
GPXFile gpxFile = new GPXFile(Version.getFullVersion(app));
for (MapMarker marker : markers) {
WptPt wpt = toWpt(marker);
wpt.setColor(ContextCompat.getColor(app, MapMarker.getColorId(marker.colorIndex)));
if (completeBackup) {
if (marker.creationDate != 0) {
wpt.getExtensionsToWrite().put(CREATION_DATE, GPX_TIME_FORMAT.format(new Date(marker.creationDate)));
}
if (marker.visitedDate != 0) {
wpt.getExtensionsToWrite().put(VISITED_DATE, GPX_TIME_FORMAT.format(new Date(marker.visitedDate)));
}
}
gpxFile.addPoint(wpt);
}
return gpxFile;
}
public GPXFile generateGpx(List<MapMarkersGroup> mapMarkersGroups) {
GPXFile gpxFile = new GPXFile(Version.getFullVersion(app));
List<ItineraryGroupInfo> groups = new ArrayList<>();
for (MapMarkersGroup group : mapMarkersGroups) {
ItineraryGroupInfo groupInfo = ItineraryGroupInfo.createGroupInfo(app, group);
for (MapMarker marker : group.getMarkers()) {
WptPt wptPt = toWpt(marker);
Map<String, String> extensions = wptPt.getExtensionsToWrite();
if (group.getType() != ItineraryType.FAVOURITES) {
String itineraryId = createShortLinkString(wptPt.lat, wptPt.lon, 15);
extensions.put(ITINERARY_ID, groupInfo.alias + ":" + itineraryId);
} else {
extensions.put(ITINERARY_ID, groupInfo.alias + ":" + marker.getName(app));
}
if (group.getType() == ItineraryType.TRACK) {
extensions.put(GPX_KEY, groupInfo.path);
} else if (group.getType() == ItineraryType.FAVOURITES && !Algorithms.isEmpty(groupInfo.name)) {
extensions.put(FAVOURITES_KEY, groupInfo.name);
}
gpxFile.addPoint(wptPt);
}
groups.add(groupInfo);
}
assignRouteExtensionWriter(gpxFile, groups);
return gpxFile;
}
public List<MapMarker> readMarkersFromGpx(GPXFile gpxFile, boolean history) {
List<MapMarker> mapMarkers = new ArrayList<>();
for (WptPt point : gpxFile.getPoints()) {
MapMarker marker = fromWpt(point, app, history);
mapMarkers.add(marker);
}
return mapMarkers;
}
public static MapMarker fromWpt(@NonNull WptPt point, @NonNull Context ctx, boolean history) {
LatLon latLon = new LatLon(point.lat, point.lon);
int colorIndex = MapMarker.getColorIndex(ctx, point.getColor());
PointDescription name = new PointDescription(PointDescription.POINT_TYPE_LOCATION, point.name);
MapMarker marker = new MapMarker(latLon, name, colorIndex, false, 0);
String visitedDateStr = point.getExtensionsToRead().get(VISITED_DATE);
String creationDateStr = point.getExtensionsToRead().get(CREATION_DATE);
marker.visitedDate = parseTime(visitedDateStr);
marker.creationDate = parseTime(creationDateStr);
marker.history = history;
marker.nextKey = history ? MapMarkersDbHelper.HISTORY_NEXT_VALUE : MapMarkersDbHelper.TAIL_NEXT_VALUE;
return marker;
}
public static WptPt toWpt(@NonNull MapMarker marker) {
WptPt wpt = new WptPt();
wpt.lat = marker.getLatitude();
wpt.lon = marker.getLongitude();
wpt.name = marker.getOnlyName();
return wpt;
}
private static long parseTime(String text) {
long time = 0;
if (text != null) {
try {
time = GPX_TIME_FORMAT.parse(text).getTime();
} catch (ParseException e) {
log.error(e);
}
}
return time;
}
public static class ItineraryGroupInfo {
public String name;
public String type;
public String path;
public String alias;
public String categories;
public static ItineraryGroupInfo createGroupInfo(OsmandApplication app, MapMarkersGroup group) {
ItineraryGroupInfo groupInfo = new ItineraryGroupInfo();
groupInfo.name = group.getName();
groupInfo.type = group.getType().getTypeName();
Set<String> wptCategories = group.getWptCategories();
if (!Algorithms.isEmpty(wptCategories)) {
groupInfo.categories = Algorithms.encodeStringSet(wptCategories, CATEGORIES_SPLIT);
}
if (group.getType() == ItineraryType.TRACK) {
String path = group.getId();
String gpxDir = app.getAppPath(IndexConstants.GPX_INDEX_DIR).getAbsolutePath();
int index = path.indexOf(gpxDir);
if (index != -1) {
path = path.substring(gpxDir.length() + 1);
}
groupInfo.path = path;
groupInfo.alias = groupInfo.type + ":" + path.replace(IndexConstants.GPX_FILE_EXT, "");
} else {
groupInfo.alias = groupInfo.type + (groupInfo.name == null ? "" : ":" + groupInfo.name);
}
return groupInfo;
}
}
}

View file

@ -0,0 +1,43 @@
package net.osmand.plus.mapmarkers;
import androidx.annotation.NonNull;
public enum ItineraryType {
MARKERS("markers", -1),
FAVOURITES("favourites", 0),
TRACK("track", 1);
private int typeId;
private String typeName;
ItineraryType(@NonNull String typeName, int typeId) {
this.typeName = typeName;
this.typeId = typeId;
}
public int getTypeId() {
return typeId;
}
public String getTypeName() {
return typeName;
}
public static ItineraryType findTypeForId(int typeId) {
for (ItineraryType type : values()) {
if (type.getTypeId() == typeId) {
return type;
}
}
return ItineraryType.MARKERS;
}
public static ItineraryType findTypeForName(String typeName) {
for (ItineraryType type : values()) {
if (type.getTypeName().equalsIgnoreCase(typeName)) {
return type;
}
}
return ItineraryType.MARKERS;
}
}

View file

@ -44,10 +44,10 @@ public class MapMarker implements LocationPoint {
this.index = index;
}
public int getType() {
public ItineraryType getType() {
return favouritePoint == null ?
(wptPt == null ? MapMarkersGroup.ANY_TYPE : MapMarkersGroup.GPX_TYPE) :
MapMarkersGroup.FAVORITES_TYPE;
(wptPt == null ? ItineraryType.MARKERS : ItineraryType.TRACK) :
ItineraryType.FAVOURITES;
}
public PointDescription getPointDescription(Context ctx) {

View file

@ -8,7 +8,6 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.HashSet;
@ -21,22 +20,22 @@ import java.util.Set;
public class MapMarkersDbHelper {
private static final int DB_VERSION = 13;
static final int DB_VERSION = 13;
public static final String DB_NAME = "map_markers_db";
private static final String MARKERS_TABLE_NAME = "map_markers";
protected static final String MARKERS_TABLE_NAME = "map_markers";
private static final String MARKERS_COL_ID = "marker_id";
private static final String MARKERS_COL_LAT = "marker_lat";
private static final String MARKERS_COL_LON = "marker_lon";
private static final String MARKERS_COL_DESCRIPTION = "marker_description";
private static final String MARKERS_COL_ACTIVE = "marker_active";
protected static final String MARKERS_COL_ACTIVE = "marker_active";
private static final String MARKERS_COL_ADDED = "marker_added";
private static final String MARKERS_COL_VISITED = "marker_visited";
private static final String MARKERS_COL_GROUP_NAME = "group_name";
private static final String MARKERS_COL_GROUP_KEY = "group_key";
protected static final String MARKERS_COL_GROUP_KEY = "group_key";
private static final String MARKERS_COL_COLOR = "marker_color";
private static final String MARKERS_COL_NEXT_KEY = "marker_next_key";
private static final String MARKERS_COL_DISABLED = "marker_disabled";
protected static final String MARKERS_COL_DISABLED = "marker_disabled";
private static final String MARKERS_COL_SELECTED = "marker_selected";
private static final String MARKERS_COL_MAP_OBJECT_NAME = "marker_map_object_name";
@ -74,54 +73,40 @@ public class MapMarkersDbHelper {
MARKERS_COL_MAP_OBJECT_NAME +
" FROM " + MARKERS_TABLE_NAME;
private static final String GROUPS_TABLE_NAME = "map_markers_groups";
private static final String GROUPS_COL_ID = "group_id";
private static final String GROUPS_COL_NAME = "group_name";
private static final String GROUPS_COL_TYPE = "group_type";
private static final String GROUPS_COL_DISABLED = "group_disabled";
private static final String GROUPS_COL_CATEGORIES = "group_categories";
private static final String GROUPS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
GROUPS_TABLE_NAME + " (" +
GROUPS_COL_ID + " TEXT PRIMARY KEY, " +
GROUPS_COL_NAME + " TEXT, " +
GROUPS_COL_TYPE + " int, " +
GROUPS_COL_DISABLED + " int, " + // 1 = true, 0 = false
GROUPS_COL_CATEGORIES + " TEXT);";
private static final String GROUPS_TABLE_SELECT = "SELECT " +
GROUPS_COL_ID + ", " +
GROUPS_COL_NAME + ", " +
GROUPS_COL_TYPE + ", " +
GROUPS_COL_DISABLED + ", " +
GROUPS_COL_CATEGORIES +
" FROM " + GROUPS_TABLE_NAME;
public static final String TAIL_NEXT_VALUE = "tail_next";
public static final String HISTORY_NEXT_VALUE = "history_next";
private final OsmandApplication context;
private final OsmandApplication app;
private final MarkersDbHelperLegacy helperLegacy;
public MapMarkersDbHelper(OsmandApplication context) {
this.context = context;
public MapMarkersDbHelper(OsmandApplication app) {
this.app = app;
this.helperLegacy = new MarkersDbHelperLegacy(app, this);
}
private SQLiteConnection openConnection(boolean readonly) {
SQLiteConnection conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
public MarkersDbHelperLegacy getHelperLegacy() {
return helperLegacy;
}
protected SQLiteConnection openConnection(boolean readonly) {
SQLiteConnection conn = app.getSQLiteAPI().getOrCreateDatabase(DB_NAME, readonly);
if (conn == null) {
return null;
}
if (conn.getVersion() < DB_VERSION) {
if (readonly) {
conn.close();
conn = context.getSQLiteAPI().getOrCreateDatabase(DB_NAME, false);
conn = app.getSQLiteAPI().getOrCreateDatabase(DB_NAME, false);
}
int version = conn.getVersion();
conn.setVersion(DB_VERSION);
if (version == 0) {
onCreate(conn);
} else {
onUpgrade(conn, version, DB_VERSION);
if (conn != null) {
int version = conn.getVersion();
conn.setVersion(DB_VERSION);
if (version == 0) {
onCreate(conn);
} else {
onUpgrade(conn, version, DB_VERSION);
}
}
}
return conn;
@ -129,18 +114,15 @@ public class MapMarkersDbHelper {
private void onCreate(SQLiteConnection db) {
db.execSQL(MARKERS_TABLE_CREATE);
db.execSQL(GROUPS_TABLE_CREATE);
helperLegacy.onCreate(db);
}
private void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) {
helperLegacy.onUpgrade(db, oldVersion, newVersion);
if (oldVersion < 8) {
db.execSQL("ALTER TABLE " + MARKERS_TABLE_NAME + " ADD " + MARKERS_COL_DISABLED + " int");
db.execSQL("ALTER TABLE " + GROUPS_TABLE_NAME + " ADD " + GROUPS_COL_DISABLED + " int");
}
if (oldVersion < 9) {
db.execSQL("UPDATE " + GROUPS_TABLE_NAME +
" SET " + GROUPS_COL_DISABLED + " = ? " +
"WHERE " + GROUPS_COL_DISABLED + " IS NULL", new Object[]{0});
db.execSQL("UPDATE " + MARKERS_TABLE_NAME +
" SET " + MARKERS_COL_DISABLED + " = ? " +
"WHERE " + MARKERS_COL_DISABLED + " IS NULL", new Object[]{0});
@ -156,68 +138,6 @@ public class MapMarkersDbHelper {
if (oldVersion < 12) {
db.execSQL("ALTER TABLE " + MARKERS_TABLE_NAME + " ADD " + MARKERS_COL_MAP_OBJECT_NAME + " TEXT");
}
if (oldVersion < 13) {
db.execSQL("ALTER TABLE " + GROUPS_TABLE_NAME + " ADD " + GROUPS_COL_CATEGORIES + " TEXT");
}
}
public void addGroup(MapMarkersGroup group) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("INSERT INTO " + GROUPS_TABLE_NAME + " VALUES (?, ?, ?, ?, ?)",
new Object[]{group.getId(), group.getName(), group.getType(), group.isDisabled(), group.getWptCategoriesString()});
} finally {
db.close();
}
}
}
public Map<String, MapMarkersGroup> getAllGroupsMap() {
Map<String, MapMarkersGroup> res = new LinkedHashMap<>();
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(GROUPS_TABLE_SELECT, null);
if (query != null && query.moveToFirst()) {
do {
MapMarkersGroup group = readGroup(query);
res.put(group.getId(), group);
} while (query.moveToNext());
}
if(query != null) {
query.close();
}
} finally {
db.close();
}
}
return res;
}
private MapMarkersGroup readGroup(SQLiteCursor query) {
String id = query.getString(0);
String name = query.getString(1);
int type = query.getInt(2);
boolean disabled = query.getInt(3) == 1;
String categories = query.getString(4);
MapMarkersGroup res = new MapMarkersGroup(id, name, type);
res.setDisabled(disabled);
res.setWptCategories(categories == null ? null : Algorithms.decodeStringSet(categories));
return res;
}
public void removeMarkersGroup(String id) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("DELETE FROM " + GROUPS_TABLE_NAME + " WHERE " + GROUPS_COL_ID + " = ?", new Object[]{id});
} finally {
db.close();
}
}
}
public void removeActiveMarkersFromGroup(String groupId) {
@ -227,49 +147,7 @@ public class MapMarkersDbHelper {
db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME +
" WHERE " + MARKERS_COL_GROUP_KEY + " = ?" +
" AND " + MARKERS_COL_ACTIVE + " = ?",
new Object[]{groupId, 1});
} finally {
db.close();
}
}
}
public void updateGroupDisabled(String id, boolean disabled) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("UPDATE " + GROUPS_TABLE_NAME +
" SET " + GROUPS_COL_DISABLED + " = ? " +
"WHERE " + GROUPS_COL_ID + " = ?", new Object[]{disabled ? 1 : 0, id});
db.execSQL("UPDATE " + MARKERS_TABLE_NAME +
" SET " + MARKERS_COL_DISABLED + " = ? " +
"WHERE " + MARKERS_COL_GROUP_KEY + " = ?", new Object[]{disabled ? 1 : 0, id});
} finally {
db.close();
}
}
}
public void updateGroupCategories(String id, String categories) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("UPDATE " + GROUPS_TABLE_NAME +
" SET " + GROUPS_COL_CATEGORIES + " = ? " +
"WHERE " + GROUPS_COL_ID + " = ?", new Object[]{categories, id});
} finally {
db.close();
}
}
}
public void removeDisabledGroups() {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("DELETE FROM " + GROUPS_TABLE_NAME + " WHERE " + GROUPS_COL_DISABLED + " = ? ", new Object[]{1});
db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME
+ " WHERE " + MARKERS_COL_DISABLED + " = ? AND " + MARKERS_COL_ACTIVE + " = ?", new Object[]{1, 1});
new Object[] {groupId, 1});
} finally {
db.close();
}
@ -281,7 +159,9 @@ public class MapMarkersDbHelper {
if (db != null) {
try {
for (MapMarker marker : markers) {
insertLast(db, marker);
if (marker.groupKey == null) {
insertLast(db, marker);
}
}
} finally {
db.close();
@ -310,8 +190,8 @@ public class MapMarkersDbHelper {
int active = marker.history ? 0 : 1;
PointDescription pointDescription = marker.getOriginalPointDescription();
if (pointDescription != null && !pointDescription.isSearchingAddress(context)) {
SearchHistoryHelper.getInstance(context)
if (pointDescription != null && !pointDescription.isSearchingAddress(app)) {
SearchHistoryHelper.getInstance(app)
.addNewItemToHistory(marker.getLatitude(), marker.getLongitude(), pointDescription);
}
@ -343,13 +223,18 @@ public class MapMarkersDbHelper {
@Nullable
public MapMarker getMarker(String id) {
return getMarker(id, false);
}
@Nullable
public MapMarker getMarker(String id, boolean legacy) {
MapMarker res = null;
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(MARKERS_TABLE_SELECT + " WHERE " + MARKERS_COL_ID + " = ?", new String[]{id});
if (query != null && query.moveToFirst()) {
res = readItem(query);
res = readItem(query, legacy);
}
if(query != null) {
query.close();
@ -362,6 +247,10 @@ public class MapMarkersDbHelper {
}
public List<MapMarker> getActiveMarkers() {
return getActiveMarkers(false);
}
public List<MapMarker> getActiveMarkers(boolean legacy) {
Map<String, MapMarker> markers = new LinkedHashMap<>();
Set<String> nextKeys = new HashSet<>();
SQLiteConnection db = openConnection(true);
@ -371,9 +260,11 @@ public class MapMarkersDbHelper {
new String[]{String.valueOf(1)});
if (query != null && query.moveToFirst()) {
do {
MapMarker marker = readItem(query);
markers.put(marker.id, marker);
nextKeys.add(marker.nextKey);
MapMarker marker = readItem(query, legacy);
if (marker != null) {
markers.put(marker.id, marker);
nextKeys.add(marker.nextKey);
}
} while (query.moveToNext());
}
if(query != null) {
@ -386,7 +277,13 @@ public class MapMarkersDbHelper {
return buildLinkedList(markers, nextKeys);
}
private MapMarker readItem(SQLiteCursor query) {
@Nullable
private MapMarker readItem(SQLiteCursor query, boolean legacy) {
String groupKey = query.getString(8);
if (groupKey != null && !legacy) {
return null;
}
String id = query.getString(0);
double lat = query.getDouble(1);
double lon = query.getDouble(2);
@ -395,7 +292,6 @@ public class MapMarkersDbHelper {
long added = query.getLong(5);
long visited = query.getLong(6);
String groupName = query.getString(7);
String groupKey = query.getString(8);
int colorIndex = query.getInt(9);
String nextKey = query.getString(10);
boolean selected = query.getInt(12) == 1;
@ -524,6 +420,10 @@ public class MapMarkersDbHelper {
}
public List<MapMarker> getMarkersHistory() {
return getMarkersHistory(false);
}
public List<MapMarker> getMarkersHistory(boolean legacy) {
List<MapMarker> markers = new ArrayList<>();
SQLiteConnection db = openConnection(true);
if (db != null) {
@ -532,7 +432,10 @@ public class MapMarkersDbHelper {
new String[]{String.valueOf(0)});
if (query != null && query.moveToFirst()) {
do {
markers.add(readItem(query));
MapMarker marker = readItem(query, legacy);
if (marker != null) {
markers.add(marker);
}
} while (query.moveToNext());
}
if(query != null) {

View file

@ -12,18 +12,15 @@ import java.util.Set;
public class MapMarkersGroup {
public static final int ANY_TYPE = -1;
public static final int FAVORITES_TYPE = 0;
public static final int GPX_TYPE = 1;
public static final String MARKERS_SYNC_GROUP_ID = "markers_sync_group_id";
private String id;
private String name;
private int type = ANY_TYPE;
private ItineraryType type = ItineraryType.MARKERS;
private Set<String> wptCategories;
private long creationDate;
private boolean disabled;
private long creationDate;
private boolean visible = true;
private boolean wasShown = false;
private boolean visibleUntilRestart;
@ -37,7 +34,7 @@ public class MapMarkersGroup {
}
public MapMarkersGroup(@NonNull String id, @NonNull String name, int type) {
public MapMarkersGroup(@NonNull String id, @NonNull String name, @NonNull ItineraryType type) {
this.id = id;
this.name = name;
this.type = type;
@ -95,7 +92,7 @@ public class MapMarkersGroup {
return name;
}
public int getType() {
public ItineraryType getType() {
return type;
}

View file

@ -5,10 +5,7 @@ import android.os.AsyncTask;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import net.osmand.FileUtils;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.IndexConstants;
@ -17,14 +14,13 @@ import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
import net.osmand.plus.GPXDatabase;
import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GeocodingLookupService;
import net.osmand.plus.GeocodingLookupService.AddressLookupRequest;
import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.wikivoyage.data.TravelArticle;
import net.osmand.plus.wikivoyage.data.TravelHelper;
import net.osmand.util.Algorithms;
@ -35,24 +31,19 @@ import org.apache.commons.logging.Log;
import java.io.File;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static net.osmand.GPXUtilities.GPX_TIME_FORMAT;
import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER;
import static net.osmand.util.MapUtils.createShortLinkString;
public class MapMarkersHelper {
@ -65,9 +56,6 @@ public class MapMarkersHelper {
public static final int BY_DATE_ADDED_ASC = 4;
public static final String VISITED_DATE = "visited_date";
public static final String CREATION_DATE = "creation_date";
private static final Log LOG = PlatformUtil.getLog(MapMarkersHelper.class);
@Retention(RetentionPolicy.SOURCE)
@ -75,8 +63,9 @@ public class MapMarkersHelper {
public @interface MapMarkersSortByDef {
}
private OsmandApplication ctx;
private OsmandApplication app;
private MapMarkersDbHelper markersDbHelper;
private ItineraryDataHelper saveHelper;
private ExecutorService executorService = Executors.newSingleThreadExecutor();
@ -102,22 +91,27 @@ public class MapMarkersHelper {
}
public boolean isStartFromMyLocation() {
return ctx.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.get();
return app.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.get();
}
public void setStartFromMyLocation(boolean startFromMyLocation) {
ctx.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.set(startFromMyLocation);
app.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.set(startFromMyLocation);
}
public MarkersPlanRouteContext getPlanRouteContext() {
return planRouteContext;
}
public MapMarkersHelper(OsmandApplication ctx) {
this.ctx = ctx;
markersDbHelper = ctx.getMapMarkersDbHelper();
planRouteContext = new MarkersPlanRouteContext(ctx);
markersDbHelper.removeDisabledGroups();
public ItineraryDataHelper getSaveHelper() {
return saveHelper;
}
public MapMarkersHelper(OsmandApplication app) {
this.app = app;
saveHelper = new ItineraryDataHelper(app, this);
markersDbHelper = app.getMapMarkersDbHelper();
planRouteContext = new MarkersPlanRouteContext(app);
markersDbHelper.getHelperLegacy().removeDisabledGroups();
loadMarkers();
loadGroups();
}
@ -133,21 +127,21 @@ public class MapMarkersHelper {
sortMarkers(markersHistory, true, BY_DATE_ADDED_DESC);
addToMapMarkersHistoryList(markersHistory);
if (!ctx.isApplicationInitializing()) {
if (!app.isApplicationInitializing()) {
lookupAddressAll();
}
}
private void loadGroups() {
Map<String, MapMarkersGroup> groupsMap = markersDbHelper.getAllGroupsMap();
Map<String, MapMarkersGroup> groupsMap = markersDbHelper.getHelperLegacy().getAllGroupsMap();
List<MapMarker> allMarkers = new ArrayList<>(mapMarkers);
allMarkers.addAll(mapMarkersHistory);
Iterator<Map.Entry<String, MapMarkersGroup>> iterator = groupsMap.entrySet().iterator();
while (iterator.hasNext()) {
MapMarkersGroup group = iterator.next().getValue();
if (group.getType() == MapMarkersGroup.GPX_TYPE && !new File(group.getId()).exists()) {
markersDbHelper.removeMarkersGroup(group.getId());
if (group.getType() == ItineraryType.TRACK && !new File(group.getId()).exists()) {
markersDbHelper.getHelperLegacy().removeMarkersGroup(group.getId());
iterator.remove();
}
}
@ -183,12 +177,17 @@ public class MapMarkersHelper {
}
}
private void saveGroups() {
saveHelper.saveGroups();
}
public void syncAllGroupsAsync() {
for (MapMarkersGroup gr : mapMarkersGroups) {
if (gr.getId() != null && gr.getName() != null) {
runSynchronization(gr);
}
}
saveGroups();
}
public void lookupAddressAll() {
@ -201,7 +200,7 @@ public class MapMarkersHelper {
}
private void lookupAddress(final MapMarker mapMarker) {
if (mapMarker != null && mapMarker.getOriginalPointDescription().isSearchingAddress(ctx)) {
if (mapMarker != null && mapMarker.getOriginalPointDescription().isSearchingAddress(app)) {
cancelPointAddressRequests(mapMarker.point);
AddressLookupRequest lookupRequest = new AddressLookupRequest(mapMarker.point,
new GeocodingLookupService.OnAddressLookupResult() {
@ -209,7 +208,7 @@ public class MapMarkersHelper {
public void geocodingDone(String address) {
PointDescription pointDescription = mapMarker.getOriginalPointDescription();
if (Algorithms.isEmpty(address)) {
pointDescription.setName(PointDescription.getAddressNotFoundStr(ctx));
pointDescription.setName(PointDescription.getAddressNotFoundStr(app));
} else {
pointDescription.setName(address);
}
@ -217,7 +216,7 @@ public class MapMarkersHelper {
refreshMarker(mapMarker);
}
}, null);
ctx.getGeocodingLookupService().lookupAddress(lookupRequest);
app.getGeocodingLookupService().lookupAddress(lookupRequest);
}
}
@ -234,7 +233,7 @@ public class MapMarkersHelper {
private void cancelPointAddressRequests(LatLon latLon) {
if (latLon != null) {
ctx.getGeocodingLookupService().cancel(latLon);
app.getGeocodingLookupService().cancel(latLon);
}
}
@ -295,8 +294,8 @@ public class MapMarkersHelper {
return sortByMode == BY_DISTANCE_DESC ? 1 : -1;
}
} else {
String n1 = mapMarker1.getName(ctx);
String n2 = mapMarker2.getName(ctx);
String n1 = mapMarker1.getName(app);
String n2 = mapMarker2.getName(app);
return n1.compareToIgnoreCase(n2);
}
}
@ -304,7 +303,7 @@ public class MapMarkersHelper {
}
public void runSynchronization(final @NonNull MapMarkersGroup group) {
ctx.runInUIThread(new Runnable() {
app.runInUIThread(new Runnable() {
@Override
public void run() {
new SyncGroupTask(group).executeOnExecutor(executorService);
@ -316,16 +315,16 @@ public class MapMarkersHelper {
if (gpx == null || gpx.path == null) {
return null;
}
return getMapMarkerGroupById(getMarkerGroupId(new File(gpx.path)), MapMarkersGroup.GPX_TYPE);
return getMapMarkerGroupById(getMarkerGroupId(new File(gpx.path)), ItineraryType.TRACK);
}
public MapMarkersGroup getMarkersGroup(FavoriteGroup favGroup) {
return getMapMarkerGroupById(getMarkerGroupId(favGroup), MapMarkersGroup.FAVORITES_TYPE);
return getMapMarkerGroupById(getMarkerGroupId(favGroup), ItineraryType.FAVOURITES);
}
public MapMarkersGroup addOrEnableGpxGroup(@NonNull File file) {
updateGpxShowAsMarkers(file);
MapMarkersGroup gr = getMapMarkerGroupById(getMarkerGroupId(file), MapMarkersGroup.GPX_TYPE);
MapMarkersGroup gr = getMapMarkerGroupById(getMarkerGroupId(file), ItineraryType.TRACK);
if (gr == null) {
gr = createGPXMarkerGroup(file);
addGroupInternally(gr);
@ -367,15 +366,15 @@ public class MapMarkersHelper {
}
private void addGroupInternally(MapMarkersGroup gr) {
markersDbHelper.addGroup(gr);
markersDbHelper.getHelperLegacy().addGroup(gr);
addHistoryMarkersToGroup(gr);
addToGroupsList(gr);
}
private void updateGpxShowAsMarkers(File file) {
GPXDatabase.GpxDataItem dataItem = ctx.getGpxDbHelper().getItem(file);
GpxDataItem dataItem = app.getGpxDbHelper().getItem(file);
if (dataItem != null) {
ctx.getGpxDbHelper().updateShowAsMarkers(dataItem, true);
app.getGpxDbHelper().updateShowAsMarkers(dataItem, true);
dataItem.setShowAsMarkers(true);
}
}
@ -391,7 +390,7 @@ public class MapMarkersHelper {
public void removeMarkersGroup(MapMarkersGroup group) {
if (group != null) {
markersDbHelper.removeMarkersGroup(group.getId());
markersDbHelper.getHelperLegacy().removeMarkersGroup(group.getId());
removeGroupActiveMarkers(group, false);
removeFromGroupsList(group);
}
@ -400,7 +399,7 @@ public class MapMarkersHelper {
public void updateGroupDisabled(@NonNull MapMarkersGroup group, boolean disabled) {
String id = group.getId();
if (id != null) {
markersDbHelper.updateGroupDisabled(id, disabled);
markersDbHelper.getHelperLegacy().updateGroupDisabled(id, disabled);
group.setDisabled(disabled);
}
}
@ -410,7 +409,7 @@ public class MapMarkersHelper {
if (id != null) {
group.setWptCategories(wptCategories);
if (wptCategories != null) {
markersDbHelper.updateGroupCategories(id, group.getWptCategoriesString());
markersDbHelper.getHelperLegacy().updateGroupCategories(id, group.getWptCategoriesString());
}
}
}
@ -456,6 +455,7 @@ public class MapMarkersHelper {
for (MapMarker marker : markers) {
addMarkerToGroup(marker);
}
saveGroups();
}
private void addMarkerToGroup(MapMarker marker) {
@ -468,7 +468,7 @@ public class MapMarkersHelper {
sortMarkers(mapMarkersGroup.getMarkers(), false, BY_DATE_ADDED_DESC);
}
} else {
mapMarkersGroup = new MapMarkersGroup(marker.groupKey, marker.groupName, MapMarkersGroup.ANY_TYPE);
mapMarkersGroup = new MapMarkersGroup(marker.groupKey, marker.groupName, ItineraryType.MARKERS);
mapMarkersGroup.setCreationDate(Long.MAX_VALUE);
mapMarkersGroup.getMarkers().add(marker);
addToGroupsList(mapMarkersGroup);
@ -479,10 +479,10 @@ public class MapMarkersHelper {
}
private void createHeadersInGroup(@NonNull MapMarkersGroup group) {
int type = group.getType();
ItineraryType type = group.getType();
int headerIconId = 0;
if (type != -1) {
headerIconId = type == MapMarkersGroup.FAVORITES_TYPE
if (type != ItineraryType.MARKERS) {
headerIconId = type == ItineraryType.FAVOURITES
? R.drawable.ic_action_favorite : R.drawable.ic_action_polygom_dark;
}
GroupHeader header = new GroupHeader(headerIconId, group);
@ -513,11 +513,11 @@ public class MapMarkersHelper {
}
@Nullable
public MapMarkersGroup getMapMarkerGroupById(String id, int type) {
public MapMarkersGroup getMapMarkerGroupById(String id, ItineraryType type) {
for (MapMarkersGroup group : mapMarkersGroups) {
if ((id == null && group.getId() == null)
|| (group.getId() != null && group.getId().equals(id))) {
if (type == MapMarkersGroup.ANY_TYPE || type == group.getType()) {
if (type == ItineraryType.MARKERS || type == group.getType()) {
return group;
}
}
@ -528,11 +528,11 @@ public class MapMarkersHelper {
private MapMarkersGroup createGPXMarkerGroup(File fl) {
return new MapMarkersGroup(getMarkerGroupId(fl),
Algorithms.getFileNameWithoutExtension(fl.getName()),
MapMarkersGroup.GPX_TYPE);
ItineraryType.TRACK);
}
private MapMarkersGroup createFavMarkerGroup(FavoriteGroup favGroup) {
return new MapMarkersGroup(favGroup.getName(), favGroup.getName(), MapMarkersGroup.FAVORITES_TYPE);
return new MapMarkersGroup(favGroup.getName(), favGroup.getName(), ItineraryType.FAVOURITES);
}
private String getMarkerGroupId(File gpx) {
@ -546,7 +546,7 @@ public class MapMarkersHelper {
@NonNull
public List<MapMarkersGroup> getGroupsForDisplayedGpx() {
List<MapMarkersGroup> res = new ArrayList<>();
List<SelectedGpxFile> selectedGpxFiles = ctx.getSelectedGpxHelper().getSelectedGPXFiles();
List<SelectedGpxFile> selectedGpxFiles = app.getSelectedGpxHelper().getSelectedGPXFiles();
for (SelectedGpxFile selected : selectedGpxFiles) {
MapMarkersGroup search = getMarkersGroup(selected.getGpxFile());
if (search == null && selected.getGpxFile() != null && selected.getGpxFile().path != null) {
@ -562,13 +562,13 @@ public class MapMarkersHelper {
@NonNull
public List<MapMarkersGroup> getGroupsForSavedArticlesTravelBook() {
List<MapMarkersGroup> res = new ArrayList<>();
TravelHelper travelHelper = ctx.getTravelHelper();
TravelHelper travelHelper = app.getTravelHelper();
if (travelHelper.isAnyTravelBookPresent()) {
List<TravelArticle> savedArticles = travelHelper.getBookmarksHelper().getSavedArticles();
for (TravelArticle art : savedArticles) {
String gpxName = travelHelper.getGPXName(art);
File path = ctx.getAppPath(IndexConstants.GPX_TRAVEL_DIR + gpxName);
MapMarkersGroup search = getMapMarkerGroupById(getMarkerGroupId(path), MapMarkersGroup.GPX_TYPE);
File path = app.getAppPath(IndexConstants.GPX_TRAVEL_DIR + gpxName);
MapMarkersGroup search = getMapMarkerGroupById(getMarkerGroupId(path), ItineraryType.TRACK);
if (search == null) {
MapMarkersGroup group = createGPXMarkerGroup(path);
group.setDisabled(true);
@ -612,7 +612,7 @@ public class MapMarkersHelper {
private List<MapMarker> getMarkers() {
List<MapMarker> res = new ArrayList<>(mapMarkers);
if (ctx.getSettings().KEEP_PASSED_MARKERS_ON_MAP.get()) {
if (app.getSettings().KEEP_PASSED_MARKERS_ON_MAP.get()) {
res.addAll(mapMarkersHistory);
}
return res;
@ -642,7 +642,7 @@ public class MapMarkersHelper {
Iterator<MapMarker> iterator = groupMarkers.iterator();
while (iterator.hasNext()) {
MapMarker marker = iterator.next();
if (marker.id.equals(group.getId() + name + MapUtils.createShortLinkString(latLon.getLatitude(), latLon.getLongitude(), 15))) {
if (marker.id.equals(getMarkerId(app, group, marker))) {
exists = true;
marker.favouritePoint = favouritePoint;
marker.wptPt = wptPt;
@ -698,7 +698,9 @@ public class MapMarkersHelper {
public void addMarker(MapMarker marker) {
if (marker != null) {
markersDbHelper.addMarker(marker);
if (marker.groupKey == null) {
markersDbHelper.addMarker(marker);
}
if (marker.history) {
addToMapMarkersHistoryList(marker);
sortMarkers(mapMarkersHistory, true, BY_DATE_ADDED_DESC);
@ -879,7 +881,7 @@ public class MapMarkersHelper {
@Nullable List<WptPt> wptPts,
@Nullable List<String> mapObjNames) {
if (points.size() > 0) {
ctx.getSettings().SHOW_MAP_MARKERS.set(true);
app.getSettings().SHOW_MAP_MARKERS.set(true);
int colorIndex = -1;
List<MapMarker> addedMarkers = new ArrayList<>();
for (int i = 0; i < points.size(); i++) {
@ -895,7 +897,7 @@ public class MapMarkersHelper {
pointDescription = historyName;
}
if (pointDescription.isLocation() && Algorithms.isEmpty(pointDescription.getName())) {
pointDescription.setName(PointDescription.getSearchAddressStr(ctx));
pointDescription.setName(PointDescription.getSearchAddressStr(app));
}
if (colorIndex == -1) {
if (mapMarkers.size() > 0) {
@ -909,7 +911,7 @@ public class MapMarkersHelper {
MapMarker marker = new MapMarker(point, pointDescription, colorIndex, false, 0);
if (group != null) {
marker.id = group.getId() + marker.getName(ctx) + MapUtils.createShortLinkString(marker.point.getLatitude(), marker.point.getLongitude(), 15);
marker.id = getMarkerId(app, group, marker);
if (markersDbHelper.getMarker(marker.id) != null) {
continue;
}
@ -921,7 +923,9 @@ public class MapMarkersHelper {
marker.favouritePoint = favouritePoint;
marker.wptPt = wptPt;
marker.mapObjectName = mapObjName;
markersDbHelper.addMarker(marker);
if (marker.groupKey == null) {
markersDbHelper.addMarker(marker);
}
addToMapMarkersList(0, marker);
addedMarkers.add(marker);
reorderActiveMarkersIfNeeded();
@ -931,6 +935,10 @@ public class MapMarkersHelper {
}
}
public static String getMarkerId(OsmandApplication app, MapMarkersGroup group, MapMarker marker) {
return group.getId() + marker.getName(app) + createShortLinkString(marker.point.getLatitude(), marker.point.getLongitude(), 15);
}
public void updateMapMarker(MapMarker marker, boolean refresh) {
if (marker != null) {
markersDbHelper.updateMarker(marker);
@ -984,7 +992,7 @@ public class MapMarkersHelper {
}
private void refreshMarker(final MapMarker marker) {
ctx.runInUIThread(new Runnable() {
app.runInUIThread(new Runnable() {
@Override
public void run() {
for (MapMarkerChangedListener l : listeners) {
@ -995,7 +1003,7 @@ public class MapMarkersHelper {
}
private void refresh() {
ctx.runInUIThread(new Runnable() {
app.runInUIThread(new Runnable() {
@Override
public void run() {
for (MapMarkerChangedListener l : listeners) {
@ -1003,12 +1011,13 @@ public class MapMarkersHelper {
}
}
});
saveGroups();
}
public List<MapMarker> getMapMarkersFromDefaultGroups(boolean history) {
List<MapMarker> mapMarkers = new ArrayList<>();
for (MapMarkersGroup group : mapMarkersGroups) {
if (group.getType() == MapMarkersGroup.ANY_TYPE) {
if (group.getType() == ItineraryType.MARKERS) {
for (MapMarker marker : group.getMarkers()) {
if (history && marker.history || !history && !marker.history) {
mapMarkers.add(marker);
@ -1019,84 +1028,6 @@ public class MapMarkersHelper {
return mapMarkers;
}
public String saveMarkersToFile(String fileName) {
GPXFile gpxFile = generateGpx();
String dirName = IndexConstants.GPX_INDEX_DIR + IndexConstants.MAP_MARKERS_INDEX_DIR;
File dir = ctx.getAppPath(dirName);
if (!dir.exists()) {
dir.mkdirs();
}
String uniqueFileName = FileUtils.createUniqueFileName(ctx, fileName, dirName, IndexConstants.GPX_FILE_EXT);
File fout = new File(dir, uniqueFileName + IndexConstants.GPX_FILE_EXT);
GPXUtilities.writeGpxFile(fout, gpxFile);
return fout.getAbsolutePath();
}
public GPXFile generateGpx() {
return generateGpx(mapMarkers, false);
}
public GPXFile generateGpx(List<MapMarker> markers, boolean completeBackup) {
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT, Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
GPXFile gpxFile = new GPXFile(Version.getFullVersion(ctx));
for (MapMarker marker : markers) {
WptPt wpt = new WptPt();
wpt.lat = marker.getLatitude();
wpt.lon = marker.getLongitude();
wpt.name = marker.getOnlyName();
wpt.setColor(ContextCompat.getColor(ctx, MapMarker.getColorId(marker.colorIndex)));
if (completeBackup) {
if (marker.creationDate != 0) {
wpt.getExtensionsToWrite().put(CREATION_DATE, format.format(new Date(marker.creationDate)));
}
if (marker.visitedDate != 0) {
wpt.getExtensionsToWrite().put(VISITED_DATE, format.format(new Date(marker.visitedDate)));
}
}
gpxFile.addPoint(wpt);
}
return gpxFile;
}
public List<MapMarker> readMarkersFromGpx(GPXFile gpxFile, boolean history) {
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT, Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
List<MapMarker> mapMarkers = new ArrayList<>();
for (WptPt point : gpxFile.getPoints()) {
LatLon latLon = new LatLon(point.lat, point.lon);
int colorIndex = MapMarker.getColorIndex(ctx, point.getColor());
PointDescription name = new PointDescription(PointDescription.POINT_TYPE_LOCATION, point.name);
MapMarker marker = new MapMarker(latLon, name, colorIndex, false, 0);
String visitedDateStr = point.getExtensionsToRead().get(VISITED_DATE);
String creationDateStr = point.getExtensionsToRead().get(CREATION_DATE);
marker.visitedDate = parseTime(visitedDateStr, format);
marker.creationDate = parseTime(creationDateStr, format);
marker.history = history;
marker.nextKey = history ? MapMarkersDbHelper.HISTORY_NEXT_VALUE : MapMarkersDbHelper.TAIL_NEXT_VALUE;
mapMarkers.add(marker);
}
return mapMarkers;
}
private static long parseTime(String text, SimpleDateFormat format) {
long time = 0;
if (text != null) {
try {
time = format.parse(text).getTime();
} catch (ParseException e) {
LOG.error(e);
}
}
return time;
}
// ---------------------------------------------------------------------------------------------
// accessors to active markers:
@ -1201,7 +1132,7 @@ public class MapMarkersHelper {
@Override
protected void onPreExecute() {
if (!syncListeners.isEmpty()) {
ctx.runInUIThread(new Runnable() {
app.runInUIThread(new Runnable() {
@Override
public void run() {
for (OnGroupSyncedListener listener : syncListeners) {
@ -1221,8 +1152,8 @@ public class MapMarkersHelper {
// TODO extract method from Asynctask to Helper directly
private void runGroupSynchronization() {
List<MapMarker> groupMarkers = new ArrayList<>(group.getMarkers());
if (group.getType() == MapMarkersGroup.FAVORITES_TYPE) {
FavoriteGroup favGroup = ctx.getFavorites().getGroup(group.getName());
if (group.getType() == ItineraryType.FAVOURITES) {
FavoriteGroup favGroup = app.getFavorites().getGroup(group.getName());
if (favGroup == null) {
return;
}
@ -1235,8 +1166,8 @@ public class MapMarkersHelper {
for (FavouritePoint fp : points) {
addNewMarkerIfNeeded(group, groupMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName(), fp, null);
}
} else if (group.getType() == MapMarkersGroup.GPX_TYPE) {
GpxSelectionHelper gpxHelper = ctx.getSelectedGpxHelper();
} else if (group.getType() == ItineraryType.TRACK) {
GpxSelectionHelper gpxHelper = app.getSelectedGpxHelper();
File file = new File(group.getId());
if (!file.exists()) {
return;
@ -1267,7 +1198,7 @@ public class MapMarkersHelper {
@Override
protected void onPostExecute(Void aVoid) {
if (!syncListeners.isEmpty()) {
ctx.runInUIThread(new Runnable() {
app.runInUIThread(new Runnable() {
@Override
public void run() {
for (OnGroupSyncedListener listener : syncListeners) {

View file

@ -0,0 +1,171 @@
package net.osmand.plus.mapmarkers;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.api.SQLiteAPI.SQLiteConnection;
import net.osmand.plus.api.SQLiteAPI.SQLiteCursor;
import net.osmand.util.Algorithms;
import java.util.LinkedHashMap;
import java.util.Map;
import static net.osmand.plus.mapmarkers.MapMarkersDbHelper.MARKERS_COL_ACTIVE;
import static net.osmand.plus.mapmarkers.MapMarkersDbHelper.MARKERS_COL_DISABLED;
import static net.osmand.plus.mapmarkers.MapMarkersDbHelper.MARKERS_COL_GROUP_KEY;
import static net.osmand.plus.mapmarkers.MapMarkersDbHelper.MARKERS_TABLE_NAME;
public class MarkersDbHelperLegacy {
private static final String GROUPS_TABLE_NAME = "map_markers_groups";
private static final String GROUPS_COL_ID = "group_id";
private static final String GROUPS_COL_NAME = "group_name";
private static final String GROUPS_COL_TYPE = "group_type";
private static final String GROUPS_COL_DISABLED = "group_disabled";
private static final String GROUPS_COL_CATEGORIES = "group_categories";
private static final String GROUPS_TABLE_CREATE = "CREATE TABLE IF NOT EXISTS " +
GROUPS_TABLE_NAME + " (" +
GROUPS_COL_ID + " TEXT PRIMARY KEY, " +
GROUPS_COL_NAME + " TEXT, " +
GROUPS_COL_TYPE + " int, " +
GROUPS_COL_DISABLED + " int, " + // 1 = true, 0 = false
GROUPS_COL_CATEGORIES + " TEXT);";
private static final String GROUPS_TABLE_SELECT = "SELECT " +
GROUPS_COL_ID + ", " +
GROUPS_COL_NAME + ", " +
GROUPS_COL_TYPE + ", " +
GROUPS_COL_DISABLED + ", " +
GROUPS_COL_CATEGORIES +
" FROM " + GROUPS_TABLE_NAME;
private final OsmandApplication app;
private final MapMarkersDbHelper markersDbHelper;
public MarkersDbHelperLegacy(OsmandApplication app, MapMarkersDbHelper markersDbHelper) {
this.app = app;
this.markersDbHelper = markersDbHelper;
}
public void onCreate(SQLiteConnection db) {
db.execSQL(GROUPS_TABLE_CREATE);
}
public void onUpgrade(SQLiteConnection db, int oldVersion, int newVersion) {
if (oldVersion < 8) {
db.execSQL("ALTER TABLE " + GROUPS_TABLE_NAME + " ADD " + GROUPS_COL_DISABLED + " int");
}
if (oldVersion < 9) {
db.execSQL("UPDATE " + GROUPS_TABLE_NAME +
" SET " + GROUPS_COL_DISABLED + " = ? " +
"WHERE " + GROUPS_COL_DISABLED + " IS NULL", new Object[] {0});
}
if (oldVersion < 13) {
db.execSQL("ALTER TABLE " + GROUPS_TABLE_NAME + " ADD " + GROUPS_COL_CATEGORIES + " TEXT");
}
}
private SQLiteConnection openConnection(boolean readonly) {
return markersDbHelper.openConnection(readonly);
}
public void updateGroupDisabled(String id, boolean disabled) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("UPDATE " + GROUPS_TABLE_NAME +
" SET " + GROUPS_COL_DISABLED + " = ? " +
"WHERE " + GROUPS_COL_ID + " = ?", new Object[] {disabled ? 1 : 0, id});
db.execSQL("UPDATE " + MARKERS_TABLE_NAME +
" SET " + MARKERS_COL_DISABLED + " = ? " +
"WHERE " + MARKERS_COL_GROUP_KEY + " = ?", new Object[] {disabled ? 1 : 0, id});
} finally {
db.close();
}
}
}
public void removeDisabledGroups() {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("DELETE FROM " + GROUPS_TABLE_NAME + " WHERE " + GROUPS_COL_DISABLED + " = ? ", new Object[] {1});
db.execSQL("DELETE FROM " + MARKERS_TABLE_NAME
+ " WHERE " + MARKERS_COL_DISABLED + " = ? AND " + MARKERS_COL_ACTIVE + " = ?", new Object[] {1, 1});
} finally {
db.close();
}
}
}
public void addGroup(MapMarkersGroup group) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("INSERT INTO " + GROUPS_TABLE_NAME + " VALUES (?, ?, ?, ?, ?)",
new Object[] {group.getId(), group.getName(), group.getType().getTypeId(), group.isDisabled(), group.getWptCategoriesString()});
} finally {
db.close();
}
}
}
public Map<String, MapMarkersGroup> getAllGroupsMap() {
Map<String, MapMarkersGroup> res = new LinkedHashMap<>();
SQLiteConnection db = openConnection(true);
if (db != null) {
try {
SQLiteCursor query = db.rawQuery(GROUPS_TABLE_SELECT, null);
if (query != null && query.moveToFirst()) {
do {
MapMarkersGroup group = readGroup(query);
res.put(group.getId(), group);
} while (query.moveToNext());
}
if (query != null) {
query.close();
}
} finally {
db.close();
}
}
return res;
}
private MapMarkersGroup readGroup(SQLiteCursor query) {
String id = query.getString(0);
String name = query.getString(1);
int type = query.getInt(2);
boolean disabled = query.getInt(3) == 1;
String categories = query.getString(4);
MapMarkersGroup res = new MapMarkersGroup(id, name, ItineraryType.findTypeForId(type));
res.setDisabled(disabled);
res.setWptCategories(categories == null ? null : Algorithms.decodeStringSet(categories));
return res;
}
public void removeMarkersGroup(String id) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("DELETE FROM " + GROUPS_TABLE_NAME + " WHERE " + GROUPS_COL_ID + " = ?", new Object[] {id});
} finally {
db.close();
}
}
}
public void updateGroupCategories(String id, String categories) {
SQLiteConnection db = openConnection(false);
if (db != null) {
try {
db.execSQL("UPDATE " + GROUPS_TABLE_NAME +
" SET " + GROUPS_COL_CATEGORIES + " = ? " +
"WHERE " + GROUPS_COL_ID + " = ?", new Object[] {categories, id});
} finally {
db.close();
}
}
}
}

View file

@ -45,11 +45,11 @@ public class MarkersPlanRouteContext {
private boolean adjustMapOnStart = true;
private boolean navigationFromMarkers;
Map<Pair<WptPt, WptPt>, List<WptPt>> getSnappedToRoadPoints() {
public Map<Pair<WptPt, WptPt>, List<WptPt>> getSnappedToRoadPoints() {
return snappedToRoadPoints;
}
TrkSegment getSnapTrkSegment() {
public TrkSegment getSnapTrkSegment() {
return snapTrkSegment;
}
@ -57,7 +57,7 @@ public class MarkersPlanRouteContext {
return snappedMode;
}
void setSnappedMode(ApplicationMode snappedMode) {
public void setSnappedMode(ApplicationMode snappedMode) {
this.snappedMode = snappedMode;
}
@ -69,11 +69,11 @@ public class MarkersPlanRouteContext {
this.listener = listener;
}
boolean isProgressBarVisible() {
public boolean isProgressBarVisible() {
return progressBarVisible;
}
void setProgressBarVisible(boolean progressBarVisible) {
public void setProgressBarVisible(boolean progressBarVisible) {
this.progressBarVisible = progressBarVisible;
}
@ -113,7 +113,7 @@ public class MarkersPlanRouteContext {
this.app = app;
}
void cancelSnapToRoad() {
public void cancelSnapToRoad() {
listener.hideProgressBar(true);
snapToRoadPairsToCalculate.clear();
if (calculationProgress != null) {
@ -151,7 +151,7 @@ public class MarkersPlanRouteContext {
}
}
void recreateSnapTrkSegment(boolean adjustMap) {
public void recreateSnapTrkSegment(boolean adjustMap) {
snapTrkSegment.points.clear();
List<WptPt> points = getPointsToCalculate();
if (snappedMode == ApplicationMode.DEFAULT) {
@ -281,7 +281,7 @@ public class MarkersPlanRouteContext {
return params;
}
interface PlanRouteProgressListener {
public interface PlanRouteProgressListener {
void showProgressBar();

View file

@ -13,13 +13,14 @@ import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.snackbar.Snackbar;
import net.osmand.data.LatLon;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.UiUtilities.UpdateLocationViewCache;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapmarkers.ItineraryType;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.util.Algorithms;
import java.util.Collections;
@ -215,7 +216,7 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter<MapMarkerItemV
final MapMarker marker = getItem(pos);
mapActivity.getMyApplication().getMapMarkersHelper().moveMapMarkerToHistory(marker);
MapMarkersGroup group = mapActivity.getMyApplication().getMapMarkersHelper().getMapMarkerGroupById(marker.groupKey,
MapMarkersGroup.ANY_TYPE);
ItineraryType.MARKERS);
if (group != null) {
mapActivity.getMyApplication().getMapMarkersHelper().updateGroup(group);
}

View file

@ -7,7 +7,6 @@ import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
@ -25,6 +24,7 @@ import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.GroupHeader;
import net.osmand.plus.mapmarkers.ItineraryType;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapmarkers.ShowHideHistoryButton;
@ -34,7 +34,7 @@ import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.UiUtilities.UpdateLocationViewCache;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapmarkers.SelectWptCategoriesBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.SelectWptCategoriesBottomSheetDialogFragment;
import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment;
import net.osmand.plus.wikivoyage.data.TravelArticle;
import net.osmand.plus.wikivoyage.data.TravelHelper;
@ -253,7 +253,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
public int getGroupHeaderPosition(String groupId) {
int pos = -1;
MapMarkersGroup group = app.getMapMarkersHelper().getMapMarkerGroupById(groupId, MapMarkersGroup.ANY_TYPE);
MapMarkersGroup group = app.getMapMarkersHelper().getMapMarkerGroupById(groupId, ItineraryType.MARKERS);
if (group != null) {
pos = items.indexOf(group.getGroupHeader());
}
@ -425,7 +425,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
String groupName = group.getName();
if (groupName.isEmpty()) {
groupName = app.getString(R.string.shared_string_favorites);
} else if (group.getType() == MapMarkersGroup.GPX_TYPE) {
} else if (group.getType() == ItineraryType.TRACK) {
groupName = groupName.replace(IndexConstants.GPX_FILE_EXT, "").replace("/", " ").replace("_", " ");
}
if (group.isDisabled()) {
@ -483,7 +483,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
fragment.show(mapActivity.getSupportFragmentManager(), SelectWptCategoriesBottomSheetDialogFragment.TAG);
}
mapMarkersHelper.updateGroupDisabled(group, disabled);
if (group.getType() == MapMarkersGroup.GPX_TYPE) {
if (group.getType() == ItineraryType.TRACK) {
group.setVisibleUntilRestart(disabled);
String gpxPath = group.getGpxPath();
SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(gpxPath);
@ -506,7 +506,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
.setAction(R.string.shared_string_undo, new View.OnClickListener() {
@Override
public void onClick(View view) {
if (group.getType() == MapMarkersGroup.GPX_TYPE && gpxFile[0] != null) {
if (group.getType() == ItineraryType.TRACK && gpxFile[0] != null) {
switchGpxVisibility(gpxFile[0], null, true);
}
mapMarkersHelper.enableGroup(group);
@ -616,7 +616,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter<RecyclerView.V
Object item = items.get(position);
if (item instanceof MapMarker) {
return MARKER_TYPE;
} else if (item instanceof GroupHeader || item instanceof Integer) {
} else if (item instanceof GroupHeader || item instanceof MarkerGroupItem) {
return HEADER_TYPE;
} else if (item instanceof ShowHideHistoryButton) {
return SHOW_HIDE_HISTORY_TYPE;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.os.Bundle;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.app.Dialog;
import android.os.Bundle;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.annotation.SuppressLint;
import android.os.AsyncTask;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.os.Bundle;
import android.view.View;
@ -65,7 +65,7 @@ public class CoordinateInputActionsBottomSheet extends MenuBottomSheetDialogFrag
return R.string.shared_string_cancel;
}
interface CoordinateInputActionsListener {
public interface CoordinateInputActionsListener {
void removeItem(int position);

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.content.Context;
import android.content.res.ColorStateList;
@ -162,7 +162,7 @@ public class CoordinateInputBottomSheetDialogFragment extends MenuBottomSheetDia
return R.string.shared_string_close;
}
interface CoordinateInputFormatChangeListener {
public interface CoordinateInputFormatChangeListener {
void onKeyboardChanged();

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.os.Bundle;
import android.view.View;
@ -9,6 +9,7 @@ import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.util.Algorithms;
import java.text.SimpleDateFormat;
@ -95,7 +96,7 @@ public class HistoryMarkerMenuBottomSheetDialogFragment extends MenuBottomSheetD
return R.string.shared_string_close;
}
interface HistoryMarkerMenuFragmentListener {
public interface HistoryMarkerMenuFragmentListener {
void onMakeMarkerActive(int pos);

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.app.Activity;
import android.os.Build;
@ -17,6 +17,8 @@ import net.osmand.AndroidUtils;
import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.mapmarkers.fragments.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.MapMarkersMode;
public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment {
@ -220,7 +222,7 @@ public class OptionsBottomSheetDialogFragment extends BottomSheetDialogFragment
return scrH - stBarH - nBarH - AndroidUtils.dpToPx(activity, 56);
}
interface MarkerOptionsFragmentListener {
public interface MarkerOptionsFragmentListener {
void sortByOnClick();

View file

@ -1,9 +1,10 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.MapMarkersHelper.MapMarkersSortByDef;
import net.osmand.plus.R;
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
@ -119,7 +120,7 @@ public class OrderByBottomSheetDialogFragment extends MenuBottomSheetDialogFragm
return R.string.shared_string_close;
}
interface OrderByFragmentListener {
public interface OrderByFragmentListener {
void onMapMarkersOrderByModeChanged(@MapMarkersSortByDef int sortByMode);
}
}

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.os.Bundle;
import android.view.View;
@ -125,7 +125,7 @@ public class PlanRouteOptionsBottomSheetDialogFragment extends MenuBottomSheetDi
return R.string.shared_string_close;
}
interface PlanRouteOptionsFragmentListener {
public interface PlanRouteOptionsFragmentListener {
void selectOnClick();

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.os.Bundle;
import android.text.format.DateFormat;
@ -31,7 +31,7 @@ import net.osmand.plus.widgets.OsmandTextFieldBoxes;
import java.util.Date;
import static net.osmand.plus.mapmarkers.CoordinateInputDialogFragment.ADDED_POINTS_NUMBER_KEY;
import static net.osmand.plus.mapmarkers.fragments.CoordinateInputDialogFragment.ADDED_POINTS_NUMBER_KEY;
public class SaveAsTrackBottomSheetDialogFragment extends BottomSheetDialogFragment {
@ -167,7 +167,7 @@ public class SaveAsTrackBottomSheetDialogFragment extends BottomSheetDialogFragm
}
}
interface MarkerSaveAsTrackFragmentListener {
public interface MarkerSaveAsTrackFragmentListener {
void saveGpx(String fileName);
}
}

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.os.Bundle;
import android.view.View;
@ -20,6 +20,8 @@ import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import java.io.File;
import java.util.ArrayList;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.bottomsheets;
import android.os.Bundle;
import android.view.View;
@ -64,7 +64,7 @@ public class SelectionMarkersGroupBottomSheetDialogFragment extends MenuBottomSh
return R.string.shared_string_close;
}
interface AddMarkersGroupFragmentListener {
public interface AddMarkersGroupFragmentListener {
void favouritesOnClick();

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.fragments;
import android.app.Activity;
import android.app.Dialog;
@ -71,11 +71,17 @@ import net.osmand.plus.Version;
import net.osmand.plus.activities.SavingTrackHelper;
import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.mapmarkers.CoordinateInputBottomSheetDialogFragment.CoordinateInputFormatChangeListener;
import net.osmand.plus.mapmarkers.CoordinateInputFormats;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.bottomsheets.CoordinateInputActionsBottomSheet;
import net.osmand.plus.mapmarkers.bottomsheets.CoordinateInputBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.CoordinateInputBottomSheetDialogFragment.CoordinateInputFormatChangeListener;
import net.osmand.plus.mapmarkers.CoordinateInputFormats.DDM;
import net.osmand.plus.mapmarkers.CoordinateInputFormats.DMS;
import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format;
import net.osmand.plus.mapmarkers.adapters.CoordinateInputAdapter;
import net.osmand.plus.mapmarkers.bottomsheets.SaveAsTrackBottomSheetDialogFragment;
import net.osmand.plus.settings.backend.OsmandPreference;
import net.osmand.plus.track.TrackMenuFragment;
import net.osmand.plus.widgets.EditTextEx;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.fragments;
import android.app.Activity;
import android.content.Context;
@ -30,6 +30,7 @@ import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCal
import com.github.ksoichiro.android.observablescrollview.ScrollState;
import net.osmand.AndroidUtils;
import net.osmand.plus.mapmarkers.MapMarkersMode;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.OsmandPreference;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.fragments;
import android.content.Context;
import android.graphics.drawable.Drawable;
@ -21,6 +21,7 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndDialogFragment;
import net.osmand.plus.base.MapViewTrackingUtilities;
import net.osmand.plus.helpers.MapMarkerDialogHelper;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu;
import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu.OnMarkerSelectListener;
import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu.PointType;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.fragments;
import android.os.Build;
import android.os.Bundle;
@ -26,6 +26,7 @@ import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.adapters.MapMarkersActiveAdapter;
import net.osmand.plus.mapmarkers.adapters.MapMarkersActiveAdapter.MapMarkersActiveAdapterListener;
import net.osmand.plus.mapmarkers.adapters.MapMarkersItemTouchHelperCallback;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.fragments;
import android.app.Dialog;
import android.graphics.drawable.Drawable;
@ -32,13 +32,18 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment.OnPointsSavedListener;
import net.osmand.plus.mapmarkers.DirectionIndicationDialogFragment.DirectionIndicationFragmentListener;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.fragments.CoordinateInputDialogFragment.OnPointsSavedListener;
import net.osmand.plus.mapmarkers.fragments.DirectionIndicationDialogFragment.DirectionIndicationFragmentListener;
import net.osmand.plus.mapmarkers.MapMarkersHelper.MapMarkersSortByDef;
import net.osmand.plus.mapmarkers.MapMarkersHelper.OnGroupSyncedListener;
import net.osmand.plus.mapmarkers.OptionsBottomSheetDialogFragment.MarkerOptionsFragmentListener;
import net.osmand.plus.mapmarkers.OrderByBottomSheetDialogFragment.OrderByFragmentListener;
import net.osmand.plus.mapmarkers.SaveAsTrackBottomSheetDialogFragment.MarkerSaveAsTrackFragmentListener;
import net.osmand.plus.mapmarkers.bottomsheets.OptionsBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.OptionsBottomSheetDialogFragment.MarkerOptionsFragmentListener;
import net.osmand.plus.mapmarkers.bottomsheets.OrderByBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.OrderByBottomSheetDialogFragment.OrderByFragmentListener;
import net.osmand.plus.mapmarkers.bottomsheets.SaveAsTrackBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.SaveAsTrackBottomSheetDialogFragment.MarkerSaveAsTrackFragmentListener;
import net.osmand.plus.track.TrackMenuFragment;
import java.io.File;
@ -46,8 +51,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static net.osmand.plus.mapmarkers.OptionsBottomSheetDialogFragment.GROUPS_MARKERS_MENU;
import static net.osmand.plus.mapmarkers.OptionsBottomSheetDialogFragment.HISTORY_MARKERS_MENU;
import static net.osmand.plus.mapmarkers.bottomsheets.OptionsBottomSheetDialogFragment.GROUPS_MARKERS_MENU;
import static net.osmand.plus.mapmarkers.bottomsheets.OptionsBottomSheetDialogFragment.HISTORY_MARKERS_MENU;
public class MapMarkersDialogFragment extends DialogFragment implements OnGroupSyncedListener {
@ -481,7 +486,7 @@ public class MapMarkersDialogFragment extends DialogFragment implements OnGroupS
@Override
public void saveGpx(final String fileName) {
final String gpxPath = mapActivity.getMyApplication().getMapMarkersHelper().saveMarkersToFile(fileName);
final String gpxPath = mapActivity.getMyApplication().getMapMarkersHelper().getSaveHelper().saveMarkersToFile(fileName);
snackbar = Snackbar.make(viewPager, String.format(getString(R.string.shared_string_file_is_saved), fileName) + ".", Snackbar.LENGTH_LONG)
.setAction(R.string.shared_string_show, new View.OnClickListener() {
@Override

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.fragments;
import android.graphics.Canvas;
import android.graphics.Paint;
@ -34,7 +34,13 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapmarkers.SelectionMarkersGroupBottomSheetDialogFragment.AddMarkersGroupFragmentListener;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.bottomsheets.AddFavouritesGroupBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.AddGroupBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.AddTracksGroupBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.HistoryMarkerMenuBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.SelectionMarkersGroupBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.SelectionMarkersGroupBottomSheetDialogFragment.AddMarkersGroupFragmentListener;
import net.osmand.plus.mapmarkers.adapters.MapMarkerItemViewHolder;
import net.osmand.plus.mapmarkers.adapters.MapMarkersGroupsAdapter;
import net.osmand.plus.widgets.EmptyStateRecyclerView;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.fragments;
import android.graphics.Canvas;
import android.graphics.Paint;
@ -24,12 +24,15 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapmarkers.MapMarkersHelper.MapMarkerChangedListener;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.adapters.MapMarkerHeaderViewHolder;
import net.osmand.plus.mapmarkers.adapters.MapMarkerItemViewHolder;
import net.osmand.plus.mapmarkers.adapters.MapMarkersHistoryAdapter;
import net.osmand.plus.mapmarkers.bottomsheets.HistoryMarkerMenuBottomSheetDialogFragment;
import net.osmand.plus.widgets.EmptyStateRecyclerView;
public class MapMarkersHistoryFragment extends Fragment implements MapMarkersHelper.MapMarkerChangedListener {
public class MapMarkersHistoryFragment extends Fragment implements MapMarkerChangedListener {
private MapMarkersHistoryAdapter adapter;
private OsmandApplication app;

View file

@ -1,4 +1,4 @@
package net.osmand.plus.mapmarkers;
package net.osmand.plus.mapmarkers.fragments;
import android.app.ProgressDialog;
import android.content.Context;
@ -48,7 +48,11 @@ import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.mapmarkers.PlanRouteOptionsBottomSheetDialogFragment.PlanRouteOptionsFragmentListener;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MarkersPlanRouteContext;
import net.osmand.plus.mapmarkers.bottomsheets.PlanRouteOptionsBottomSheetDialogFragment;
import net.osmand.plus.mapmarkers.bottomsheets.PlanRouteOptionsBottomSheetDialogFragment.PlanRouteOptionsFragmentListener;
import net.osmand.plus.mapmarkers.adapters.MapMarkersItemTouchHelperCallback;
import net.osmand.plus.mapmarkers.adapters.MapMarkersListAdapter;
import net.osmand.plus.measurementtool.SnapToRoadBottomSheetDialogFragment;

View file

@ -76,7 +76,7 @@ import net.osmand.plus.base.OsmandExpandableListFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType;
import net.osmand.plus.helpers.enums.TracksSortByMode;
import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment;
import net.osmand.plus.mapmarkers.fragments.CoordinateInputDialogFragment;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.myplaces.MoveGpxFileBottomSheet.OnTrackFileMoveListener;
import net.osmand.plus.osmedit.OsmEditingPlugin;
@ -107,7 +107,6 @@ import static net.osmand.plus.track.TrackMenuFragment.openTrack;
import static net.osmand.util.Algorithms.capitalizeFirstLetter;
import static net.osmand.util.Algorithms.formatDuration;
import static net.osmand.util.Algorithms.objectEquals;
import static net.osmand.util.Algorithms.removeAllFiles;
public class AvailableGPXFragment extends OsmandExpandableListFragment implements
FavoritesFragmentStateHolder, OsmAuthorizationListener, OnTrackFileMoveListener, RenameCallback {

View file

@ -62,7 +62,7 @@ import net.osmand.plus.activities.TrackActivity;
import net.osmand.plus.base.OsmandExpandableListFragment;
import net.osmand.plus.base.PointImageDrawable;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment;
import net.osmand.plus.mapmarkers.fragments.CoordinateInputDialogFragment;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener;

View file

@ -71,7 +71,7 @@ import net.osmand.plus.helpers.WaypointDialogHelper;
import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenuFragment;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkerSelectionFragment;
import net.osmand.plus.mapmarkers.fragments.MapMarkerSelectionFragment;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.profiles.AppModesBottomSheetDialogFragment.UpdateMapRouteMenuListener;
import net.osmand.plus.profiles.ConfigureAppModesBottomSheetDialogFragment;

View file

@ -6,14 +6,12 @@ import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.plus.track.GradientScaleType;
import net.osmand.util.Algorithms;
public class RouteLineDrawInfo {
private static final String LINE_COLOR_DAY = "line_color_day";
private static final String LINE_COLOR_NIGHT = "line_color_night";
private static final String LINE_COLOR_GRADIENT = "line_color_gradient";
private static final String LINE_WIDTH = "line_width";
private static final String NAVIGATION_ICON_ID = "navigation_icon_id";
private static final String NAVIGATION_ICON_COLOR = "navigation_icon_color";
@ -26,7 +24,6 @@ public class RouteLineDrawInfo {
@ColorInt
private Integer colorDay;
private Integer colorNight;
private GradientScaleType scaleType;
private String width;
// temporally parameters to show in preview
@ -40,11 +37,9 @@ public class RouteLineDrawInfo {
public RouteLineDrawInfo(@Nullable @ColorInt Integer colorDay,
@Nullable @ColorInt Integer colorNight,
@Nullable GradientScaleType gradientScaleType,
@Nullable String width) {
this.colorDay = colorDay;
this.colorNight = colorNight;
this.scaleType = gradientScaleType;
this.width = width;
}
@ -55,7 +50,6 @@ public class RouteLineDrawInfo {
public RouteLineDrawInfo(@NonNull RouteLineDrawInfo existed) {
this.colorDay = existed.colorDay;
this.colorNight = existed.colorNight;
this.scaleType = existed.scaleType;
this.width = existed.width;
this.iconId = existed.iconId;
this.iconColor = existed.iconColor;
@ -77,10 +71,6 @@ public class RouteLineDrawInfo {
this.useDefaultColor = useDefaultColor;
}
public void setGradientScaleType(@Nullable GradientScaleType scaleType) {
this.scaleType = scaleType;
}
public void setWidth(@Nullable String width) {
this.width = width;
}
@ -118,11 +108,6 @@ public class RouteLineDrawInfo {
return nightMode ? colorNight : colorDay;
}
@Nullable
public GradientScaleType getGradientScaleType() {
return scaleType;
}
@Nullable
public String getWidth() {
return width;
@ -156,9 +141,6 @@ public class RouteLineDrawInfo {
if (bundle.containsKey(LINE_COLOR_NIGHT)) {
colorNight = bundle.getInt(LINE_COLOR_NIGHT);
}
if (bundle.containsKey(LINE_COLOR_GRADIENT)) {
scaleType = GradientScaleType.getGradientTypeByName(bundle.getString(LINE_COLOR_GRADIENT));
}
width = bundle.getString(LINE_WIDTH);
iconId = bundle.getInt(NAVIGATION_ICON_ID);
iconColor = bundle.getInt(NAVIGATION_ICON_COLOR);
@ -175,9 +157,6 @@ public class RouteLineDrawInfo {
if (colorNight != null) {
bundle.putInt(LINE_COLOR_NIGHT, colorNight);
}
if (scaleType != null) {
bundle.putString(LINE_COLOR_GRADIENT, scaleType.getTypeName());
}
if (width != null) {
bundle.putString(LINE_WIDTH, width);
}
@ -198,7 +177,6 @@ public class RouteLineDrawInfo {
if (!Algorithms.objectEquals(getColor(false), that.getColor(false))) return false;
if (!Algorithms.objectEquals(getColor(true), that.getColor(true))) return false;
if (!Algorithms.objectEquals(scaleType, that.scaleType)) return false;
return Algorithms.objectEquals(width, that.width);
}
@ -206,7 +184,6 @@ public class RouteLineDrawInfo {
public int hashCode() {
int result = colorDay != null ? colorDay.hashCode() : 0;
result = 31 * result + (colorNight != null ? colorNight.hashCode() : 0);
result = 31 * result + (scaleType != null ? scaleType.getTypeName().hashCode() : 0);
result = 31 * result + (width != null ? width.hashCode() : 0);
return result;
}

View file

@ -21,7 +21,6 @@ import net.osmand.AndroidUtils;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.ColorDialogs;
import net.osmand.plus.helpers.enums.DayNightMode;
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
@ -33,8 +32,6 @@ import net.osmand.plus.settings.fragments.HeaderUiAdapter;
import net.osmand.plus.track.AppearanceViewHolder;
import net.osmand.plus.track.ColorsCard;
import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener;
import net.osmand.plus.track.GradientCard;
import net.osmand.plus.track.GradientScaleType;
import net.osmand.plus.widgets.multistatetoggle.RadioItem;
import net.osmand.plus.widgets.multistatetoggle.RadioItem.OnRadioItemClickListener;
import net.osmand.plus.widgets.multistatetoggle.TextToggleButton;
@ -54,7 +51,6 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
private HeaderUiAdapter headerUiAdapter;
private ColorsCard colorsCard;
private GradientCard gradientCard;
private ColorTypeAdapter colorAdapter;
private RecyclerView groupRecyclerView;
private TextView tvDescription;
@ -68,9 +64,7 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
private enum ColorMode {
DEFAULT(R.string.map_widget_renderer, R.drawable.ic_action_map_style),
CUSTOM(R.string.shared_string_custom, R.drawable.ic_action_settings),
ALTITUDE(R.string.altitude, R.drawable.ic_action_hillshade_dark),
SLOPE(R.string.shared_string_slope, R.drawable.ic_action_altitude_ascent);
CUSTOM(R.string.shared_string_custom, R.drawable.ic_action_settings);
ColorMode(int titleId, int iconId) {
this.titleId = titleId;
@ -114,43 +108,28 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
setupRadioGroup(radioGroup);
cardsContainer = (ViewGroup) view.findViewById(R.id.colors_card_container);
createCards(cardsContainer);
createColorSelector(cardsContainer);
initSelectedMode();
}
private void initSelectedMode() {
if (routeLineDrawInfo.getGradientScaleType() == GradientScaleType.ALTITUDE) {
selectedMode = ColorMode.ALTITUDE;
} else if (routeLineDrawInfo.getGradientScaleType() == GradientScaleType.SLOPE) {
selectedMode = ColorMode.SLOPE;
} else {
selectedMode = getRouteLineColor() == null ? ColorMode.DEFAULT : ColorMode.CUSTOM;
}
selectedMode = getRouteLineColor() == null ? ColorMode.DEFAULT : ColorMode.CUSTOM;
modeChanged();
}
private void modeChanged() {
if (selectedMode == ColorMode.DEFAULT) {
themeToggleContainer.setVisibility(View.GONE);
AndroidUiHelper.updateVisibility(colorsCard.getView(), false);
AndroidUiHelper.updateVisibility(gradientCard.getView(), false);
cardsContainer.setVisibility(View.GONE);
routeLineDrawInfo.setUseDefaultColor(true);
changeMapTheme(initMapTheme);
} else if (selectedMode == ColorMode.CUSTOM) {
} else {
themeToggleContainer.setVisibility(View.VISIBLE);
AndroidUiHelper.updateVisibility(colorsCard.getView(), true);
AndroidUiHelper.updateVisibility(gradientCard.getView(), false);
cardsContainer.setVisibility(View.VISIBLE);
routeLineDrawInfo.setUseDefaultColor(false);
changeMapTheme(isNightMap() ? DayNightMode.NIGHT : DayNightMode.DAY);
} else {
gradientCard.setSelectedScaleType(getGradientScaleTypeFromMode());
AndroidUiHelper.updateVisibility(colorsCard.getView(), false);
AndroidUiHelper.updateVisibility(gradientCard.getView(), true);
themeToggleContainer.setVisibility(View.GONE);
routeLineDrawInfo.setUseDefaultColor(false);
}
routeLineDrawInfo.setGradientScaleType(getGradientScaleTypeFromMode());
updateColorItems();
updateDescription();
}
@ -191,7 +170,7 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
}
}
private void createCards(ViewGroup container) {
private void createColorSelector(ViewGroup container) {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
List<Integer> colors = new ArrayList<>();
@ -205,9 +184,6 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
colorsCard = new ColorsCard(mapActivity, selectedColor, targetFragment, colors, preference, null);
colorsCard.setListener(this);
container.addView(colorsCard.build(mapActivity));
gradientCard = new GradientCard(mapActivity, routeLineDrawInfo.getGradientScaleType());
container.addView(gradientCard.build(mapActivity));
}
}
@ -236,17 +212,6 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
return routeLineDrawInfo.getColor(isNightMap());
}
@Nullable
private GradientScaleType getGradientScaleTypeFromMode() {
if (selectedMode == ColorMode.ALTITUDE) {
return GradientScaleType.ALTITUDE;
} else if (selectedMode == ColorMode.SLOPE) {
return GradientScaleType.SLOPE;
} else {
return null;
}
}
private void updateSelectedColor() {
int selectedColor = colorsCard.getSelectedColor();
routeLineDrawInfo.setColor(selectedColor, isNightMap());
@ -270,8 +235,6 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
String colorName = "";
if (selectedMode == ColorMode.DEFAULT) {
colorName = app.getString(R.string.map_widget_renderer);
} else if (selectedMode == ColorMode.ALTITUDE || selectedMode == ColorMode.SLOPE) {
colorName = app.getString(selectedMode.titleId);
} else if (getRouteLineColor() != null) {
int colorNameId = ColorDialogs.getColorName(getRouteLineColor());
colorName = app.getString(colorNameId);
@ -285,12 +248,10 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
String pattern = app.getString(R.string.route_line_use_map_style_appearance);
String color = app.getString(R.string.shared_string_color).toLowerCase();
description = String.format(pattern, color, app.getRendererRegistry().getSelectedRendererName());
} else if (selectedMode == ColorMode.CUSTOM) {
} else {
String pattern = app.getString(R.string.specify_color_for_map_mode);
String mapModeTitle = app.getString(isNightMap() ? NIGHT_TITLE_ID : DAY_TITLE_ID);
description = String.format(pattern, mapModeTitle.toLowerCase());
} else {
description = app.getString(R.string.route_line_use_gradient_coloring);
}
tvDescription.setText(description);
}

View file

@ -6,8 +6,6 @@ import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import net.osmand.AndroidNetworkUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
@ -73,7 +71,7 @@ public class SendSearchQueryBottomSheet extends MenuBottomSheetDialogFragment {
AndroidNetworkUtils.sendRequestAsync(app, "https://osmand.net/api/missing_search", params,
null, true, true, new AndroidNetworkUtils.OnRequestResultListener() {
@Override
public void onResult(@Nullable String result, @Nullable String error) {
public void onResult(String result) {
if (result != null && isAdded()) {
try {
JSONObject obj = new JSONObject(result);

View file

@ -2708,7 +2708,6 @@ public class OsmandSettings {
public final ListStringPreference CUSTOM_ROUTE_LINE_COLORS = (ListStringPreference) new ListStringPreference(this, "custom_route_line_colors", null, ",").makeShared().makeGlobal();
public final CommonPreference<Integer> ROUTE_LINE_COLOR_DAY = new IntPreference(this, "route_line_color", 0).cache().makeProfile();
public final CommonPreference<Integer> ROUTE_LINE_COLOR_NIGHT = new IntPreference(this, "route_line_color_night", 0).cache().makeProfile();
public final CommonPreference<GradientScaleType> ROUTE_LINE_GRADIENT = new EnumStringPreference<>(this, "route_line_gradient", null, new GradientScaleType[] {GradientScaleType.ALTITUDE, GradientScaleType.SLOPE}).cache().makeProfile();
public final CommonPreference<String> ROUTE_LINE_WIDTH = new StringPreference(this, "route_line_width", null).makeProfile();
public final OsmandPreference<Boolean> USE_OSM_LIVE_FOR_ROUTING = new BooleanPreference(this, "enable_osmc_routing", true).makeProfile();

View file

@ -10,6 +10,7 @@ import net.osmand.GPXUtilities.GPXFile;
import net.osmand.data.PointDescription;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.mapmarkers.ItineraryType;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
@ -125,7 +126,7 @@ public class HistoryMarkersSettingsItem extends CollectionSettingsItem<MapMarker
public MapMarkersGroup getMarkersGroup() {
String name = app.getString(R.string.markers_history);
String groupId = ExportSettingsType.HISTORY_MARKERS.name();
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE);
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, ItineraryType.MARKERS);
markersGroup.setMarkers(items);
return markersGroup;
}
@ -142,7 +143,7 @@ public class HistoryMarkersSettingsItem extends CollectionSettingsItem<MapMarker
warnings.add(app.getString(R.string.settings_item_read_error, String.valueOf(getType())));
SettingsHelper.LOG.error("Failed read gpx file", gpxFile.error);
} else {
List<MapMarker> mapMarkers = markersHelper.readMarkersFromGpx(gpxFile, true);
List<MapMarker> mapMarkers = markersHelper.getSaveHelper().readMarkersFromGpx(gpxFile, true);
items.addAll(mapMarkers);
}
}
@ -152,7 +153,7 @@ public class HistoryMarkersSettingsItem extends CollectionSettingsItem<MapMarker
@Nullable
@Override
SettingsItemWriter<? extends SettingsItem> getWriter() {
GPXFile gpxFile = markersHelper.generateGpx(items, true);
GPXFile gpxFile = markersHelper.getSaveHelper().generateGpx(items, true);
return getGpxWriter(gpxFile);
}
}

View file

@ -10,6 +10,7 @@ import net.osmand.GPXUtilities.GPXFile;
import net.osmand.data.PointDescription;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.mapmarkers.ItineraryType;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersDbHelper;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
@ -125,7 +126,7 @@ public class MarkersSettingsItem extends CollectionSettingsItem<MapMarker> {
public MapMarkersGroup getMarkersGroup() {
String name = app.getString(R.string.map_markers);
String groupId = ExportSettingsType.ACTIVE_MARKERS.name();
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE);
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, ItineraryType.MARKERS);
markersGroup.setMarkers(items);
return markersGroup;
}
@ -142,7 +143,7 @@ public class MarkersSettingsItem extends CollectionSettingsItem<MapMarker> {
warnings.add(app.getString(R.string.settings_item_read_error, String.valueOf(getType())));
SettingsHelper.LOG.error("Failed read gpx file", gpxFile.error);
} else {
List<MapMarker> mapMarkers = markersHelper.readMarkersFromGpx(gpxFile, false);
List<MapMarker> mapMarkers = markersHelper.getSaveHelper().readMarkersFromGpx(gpxFile, false);
items.addAll(mapMarkers);
}
}
@ -152,7 +153,7 @@ public class MarkersSettingsItem extends CollectionSettingsItem<MapMarker> {
@Nullable
@Override
SettingsItemWriter<? extends SettingsItem> getWriter() {
GPXFile gpxFile = markersHelper.generateGpx(items, true);
GPXFile gpxFile = markersHelper.getSaveHelper().generateGpx(items, true);
return getGpxWriter(gpxFile);
}
}

View file

@ -30,11 +30,11 @@ import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo;
import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.helpers.LocaleHelper;
import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapmarkers.ItineraryType;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.osmedit.OpenstreetmapPoint;
import net.osmand.plus.osmedit.OsmEditingPlugin;
@ -610,7 +610,7 @@ public class SettingsHelper {
if (!mapMarkers.isEmpty()) {
String name = app.getString(R.string.map_markers);
String groupId = ExportSettingsType.ACTIVE_MARKERS.name();
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE);
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, ItineraryType.MARKERS);
markersGroup.setMarkers(mapMarkers);
myPlacesItems.put(ExportSettingsType.ACTIVE_MARKERS, Collections.singletonList(markersGroup));
}
@ -618,7 +618,7 @@ public class SettingsHelper {
if (!markersHistory.isEmpty()) {
String name = app.getString(R.string.shared_string_history);
String groupId = ExportSettingsType.HISTORY_MARKERS.name();
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE);
MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, ItineraryType.MARKERS);
markersGroup.setMarkers(markersHistory);
myPlacesItems.put(ExportSettingsType.HISTORY_MARKERS, Collections.singletonList(markersGroup));
}

View file

@ -63,7 +63,6 @@ import net.osmand.plus.settings.backend.backup.SettingsHelper;
import net.osmand.plus.settings.fragments.RouteLineAppearanceFragment.OnApplyRouteLineListener;
import net.osmand.plus.track.ColorsCard;
import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener;
import net.osmand.plus.track.GradientScaleType;
import net.osmand.plus.widgets.FlowLayout;
import net.osmand.plus.widgets.OsmandTextFieldBoxes;
import net.osmand.util.Algorithms;
@ -1022,9 +1021,8 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
private RouteLineDrawInfo createRouteLineDrawInfo(@NonNull ApplicationMode appMode) {
Integer colorDay = getRouteLineColor(appMode, settings.ROUTE_LINE_COLOR_DAY);
Integer colorNight = getRouteLineColor(appMode, settings.ROUTE_LINE_COLOR_NIGHT);
GradientScaleType scaleType = settings.ROUTE_LINE_GRADIENT.getModeValue(appMode);
String widthKey = settings.ROUTE_LINE_WIDTH.getModeValue(appMode);
return new RouteLineDrawInfo(colorDay, colorNight, scaleType, widthKey);
return new RouteLineDrawInfo(colorDay, colorNight, widthKey);
}
private Integer getRouteLineColor(@NonNull ApplicationMode appMode,
@ -1037,7 +1035,6 @@ public class ProfileAppearanceFragment extends BaseSettingsFragment implements O
@NonNull RouteLineDrawInfo drawInfo) {
saveRouteLineColor(appMode, settings.ROUTE_LINE_COLOR_DAY, drawInfo.getColor(false));
saveRouteLineColor(appMode, settings.ROUTE_LINE_COLOR_NIGHT, drawInfo.getColor(true));
settings.ROUTE_LINE_GRADIENT.setModeValue(appMode, drawInfo.getGradientScaleType());
settings.ROUTE_LINE_WIDTH.setModeValue(appMode, drawInfo.getWidth());
}

View file

@ -19,24 +19,15 @@ import androidx.annotation.Nullable;
public class GradientCard extends BaseCard {
private final GPXTrackAnalysis gpxTrackAnalysis;
private GPXTrackAnalysis gpxTrackAnalysis;
private GradientScaleType selectedScaleType;
private final int minSlope = 0;
private final int maxSlope = 60;
public GradientCard(@NonNull MapActivity mapActivity, @NonNull GPXTrackAnalysis gpxTrackAnalysis, @Nullable GradientScaleType selectedScaleType) {
super(mapActivity);
this.gpxTrackAnalysis = gpxTrackAnalysis;
this.selectedScaleType = selectedScaleType;
}
public GradientCard(@NonNull MapActivity mapActivity, @Nullable GradientScaleType scaleType) {
super(mapActivity);
this.gpxTrackAnalysis = null;
this.selectedScaleType = scaleType;
}
@Override
public int getCardLayoutId() {
return R.layout.gradient_card;
@ -49,27 +40,14 @@ public class GradientCard extends BaseCard {
return;
}
AndroidUiHelper.updateVisibility(view, true);
TextView minValue = view.findViewById(R.id.min_value);
TextView maxValue = view.findViewById(R.id.max_value);
if (gpxTrackAnalysis != null) {
AndroidUiHelper.updateVisibility(view, true);
double min = RouteColorize.getMinValue(selectedScaleType.toColorizationType(), gpxTrackAnalysis);
double max = RouteColorize.getMaxValue(selectedScaleType.toColorizationType(),
gpxTrackAnalysis, min, app.getSettings().getApplicationMode().getMaxSpeed());
minValue.setText(formatValue(min));
maxValue.setText(formatValue(max));
AndroidUiHelper.updateVisibility(view.findViewById(R.id.space), true);
} else {
if (selectedScaleType == GradientScaleType.ALTITUDE) {
minValue.setText(R.string.shared_string_min_height);
maxValue.setText(R.string.shared_string_max_height);
} else if (selectedScaleType == GradientScaleType.SLOPE) {
minValue.setText(formatValue(minSlope));
maxValue.setText(formatValue(maxSlope));
}
AndroidUiHelper.updateVisibility(view.findViewById(R.id.space), false);
}
double min = RouteColorize.getMinValue(selectedScaleType.toColorizationType(), gpxTrackAnalysis);
double max = RouteColorize.getMaxValue(selectedScaleType.toColorizationType(),
gpxTrackAnalysis, min, app.getSettings().getApplicationMode().getMaxSpeed());
minValue.setText(formatValue(min));
maxValue.setText(formatValue(max));
}
public void setSelectedScaleType(GradientScaleType type) {
@ -81,7 +59,7 @@ public class GradientCard extends BaseCard {
if (selectedScaleType == GradientScaleType.ALTITUDE) {
return OsmAndFormatter.getFormattedAlt(value, app);
} else if (selectedScaleType == GradientScaleType.SLOPE) {
return app.getString(R.string.ltr_or_rtl_combine_via_space, String.valueOf((int) value), "%");
return (int) value + " %";
}
String speed = OsmAndFormatter.getFormattedSpeed((float) value, app);
String speedUnit = app.getSettings().SPEED_SYSTEM.get().toShortString(app);

View file

@ -357,7 +357,19 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
@Override
public PointDescription getObjectName(Object o) {
if (o instanceof Amenity) {
return new PointDescription(PointDescription.POINT_TYPE_POI, getAmenityName((Amenity) o));
Amenity amenity = (Amenity) o;
String preferredLang = app.getSettings().MAP_PREFERRED_LOCALE.get();
boolean transliterateNames = app.getSettings().MAP_TRANSLITERATE_NAMES.get();
if (amenity.getType().isWiki()) {
if (Algorithms.isEmpty(preferredLang)) {
preferredLang = app.getLanguage();
}
preferredLang = OsmandPlugin.onGetMapObjectsLocale(amenity, preferredLang);
}
return new PointDescription(PointDescription.POINT_TYPE_POI,
amenity.getName(preferredLang, transliterateNames));
}
return null;
}
@ -419,20 +431,8 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
@Override
public String getText(Amenity o) {
return getAmenityName(o);
}
private String getAmenityName(Amenity amenity) {
String locale = app.getSettings().MAP_PREFERRED_LOCALE.get();
if (amenity.getType().isWiki()) {
if (Algorithms.isEmpty(locale)) {
locale = app.getLanguage();
}
locale = OsmandPlugin.onGetMapObjectsLocale(amenity, locale);
}
return amenity.getName(locale, app.getSettings().MAP_TRANSLITERATE_NAMES.get());
return o.getName(view.getSettings().MAP_PREFERRED_LOCALE.get(),
view.getSettings().MAP_TRANSLITERATE_NAMES.get());
}
@Override

View file

@ -4,7 +4,6 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
@ -12,7 +11,6 @@ import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
@ -46,7 +44,6 @@ import net.osmand.plus.routing.RouteService;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.routing.TransportRoutingHelper;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.track.GradientScaleType;
import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.layers.ContextMenuLayer.IContextMenuProvider;
@ -57,7 +54,6 @@ import net.osmand.plus.views.layers.geometry.RouteGeometryWayContext;
import net.osmand.render.RenderingRuleProperty;
import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage;
import net.osmand.router.RouteColorize;
import net.osmand.router.TransportRouteResult;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
@ -113,7 +109,6 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider {
private int routeLineColor;
private Integer directionArrowsColor;
private GradientScaleType gradientScaleType = null;
public RouteLayer(RoutingHelper helper) {
this.helper = helper;
@ -141,8 +136,6 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider {
attrs.defaultWidth = (int) (12 * density);
attrs.defaultWidth3 = (int) (7 * density);
attrs.defaultColor = view.getResources().getColor(R.color.nav_track);
attrs.shadowPaint.setColor(0x80000000);
attrs.shadowPaint.setStrokeCap(Cap.ROUND);
attrs.paint3.setStrokeCap(Cap.BUTT);
attrs.paint3.setColor(Color.WHITE);
attrs.paint2.setStrokeCap(Cap.BUTT);
@ -338,24 +331,14 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider {
DrawSettings settings,
RouteLineDrawInfo drawInfo) {
updateAttrs(settings, tileBox);
updateRouteColors(nightMode);
paintRouteLinePreview.setColor(getRouteLineColor());
paintRouteLinePreview.setStrokeWidth(getRouteLineWidth(tileBox));
int centerX = drawInfo.getCenterX();
int centerY = drawInfo.getCenterY();
int screenHeight = drawInfo.getScreenHeight();
updateRouteColors(nightMode);
updateRouteGradient();
LinearGradient gradient = null;
if (gradientScaleType == GradientScaleType.ALTITUDE || gradientScaleType == GradientScaleType.SLOPE) {
int[] colors = new int[] {RouteColorize.RED, RouteColorize.YELLOW, RouteColorize.GREEN};
float[] positions = new float[] {0, 0.5f, 1};
gradient = new LinearGradient(centerX, 0, centerX, screenHeight, colors, positions, Shader.TileMode.CLAMP);
}
paintRouteLinePreview.setShader(gradient);
paintRouteLinePreview.setColor(getRouteLineColor());
canvas.drawLine(centerX, 0, centerX, screenHeight, paintRouteLinePreview);
if (previewIcon == null) {
@ -477,14 +460,6 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider {
routeLineColor = color;
}
private void updateRouteGradient() {
if (routeLineDrawInfo != null) {
gradientScaleType = routeLineDrawInfo.getGradientScaleType();
} else {
gradientScaleType = view.getSettings().ROUTE_LINE_GRADIENT.getModeValue(helper.getAppMode());
}
}
private float getRouteLineWidth(@NonNull RotatedTileBox tileBox) {
String widthKey;
if (routeLineDrawInfo != null) {
@ -549,10 +524,9 @@ public class RouteLayer extends OsmandMapLayer implements IContextMenuProvider {
boolean directTo = route.getRouteService() == RouteService.DIRECT_TO;
boolean straight = route.getRouteService() == RouteService.STRAIGHT;
publicTransportRouteGeometry.clearRoute();
routeGeometry.updateRoute(tb, route);
updateRouteColors(nightMode);
updateRouteGradient();
routeGeometry.setRouteStyleParams(getRouteLineColor(), getRouteLineWidth(tb), getDirectionArrowsColor(), gradientScaleType);
routeGeometry.updateRoute(tb, route, view.getApplication());
routeGeometry.setRouteStyleParams(getRouteLineColor(), getRouteLineWidth(tb), getDirectionArrowsColor());
if (directTo) {
routeGeometry.drawSegments(tb, canvas, topLatitude, leftLongitude, bottomLatitude, rightLongitude,
null, 0);

View file

@ -126,7 +126,7 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
zooms.clear();
}
protected PathGeometryZoom getGeometryZoom(RotatedTileBox tb, Map<Integer, PathGeometryZoom> zooms) {
private PathGeometryZoom getGeometryZoom(RotatedTileBox tb) {
int zoom = tb.getZoom();
PathGeometryZoom zm = zooms.size() > zoom ? zooms.get(zoom) : null;
if (zm == null) {
@ -139,11 +139,6 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
@NonNull
public abstract GeometryWayStyle<?> getDefaultWayStyle();
@NonNull
protected Map<Integer, GeometryWayStyle<?>> getStyleMap() {
return styleMap;
}
public Location getNextVisiblePoint() {
return null;
}
@ -153,7 +148,7 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
if (locationProvider == null || locationProvider.getSize() == 0) {
return;
}
PathGeometryZoom geometryZoom = getGeometryZoom(tb, zooms);
PathGeometryZoom geometryZoom = getGeometryZoom(tb);
TByteArrayList simplification = geometryZoom.getSimplifyPoints();
List<Double> odistances = geometryZoom.getDistances();
@ -173,27 +168,32 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
int previous = -1;
for (int i = startLocationIndex; i < locationProvider.getSize(); i++) {
style = getStyle(i, defaultWayStyle);
if (shouldSkipLocation(simplification, styleMap, i)) {
if (simplification.getQuick(i) == 0 && !styleMap.containsKey(i)) {
continue;
}
double lat = locationProvider.getLatitude(i);
double lon = locationProvider.getLongitude(i);
if (shouldAddLocation(simplification, leftLongitude, rightLongitude, bottomLatitude, topLatitude,
locationProvider, i)) {
double dist = previous == -1 ? 0 : odistances.get(i);
if (!previousVisible) {
double prevLat = Double.NaN;
double prevLon = Double.NaN;
if (previous != -1) {
addLocation(tb, previous, style, tx, ty, angles, distances, dist, styles);
prevLat = locationProvider.getLatitude(previous);
prevLon = locationProvider.getLongitude(previous);
} else if (lastProjection != null) {
double prevLat = lastProjection.getLatitude();
double prevLon = lastProjection.getLongitude();
if (!Double.isNaN(prevLat) && !Double.isNaN(prevLon)) {
addLocation(tb, prevLat, prevLon, getStyle(i - 1, style), tx, ty, angles, distances, dist, styles); // first point
}
prevLat = lastProjection.getLatitude();
prevLon = lastProjection.getLongitude();
}
if (!Double.isNaN(prevLat) && !Double.isNaN(prevLon)) {
addLocation(tb, prevLat, prevLon, getStyle(i - 1, style), tx, ty, angles, distances, dist, styles); // first point
}
}
addLocation(tb, i, style, tx, ty, angles, distances, dist, styles);
addLocation(tb, lat, lon, style, tx, ty, angles, distances, dist, styles);
previousVisible = true;
} else if (previousVisible) {
addLocation(tb, i, style, tx, ty, angles, distances, previous == -1 ? 0 : odistances.get(i), styles);
addLocation(tb, lat, lon, style, tx, ty, angles, distances, previous == -1 ? 0 : odistances.get(i), styles);
double distToFinish = 0;
for (int ki = i + 1; ki < odistances.size(); ki++) {
distToFinish += odistances.get(ki);
@ -207,10 +207,6 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
drawRouteSegment(tb, canvas, tx, ty, angles, distances, 0, styles);
}
protected boolean shouldSkipLocation(TByteArrayList simplification, Map<Integer, GeometryWayStyle<?>> styleMap, int locationIdx) {
return simplification.getQuick(locationIdx) == 0 && !styleMap.containsKey(locationIdx);
}
protected boolean shouldAddLocation(TByteArrayList simplification, double leftLon, double rightLon, double bottomLat,
double topLat, GeometryWayProvider provider, int currLocationIdx) {
double lat = provider.getLatitude(currLocationIdx);
@ -218,14 +214,7 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
return leftLon <= lon && lon <= rightLon && bottomLat <= lat && lat <= topLat;
}
protected void addLocation(RotatedTileBox tb, int locationIdx, GeometryWayStyle<?> style,
List<Float> tx, List<Float> ty, List<Double> angles, List<Double> distances,
double dist, List<GeometryWayStyle<?>> styles) {
addLocation(tb, locationProvider.getLatitude(locationIdx), locationProvider.getLongitude(locationIdx),
style, tx, ty, angles, distances, dist, styles);
}
protected void addLocation(RotatedTileBox tb, double latitude, double longitude, GeometryWayStyle<?> style,
private void addLocation(RotatedTileBox tb, double latitude, double longitude, GeometryWayStyle<?> style,
List<Float> tx, List<Float> ty, List<Double> angles, List<Double> distances,
double dist, List<GeometryWayStyle<?>> styles) {
float x = tb.getPixXFromLatLon(latitude, longitude);
@ -367,26 +356,13 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
List<Pair<Path, GeometryWayStyle<?>>> paths = new ArrayList<>();
canvas.rotate(-tb.getRotate(), tb.getCenterPixelX(), tb.getCenterPixelY());
calculatePath(tb, tx, ty, styles, paths);
drawer.drawFullBorder(canvas, tb.getZoom(), paths);
drawer.drawSegmentBorder(canvas, tb.getZoom(), paths.get(0).first, paths.get(0).second);
for (int i = 1; i <= paths.size(); i++) {
if (i != paths.size()) {
Pair<Path, GeometryWayStyle<?>> prev = paths.get(i);
if (prev.second.hasPathLine()) {
drawer.drawSegmentBorder(canvas, tb.getZoom(), prev.first, prev.second);
}
}
Pair<Path, GeometryWayStyle<?>> pc = paths.get(i - 1);
for (Pair<Path, GeometryWayStyle<?>> pc : paths) {
GeometryWayStyle<?> style = pc.second;
if (style.hasPathLine()) {
drawer.drawPath(canvas, pc.first, style);
}
}
context.clearCustomColor();
context.clearCustomShader();
}
drawer.drawArrowsOverPath(canvas, tb, tx, ty, angles, distances, distToFinish, styles);
} finally {
@ -396,7 +372,7 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
}
}
protected static class PathGeometryZoom {
private static class PathGeometryZoom {
private static final float EPSILON_IN_DPI = 2;
@ -414,7 +390,12 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
angles = new ArrayList<>(size);
if (simplify) {
simplifyPoints.fill(0, size, (byte) 0);
simplify(tb, locationProvider, simplifyPoints);
if (size > 0) {
simplifyPoints.set(0, (byte) 1);
}
double distInPix = (tb.getDistance(0, 0, tb.getPixWidth(), 0) / tb.getPixWidth());
double cullDistance = (distInPix * (EPSILON_IN_DPI * Math.max(1, tb.getDensity())));
cullRamerDouglasPeucker(simplifyPoints, locationProvider, 0, size - 1, cullDistance);
} else {
simplifyPoints.fill(0, size, (byte) 1);
}
@ -441,16 +422,6 @@ public abstract class GeometryWay<T extends GeometryWayContext, D extends Geomet
}
}
protected void simplify(RotatedTileBox tb, GeometryWayProvider locationProvider, TByteArrayList simplifyPoints) {
int size = locationProvider.getSize();
if (size > 0) {
simplifyPoints.set(0, (byte) 1);
}
double distInPix = (tb.getDistance(0, 0, tb.getPixWidth(), 0) / tb.getPixWidth());
double cullDistance = (distInPix * (EPSILON_IN_DPI * Math.max(1, tb.getDensity())));
cullRamerDouglasPeucker(simplifyPoints, locationProvider, 0, size - 1, cullDistance);
}
public List<Double> getDistances() {
return distances;
}

View file

@ -105,10 +105,6 @@ public abstract class GeometryWayContext {
attrs.customColor = 0;
}
public void clearCustomShader() {
attrs.customColorPaint.setShader(null);
}
public int getStrokeColor(int sourceColor) {
return ColorUtils.blendARGB(sourceColor, Color.BLACK, 0.6f);
}

View file

@ -7,7 +7,6 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.util.Pair;
import net.osmand.data.RotatedTileBox;
@ -90,12 +89,6 @@ public class GeometryWayDrawer<T extends GeometryWayContext> {
}
}
protected void drawFullBorder(Canvas canvas, int zoom, List<Pair<Path, GeometryWayStyle<?>>> paths) {
}
protected void drawSegmentBorder(Canvas canvas, int zoom, Path path, GeometryWayStyle<?> style) {
}
protected PathPoint getArrowPathPoint(float iconx, float icony, GeometryWayStyle<?> style, double angle) {
return new PathPoint(iconx, icony, angle, style);
}

View file

@ -2,32 +2,20 @@ package net.osmand.plus.views.layers.geometry;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.PointF;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.Location;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.track.GradientScaleType;
import net.osmand.router.RouteColorize;
import net.osmand.router.RouteColorize.RouteColorizationPoint;
import net.osmand.util.Algorithms;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import gnu.trove.list.array.TByteArrayList;
public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, RouteGeometryWayDrawer> {
import net.osmand.Location;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.routing.RoutingHelper;
import java.util.Collections;
import java.util.List;
public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, GeometryWayDrawer<RouteGeometryWayContext>> {
private RoutingHelper helper;
private RouteCalculationResult route;
@ -35,101 +23,34 @@ public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, Route
private Integer customColor;
private Float customWidth;
private Integer customPointColor;
private GradientScaleType scaleType;
private GradientScaleType prevScaleType;
public RouteGeometryWay(RouteGeometryWayContext context) {
super(context, new RouteGeometryWayDrawer(context, true));
super(context, new GeometryWayDrawer<>(context));
this.helper = context.getApp().getRoutingHelper();
}
public void setRouteStyleParams(@Nullable @ColorInt Integer color,
@Nullable Float width,
@Nullable @ColorInt Integer pointColor,
@Nullable GradientScaleType scaleType) {
if (scaleType != null && !Algorithms.objectEquals(customWidth, width)) {
for (GeometryWayStyle<?> style : getStyleMap().values()) {
style.width = width;
}
}
@Nullable @ColorInt Integer pointColor) {
this.customColor = color;
this.customWidth = width;
this.customPointColor = pointColor;
this.prevScaleType = this.scaleType;
this.scaleType = scaleType;
if (width != null) {
getContext().getAttrs().shadowPaint.setStrokeWidth(width + getContext().getDensity() * 2);
}
getContext().getAttrs().customColorPaint.setStrokeCap(scaleType != null ? Paint.Cap.ROUND : Paint.Cap.BUTT);
}
public void updateRoute(RotatedTileBox tb, RouteCalculationResult route, OsmandApplication app) {
if (tb.getMapDensity() != getMapDensity() || this.route != route || prevScaleType != scaleType) {
@NonNull
@Override
public GeometryWayStyle<RouteGeometryWayContext> getDefaultWayStyle() {
Paint paint = getContext().getAttrs().paint;
int color = customColor != null ? customColor : paint.getColor();
float width = customWidth != null ? customWidth : paint.getStrokeWidth();
return new GeometrySolidWayStyle(getContext(), color, width, customPointColor);
}
public void updateRoute(RotatedTileBox tb, RouteCalculationResult route) {
if (tb.getMapDensity() != getMapDensity() || this.route != route) {
this.route = route;
List<Location> locations = route != null ? route.getImmutableAllLocations() : Collections.<Location>emptyList();
if (scaleType == null || locations.size() < 2) {
updateWay(locations, tb);
return;
}
GPXFile gpxFile = GpxUiHelper.makeGpxFromLocations(locations, app);
if (!gpxFile.hasAltitude) {
updateWay(locations, tb);
return;
}
// Start point can have wrong zero altitude
List<GPXUtilities.WptPt> pts = gpxFile.tracks.get(0).segments.get(0).points;
GPXUtilities.WptPt firstPt = pts.get(0);
if (firstPt.ele == 0) {
firstPt.ele = pts.get(1).ele;
}
RouteColorize routeColorize = new RouteColorize(tb.getZoom(), gpxFile, null, scaleType.toColorizationType(), 0);
List<RouteColorizationPoint> points = routeColorize.getResult(false);
updateWay(new GradientGeometryWayProvider(routeColorize, points), createStyles(points), tb);
}
}
private Map<Integer, GeometryWayStyle<?>> createStyles(List<RouteColorizationPoint> points) {
Map<Integer, GeometryWayStyle<?>> styleMap = new TreeMap<>();
for (int i = 1; i < points.size(); i++) {
GeometryGradientWayStyle style = getGradientWayStyle();
style.startColor = points.get(i - 1).color;
style.endColor = points.get(i).color;
styleMap.put(i, style);
}
return styleMap;
}
@Override
protected boolean shouldSkipLocation(TByteArrayList simplification, Map<Integer, GeometryWayStyle<?>> styleMap, int locationIdx) {
return scaleType == null ?
super.shouldSkipLocation(simplification, styleMap, locationIdx) :
simplification.getQuick(locationIdx) == 0;
}
@Override
protected void addLocation(RotatedTileBox tb, int locationIdx, GeometryWayStyle<?> style, List<Float> tx, List<Float> ty, List<Double> angles, List<Double> distances, double dist, List<GeometryWayStyle<?>> styles) {
super.addLocation(tb, getLocationProvider().getLatitude(locationIdx),
getLocationProvider().getLongitude(locationIdx), style, tx, ty, angles, distances, dist, styles);
if (scaleType != null && tx.size() - 1 > 0) {
int idx = tx.size() - 1;
((GeometryGradientWayStyle) style).startXY = new PointF(tx.get(idx - 1), ty.get(idx - 1));
((GeometryGradientWayStyle) style).endXY = new PointF(tx.get(idx), ty.get(idx));
}
}
@Override
protected void addLocation(RotatedTileBox tb, double latitude, double longitude, GeometryWayStyle<?> style, List<Float> tx, List<Float> ty, List<Double> angles, List<Double> distances, double dist, List<GeometryWayStyle<?>> styles) {
super.addLocation(tb, latitude, longitude, style, tx, ty, angles, distances, dist, styles);
if (scaleType != null) {
int lastIdx = tx.size() - 1;
((GeometryGradientWayStyle) style).startXY = new PointF(tx.get(lastIdx), ty.get(lastIdx));
((GeometryGradientWayStyle) style).endXY = new PointF(tx.get(lastIdx), ty.get(lastIdx));
((GeometryGradientWayStyle) style).startColor = getGradientLocationProvider().getColor(0);
((GeometryGradientWayStyle) style).endColor = getGradientLocationProvider().getColor(0);
updateWay(locations, tb);
}
}
@ -140,125 +61,17 @@ public class RouteGeometryWay extends GeometryWay<RouteGeometryWayContext, Route
}
}
@NonNull
@Override
public GeometryWayStyle<RouteGeometryWayContext> getDefaultWayStyle() {
Paint paint = getContext().getAttrs().paint;
int color = customColor != null ? customColor : paint.getColor();
float width = customWidth != null ? customWidth : paint.getStrokeWidth();
return scaleType == null ?
new GeometrySolidWayStyle(getContext(), color, width, customPointColor) :
new GeometryGradientWayStyle(getContext(), color, width);
}
private GeometryGradientWayStyle getGradientWayStyle() {
return (GeometryGradientWayStyle) getDefaultWayStyle();
}
@Override
public Location getNextVisiblePoint() {
return helper.getRoute().getCurrentStraightAnglePoint();
}
private GradientGeometryWayProvider getGradientLocationProvider() {
return (GradientGeometryWayProvider) getLocationProvider();
}
@Override
protected PathGeometryZoom getGeometryZoom(RotatedTileBox tb, Map<Integer, PathGeometryZoom> zooms) {
if (scaleType == null) {
return super.getGeometryZoom(tb, zooms);
}
int zoom = tb.getZoom();
PathGeometryZoom zm = zooms.get(zoom);
if (zm == null) {
zm = new GradientPathGeometryZoom(getLocationProvider(), tb, true);
zooms.put(zoom, zm);
}
return zm;
}
private static class GradientGeometryWayProvider implements GeometryWayProvider {
private final RouteColorize routeColorize;
private final List<RouteColorizationPoint> locations;
public GradientGeometryWayProvider(RouteColorize routeColorize, List<RouteColorizationPoint> locations) {
this.routeColorize = routeColorize;
this.locations = locations;
}
public List<RouteColorizationPoint> simplify(int zoom) {
return routeColorize.simplify(zoom);
}
public int getColor(int index) {
return locations.get(index).color;
}
@Override
public double getLatitude(int index) {
return locations.get(index).lat;
}
@Override
public double getLongitude(int index) {
return locations.get(index).lon;
}
@Override
public int getSize() {
return locations.size();
}
}
private static class GradientPathGeometryZoom extends PathGeometryZoom {
public GradientPathGeometryZoom(GeometryWayProvider locationProvider, RotatedTileBox tb, boolean simplify) {
super(locationProvider, tb, simplify);
}
@Override
protected void simplify(RotatedTileBox tb, GeometryWayProvider locationProvider, TByteArrayList simplifyPoints) {
if (locationProvider instanceof GradientGeometryWayProvider) {
GradientGeometryWayProvider provider = (GradientGeometryWayProvider) locationProvider;
List<RouteColorizationPoint> simplified = provider.simplify(tb.getZoom());
for (RouteColorizationPoint location : simplified) {
simplifyPoints.set(location.id, (byte) 1);
}
}
}
}
public static class GeometryGradientWayStyle extends GeometryWayStyle<RouteGeometryWayContext> {
public int startColor;
public int endColor;
public PointF startXY;
public PointF endXY;
public GeometryGradientWayStyle(RouteGeometryWayContext context, Integer color, Float width) {
super(context, color, width);
}
@Override
public Bitmap getPointBitmap() {
return getContext().getArrowBitmap();
}
@Override
public boolean equals(Object other) {
return this == other;
}
}
private static class GeometrySolidWayStyle extends GeometryWayStyle<RouteGeometryWayContext> {
private Integer pointColor;
GeometrySolidWayStyle(RouteGeometryWayContext context, Integer color, Float width,
Integer pointColor) {
Integer pointColor) {
super(context, color, width);
this.pointColor = pointColor;
}

View file

@ -1,57 +0,0 @@
package net.osmand.plus.views.layers.geometry;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Shader;
import android.util.Pair;
import net.osmand.plus.views.MapTileLayer;
import net.osmand.plus.views.layers.geometry.RouteGeometryWay.GeometryGradientWayStyle;
import java.util.List;
public class RouteGeometryWayDrawer extends GeometryWayDrawer<RouteGeometryWayContext> {
private static final int BORDER_TYPE_ZOOM_THRESHOLD = MapTileLayer.DEFAULT_MAX_ZOOM + MapTileLayer.OVERZOOM_IN;
private final boolean drawBorder;
public RouteGeometryWayDrawer(RouteGeometryWayContext context, boolean drawBorder) {
super(context);
this.drawBorder = drawBorder;
}
@Override
protected void drawFullBorder(Canvas canvas, int zoom, List<Pair<Path, GeometryWayStyle<?>>> paths) {
if (drawBorder && zoom < BORDER_TYPE_ZOOM_THRESHOLD) {
Paint borderPaint = getContext().getAttrs().shadowPaint;
Path fullPath = new Path();
for (Pair<Path, GeometryWayStyle<?>> path : paths) {
if (path.second instanceof GeometryGradientWayStyle) {
fullPath.addPath(path.first);
}
}
canvas.drawPath(fullPath, borderPaint);
}
}
@Override
public void drawPath(Canvas canvas, Path path, GeometryWayStyle<?> s) {
if (s instanceof GeometryGradientWayStyle) {
GeometryGradientWayStyle style = (GeometryGradientWayStyle) s;
LinearGradient gradient = new LinearGradient(style.startXY.x, style.startXY.y, style.endXY.x, style.endXY.y,
style.startColor, style.endColor, Shader.TileMode.CLAMP);
getContext().getAttrs().customColorPaint.setShader(gradient);
}
super.drawPath(canvas, path, s);
}
@Override
protected void drawSegmentBorder(Canvas canvas, int zoom, Path path, GeometryWayStyle<?> style) {
if (drawBorder && zoom >= BORDER_TYPE_ZOOM_THRESHOLD) {
canvas.drawPath(path, getContext().getAttrs().shadowPaint);
}
}
}

View file

@ -14,7 +14,7 @@ import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.fragments.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.views.AnimateDraggingMapThread;
import net.osmand.plus.views.DirectionDrawable;

View file

@ -20,7 +20,7 @@ import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dialogs.ConfigureMapMenu;
import net.osmand.plus.mapmarkers.DirectionIndicationDialogFragment;
import net.osmand.plus.mapmarkers.fragments.DirectionIndicationDialogFragment;
import net.osmand.plus.quickaction.QuickActionListFragment;
import net.osmand.plus.views.layers.MapInfoLayer;
import net.osmand.plus.views.layers.MapQuickActionLayer;