diff options
Diffstat (limited to 'main/src')
| -rw-r--r-- | main/src/cgeo/geocaching/DataStore.java | 14 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/Geocache.java | 8 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/Waypoint.java | 21 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/connector/AbstractConnector.java | 12 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/connector/IConnector.java | 19 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/connector/gc/GCConnector.java | 18 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/connector/oc/OkapiClient.java | 1 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/export/GpxSerializer.java | 59 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/files/GPXParser.java | 57 |
9 files changed, 177 insertions, 32 deletions
diff --git a/main/src/cgeo/geocaching/DataStore.java b/main/src/cgeo/geocaching/DataStore.java index a231e8b..9075d45 100644 --- a/main/src/cgeo/geocaching/DataStore.java +++ b/main/src/cgeo/geocaching/DataStore.java @@ -1107,7 +1107,7 @@ public class DataStore { try { saveAttributesWithoutTransaction(cache); - saveOriginalWaypointsWithoutTransaction(cache); + saveWaypointsWithoutTransaction(cache); saveSpoilersWithoutTransaction(cache); saveLogsWithoutTransaction(cache.getGeocode(), cache.getLogs()); saveLogCountsWithoutTransaction(cache); @@ -1175,7 +1175,7 @@ public class DataStore { database.beginTransaction(); try { - saveOriginalWaypointsWithoutTransaction(cache); + saveWaypointsWithoutTransaction(cache); database.setTransactionSuccessful(); return true; } catch (Exception e) { @@ -1186,7 +1186,7 @@ public class DataStore { return false; } - private static void saveOriginalWaypointsWithoutTransaction(final Geocache cache) { + private static void saveWaypointsWithoutTransaction(final Geocache cache) { String geocode = cache.getGeocode(); List<Waypoint> waypoints = cache.getWaypoints(); @@ -1195,10 +1195,6 @@ public class DataStore { ContentValues values = new ContentValues(); long timeStamp = System.currentTimeMillis(); for (Waypoint oneWaypoint : waypoints) { - if (oneWaypoint.isUserDefined()) { - currentWaypointIds.add(Integer.toString(oneWaypoint.getId())); - continue; - } values.clear(); values.put("geocode", geocode); @@ -1227,7 +1223,7 @@ public class DataStore { /** * remove all waypoints of the given cache, where the id is not in the given list - * + * * @param cache * @param remainingWaypointIds * ids of waypoints which shall not be deleted @@ -1239,7 +1235,7 @@ public class DataStore { /** * Save coordinates into a ContentValues - * + * * @param values * a ContentValues to save coordinates in * @param oneWaypoint diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java index 8cfedb3..731f214 100644 --- a/main/src/cgeo/geocaching/Geocache.java +++ b/main/src/cgeo/geocaching/Geocache.java @@ -1771,4 +1771,12 @@ public class Geocache implements ICache, IWaypoint { public void setLogPasswordRequired(boolean required) { logPasswordRequired = required; } + + public String getWaypointGpxId(String prefix) { + return getConnector().getWaypointGpxId(prefix, geocode); + } + + public String getWaypointPrefix(String name) { + return getConnector().getWaypointPrefix(name); + } } diff --git a/main/src/cgeo/geocaching/Waypoint.java b/main/src/cgeo/geocaching/Waypoint.java index facd914..dda83d9 100644 --- a/main/src/cgeo/geocaching/Waypoint.java +++ b/main/src/cgeo/geocaching/Waypoint.java @@ -1,5 +1,6 @@ package cgeo.geocaching; +import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.Geopoint; @@ -265,4 +266,24 @@ public class Waypoint implements IWaypoint { return left.order() - right.order(); } }; + + /** + * Delegates the creation of the waypoint-id for gpx-export to the waypoint + * + * @param prefix + * @return + */ + public String getGpxId() { + + String gpxId = prefix; + + if (StringUtils.isNotBlank(geocode)) { + Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + if (cache != null) { + gpxId = cache.getWaypointGpxId(prefix); + } + } + + return gpxId; + } } diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java index 3ec0580..b10366e 100644 --- a/main/src/cgeo/geocaching/connector/AbstractConnector.java +++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java @@ -188,4 +188,16 @@ public abstract class AbstractConnector implements IConnector { } return logTypes; } + + @Override + public String getWaypointGpxId(String prefix, String geocode) { + // Default: just return the prefix + return prefix; + } + + @Override + public String getWaypointPrefix(String name) { + // Default: just return the name + return name; + } } diff --git a/main/src/cgeo/geocaching/connector/IConnector.java b/main/src/cgeo/geocaching/connector/IConnector.java index 2262e47..a96ee10 100644 --- a/main/src/cgeo/geocaching/connector/IConnector.java +++ b/main/src/cgeo/geocaching/connector/IConnector.java @@ -215,9 +215,26 @@ public interface IConnector { /** * Get the list of <b>potentially</b> possible log types for a cache. Those may still be filter further during the * actual logging activity. - * + * * @param geocache * @return */ public List<LogType> getPossibleLogTypes(Geocache geocache); + + /** + * Get the gpx id for a waypoint when exporting. For some connectors there is an inherent name logic, + * for others its just the 'prefix' + * + * @param prefix + * @return + */ + public String getWaypointGpxId(String prefix, String geocode); + + /** + * Get the 'prefix' (key) for a waypoint from the 'name' in the gpx file + * + * @param name + * @return + */ + public String getWaypointPrefix(String name); } diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java index d5f7bf4..6a61405 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java @@ -335,4 +335,22 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, public boolean isLoggedIn() { return Login.isActualLoginStatus(); } + + @Override + public String getWaypointGpxId(String prefix, String geocode) { + String gpxId = prefix; + if (StringUtils.isNotBlank(geocode) && geocode.length() > 2) { + gpxId += geocode.substring(2); + } + return gpxId; + } + + @Override + public String getWaypointPrefix(String name) { + String prefix = name; + if (StringUtils.isNotBlank(prefix) && prefix.length() >= 2) { + prefix = name.substring(0, 2); + } + return prefix; + } } diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java index 686e314..24e30e7 100644 --- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java +++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java @@ -445,6 +445,7 @@ final class OkapiClient { if (result == null) { result = new ArrayList<Waypoint>(); } + wpt.setPrefix(wpt.getName()); result.add(wpt); } catch (final JSONException e) { Log.e("OkapiClient.parseWaypoints", e); diff --git a/main/src/cgeo/geocaching/export/GpxSerializer.java b/main/src/cgeo/geocaching/export/GpxSerializer.java index 3ff8879..7d6067e 100644 --- a/main/src/cgeo/geocaching/export/GpxSerializer.java +++ b/main/src/cgeo/geocaching/export/GpxSerializer.java @@ -33,6 +33,8 @@ public final class GpxSerializer { public static final String PREFIX_XSI = "http://www.w3.org/2001/XMLSchema-instance"; public static final String PREFIX_GPX = "http://www.topografix.com/GPX/1/0"; public static final String PREFIX_GROUNDSPEAK = "http://www.groundspeak.com/cache/1/0"; + public static final String PREFIX_GSAK = "http://www.gsak.net/xmlv1/4"; + public static final String PREFIX_CGEO = "http://www.cgeo.org/wptext/1/0"; /** * During the export, only this number of geocaches is fully loaded into memory. @@ -63,12 +65,15 @@ public final class GpxSerializer { gpx.setPrefix("", PREFIX_GPX); gpx.setPrefix("xsi", PREFIX_XSI); gpx.setPrefix("groundspeak", PREFIX_GROUNDSPEAK); + gpx.setPrefix("gsak", PREFIX_GSAK); + gpx.setPrefix("cgeo", PREFIX_CGEO); gpx.startTag(PREFIX_GPX, "gpx"); gpx.attribute("", "version", "1.0"); gpx.attribute("", "creator", "c:geo - http://www.cgeo.org/"); gpx.attribute(PREFIX_XSI, "schemaLocation", PREFIX_GPX + " http://www.topografix.com/GPX/1/0/gpx.xsd " + - PREFIX_GROUNDSPEAK + " http://www.groundspeak.com/cache/1/0/1/cache.xsd"); + PREFIX_GROUNDSPEAK + " http://www.groundspeak.com/cache/1/0/1/cache.xsd " + + PREFIX_GSAK + " http://www.gsak.net/xmlv1/4/gsak.xsd"); // Split the overall set of geocodes into small chunks. That is a compromise between memory efficiency (because // we don't load all caches fully into memory) and speed (because we don't query each cache separately). @@ -150,29 +155,35 @@ public final class GpxSerializer { final List<Waypoint> waypoints = cache.getWaypoints(); final List<Waypoint> ownWaypoints = new ArrayList<Waypoint>(waypoints.size()); final List<Waypoint> originWaypoints = new ArrayList<Waypoint>(waypoints.size()); + int maxPrefix = 0; for (final Waypoint wp : cache.getWaypoints()) { + + // Retrieve numerical prefixes to have a basis for assigning prefixes to own waypoints + final String prefix = wp.getPrefix(); + if (StringUtils.isNotBlank(prefix)) { + try { + final int numericPrefix = Integer.parseInt(prefix); + maxPrefix = Math.max(numericPrefix, maxPrefix); + } catch (final NumberFormatException ex) { + // ignore non numeric prefix, as it should be unique in the list of non-own waypoints already + } + } if (wp.isUserDefined()) { ownWaypoints.add(wp); } else { originWaypoints.add(wp); } } - int maxPrefix = 0; for (final Waypoint wp : originWaypoints) { - final String prefix = wp.getPrefix(); - try { - final int numericPrefix = Integer.parseInt(prefix); - maxPrefix = Math.max(numericPrefix, maxPrefix); - } catch (final NumberFormatException ex) { - // ignore non numeric prefix, as it should be unique in the list of non-own waypoints already - } - writeCacheWaypoint(wp, prefix); + writeCacheWaypoint(wp); } - // Prefixes must be unique. There use numeric strings as prefixes in OWN waypoints + // Prefixes must be unique. There use numeric strings as prefixes in OWN waypoints where they are missing for (final Waypoint wp : ownWaypoints) { - maxPrefix++; - final String prefix = StringUtils.leftPad(String.valueOf(maxPrefix), 2, '0'); - writeCacheWaypoint(wp, prefix); + if (StringUtils.isBlank(wp.getPrefix()) || StringUtils.equalsIgnoreCase("OWN", wp.getPrefix())) { + maxPrefix++; + wp.setPrefix(StringUtils.leftPad(String.valueOf(maxPrefix), 2, '0')); + } + writeCacheWaypoint(wp); } } @@ -185,7 +196,7 @@ public final class GpxSerializer { * @param prefix * @throws IOException */ - private void writeCacheWaypoint(final Waypoint wp, final String prefix) throws IOException { + private void writeCacheWaypoint(final Waypoint wp) throws IOException { final Geopoint coords = wp.getCoords(); // TODO: create some extension to GPX to include waypoint without coords if (coords != null) { @@ -193,11 +204,27 @@ public final class GpxSerializer { gpx.attribute("", "lat", Double.toString(coords.getLatitude())); gpx.attribute("", "lon", Double.toString(coords.getLongitude())); XmlUtils.multipleTexts(gpx, PREFIX_GPX, - "name", prefix + wp.getGeocode().substring(2), + "name", wp.getGpxId(), "cmt", wp.getNote(), "desc", wp.getName(), "sym", wp.getWaypointType().toString(), //TODO: Correct identifier string "type", "Waypoint|" + wp.getWaypointType().toString()); //TODO: Correct identifier string + // add parent reference the GSAK-way + gpx.startTag(PREFIX_GSAK, "wptExtension"); + gpx.startTag(PREFIX_GSAK, "Parent"); + gpx.text(wp.getGeocode()); + gpx.endTag(PREFIX_GSAK, "Parent"); + gpx.endTag(PREFIX_GSAK, "wptExtension"); + if (wp.isVisited()) { + gpx.startTag(PREFIX_CGEO, "visited"); + gpx.text("true"); + gpx.endTag(PREFIX_CGEO, "visited"); + } + if (wp.isUserDefined()) { + gpx.startTag(PREFIX_CGEO, "userdefined"); + gpx.text("true"); + gpx.endTag(PREFIX_CGEO, "userdefined"); + } gpx.endTag(PREFIX_GPX, "wpt"); } } diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java index e01c191..3e96291 100644 --- a/main/src/cgeo/geocaching/files/GPXParser.java +++ b/main/src/cgeo/geocaching/files/GPXParser.java @@ -70,9 +70,14 @@ public abstract class GPXParser extends FileParser { * supported GSAK extension of the GPX format */ private static final String[] GSAK_NS = new String[] { + "http://www.gsak.net/xmlv1/4", "http://www.gsak.net/xmlv1/5", "http://www.gsak.net/xmlv1/6" }; + /** + * c:geo extensions of the gpx format + */ + private static final String CGEO_NS = "http://www.cgeo.org/wptext/1/0"; private static final Pattern PATTERN_MILLISECONDS = Pattern.compile("\\.\\d{3,7}"); @@ -90,6 +95,9 @@ public abstract class GPXParser extends FileParser { private String cmt = null; private String desc = null; protected final String[] userData = new String[5]; // take 5 cells, that makes indexing 1..4 easier + private String parentCacheCode = null; + private boolean wptVisited = false; + private boolean wptUserDefined = false; /** * Parser result. Maps geocode to cache. @@ -328,20 +336,25 @@ public abstract class GPXParser extends FileParser { private void addWaypointToCache() { fixCache(cache); - if (cache.getName().length() > 2) { - final String cacheGeocodeForWaypoint = "GC" + cache.getName().substring(2).toUpperCase(Locale.US); + if (cache.getName().length() > 2 || StringUtils.isNotBlank(parentCacheCode)) { + if (StringUtils.isBlank(parentCacheCode)) { + parentCacheCode = "GC" + cache.getName().substring(2).toUpperCase(Locale.US); + } // lookup cache for waypoint in already parsed caches - final Geocache cacheForWaypoint = DataStore.loadCache(cacheGeocodeForWaypoint, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cacheForWaypoint = DataStore.loadCache(parentCacheCode, LoadFlags.LOAD_CACHE_OR_DB); if (cacheForWaypoint != null) { final Waypoint waypoint = new Waypoint(cache.getShortDescription(), convertWaypointSym2Type(sym), false); + if (wptUserDefined) { + waypoint.setUserDefined(); + } waypoint.setId(-1); - waypoint.setGeocode(cacheGeocodeForWaypoint); - waypoint.setPrefix(cache.getName().substring(0, 2)); + waypoint.setGeocode(parentCacheCode); + waypoint.setPrefix(cacheForWaypoint.getWaypointPrefix(cache.getName())); waypoint.setLookup("---"); // there is no lookup code in gpx file waypoint.setCoords(cache.getCoords()); waypoint.setNote(cache.getDescription()); - + waypoint.setVisited(wptVisited); final ArrayList<Waypoint> mergedWayPoints = new ArrayList<Waypoint>(); mergedWayPoints.addAll(cacheForWaypoint.getWaypoints()); @@ -480,8 +493,37 @@ public abstract class GPXParser extends FileParser { for (int i = 2; i <= 4; i++) { gsak.getChild(gsakNamespace, "User" + i).setEndTextElementListener(new UserDataListener(i)); } + + gsak.getChild(gsakNamespace, "Parent").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + parentCacheCode = body; + } + }); } + // c:geo extensions + final Element cgeoVisited = cacheParent.getChild(CGEO_NS, "visited"); + + cgeoVisited.setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String visited) { + wptVisited = Boolean.valueOf(visited.trim()); + } + }); + + final Element cgeoUserDefined = cacheParent.getChild(CGEO_NS, "userdefined"); + + cgeoUserDefined.setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String userDefined) { + wptUserDefined = Boolean.valueOf(userDefined.trim()); + } + }); + // 3 different versions of the GC schema for (final String nsGC : GROUNDSPEAK_NAMESPACE) { // waypoints.cache @@ -869,6 +911,9 @@ public abstract class GPXParser extends FileParser { name = null; desc = null; cmt = null; + parentCacheCode = null; + wptVisited = false; + wptUserDefined = false; cache = new Geocache(this); |
