Fix file saving
This commit is contained in:
parent
f5e68691eb
commit
de9fde3df6
11 changed files with 425 additions and 263 deletions
|
@ -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 {
|
||||
|
@ -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,18 +2146,19 @@ 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 f, GPXExtensionsReader extensionsReader) {
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(f);
|
||||
GPXFile file = loadGPXFile(fis);
|
||||
GPXFile file = loadGPXFile(fis, extensionsReader);
|
||||
file.path = f.getAbsolutePath();
|
||||
file.modifiedTime = f.lastModified();
|
||||
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
Algorithms.closeStream(fis);
|
||||
return file;
|
||||
} catch (IOException e) {
|
||||
GPXFile res = new GPXFile(null);
|
||||
|
@ -2166,24 +2167,15 @@ public class GPXUtilities {
|
|||
res.error = e;
|
||||
return res;
|
||||
} finally {
|
||||
try {
|
||||
if (fis != null)
|
||||
fis.close();
|
||||
} catch (IOException ignore) {
|
||||
// ignore
|
||||
}
|
||||
Algorithms.closeStream(fis);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ItineraryGroupItem {
|
||||
public String name;
|
||||
public String type;
|
||||
public String path;
|
||||
public String alias;
|
||||
public String categories;
|
||||
public static GPXFile loadGPXFile(InputStream stream) {
|
||||
return loadGPXFile(stream, null);
|
||||
}
|
||||
|
||||
public static GPXFile loadGPXFile(InputStream f) {
|
||||
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"));
|
||||
|
@ -2191,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);
|
||||
|
@ -2239,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -305,7 +305,7 @@ public class Algorithms {
|
|||
if (isEmpty(s)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return new HashSet<>(Arrays.asList(s.split(split)));
|
||||
return new LinkedHashSet<>(Arrays.asList(s.split(split)));
|
||||
}
|
||||
|
||||
public static String encodeStringSet(Set<String> set) {
|
||||
|
|
|
@ -24,12 +24,11 @@ import net.osmand.util.Algorithms;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
import static net.osmand.plus.itinerary.ItineraryHelper.PASSED_TIMESTAMP;
|
||||
|
||||
|
||||
public class FavouritePoint implements Serializable, LocationPoint {
|
||||
private static final long serialVersionUID = 729654300829771466L;
|
||||
|
||||
private static final String PASSED_TIMESTAMP = "passed_timestamp";
|
||||
private static final String HIDDEN = "hidden";
|
||||
private static final String ADDRESS_EXTENSION = "address";
|
||||
public static final BackgroundType DEFAULT_BACKGROUND_TYPE = BackgroundType.CIRCLE;
|
||||
|
@ -348,8 +347,8 @@ 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) Math.floor(passedTimestamp * 10000);
|
||||
result = prime * result + (int) (timestamp ^ (timestamp >>> 32));
|
||||
result = prime * result + (int) (passedTimestamp ^ (passedTimestamp >>> 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());
|
||||
|
@ -487,7 +486,6 @@ public class FavouritePoint implements Serializable, LocationPoint {
|
|||
String time = pt.getExtensionsToWrite().get(PASSED_TIMESTAMP);
|
||||
fp.setPassedTimestamp(Algorithms.parseLongSilently(time, 0));
|
||||
}
|
||||
|
||||
BackgroundType backgroundType = BackgroundType.getByTypeName(pt.getBackgroundType(), null);
|
||||
fp.setBackgroundType(backgroundType);
|
||||
return fp;
|
||||
|
|
|
@ -685,7 +685,7 @@ public class AppInitializer implements IProgress {
|
|||
// restore backuped favorites to normal file
|
||||
restoreBackupForFavoritesFiles();
|
||||
notifyEvent(InitEvents.RESTORE_BACKUPS);
|
||||
app.itineraryHelper.syncMarkersGroups();
|
||||
app.itineraryHelper.syncAllGroups();
|
||||
app.searchUICore.initSearchUICore();
|
||||
|
||||
checkLiveUpdatesAlerts();
|
||||
|
|
|
@ -711,17 +711,6 @@ public class FavouritesDbHelper {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FavouritePoint getFavByLatLon(@NonNull LatLon latLon, String name) {
|
||||
for (FavouritePoint fav : cachedFavoritePoints) {
|
||||
if (latLon.equals(new LatLon(fav.getLatitude(), fav.getLongitude()))
|
||||
&& Algorithms.stringsEqual(fav.getName(), name)) {
|
||||
return fav;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<FavoriteGroup> getFavoriteGroups() {
|
||||
return favoriteGroups;
|
||||
}
|
||||
|
@ -848,9 +837,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;
|
||||
}
|
||||
|
|
69
OsmAnd/src/net/osmand/plus/itinerary/ItineraryGroup.java
Normal file
69
OsmAnd/src/net/osmand/plus/itinerary/ItineraryGroup.java
Normal file
|
@ -0,0 +1,69 @@
|
|||
package net.osmand.plus.itinerary;
|
||||
|
||||
import net.osmand.plus.mapmarkers.MapMarkersGroup;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static net.osmand.plus.itinerary.ItineraryHelper.CATEGORIES_SPLIT;
|
||||
|
||||
public class ItineraryGroup {
|
||||
|
||||
public String id;
|
||||
public String name;
|
||||
public ItineraryType type = ItineraryType.POINTS;
|
||||
public Set<String> wptCategories;
|
||||
public List<ItineraryItem> itineraryItems = new ArrayList<>();
|
||||
|
||||
public ItineraryGroup() {
|
||||
|
||||
}
|
||||
|
||||
public ItineraryGroup(ItineraryGroup group) {
|
||||
this.id = group.id;
|
||||
this.name = group.name;
|
||||
this.type = group.type;
|
||||
this.wptCategories = group.wptCategories;
|
||||
this.itineraryItems.addAll(group.itineraryItems);
|
||||
}
|
||||
|
||||
public static ItineraryGroup createGroup(MapMarkersGroup markersGroup) {
|
||||
ItineraryGroup group = new ItineraryGroup();
|
||||
group.id = markersGroup.getId();
|
||||
group.name = markersGroup.getName();
|
||||
group.type = markersGroup.getType();
|
||||
group.wptCategories = markersGroup.getWptCategories();
|
||||
return group;
|
||||
}
|
||||
|
||||
public static ItineraryGroup createGroup(ItineraryGroupInfo groupInfo) {
|
||||
ItineraryGroup group = new ItineraryGroup();
|
||||
group.name = groupInfo.name;
|
||||
group.type = ItineraryType.findTypeForName(groupInfo.type);
|
||||
group.id = group.type == ItineraryType.TRACK ? groupInfo.path : groupInfo.name;
|
||||
group.wptCategories = Algorithms.decodeStringSet(groupInfo.categories, CATEGORIES_SPLIT);
|
||||
return group;
|
||||
}
|
||||
|
||||
public ItineraryGroupInfo convertToGroupInfo() {
|
||||
ItineraryGroupInfo groupInfo = new ItineraryGroupInfo();
|
||||
groupInfo.name = name;
|
||||
groupInfo.type = type.name().toLowerCase();
|
||||
groupInfo.path = type == ItineraryType.TRACK ? id : null;
|
||||
groupInfo.alias = groupInfo.type + ":" + (name != null ? name : "");
|
||||
if (!Algorithms.isEmpty(wptCategories)) {
|
||||
groupInfo.categories = Algorithms.encodeStringSet(wptCategories, CATEGORIES_SPLIT);
|
||||
}
|
||||
return groupInfo;
|
||||
}
|
||||
|
||||
public static class ItineraryGroupInfo {
|
||||
public String name;
|
||||
public String type;
|
||||
public String path;
|
||||
public String alias;
|
||||
public String categories;
|
||||
}
|
||||
}
|
|
@ -6,9 +6,9 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXExtensionsReader;
|
||||
import net.osmand.GPXUtilities.GPXExtensionsWriter;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.ItineraryGroupItem;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.PlatformUtil;
|
||||
|
@ -22,6 +22,8 @@ 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.itinerary.ItineraryGroup.ItineraryGroupInfo;
|
||||
import net.osmand.plus.mapmarkers.CategoriesSubHeader;
|
||||
import net.osmand.plus.mapmarkers.GroupHeader;
|
||||
import net.osmand.plus.mapmarkers.MapMarker;
|
||||
|
@ -35,6 +37,8 @@ import net.osmand.plus.wikivoyage.data.TravelHelper;
|
|||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -51,18 +55,21 @@ import java.util.Set;
|
|||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static net.osmand.GPXUtilities.readText;
|
||||
import static net.osmand.GPXUtilities.writeNotNullText;
|
||||
import static net.osmand.plus.FavouritesDbHelper.backup;
|
||||
import static net.osmand.plus.mapmarkers.MapMarkersHelper.BY_DATE_ADDED_DESC;
|
||||
import static net.osmand.util.Algorithms.getFileNameWithoutExtension;
|
||||
|
||||
public class ItineraryHelper {
|
||||
|
||||
private static final Log log = PlatformUtil.getLog(ItineraryHelper.class);
|
||||
|
||||
public static final String PASSED_TIMESTAMP = "passed_timestamp";
|
||||
|
||||
private static final String CATEGORIES_SPLIT = ",";
|
||||
protected 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 OsmandApplication app;
|
||||
|
||||
|
@ -82,179 +89,124 @@ public class ItineraryHelper {
|
|||
loadMarkersGroups();
|
||||
}
|
||||
|
||||
public static class ItineraryItem {
|
||||
|
||||
public final String id;
|
||||
public final Object object;
|
||||
public final ItineraryType type;
|
||||
public final ItineraryGroup group;
|
||||
|
||||
public ItineraryItem(ItineraryGroup group, Object object, ItineraryType type) {
|
||||
this.type = type;
|
||||
this.group = group;
|
||||
this.object = object;
|
||||
this.id = acquireItemId(object);
|
||||
}
|
||||
|
||||
private String acquireItemId(Object object) {
|
||||
if (object instanceof MapMarker) {
|
||||
return (((MapMarker) object)).id;
|
||||
} else if (object instanceof WptPt) {
|
||||
return (((WptPt) object)).name;
|
||||
} else if (object instanceof FavouritePoint) {
|
||||
return (((FavouritePoint) object)).getName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
public List<ItineraryGroup> getItineraryGroups() {
|
||||
return itineraryGroups;
|
||||
}
|
||||
|
||||
public static class ItineraryGroup {
|
||||
|
||||
public String id;
|
||||
public String name;
|
||||
public ItineraryType type = ItineraryType.POINTS;
|
||||
public Set<String> wptCategories;
|
||||
|
||||
private List<ItineraryItem> itineraryItems = new ArrayList<>();
|
||||
|
||||
public List<MapMarkersGroup> getMapMarkersGroups() {
|
||||
return mapMarkersGroups;
|
||||
}
|
||||
|
||||
public void syncItineraryGroups() {
|
||||
for (MapMarkersGroup markersGroup : mapMarkersGroups) {
|
||||
ItineraryGroup itineraryGroup = new ItineraryGroup();
|
||||
itineraryGroup.id = markersGroup.getId();
|
||||
itineraryGroup.name = markersGroup.getName();
|
||||
itineraryGroup.type = markersGroup.getType();
|
||||
itineraryGroup.wptCategories = markersGroup.getWptCategories();
|
||||
public void syncAllGroups() {
|
||||
itineraryGroups.clear();
|
||||
}
|
||||
|
||||
if (markersGroup.getType() == ItineraryType.FAVOURITES) {
|
||||
syncFavoriteGroup(itineraryGroup, markersGroup);
|
||||
} else if (markersGroup.getType() == ItineraryType.TRACK) {
|
||||
syncTrackGroup(itineraryGroup, markersGroup);
|
||||
} else {
|
||||
syncMarkersGroup(itineraryGroup, markersGroup);
|
||||
private boolean merge(Map<Object, ItineraryGroup> source, Map<Object, ItineraryGroup> destination) {
|
||||
boolean changed = false;
|
||||
for (Map.Entry<Object, ItineraryGroup> entry : source.entrySet()) {
|
||||
Object ks = entry.getKey();
|
||||
if (!destination.containsKey(ks)) {
|
||||
changed = true;
|
||||
destination.put(ks, entry.getValue());
|
||||
}
|
||||
}
|
||||
trimEmptyGroups();
|
||||
return changed;
|
||||
}
|
||||
|
||||
public void trimEmptyGroups() {
|
||||
Iterator<ItineraryGroup> iterator = itineraryGroups.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ItineraryGroup group = iterator.next();
|
||||
if (Algorithms.isEmpty(group.itineraryItems)) {
|
||||
iterator.remove();
|
||||
}
|
||||
private boolean loadGPXFile(File file, Map<Object, ItineraryGroup> groups) {
|
||||
if (!file.exists()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void syncFavoriteGroup(ItineraryGroup itineraryGroup, MapMarkersGroup markersGroup) {
|
||||
FavoriteGroup favoriteGroup = app.getFavorites().getGroup(markersGroup.getId());
|
||||
if (favoriteGroup != null) {
|
||||
for (FavouritePoint favouritePoint : favoriteGroup.getPoints()) {
|
||||
if (favouritePoint.getPassedTimestamp() == 0) {
|
||||
ItineraryItem itineraryItem = new ItineraryItem(itineraryGroup, favouritePoint, ItineraryType.FAVOURITES);
|
||||
itineraryGroup.itineraryItems.add(itineraryItem);
|
||||
}
|
||||
}
|
||||
itineraryGroups.add(itineraryGroup);
|
||||
List<ItineraryGroupInfo> groupInfos = new ArrayList<>();
|
||||
GPXFile gpxFile = loadGPXFile(file, groupInfos);
|
||||
if (gpxFile.error != null) {
|
||||
return false;
|
||||
}
|
||||
for (ItineraryGroupInfo groupInfo : groupInfos) {
|
||||
ItineraryGroup group = ItineraryGroup.createGroup(groupInfo);
|
||||
Object key = group.name != null ? group.name : group.type;
|
||||
groups.put(key, group);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void syncTrackGroup(ItineraryGroup itineraryGroup, MapMarkersGroup markersGroup) {
|
||||
File file = new File(markersGroup.getId());
|
||||
if (file.exists()) {
|
||||
GPXFile gpxFile;
|
||||
SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(markersGroup.getId());
|
||||
if (selectedGpxFile != null) {
|
||||
gpxFile = selectedGpxFile.getGpxFile();
|
||||
} else {
|
||||
gpxFile = GPXUtilities.loadGPXFile(file);
|
||||
}
|
||||
if (gpxFile != null && gpxFile.error == null) {
|
||||
for (WptPt wptPt : gpxFile.getPoints()) {
|
||||
if (shouldAddWpt(wptPt, itineraryGroup.wptCategories)) {
|
||||
ItineraryItem itineraryItem = new ItineraryItem(itineraryGroup, wptPt, ItineraryType.TRACK);
|
||||
itineraryGroup.itineraryItems.add(itineraryItem);
|
||||
private GPXFile loadGPXFile(File file, final List<ItineraryGroupInfo> groupInfos) {
|
||||
return GPXUtilities.loadGPXFile(file, new GPXExtensionsReader() {
|
||||
@Override
|
||||
public boolean readExtensions(GPXFile res, XmlPullParser parser) throws IOException, XmlPullParserException {
|
||||
if (ITINERARY_GROUP.equalsIgnoreCase(parser.getName())) {
|
||||
ItineraryGroupInfo groupInfo = new ItineraryGroupInfo();
|
||||
|
||||
int tok;
|
||||
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||
if (tok == XmlPullParser.START_TAG) {
|
||||
String tagName = parser.getName().toLowerCase();
|
||||
if ("name".equalsIgnoreCase(tagName)) {
|
||||
groupInfo.name = readText(parser, tagName);
|
||||
} else if ("type".equalsIgnoreCase(tagName)) {
|
||||
groupInfo.type = readText(parser, tagName);
|
||||
} else if ("path".equalsIgnoreCase(tagName)) {
|
||||
groupInfo.path = readText(parser, tagName);
|
||||
} else if ("alias".equalsIgnoreCase(tagName)) {
|
||||
groupInfo.alias = readText(parser, tagName);
|
||||
} else if ("categories".equalsIgnoreCase(tagName)) {
|
||||
groupInfo.categories = readText(parser, tagName);
|
||||
}
|
||||
} else if (tok == XmlPullParser.END_TAG) {
|
||||
if (ITINERARY_GROUP.equalsIgnoreCase(parser.getName())) {
|
||||
groupInfos.add(groupInfo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
itineraryGroups.add(itineraryGroup);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void saveGroupsIntoFile() {
|
||||
try {
|
||||
saveFile(getInternalFile());
|
||||
saveFile(getExternalFile());
|
||||
backup(getBackupFile(), getExternalFile());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void syncMarkersGroup(ItineraryGroup itineraryGroup, MapMarkersGroup markersGroup) {
|
||||
for (MapMarker marker : markersGroup.getMarkers()) {
|
||||
if (!marker.history) {
|
||||
PointDescription pointDescription = marker.getOriginalPointDescription();
|
||||
if (pointDescription == null || !pointDescription.isWpt() && !pointDescription.isFavorite()) {
|
||||
ItineraryItem itineraryItem = new ItineraryItem(itineraryGroup, marker, ItineraryType.MARKERS);
|
||||
itineraryGroup.itineraryItems.add(itineraryItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
itineraryGroups.add(itineraryGroup);
|
||||
public Exception saveFile(File file) {
|
||||
GPXFile gpxFile = asGpxFile();
|
||||
return GPXUtilities.writeGpxFile(file, gpxFile);
|
||||
}
|
||||
|
||||
private boolean shouldAddWpt(WptPt wptPt, Set<String> wptCategories) {
|
||||
boolean addAll = wptCategories == null || wptCategories.isEmpty();
|
||||
return addAll || wptCategories.contains(wptPt.category)
|
||||
|| wptPt.category == null && wptCategories.contains("");
|
||||
public GPXFile asGpxFile() {
|
||||
GPXFile gpxFile = new GPXFile(Version.getFullVersion(app));
|
||||
List<ItineraryGroupInfo> groups = new ArrayList<>();
|
||||
for (ItineraryGroup group : itineraryGroups) {
|
||||
ItineraryGroupInfo groupInfo = group.convertToGroupInfo();
|
||||
|
||||
for (ItineraryItem item : group.itineraryItems) {
|
||||
WptPt wptPt = new WptPt();
|
||||
wptPt.lat = item.latLon.getLatitude();
|
||||
wptPt.lon = item.latLon.getLongitude();
|
||||
wptPt.getExtensionsToWrite().put(ITINERARY_ID, groupInfo.alias + ":" + item.id);
|
||||
gpxFile.addPoint(wptPt);
|
||||
}
|
||||
groups.add(groupInfo);
|
||||
}
|
||||
assignRouteExtensionWriter(gpxFile, groups);
|
||||
return gpxFile;
|
||||
}
|
||||
|
||||
private void loadMarkersGroups() {
|
||||
Map<String, MapMarkersGroup> groupsMap = markersDbHelper.getAllGroupsMap();
|
||||
List<MapMarker> allMarkers = new ArrayList<>(markersHelper.getMapMarkers());
|
||||
allMarkers.addAll(markersHelper.getMapMarkersHistory());
|
||||
|
||||
Iterator<Entry<String, MapMarkersGroup>> iterator = groupsMap.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
MapMarkersGroup group = iterator.next().getValue();
|
||||
if (group.getType() == ItineraryType.TRACK && !new File(group.getId()).exists()) {
|
||||
markersDbHelper.removeMarkersGroup(group.getId());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
MapMarkersGroup noGroup = null;
|
||||
|
||||
for (MapMarker marker : allMarkers) {
|
||||
MapMarkersGroup group = groupsMap.get(marker.groupKey);
|
||||
if (group == null) {
|
||||
if (noGroup == null) {
|
||||
noGroup = new MapMarkersGroup();
|
||||
noGroup.setCreationDate(Long.MAX_VALUE);
|
||||
}
|
||||
noGroup.getMarkers().add(marker);
|
||||
} else {
|
||||
if (marker.creationDate < group.getCreationDate()) {
|
||||
group.setCreationDate(marker.creationDate);
|
||||
}
|
||||
group.getMarkers().add(marker);
|
||||
}
|
||||
}
|
||||
|
||||
mapMarkersGroups = new ArrayList<>(groupsMap.values());
|
||||
if (noGroup != null) {
|
||||
markersHelper.sortMarkers(noGroup.getMarkers(), false, BY_DATE_ADDED_DESC);
|
||||
addToGroupsList(noGroup);
|
||||
}
|
||||
|
||||
sortGroups();
|
||||
|
||||
for (MapMarkersGroup group : mapMarkersGroups) {
|
||||
updateGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
private void assignRouteExtensionWriter(GPXFile gpx, final List<ItineraryGroupItem> groups) {
|
||||
if (gpx.getExtensionsWriter() == null) {
|
||||
gpx.setExtensionsWriter(new GPXExtensionsWriter() {
|
||||
private void assignRouteExtensionWriter(GPXFile gpxFile, final List<ItineraryGroupInfo> groups) {
|
||||
if (gpxFile.getExtensionsWriter() == null) {
|
||||
gpxFile.setExtensionsWriter(new GPXExtensionsWriter() {
|
||||
@Override
|
||||
public void writeExtensions(XmlSerializer serializer) {
|
||||
for (ItineraryGroupItem group : groups) {
|
||||
for (ItineraryGroupInfo group : groups) {
|
||||
try {
|
||||
serializer.startTag(null, "itinerary_group");
|
||||
serializer.startTag(null, "osmand:itinerary_group");
|
||||
|
||||
writeNotNullText(serializer, "osmand:name", group.name);
|
||||
writeNotNullText(serializer, "osmand:type", group.type);
|
||||
|
@ -262,7 +214,7 @@ public class ItineraryHelper {
|
|||
writeNotNullText(serializer, "osmand:alias", group.alias);
|
||||
writeNotNullText(serializer, "osmand:categories", group.categories);
|
||||
|
||||
serializer.endTag(null, "itinerary_group");
|
||||
serializer.endTag(null, "osmand:itinerary_group");
|
||||
} catch (IOException e) {
|
||||
log.error(e);
|
||||
}
|
||||
|
@ -272,6 +224,95 @@ public class ItineraryHelper {
|
|||
}
|
||||
}
|
||||
|
||||
public void syncMarkersGroups() {
|
||||
for (MapMarkersGroup group : mapMarkersGroups) {
|
||||
if (group.getId() != null && group.getName() != null) {
|
||||
runGroupSynchronization(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<ItineraryGroup> convertToItineraryGroups() {
|
||||
List<ItineraryGroup> groups = new ArrayList<>();
|
||||
for (MapMarkersGroup markersGroup : mapMarkersGroups) {
|
||||
groups.add(ItineraryGroup.createGroup(markersGroup));
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
public void syncItineraryGroups() {
|
||||
syncItineraryGroups(convertToItineraryGroups());
|
||||
}
|
||||
|
||||
public void syncItineraryGroups(List<ItineraryGroup> itineraryGroups) {
|
||||
for (ItineraryGroup group : itineraryGroups) {
|
||||
if (group.type == ItineraryType.FAVOURITES) {
|
||||
syncFavoriteGroup(group);
|
||||
} else if (group.type == ItineraryType.TRACK) {
|
||||
syncTrackGroup(group);
|
||||
} else if (group.type == ItineraryType.MARKERS) {
|
||||
syncMarkersGroup(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void syncFavoriteGroup(ItineraryGroup group) {
|
||||
FavoriteGroup favoriteGroup = app.getFavorites().getGroup(group.id);
|
||||
if (favoriteGroup != null && favoriteGroup.isVisible()) {
|
||||
for (FavouritePoint point : favoriteGroup.getPoints()) {
|
||||
if (point.getPassedTimestamp() == 0) {
|
||||
ItineraryItem item = new ItineraryItem(group, point, ItineraryType.FAVOURITES);
|
||||
group.itineraryItems.add(item);
|
||||
}
|
||||
}
|
||||
itineraryGroups.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
private void syncTrackGroup(ItineraryGroup group) {
|
||||
SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().getSelectedFileByPath(group.id);
|
||||
if (selectedGpxFile != null) {
|
||||
for (WptPt wptPt : selectedGpxFile.getGpxFile().getPoints()) {
|
||||
if (shouldAddWpt(wptPt, group.wptCategories)) {
|
||||
ItineraryItem item = new ItineraryItem(group, wptPt, ItineraryType.TRACK);
|
||||
group.itineraryItems.add(item);
|
||||
}
|
||||
}
|
||||
itineraryGroups.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
private void syncMarkersGroup(ItineraryGroup group) {
|
||||
ItineraryGroup pointsGroup = new ItineraryGroup(group);
|
||||
ItineraryGroup markersGroup = new ItineraryGroup(group);
|
||||
|
||||
pointsGroup.type = ItineraryType.POINTS;
|
||||
markersGroup.type = ItineraryType.MARKERS;
|
||||
|
||||
List<MapMarker> allMarkers = new ArrayList<>(markersHelper.getMapMarkers());
|
||||
for (MapMarker marker : allMarkers) {
|
||||
PointDescription description = marker.getOriginalPointDescription();
|
||||
if (description.isFavorite()) {
|
||||
FavouritePoint point = app.getFavorites().getVisibleFavByLatLon(marker.point);
|
||||
if (point != null && point.getPassedTimestamp() == 0) {
|
||||
ItineraryItem item = new ItineraryItem(pointsGroup, point, ItineraryType.FAVOURITES);
|
||||
pointsGroup.itineraryItems.add(item);
|
||||
}
|
||||
} else if (description.isWpt()) {
|
||||
WptPt wptPt = app.getSelectedGpxHelper().getVisibleWayPointByLatLon(marker.point);
|
||||
if (wptPt != null && shouldAddWpt(wptPt, null)) {
|
||||
ItineraryItem item = new ItineraryItem(pointsGroup, wptPt, ItineraryType.TRACK);
|
||||
pointsGroup.itineraryItems.add(item);
|
||||
}
|
||||
} else if (!marker.history) {
|
||||
ItineraryItem item = new ItineraryItem(markersGroup, marker, ItineraryType.MARKERS);
|
||||
markersGroup.itineraryItems.add(item);
|
||||
}
|
||||
}
|
||||
itineraryGroups.add(pointsGroup);
|
||||
itineraryGroups.add(markersGroup);
|
||||
}
|
||||
|
||||
public File getExternalFile() {
|
||||
return new File(app.getAppPath(null), FILE_TO_SAVE);
|
||||
}
|
||||
|
@ -284,18 +325,6 @@ public class ItineraryHelper {
|
|||
return FavouritesDbHelper.getBackupFile(app, "itinerary_bak_");
|
||||
}
|
||||
|
||||
public List<MapMarkersGroup> getMapMarkersGroups() {
|
||||
return mapMarkersGroups;
|
||||
}
|
||||
|
||||
public void syncMarkersGroups() {
|
||||
for (MapMarkersGroup group : mapMarkersGroups) {
|
||||
if (group.getType() != ItineraryType.MARKERS) {
|
||||
runGroupSynchronization(group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateGroupWptCategories(@NonNull MapMarkersGroup group, Set<String> wptCategories) {
|
||||
String id = group.getId();
|
||||
if (id != null) {
|
||||
|
@ -345,10 +374,54 @@ public class ItineraryHelper {
|
|||
return mapMarkers;
|
||||
}
|
||||
|
||||
public void addGroupInternally(MapMarkersGroup gr) {
|
||||
markersDbHelper.addGroup(gr);
|
||||
markersHelper.addHistoryMarkersToGroup(gr);
|
||||
addToGroupsList(gr);
|
||||
private void loadMarkersGroups() {
|
||||
Map<String, MapMarkersGroup> groupsMap = markersDbHelper.getAllGroupsMap();
|
||||
List<MapMarker> allMarkers = new ArrayList<>(markersHelper.getMapMarkers());
|
||||
allMarkers.addAll(markersHelper.getMapMarkersHistory());
|
||||
|
||||
Iterator<Entry<String, MapMarkersGroup>> iterator = groupsMap.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
MapMarkersGroup group = iterator.next().getValue();
|
||||
if (group.getType() == ItineraryType.TRACK && !new File(group.getId()).exists()) {
|
||||
markersDbHelper.removeMarkersGroup(group.getId());
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
MapMarkersGroup noGroup = null;
|
||||
for (MapMarker marker : allMarkers) {
|
||||
MapMarkersGroup group = groupsMap.get(marker.groupKey);
|
||||
if (group == null) {
|
||||
if (noGroup == null) {
|
||||
noGroup = new MapMarkersGroup();
|
||||
noGroup.setCreationDate(Long.MAX_VALUE);
|
||||
}
|
||||
noGroup.getMarkers().add(marker);
|
||||
} else {
|
||||
if (marker.creationDate < group.getCreationDate()) {
|
||||
group.setCreationDate(marker.creationDate);
|
||||
}
|
||||
group.getMarkers().add(marker);
|
||||
}
|
||||
}
|
||||
|
||||
mapMarkersGroups = new ArrayList<>(groupsMap.values());
|
||||
if (noGroup != null) {
|
||||
markersHelper.sortMarkers(noGroup.getMarkers(), false, BY_DATE_ADDED_DESC);
|
||||
addToGroupsList(noGroup);
|
||||
}
|
||||
|
||||
sortGroups();
|
||||
|
||||
for (MapMarkersGroup group : mapMarkersGroups) {
|
||||
updateGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
public void addGroupInternally(MapMarkersGroup group) {
|
||||
markersDbHelper.addGroup(group);
|
||||
markersHelper.addHistoryMarkersToGroup(group);
|
||||
addToGroupsList(group);
|
||||
}
|
||||
|
||||
public void updateGpxShowAsMarkers(File file) {
|
||||
|
@ -403,22 +476,20 @@ public class ItineraryHelper {
|
|||
}
|
||||
|
||||
public void addMarkerToGroup(MapMarker marker) {
|
||||
if (marker != null) {
|
||||
MapMarkersGroup mapMarkersGroup = app.getItineraryHelper().getMapMarkerGroupById(marker.groupKey, marker.getType());
|
||||
if (mapMarkersGroup != null) {
|
||||
mapMarkersGroup.getMarkers().add(marker);
|
||||
updateGroup(mapMarkersGroup);
|
||||
if (mapMarkersGroup.getName() == null) {
|
||||
markersHelper.sortMarkers(mapMarkersGroup.getMarkers(), false, BY_DATE_ADDED_DESC);
|
||||
}
|
||||
} else {
|
||||
mapMarkersGroup = new MapMarkersGroup(marker.groupKey, marker.groupName, ItineraryType.MARKERS);
|
||||
mapMarkersGroup.setCreationDate(Long.MAX_VALUE);
|
||||
mapMarkersGroup.getMarkers().add(marker);
|
||||
addToGroupsList(mapMarkersGroup);
|
||||
sortGroups();
|
||||
updateGroup(mapMarkersGroup);
|
||||
MapMarkersGroup mapMarkersGroup = app.getItineraryHelper().getMapMarkerGroupById(marker.groupKey, marker.getType());
|
||||
if (mapMarkersGroup != null) {
|
||||
mapMarkersGroup.getMarkers().add(marker);
|
||||
updateGroup(mapMarkersGroup);
|
||||
if (mapMarkersGroup.getName() == null) {
|
||||
markersHelper.sortMarkers(mapMarkersGroup.getMarkers(), false, BY_DATE_ADDED_DESC);
|
||||
}
|
||||
} else {
|
||||
mapMarkersGroup = new MapMarkersGroup(marker.groupKey, marker.groupName, ItineraryType.MARKERS);
|
||||
mapMarkersGroup.setCreationDate(Long.MAX_VALUE);
|
||||
mapMarkersGroup.getMarkers().add(marker);
|
||||
addToGroupsList(mapMarkersGroup);
|
||||
sortGroups();
|
||||
updateGroup(mapMarkersGroup);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -500,9 +571,7 @@ public class ItineraryHelper {
|
|||
}
|
||||
|
||||
private MapMarkersGroup createGPXMarkerGroup(File fl) {
|
||||
return new MapMarkersGroup(getMarkerGroupId(fl),
|
||||
Algorithms.getFileNameWithoutExtension(fl.getName()),
|
||||
ItineraryType.TRACK);
|
||||
return new MapMarkersGroup(getMarkerGroupId(fl), getFileNameWithoutExtension(fl), ItineraryType.TRACK);
|
||||
}
|
||||
|
||||
private MapMarkersGroup createFavMarkerGroup(FavoriteGroup favGroup) {
|
||||
|
@ -665,6 +734,12 @@ public class ItineraryHelper {
|
|||
markersHelper.removeOldMarkersIfPresent(groupMarkers);
|
||||
}
|
||||
|
||||
private boolean shouldAddWpt(WptPt wptPt, Set<String> wptCategories) {
|
||||
boolean addAll = wptCategories == null || wptCategories.isEmpty();
|
||||
return addAll || wptCategories.contains(wptPt.category)
|
||||
|| wptPt.category == null && wptCategories.contains("");
|
||||
}
|
||||
|
||||
private class SyncGroupTask extends AsyncTask<Void, Void, Void> {
|
||||
|
||||
private MapMarkersGroup group;
|
||||
|
|
46
OsmAnd/src/net/osmand/plus/itinerary/ItineraryItem.java
Normal file
46
OsmAnd/src/net/osmand/plus/itinerary/ItineraryItem.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
package net.osmand.plus.itinerary;
|
||||
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.data.FavouritePoint;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.mapmarkers.MapMarker;
|
||||
|
||||
public class ItineraryItem {
|
||||
|
||||
public final String id;
|
||||
public final Object object;
|
||||
public final LatLon latLon;
|
||||
public final ItineraryType type;
|
||||
public final ItineraryGroup group;
|
||||
|
||||
public ItineraryItem(ItineraryGroup group, Object object, ItineraryType type) {
|
||||
this.type = type;
|
||||
this.group = group;
|
||||
this.object = object;
|
||||
this.id = acquireItemId(object);
|
||||
|
||||
if (object instanceof MapMarker) {
|
||||
MapMarker marker = (MapMarker) object;
|
||||
latLon = marker.point;
|
||||
} else if (object instanceof WptPt) {
|
||||
WptPt point = (WptPt) object;
|
||||
latLon = new LatLon(point.lat, point.lon);
|
||||
} else if (object instanceof FavouritePoint) {
|
||||
FavouritePoint point = (FavouritePoint) object;
|
||||
latLon = new LatLon(point.getLatitude(), point.getLongitude());
|
||||
} else {
|
||||
latLon = null;
|
||||
}
|
||||
}
|
||||
|
||||
private String acquireItemId(Object object) {
|
||||
if (object instanceof MapMarker) {
|
||||
return (((MapMarker) object)).id;
|
||||
} else if (object instanceof WptPt) {
|
||||
return (((WptPt) object)).name;
|
||||
} else if (object instanceof FavouritePoint) {
|
||||
return (((FavouritePoint) object)).getName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
|
@ -1,18 +1,14 @@
|
|||
package net.osmand.plus.itinerary;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public enum ItineraryType {
|
||||
MARKERS("markers", -1),
|
||||
FAVOURITES("favourites", 0),
|
||||
TRACK("track", 1),
|
||||
POINTS("points", 2);
|
||||
MARKERS(-1),
|
||||
FAVOURITES(0),
|
||||
TRACK(1),
|
||||
POINTS(2);
|
||||
|
||||
private int typeId;
|
||||
private String typeName;
|
||||
|
||||
ItineraryType(@NonNull String typeName, int typeId) {
|
||||
this.typeName = typeName;
|
||||
ItineraryType(int typeId) {
|
||||
this.typeId = typeId;
|
||||
}
|
||||
|
||||
|
@ -20,25 +16,21 @@ public enum ItineraryType {
|
|||
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;
|
||||
return ItineraryType.POINTS;
|
||||
}
|
||||
|
||||
public static ItineraryType findTypeForName(String typeName) {
|
||||
for (ItineraryType type : values()) {
|
||||
if (type.getTypeName().equalsIgnoreCase(typeName)) {
|
||||
if (type.name().equalsIgnoreCase(typeName)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return ItineraryType.MARKERS;
|
||||
return ItineraryType.POINTS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,21 +4,20 @@ import android.graphics.drawable.Drawable;
|
|||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.graphics.drawable.shapes.OvalShape;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersHelper;
|
||||
import net.osmand.plus.mapmarkers.MapMarker;
|
||||
import net.osmand.plus.settings.backend.OsmandPreference;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.helpers.MapMarkerDialogHelper;
|
||||
import net.osmand.plus.mapcontextmenu.MenuBuilder;
|
||||
import net.osmand.plus.mapcontextmenu.MenuController;
|
||||
import net.osmand.plus.mapmarkers.MapMarker;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersHelper;
|
||||
import net.osmand.plus.settings.backend.OsmandPreference;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class MapMarkerMenuController extends MenuController {
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.osmand.plus.mapmarkers;
|
|||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
|
@ -37,7 +38,7 @@ public class MapMarker implements LocationPoint {
|
|||
public FavouritePoint favouritePoint;
|
||||
public String mapObjectName;
|
||||
|
||||
public MapMarker(LatLon point, PointDescription name, int colorIndex, boolean selected, int index) {
|
||||
public MapMarker(@NonNull LatLon point, @NonNull PointDescription name, int colorIndex, boolean selected, int index) {
|
||||
this.point = point;
|
||||
this.pointDescription = name;
|
||||
this.colorIndex = colorIndex;
|
||||
|
@ -66,11 +67,12 @@ public class MapMarker implements LocationPoint {
|
|||
return name;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public PointDescription getOriginalPointDescription() {
|
||||
return pointDescription;
|
||||
}
|
||||
|
||||
public void setOriginalPointDescription(PointDescription pointDescription) {
|
||||
public void setOriginalPointDescription(@NonNull PointDescription pointDescription) {
|
||||
this.pointDescription = pointDescription;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue