Save itinerary.gpx

This commit is contained in:
Vitaliy 2021-04-22 05:09:03 +03:00
parent 4cc970c0d2
commit 311771f03c
6 changed files with 430 additions and 230 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

@ -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

@ -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.ItineraryGroup;
import net.osmand.plus.mapmarkers.ItineraryHelper;
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;
@ -280,16 +281,16 @@ public class FavouritesDbHelper {
}
private void runSyncWithMarkers(FavoriteGroup favGroup) {
MapMarkersHelper helper = context.getMapMarkersHelper();
MapMarkersGroup group = helper.getMarkersGroup(favGroup);
ItineraryHelper helper = context.getItineraryHelper();
ItineraryGroup group = helper.getMarkersGroup(favGroup);
if (group != null) {
helper.runSynchronization(group);
}
}
private boolean removeFromMarkers(FavoriteGroup favGroup) {
MapMarkersHelper helper = context.getMapMarkersHelper();
MapMarkersGroup group = helper.getMarkersGroup(favGroup);
ItineraryHelper helper = context.getItineraryHelper();
ItineraryGroup group = helper.getMarkersGroup(favGroup);
if (group != null) {
helper.removeMarkersGroup(group);
return true;
@ -298,7 +299,7 @@ public class FavouritesDbHelper {
}
private void addToMarkers(FavoriteGroup favGroup) {
MapMarkersHelper helper = context.getMapMarkersHelper();
ItineraryHelper helper = context.getItineraryHelper();
helper.addOrEnableGroup(favGroup);
}
@ -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

@ -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,26 +31,20 @@ 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;
public class MapMarkersHelper {
public class ItineraryHelper {
public static final int MAP_MARKERS_COLORS_COUNT = 7;
@ -65,24 +55,22 @@ 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);
private static final Log LOG = PlatformUtil.getLog(ItineraryHelper.class);
@Retention(RetentionPolicy.SOURCE)
@IntDef({BY_NAME, BY_DISTANCE_DESC, BY_DISTANCE_ASC, BY_DATE_ADDED_DESC, BY_DATE_ADDED_ASC})
public @interface MapMarkersSortByDef {
}
private OsmandApplication ctx;
private OsmandApplication app;
private MapMarkersDbHelper markersDbHelper;
private ItinerarySaveHelper saveHelper;
private ExecutorService executorService = Executors.newSingleThreadExecutor();
private List<MapMarker> mapMarkers = new ArrayList<>();
private List<MapMarker> mapMarkersHistory = new ArrayList<>();
private List<MapMarkersGroup> mapMarkersGroups = new ArrayList<>();
private List<ItineraryGroup> itineraryGroups = new ArrayList<>();
private List<MapMarkerChangedListener> listeners = new ArrayList<>();
private Set<OnGroupSyncedListener> syncListeners = new HashSet<>();
@ -97,26 +85,31 @@ public class MapMarkersHelper {
return mapMarkersHistory;
}
public List<MapMarkersGroup> getMapMarkersGroups() {
return mapMarkersGroups;
public List<ItineraryGroup> getItineraryGroups() {
return itineraryGroups;
}
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);
public ItinerarySaveHelper getSaveHelper() {
return saveHelper;
}
public ItineraryHelper(OsmandApplication app) {
this.app = app;
saveHelper = new ItinerarySaveHelper(app, this);
markersDbHelper = app.getMapMarkersDbHelper();
planRouteContext = new MarkersPlanRouteContext(app);
markersDbHelper.removeDisabledGroups();
loadMarkers();
loadGroups();
@ -133,7 +126,7 @@ public class MapMarkersHelper {
sortMarkers(markersHistory, true, BY_DATE_ADDED_DESC);
addToMapMarkersHistoryList(markersHistory);
if (!ctx.isApplicationInitializing()) {
if (!app.isApplicationInitializing()) {
lookupAddressAll();
}
}
@ -152,13 +145,13 @@ public class MapMarkersHelper {
}
}
MapMarkersGroup noGroup = null;
ItineraryGroup noGroup = null;
for (MapMarker marker : allMarkers) {
MapMarkersGroup group = groupsMap.get(marker.groupKey);
ItineraryGroup group = groupsMap.get(marker.groupKey);
if (group == null) {
if (noGroup == null) {
noGroup = new MapMarkersGroup();
noGroup = new ItineraryGroup();
noGroup.setCreationDate(Long.MAX_VALUE);
}
noGroup.getMarkers().add(marker);
@ -170,7 +163,7 @@ public class MapMarkersHelper {
}
}
mapMarkersGroups = new ArrayList<>(groupsMap.values());
itineraryGroups = new ArrayList<>(groupsMap.values());
if (noGroup != null) {
sortMarkers(noGroup.getMarkers(), false, BY_DATE_ADDED_DESC);
addToGroupsList(noGroup);
@ -178,13 +171,17 @@ public class MapMarkersHelper {
sortGroups();
for (MapMarkersGroup group : mapMarkersGroups) {
for (ItineraryGroup group : itineraryGroups) {
updateGroup(group);
}
}
private void saveGroups() {
saveHelper.saveGroups();
}
public void syncAllGroupsAsync() {
for (MapMarkersGroup gr : mapMarkersGroups) {
for (ItineraryGroup gr : itineraryGroups) {
if (gr.getId() != null && gr.getName() != null) {
runSynchronization(gr);
}
@ -201,7 +198,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 +206,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 +214,7 @@ public class MapMarkersHelper {
refreshMarker(mapMarker);
}
}, null);
ctx.getGeocodingLookupService().lookupAddress(lookupRequest);
app.getGeocodingLookupService().lookupAddress(lookupRequest);
}
}
@ -234,7 +231,7 @@ public class MapMarkersHelper {
private void cancelPointAddressRequests(LatLon latLon) {
if (latLon != null) {
ctx.getGeocodingLookupService().cancel(latLon);
app.getGeocodingLookupService().cancel(latLon);
}
}
@ -295,16 +292,16 @@ 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);
}
}
});
}
public void runSynchronization(final @NonNull MapMarkersGroup group) {
ctx.runInUIThread(new Runnable() {
public void runSynchronization(final @NonNull ItineraryGroup group) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
new SyncGroupTask(group).executeOnExecutor(executorService);
@ -312,7 +309,7 @@ public class MapMarkersHelper {
});
}
public MapMarkersGroup getMarkersGroup(GPXFile gpx) {
public ItineraryGroup getMarkersGroup(GPXFile gpx) {
if (gpx == null || gpx.path == null) {
return null;
}
@ -334,9 +331,9 @@ public class MapMarkersHelper {
return gr;
}
public MapMarkersGroup addOrEnableGroup(@NonNull GPXFile file) {
public ItineraryGroup addOrEnableGroup(@NonNull GPXFile file) {
updateGpxShowAsMarkers(new File(file.path));
MapMarkersGroup gr = getMarkersGroup(file);
ItineraryGroup gr = getMarkersGroup(file);
if (gr == null) {
gr = createGPXMarkerGroup(new File(file.path));
addGroupInternally(gr);
@ -345,8 +342,8 @@ public class MapMarkersHelper {
return gr;
}
public MapMarkersGroup addOrEnableGroup(@NonNull FavoriteGroup group) {
MapMarkersGroup gr = getMarkersGroup(group);
public ItineraryGroup addOrEnableGroup(@NonNull FavoriteGroup group) {
ItineraryGroup gr = getMarkersGroup(group);
if (gr == null) {
gr = createFavMarkerGroup(group);
addGroupInternally(gr);
@ -355,9 +352,9 @@ public class MapMarkersHelper {
return gr;
}
public void enableGroup(@NonNull MapMarkersGroup gr) {
public void enableGroup(@NonNull ItineraryGroup gr) {
// check if group doesn't exist internally
if (!mapMarkersGroups.contains(gr)) {
if (!itineraryGroups.contains(gr)) {
addGroupInternally(gr);
}
if (gr.isDisabled()) {
@ -366,21 +363,21 @@ public class MapMarkersHelper {
runSynchronization(gr);
}
private void addGroupInternally(MapMarkersGroup gr) {
private void addGroupInternally(ItineraryGroup gr) {
markersDbHelper.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);
}
}
private void addHistoryMarkersToGroup(@NonNull MapMarkersGroup group) {
private void addHistoryMarkersToGroup(@NonNull ItineraryGroup group) {
List<MapMarker> historyMarkers = new ArrayList<>(mapMarkersHistory);
for (MapMarker m : historyMarkers) {
if (m.groupKey != null && group.getId() != null && m.groupKey.equals(group.getId())) {
@ -389,7 +386,7 @@ public class MapMarkersHelper {
}
}
public void removeMarkersGroup(MapMarkersGroup group) {
public void removeMarkersGroup(ItineraryGroup group) {
if (group != null) {
markersDbHelper.removeMarkersGroup(group.getId());
removeGroupActiveMarkers(group, false);
@ -397,7 +394,7 @@ public class MapMarkersHelper {
}
}
public void updateGroupDisabled(@NonNull MapMarkersGroup group, boolean disabled) {
public void updateGroupDisabled(@NonNull ItineraryGroup group, boolean disabled) {
String id = group.getId();
if (id != null) {
markersDbHelper.updateGroupDisabled(id, disabled);
@ -405,7 +402,7 @@ public class MapMarkersHelper {
}
}
public void updateGroupWptCategories(@NonNull MapMarkersGroup group, Set<String> wptCategories) {
public void updateGroupWptCategories(@NonNull ItineraryGroup group, Set<String> wptCategories) {
String id = group.getId();
if (id != null) {
group.setWptCategories(wptCategories);
@ -415,7 +412,7 @@ public class MapMarkersHelper {
}
}
private void removeGroupActiveMarkers(MapMarkersGroup group, boolean updateGroup) {
private void removeGroupActiveMarkers(ItineraryGroup group, boolean updateGroup) {
if (group != null) {
markersDbHelper.removeActiveMarkersFromGroup(group.getId());
removeFromMapMarkersList(group.getActiveMarkers());
@ -429,26 +426,26 @@ public class MapMarkersHelper {
}
public void updateGroups() {
for (MapMarkersGroup group : mapMarkersGroups) {
for (ItineraryGroup group : itineraryGroups) {
updateGroup(group);
}
}
public void updateGroup(MapMarkersGroup mapMarkersGroup) {
if (mapMarkersGroup.getId() == null || mapMarkersGroup.getName() == null) {
public void updateGroup(ItineraryGroup itineraryGroup) {
if (itineraryGroup.getId() == null || itineraryGroup.getName() == null) {
return;
}
createHeadersInGroup(mapMarkersGroup);
int historyMarkersCount = mapMarkersGroup.getHistoryMarkers().size();
ShowHideHistoryButton showHideHistoryButton = mapMarkersGroup.getShowHideHistoryButton();
createHeadersInGroup(itineraryGroup);
int historyMarkersCount = itineraryGroup.getHistoryMarkers().size();
ShowHideHistoryButton showHideHistoryButton = itineraryGroup.getShowHideHistoryButton();
if (showHideHistoryButton != null) {
if (historyMarkersCount == 0) {
mapMarkersGroup.setShowHideHistoryButton(null);
itineraryGroup.setShowHideHistoryButton(null);
}
} else if (historyMarkersCount > 0) {
showHideHistoryButton = new ShowHideHistoryButton();
showHideHistoryButton.showHistory = false;
mapMarkersGroup.setShowHideHistoryButton(showHideHistoryButton);
itineraryGroup.setShowHideHistoryButton(showHideHistoryButton);
}
}
@ -456,6 +453,7 @@ public class MapMarkersHelper {
for (MapMarker marker : markers) {
addMarkerToGroup(marker);
}
saveGroups();
}
private void addMarkerToGroup(MapMarker marker) {
@ -500,10 +498,10 @@ public class MapMarkersHelper {
}
private void sortGroups() {
if (mapMarkersGroups.size() > 0) {
Collections.sort(mapMarkersGroups, new Comparator<MapMarkersGroup>() {
if (itineraryGroups.size() > 0) {
Collections.sort(itineraryGroups, new Comparator<ItineraryGroup>() {
@Override
public int compare(MapMarkersGroup group1, MapMarkersGroup group2) {
public int compare(ItineraryGroup group1, ItineraryGroup group2) {
long t1 = group1.getCreationDate();
long t2 = group2.getCreationDate();
return (t1 > t2) ? -1 : ((t1 == t2) ? 0 : 1);
@ -544,13 +542,13 @@ public class MapMarkersHelper {
}
@NonNull
public List<MapMarkersGroup> getGroupsForDisplayedGpx() {
List<MapMarkersGroup> res = new ArrayList<>();
List<SelectedGpxFile> selectedGpxFiles = ctx.getSelectedGpxHelper().getSelectedGPXFiles();
public List<ItineraryGroup> getGroupsForDisplayedGpx() {
List<ItineraryGroup> res = new ArrayList<>();
List<SelectedGpxFile> selectedGpxFiles = app.getSelectedGpxHelper().getSelectedGPXFiles();
for (SelectedGpxFile selected : selectedGpxFiles) {
MapMarkersGroup search = getMarkersGroup(selected.getGpxFile());
ItineraryGroup search = getMarkersGroup(selected.getGpxFile());
if (search == null && selected.getGpxFile() != null && selected.getGpxFile().path != null) {
MapMarkersGroup group = createGPXMarkerGroup(new File(selected.getGpxFile().path));
ItineraryGroup group = createGPXMarkerGroup(new File(selected.getGpxFile().path));
group.setDisabled(true);
createHeadersInGroup(group);
res.add(group);
@ -612,7 +610,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;
@ -631,7 +629,7 @@ public class MapMarkersHelper {
return null;
}
private void addNewMarkerIfNeeded(@NonNull MapMarkersGroup group,
private void addNewMarkerIfNeeded(@NonNull ItineraryGroup group,
@NonNull List<MapMarker> groupMarkers,
@NonNull LatLon latLon,
@NonNull String name,
@ -868,18 +866,18 @@ public class MapMarkersHelper {
public void addMapMarkers(@NonNull List<LatLon> points,
@NonNull List<PointDescription> historyNames,
@Nullable MapMarkersGroup group) {
@Nullable ItineraryGroup group) {
addMarkers(points, historyNames, group, null, null, null);
}
private void addMarkers(@NonNull List<LatLon> points,
@NonNull List<PointDescription> historyNames,
@Nullable MapMarkersGroup group,
@Nullable ItineraryGroup group,
@Nullable List<FavouritePoint> favouritePoints,
@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 +893,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 +907,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 = group.getId() + marker.getName(app) + MapUtils.createShortLinkString(marker.point.getLatitude(), marker.point.getLongitude(), 15);
if (markersDbHelper.getMarker(marker.id) != null) {
continue;
}
@ -984,7 +982,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 +993,7 @@ public class MapMarkersHelper {
}
private void refresh() {
ctx.runInUIThread(new Runnable() {
app.runInUIThread(new Runnable() {
@Override
public void run() {
for (MapMarkerChangedListener l : listeners) {
@ -1003,6 +1001,7 @@ public class MapMarkersHelper {
}
}
});
saveGroups();
}
public List<MapMarker> getMapMarkersFromDefaultGroups(boolean history) {
@ -1019,84 +1018,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:
@ -1161,16 +1082,16 @@ public class MapMarkersHelper {
// accessors to markers groups:
private void addToGroupsList(MapMarkersGroup group) {
List<MapMarkersGroup> copyList = new ArrayList<>(mapMarkersGroups);
private void addToGroupsList(ItineraryGroup group) {
List<ItineraryGroup> copyList = new ArrayList<>(itineraryGroups);
copyList.add(group);
mapMarkersGroups = copyList;
itineraryGroups = copyList;
}
private void removeFromGroupsList(MapMarkersGroup group) {
List<MapMarkersGroup> copyList = new ArrayList<>(mapMarkersGroups);
private void removeFromGroupsList(ItineraryGroup group) {
List<ItineraryGroup> copyList = new ArrayList<>(itineraryGroups);
copyList.remove(group);
mapMarkersGroups = copyList;
itineraryGroups = copyList;
}
// ---------------------------------------------------------------------------------------------
@ -1192,16 +1113,16 @@ public class MapMarkersHelper {
private class SyncGroupTask extends AsyncTask<Void, Void, Void> {
private MapMarkersGroup group;
private ItineraryGroup group;
SyncGroupTask(MapMarkersGroup group) {
SyncGroupTask(ItineraryGroup group) {
this.group = group;
}
@Override
protected void onPreExecute() {
if (!syncListeners.isEmpty()) {
ctx.runInUIThread(new Runnable() {
app.runInUIThread(new Runnable() {
@Override
public void run() {
for (OnGroupSyncedListener listener : syncListeners) {
@ -1267,7 +1188,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,265 @@
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.Set;
import java.util.TimeZone;
import static net.osmand.GPXUtilities.writeNotNullText;
import static net.osmand.plus.FavouritesDbHelper.backup;
public class ItinerarySaveHelper {
private static final Log log = PlatformUtil.getLog(ItinerarySaveHelper.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_ORIGIN = "gpx_origin";
private static final String FAVOURITES_ORIGIN = "favourites_origin";
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 ItineraryHelper itineraryHelper;
public ItinerarySaveHelper(OsmandApplication app, ItineraryHelper itineraryHelper) {
this.app = app;
this.itineraryHelper = itineraryHelper;
}
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<ItineraryGroup> groups = itineraryHelper.getItineraryGroups();
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(itineraryHelper.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<ItineraryGroup> itineraryGroups) {
GPXFile gpxFile = new GPXFile(Version.getFullVersion(app));
List<ItineraryGroupInfo> groups = new ArrayList<>();
for (ItineraryGroup group : itineraryGroups) {
ItineraryGroupInfo groupInfo = ItineraryGroupInfo.createGroupInfo(app, group);
for (MapMarker marker : group.getMarkers()) {
WptPt wptPt = toWpt(marker);
String markerId = marker.id;
String name = marker.getName(app);
int index = markerId.indexOf(name);
if (index != -1) {
markerId = markerId.substring(index + name.length());
}
wptPt.getExtensionsToWrite().put(ITINERARY_ID, groupInfo.type + ":" + markerId);
if (group.getType() == ItineraryType.TRACK) {
wptPt.getExtensionsToWrite().put(GPX_ORIGIN, groupInfo.path);
} else {
wptPt.getExtensionsToWrite().put(FAVOURITES_ORIGIN, 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, ItineraryGroup group) {
ItineraryGroupInfo groupInfo = new ItineraryGroupInfo();
groupInfo.type = group.getType().getTypeName();
groupInfo.name = !Algorithms.isEmpty(group.getName()) ? group.getName() : null;
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;
} else {
groupInfo.alias = groupInfo.type + (Algorithms.isEmpty(groupInfo.name) ? "" : ":" + groupInfo.name);
}
return groupInfo;
}
}
}

View file

@ -16,9 +16,10 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import static net.osmand.util.MapUtils.createShortLinkString;
public class MapMarkersDbHelper {
private static final int DB_VERSION = 13;
@ -303,7 +304,7 @@ public class MapMarkersDbHelper {
private void insertLast(SQLiteConnection db, MapMarker marker) {
long currentTime = System.currentTimeMillis();
if (marker.id == null) {
marker.id = String.valueOf(currentTime) + String.valueOf(new Random().nextInt(900) + 100);
marker.id = marker.getName(context) + createShortLinkString(marker.point.getLatitude(), marker.point.getLongitude(), 15);
}
marker.creationDate = currentTime;
String descr = PointDescription.serializeToString(marker.getOriginalPointDescription());