aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/connector/gc/GCMap.java
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo/geocaching/connector/gc/GCMap.java')
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCMap.java177
1 files changed, 83 insertions, 94 deletions
diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java
index 27ce06e..243d84c 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCMap.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java
@@ -1,35 +1,40 @@
package cgeo.geocaching.connector.gc;
-import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.DataStore;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
-import cgeo.geocaching.enumerations.LiveMapStrategy.Strategy;
-import cgeo.geocaching.enumerations.LiveMapStrategy.StrategyFlag;
import cgeo.geocaching.enumerations.StatusCode;
-import cgeo.geocaching.geopoint.Geopoint;
-import cgeo.geocaching.geopoint.GeopointFormatter.Format;
-import cgeo.geocaching.geopoint.Units;
-import cgeo.geocaching.geopoint.Viewport;
+import cgeo.geocaching.files.ParserException;
+import cgeo.geocaching.location.Geopoint;
+import cgeo.geocaching.location.GeopointFormatter.Format;
+import cgeo.geocaching.location.Units;
+import cgeo.geocaching.location.Viewport;
+import cgeo.geocaching.maps.LivemapStrategy;
+import cgeo.geocaching.maps.LivemapStrategy.Flag;
import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.sensors.Sensors;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.Formatter;
+import cgeo.geocaching.utils.JsonUtils;
import cgeo.geocaching.utils.LeastRecentlyUsedMap;
import cgeo.geocaching.utils.Log;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
+import org.eclipse.jdt.annotation.NonNull;
import rx.Observable;
import rx.functions.Func2;
import android.graphics.Bitmap;
+import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -43,7 +48,7 @@ import java.util.Set;
public class GCMap {
private static Viewport lastSearchViewport = null;
- public static SearchResult searchByGeocodes(Set<String> geocodes) {
+ public static SearchResult searchByGeocodes(final Set<String> geocodes) {
final SearchResult result = new SearchResult();
final String geocodeList = StringUtils.join(geocodes.toArray(), "|");
@@ -60,53 +65,41 @@ public class GCMap {
// {"name":"HP: Hannover - Sahlkamp","gc":"GC2Q97X","g":"a09149ca-00e0-4aa2-b332-db2b4dfb18d2","available":true,"archived":false,"subrOnly":false,"li":false,"fp":"0","difficulty":{"text":1.0,"value":"1"},"terrain":{"text":1.5,"value":"1_5"},"hidden":"5/29/2011","container":{"text":"Small","value":"small.gif"},"type":{"text":"Traditional Cache","value":2},"owner":{"text":"GeoM@n","value":"1deaa69e-6bcc-421d-95a1-7d32b468cb82"}}]
// }
- final JSONObject json = new JSONObject(data);
- final String status = json.getString("status");
+ final ObjectNode json = (ObjectNode) JsonUtils.reader.readTree(data);
+ final String status = json.path("status").asText();
if (StringUtils.isBlank(status)) {
-
- throw new JSONException("No status inside JSON");
+ throw new ParserException("No status inside JSON");
}
if ("success".compareTo(status) != 0) {
- throw new JSONException("Wrong status inside JSON");
+ throw new ParserException("Wrong status inside JSON");
}
- final JSONArray dataArray = json.getJSONArray("data");
+ final ArrayNode dataArray = (ArrayNode) json.get("data");
if (dataArray == null) {
- throw new JSONException("No data inside JSON");
+ throw new ParserException("No data inside JSON");
}
final ArrayList<Geocache> caches = new ArrayList<>();
- for (int j = 0; j < dataArray.length(); j++) {
+ for (final JsonNode dataObject: dataArray) {
final Geocache cache = new Geocache();
-
- JSONObject dataObject = dataArray.getJSONObject(j);
- cache.setName(dataObject.getString("name"));
- cache.setGeocode(dataObject.getString("gc"));
- cache.setGuid(dataObject.getString("g")); // 34c2e609-5246-4f91-9029-d6c02b0f2a82"
- cache.setDisabled(!dataObject.getBoolean("available"));
- cache.setArchived(dataObject.getBoolean("archived"));
- cache.setPremiumMembersOnly(dataObject.getBoolean("subrOnly"));
+ cache.setName(dataObject.path("name").asText());
+ cache.setGeocode(dataObject.path("gc").asText());
+ cache.setGuid(dataObject.path("g").asText()); // 34c2e609-5246-4f91-9029-d6c02b0f2a82"
+ cache.setDisabled(!dataObject.path("available").asBoolean());
+ cache.setArchived(dataObject.path("archived").asBoolean());
+ cache.setPremiumMembersOnly(dataObject.path("subrOnly").asBoolean());
// "li" seems to be "false" always
- cache.setFavoritePoints(Integer.parseInt(dataObject.getString("fp")));
- JSONObject difficultyObj = dataObject.getJSONObject("difficulty");
- cache.setDifficulty(Float.parseFloat(difficultyObj.getString("text"))); // 3.5
- JSONObject terrainObj = dataObject.getJSONObject("terrain");
- cache.setTerrain(Float.parseFloat(terrainObj.getString("text"))); // 1.5
- cache.setHidden(GCLogin.parseGcCustomDate(dataObject.getString("hidden"), "MM/dd/yyyy")); // 7/23/2001
- JSONObject containerObj = dataObject.getJSONObject("container");
- cache.setSize(CacheSize.getById(containerObj.getString("text"))); // Regular
- JSONObject typeObj = dataObject.getJSONObject("type");
- cache.setType(CacheType.getByPattern(typeObj.getString("text"))); // Traditional Cache
- JSONObject ownerObj = dataObject.getJSONObject("owner");
- cache.setOwnerDisplayName(ownerObj.getString("text"));
+ cache.setFavoritePoints(Integer.parseInt(dataObject.path("fp").asText()));
+ cache.setDifficulty(Float.parseFloat(dataObject.path("difficulty").path("text").asText())); // 3.5
+ cache.setTerrain(Float.parseFloat(dataObject.path("terrain").path("text").asText())); // 1.5
+ cache.setHidden(GCLogin.parseGcCustomDate(dataObject.path("hidden").asText(), "MM/dd/yyyy")); // 7/23/2001
+ cache.setSize(CacheSize.getById(dataObject.path("container").path("text").asText())); // Regular
+ cache.setType(CacheType.getByPattern(dataObject.path("type").path("text").asText())); // Traditional Cache
+ cache.setOwnerDisplayName(dataObject.path("owner").path("text").asText());
caches.add(cache);
}
result.addAndPutInCache(caches);
- } catch (JSONException e) {
- result.setError(StatusCode.UNKNOWN_ERROR);
- } catch (ParseException e) {
- result.setError(StatusCode.UNKNOWN_ERROR);
- } catch (NumberFormatException e) {
+ } catch (ParserException | ParseException | IOException | NumberFormatException ignored) {
result.setError(StatusCode.UNKNOWN_ERROR);
}
return result;
@@ -117,7 +110,7 @@ public class GCMap {
* Retrieved data.
* @return SearchResult. Never null.
*/
- public static SearchResult parseMapJSON(final String data, Tile tile, Bitmap bitmap, final Strategy strategy) {
+ public static SearchResult parseMapJSON(final String data, final Tile tile, final Bitmap bitmap, final LivemapStrategy strategy) {
final SearchResult searchResult = new SearchResult();
try {
@@ -125,7 +118,7 @@ public class GCMap {
final LeastRecentlyUsedMap<String, String> nameCache = new LeastRecentlyUsedMap.LruCache<>(2000); // JSON id, cache name
if (StringUtils.isEmpty(data)) {
- throw new JSONException("No page given");
+ throw new ParserException("No page given");
}
// Example JSON information
@@ -134,34 +127,33 @@ public class GCMap {
// "data":{"55_55":[{"i":"gEaR","n":"Spiel & Sport"}],"55_54":[{"i":"gEaR","n":"Spiel & Sport"}],"17_25":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"55_53":[{"i":"gEaR","n":"Spiel & Sport"}],"17_27":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"17_26":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"57_53":[{"i":"gEaR","n":"Spiel & Sport"}],"57_55":[{"i":"gEaR","n":"Spiel & Sport"}],"3_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"3_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"57_54":[{"i":"gEaR","n":"Spiel & Sport"}],"3_60":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"15_27":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"15_26":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"15_25":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"4_60":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"4_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"4_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"16_25":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"16_26":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"16_27":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"2_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"2_60":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"2_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"56_53":[{"i":"gEaR","n":"Spiel & Sport"}],"56_54":[{"i":"gEaR","n":"Spiel & Sport"}],"56_55":[{"i":"gEaR","n":"Spiel & Sport"}]}
// }
- final JSONObject json = new JSONObject(data);
+ final ObjectNode json = (ObjectNode) JsonUtils.reader.readTree(data);
- final JSONArray grid = json.getJSONArray("grid");
- if (grid == null || grid.length() != (UTFGrid.GRID_MAXY + 1)) {
- throw new JSONException("No grid inside JSON");
+ final ArrayNode grid = (ArrayNode) json.get("grid");
+ if (grid == null || grid.size() != (UTFGrid.GRID_MAXY + 1)) {
+ throw new ParserException("No grid inside JSON");
}
- final JSONArray keys = json.getJSONArray("keys");
+ final ArrayNode keys = (ArrayNode) json.get("keys");
if (keys == null) {
- throw new JSONException("No keys inside JSON");
+ throw new ParserException("No keys inside JSON");
}
- final JSONObject dataObject = json.getJSONObject("data");
+ final ObjectNode dataObject = (ObjectNode) json.get("data");
if (dataObject == null) {
- throw new JSONException("No data inside JSON");
+ throw new ParserException("No data inside JSON");
}
// iterate over the data and construct all caches in this tile
- Map<String, List<UTFGridPosition>> positions = new HashMap<>(); // JSON id as key
- Map<String, List<UTFGridPosition>> singlePositions = new HashMap<>(); // JSON id as key
-
- for (int i = 1; i < keys.length(); i++) { // index 0 is empty
- String key = keys.getString(i);
- if (StringUtils.isNotBlank(key)) {
- UTFGridPosition pos = UTFGridPosition.fromString(key);
- JSONArray dataForKey = dataObject.getJSONArray(key);
- for (int j = 0; j < dataForKey.length(); j++) {
- JSONObject cacheInfo = dataForKey.getJSONObject(j);
- String id = cacheInfo.getString("i");
- nameCache.put(id, cacheInfo.getString("n"));
+ final Map<String, List<UTFGridPosition>> positions = new HashMap<>(); // JSON id as key
+ final Map<String, List<UTFGridPosition>> singlePositions = new HashMap<>(); // JSON id as key
+
+ for (final JsonNode rawKey: keys) {
+ final String key = rawKey.asText();
+ if (StringUtils.isNotBlank(key)) { // index 0 is empty
+ final UTFGridPosition pos = UTFGridPosition.fromString(key);
+ final ArrayNode dataForKey = (ArrayNode) dataObject.get(key);
+ for (final JsonNode cacheInfo: dataForKey) {
+ final String id = cacheInfo.get("i").asText();
+ nameCache.put(id, cacheInfo.get("n").asText());
List<UTFGridPosition> listOfPositions = positions.get(id);
List<UTFGridPosition> singleListOfPositions = singlePositions.get(id);
@@ -174,7 +166,7 @@ public class GCMap {
}
listOfPositions.add(pos);
- if (dataForKey.length() == 1) {
+ if (dataForKey.size() == 1) {
singleListOfPositions.add(pos);
}
@@ -183,18 +175,18 @@ public class GCMap {
}
final ArrayList<Geocache> caches = new ArrayList<>();
- for (Entry<String, List<UTFGridPosition>> entry : positions.entrySet()) {
- String id = entry.getKey();
- List<UTFGridPosition> pos = entry.getValue();
- UTFGridPosition xy = UTFGrid.getPositionInGrid(pos);
- Geocache cache = new Geocache();
+ for (final Entry<String, List<UTFGridPosition>> entry : positions.entrySet()) {
+ final String id = entry.getKey();
+ final List<UTFGridPosition> pos = entry.getValue();
+ final UTFGridPosition xy = UTFGrid.getPositionInGrid(pos);
+ final Geocache cache = new Geocache();
cache.setDetailed(false);
cache.setReliableLatLon(false);
cache.setGeocode(id);
cache.setName(nameCache.get(id));
cache.setCoords(tile.getCoord(xy), tile.getZoomLevel());
- if (strategy.flags.contains(StrategyFlag.PARSE_TILES) && bitmap != null) {
- for (UTFGridPosition singlePos : singlePositions.get(id)) {
+ if (strategy.flags.contains(LivemapStrategy.Flag.PARSE_TILES) && bitmap != null) {
+ for (final UTFGridPosition singlePos : singlePositions.get(id)) {
if (IconDecoder.parseMapPNG(cache, bitmap, singlePos, tile.getZoomLevel())) {
break; // cache parsed
}
@@ -220,9 +212,7 @@ public class GCMap {
searchResult.addAndPutInCache(caches);
Log.d("Retrieved " + searchResult.getCount() + " caches for tile " + tile.toString());
- } catch (RuntimeException e) {
- Log.e("GCMap.parseMapJSON", e);
- } catch (JSONException e) {
+ } catch (RuntimeException | ParserException | IOException e) {
Log.e("GCMap.parseMapJSON", e);
}
@@ -236,19 +226,19 @@ public class GCMap {
* Area to search
* @param tokens
* Live map tokens
- * @return
*/
+ @NonNull
public static SearchResult searchByViewport(final Viewport viewport, final MapTokens tokens) {
- int speed = (int) CgeoApplication.getInstance().currentGeo().getSpeed() * 60 * 60 / 1000; // in km/h
- Strategy strategy = Settings.getLiveMapStrategy();
- if (strategy == Strategy.AUTO) {
- strategy = speed >= 30 ? Strategy.FAST : Strategy.DETAILED;
+ final int speed = (int) Sensors.getInstance().currentGeo().getSpeed() * 60 * 60 / 1000; // in km/h
+ LivemapStrategy strategy = Settings.getLiveMapStrategy();
+ if (strategy == LivemapStrategy.AUTO) {
+ strategy = speed >= 30 ? LivemapStrategy.FAST : LivemapStrategy.DETAILED;
}
- SearchResult result = searchByViewport(viewport, tokens, strategy);
+ final SearchResult result = searchByViewport(viewport, tokens, strategy);
if (Settings.isDebug()) {
- StringBuilder text = new StringBuilder(Formatter.SEPARATOR).append(strategy.getL10n()).append(Formatter.SEPARATOR).append(Units.getSpeed(speed));
+ final StringBuilder text = new StringBuilder(Formatter.SEPARATOR).append(strategy.getL10n()).append(Formatter.SEPARATOR).append(Units.getSpeed(speed));
result.setUrl(result.getUrl() + text);
}
@@ -266,9 +256,9 @@ public class GCMap {
* Live map tokens
* @param strategy
* Strategy for data retrieval and parsing, @see Strategy
- * @return
*/
- private static SearchResult searchByViewport(final Viewport viewport, final MapTokens tokens, final Strategy strategy) {
+ @NonNull
+ private static SearchResult searchByViewport(final Viewport viewport, final MapTokens tokens, final LivemapStrategy strategy) {
Log.d("GCMap.searchByViewport" + viewport.toString());
final SearchResult searchResult = new SearchResult();
@@ -277,7 +267,7 @@ public class GCMap {
searchResult.setUrl(viewport.getCenter().format(Format.LAT_LON_DECMINUTE));
}
- if (strategy.flags.contains(StrategyFlag.LOAD_TILES)) {
+ if (strategy.flags.contains(LivemapStrategy.Flag.LOAD_TILES)) {
final Set<Tile> tiles = Tile.getTilesForViewport(viewport);
if (Settings.isDebug()) {
@@ -347,11 +337,11 @@ public class GCMap {
}
}
- if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY) && Settings.isGCPremiumMember()) {
+ if (strategy.flags.contains(Flag.SEARCH_NEARBY) && Settings.isGCPremiumMember()) {
final Geopoint center = viewport.getCenter();
if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) {
//FIXME We don't have a RecaptchaReceiver!?
- SearchResult search = GCParser.searchByCoords(center, Settings.getCacheType(), false, null);
+ final SearchResult search = GCParser.searchByCoords(center, Settings.getCacheType(), false, null);
if (search != null && !search.isEmpty()) {
final Set<String> geocodes = search.getGeocodes();
lastSearchViewport = DataStore.getBounds(geocodes);
@@ -365,11 +355,10 @@ public class GCMap {
/**
* Creates a list of caches types to filter on the live map (exclusion string)
- *
+ *
* @param typeToDisplay
* - cache type to omit from exclusion list so it gets displayed
- * @return
- *
+ *
* cache types for live map filter:
* 2 = traditional, 9 = ape, 5 = letterbox
* 3 = multi
@@ -377,8 +366,8 @@ public class GCMap {
* 4 = virtual, 11 = webcam, 137 = earth
* 8 = mystery, 1858 = whereigo
*/
- private static String getCacheTypeFilter(CacheType typeToDisplay) {
- Set<String> filterTypes = new HashSet<>();
+ private static String getCacheTypeFilter(final CacheType typeToDisplay) {
+ final Set<String> filterTypes = new HashSet<>();
// Put all types in set, remove what should be visible in a second step
filterTypes.addAll(Arrays.asList("2", "9", "5", "3", "6", "453", "13", "1304", "4", "11", "137", "8", "1858"));
switch (typeToDisplay) {