aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/connector/gc/GCBase.java
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo/geocaching/connector/gc/GCBase.java')
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCBase.java177
1 files changed, 78 insertions, 99 deletions
diff --git a/main/src/cgeo/geocaching/connector/gc/GCBase.java b/main/src/cgeo/geocaching/connector/gc/GCBase.java
index d09f9af..2f79fab 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCBase.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCBase.java
@@ -31,6 +31,7 @@ import android.graphics.Bitmap;
import java.text.ParseException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -52,6 +53,9 @@ public class GCBase {
protected final static long GC_BASE31 = 31;
protected final static long GC_BASE16 = 16;
+ private final static LeastRecentlyUsedMap<Integer, Tile> tileCache = new LeastRecentlyUsedMap.LruCache<Integer, Tile>(64);
+ private static Viewport lastSearchViewport = null;
+
/**
* Searches the view port on the live map with Strategy.AUTO
*
@@ -84,6 +88,17 @@ public class GCBase {
}
}
+ public static void removeFromTileCache(Geopoint coords) {
+ if (coords != null) {
+ Collection<Tile> tiles = new ArrayList<Tile>(tileCache.values());
+ for (Tile tile : tiles) {
+ if (tile.containsPoint(coords)) {
+ tileCache.remove(tile.hashCode());
+ }
+ }
+ }
+ }
+
/**
* Searches the view port on the live map for caches.
* The strategy dictates if only live map information is used or if an additional
@@ -110,58 +125,78 @@ public class GCBase {
for (Tile tile : tiles) {
- StringBuilder url = new StringBuilder();
- url.append("?x=").append(tile.getX()) // x tile
- .append("&y=").append(tile.getY()) // y tile
- .append("&z=").append(tile.getZoomlevel()); // zoom level
- if (tokens != null) {
- url.append("&k=").append(tokens[0]); // user session
- url.append("&st=").append(tokens[1]); // session token
- }
- url.append("&ep=1");
- if (Settings.isExcludeMyCaches()) {
- url.append("&hf=1").append("&hh=1"); // hide found, hide hidden
- }
- if (Settings.getCacheType() == CacheType.TRADITIONAL) {
- url.append("&ect=9,5,3,6,453,13,1304,137,11,4,8,1858"); // 2 = tradi 3 = multi 8 = mystery
- }
- if (Settings.getCacheType() == CacheType.MULTI) {
- url.append("&ect=9,5,2,6,453,13,1304,137,11,4,8,1858");
- }
- if (Settings.getCacheType() == CacheType.MYSTERY) {
- url.append("&ect=9,5,3,6,453,13,1304,137,11,4,2,1858");
- }
- if (tile.getZoomlevel() != 14) {
- url.append("&_=").append(String.valueOf(System.currentTimeMillis()));
- }
- // other types t.b.d
- final String urlString = url.toString();
+ if (!tileCache.containsKey(tile.hashCode())) {
- // The PNG must be request before ! Else the following request would return with 204 - No Content
- Bitmap bitmap = Tile.requestMapTile(GCConstants.URL_MAP_TILE + urlString, referer);
+ StringBuilder url = new StringBuilder();
+ url.append("?x=").append(tile.getX()) // x tile
+ .append("&y=").append(tile.getY()) // y tile
+ .append("&z=").append(tile.getZoomlevel()); // zoom level
+ if (tokens != null) {
+ url.append("&k=").append(tokens[0]); // user session
+ url.append("&st=").append(tokens[1]); // session token
+ }
+ url.append("&ep=1");
+ if (Settings.isExcludeMyCaches()) {
+ url.append("&hf=1").append("&hh=1"); // hide found, hide hidden
+ }
+ if (Settings.getCacheType() == CacheType.TRADITIONAL) {
+ url.append("&ect=9,5,3,6,453,13,1304,137,11,4,8,1858"); // 2 = tradi 3 = multi 8 = mystery
+ }
+ if (Settings.getCacheType() == CacheType.MULTI) {
+ url.append("&ect=9,5,2,6,453,13,1304,137,11,4,8,1858");
+ }
+ if (Settings.getCacheType() == CacheType.MYSTERY) {
+ url.append("&ect=9,5,3,6,453,13,1304,137,11,4,2,1858");
+ }
+ if (tile.getZoomlevel() != 14) {
+ url.append("&_=").append(String.valueOf(System.currentTimeMillis()));
+ }
+ // other types t.b.d
+ final String urlString = url.toString();
- assert bitmap.getWidth() == Tile.TILE_SIZE : "Bitmap has wrong width";
- assert bitmap.getHeight() == Tile.TILE_SIZE : "Bitmap has wrong height";
+ // The PNG must be requested first, otherwise the following request would always return with 204 - No Content
+ Bitmap bitmap = Tile.requestMapTile(GCConstants.URL_MAP_TILE + urlString, referer);
- String data = Tile.requestMapInfo(GCConstants.URL_MAP_INFO + urlString, referer);
- if (StringUtils.isEmpty(data)) {
- Log.e(Settings.tag, "GCBase.searchByViewport: No data from server for tile (" + tile.getX() + "/" + tile.getY() + ")");
- } else {
- final SearchResult search = parseMapJSON(data, tile, bitmap, strategy);
- if (search == null || CollectionUtils.isEmpty(search.getGeocodes())) {
- Log.e(Settings.tag, "GCBase.searchByViewport: No cache parsed for viewport " + viewport);
+ // Check bitmap size
+ if (bitmap.getWidth() != Tile.TILE_SIZE ||
+ bitmap.getHeight() != Tile.TILE_SIZE) {
+ bitmap.recycle();
+ bitmap = null;
+ }
+
+ String data = Tile.requestMapInfo(GCConstants.URL_MAP_INFO + urlString, referer);
+ if (StringUtils.isEmpty(data)) {
+ Log.e(Settings.tag, "GCBase.searchByViewport: No data from server for tile (" + tile.getX() + "/" + tile.getY() + ")");
+ } else {
+ final SearchResult search = parseMapJSON(data, tile, bitmap, strategy);
+ if (search == null || CollectionUtils.isEmpty(search.getGeocodes())) {
+ Log.e(Settings.tag, "GCBase.searchByViewport: No cache parsed for viewport " + viewport);
+ }
+ else {
+ searchResult.addGeocodes(search.getGeocodes());
+ }
+ tileCache.put(tile.hashCode(), tile);
}
- else {
- searchResult.addGeocodes(search.getGeocodes());
+
+ // release native bitmap memory
+ if (bitmap != null) {
+ bitmap.recycle();
}
+
}
}
}
if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY)) {
- SearchResult search = cgBase.searchByCoords(null, viewport.getCenter(), Settings.getCacheType(), false);
- if (search != null) {
- searchResult.addGeocodes(search.getGeocodes());
+ Geopoint center = viewport.getCenter();
+ if ((lastSearchViewport == null) || !lastSearchViewport.isInViewport(center)) {
+ SearchResult search = cgBase.searchByCoords(null, center, Settings.getCacheType(), false);
+ if (search != null) {
+
+ List<Number> bounds = cgeoapplication.getInstance().getBounds(search.getGeocodes());
+ lastSearchViewport = new Viewport(bounds.get(1).doubleValue(), bounds.get(2).doubleValue(), bounds.get(4).doubleValue(), bounds.get(3).doubleValue());
+ searchResult.addGeocodes(search.getGeocodes());
+ }
}
}
@@ -265,7 +300,7 @@ public class GCBase {
cache.setName(nameCache.get(id));
cache.setZoomlevel(tile.getZoomlevel());
cache.setCoords(tile.getCoord(xy));
- if (strategy.flags.contains(StrategyFlag.PARSE_TILES) && positions.size() < 64) {
+ if (strategy.flags.contains(StrategyFlag.PARSE_TILES) && positions.size() < 64 && bitmap != null) {
// don't parse if there are too many caches. The decoding would return too much wrong results
IconDecoder.parseMapPNG(cache, bitmap, xy, tile.getZoomlevel());
} else {
@@ -325,62 +360,6 @@ public class GCBase {
return gcid;
}
- private static String modulo(final long value, final long base, final String sequence) {
- String result = "";
- long rest = 0;
- long divResult = value;
- do
- {
- rest = divResult % base;
- divResult = (int) Math.floor(divResult / base);
- result = sequence.charAt((int) rest) + result;
- } while (divResult != 0);
- return result;
- }
-
- /**
- * Convert (old) GCIds to GCCode (geocode)
- *
- * Based on http://www.geoclub.de/viewtopic.php?f=111&t=54859&start=40
- */
- public static String gcidToGCCode(final long gcid) {
- String gccode = modulo(gcid + 411120, GC_BASE31, SEQUENCE_GCID);
- if ((gccode.length() < 4) || (gccode.length() == 4 && SEQUENCE_GCID.indexOf(gccode.charAt(0)) < 16)) {
- gccode = modulo(gcid, GC_BASE16, SEQUENCE_GCID);
- }
- return "GC" + gccode;
- }
-
- /**
- * Convert ids from the live map to (old) GCIds
- *
- * Based on http://www.geoclub.de/viewtopic.php?f=111&t=54859&start=40
- */
- public static long newidToGCId(final String newid) {
- long gcid = 0;
- for (int p = 0; p < newid.length(); p++) {
- gcid = GC_BASE57 * gcid + SEQUENCE_NEWID.indexOf(newid.charAt(p));
- }
- return gcid;
- }
-
- /**
- * Convert (old) GCIds to ids used in the live map
- *
- * Based on http://www.geoclub.de/viewtopic.php?f=111&t=54859&start=40
- */
- public static String gcidToNewId(final long gcid) {
- return modulo(gcid, GC_BASE57, SEQUENCE_NEWID);
- }
-
- /**
- * Convert ids from the live map into GCCode (geocode)
- */
- public static String newidToGeocode(final String newid) {
- long gcid = GCBase.newidToGCId(newid);
- return GCBase.gcidToGCCode(gcid);
- }
-
/** Get user session & session token from the Live Map. Needed for following requests */
public static String[] getTokens() {
final HttpResponse response = Network.request(GCConstants.URL_LIVE_MAP, null, false);