aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo')
-rw-r--r--main/src/cgeo/geocaching/CacheCache.java4
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java10
-rw-r--r--main/src/cgeo/geocaching/SearchResult.java13
-rw-r--r--main/src/cgeo/geocaching/cgCache.java20
-rw-r--r--main/src/cgeo/geocaching/cgeocaches.java146
-rw-r--r--main/src/cgeo/geocaching/cgeopopup.java6
-rw-r--r--main/src/cgeo/geocaching/cgeowaypoint.java2
-rw-r--r--main/src/cgeo/geocaching/connector/AbstractConnector.java30
-rw-r--r--main/src/cgeo/geocaching/connector/ConnectorFactory.java17
-rw-r--r--main/src/cgeo/geocaching/connector/IConnector.java26
-rw-r--r--main/src/cgeo/geocaching/connector/capability/ISearchByCenter.java13
-rw-r--r--main/src/cgeo/geocaching/connector/capability/ISearchByGeocode.java12
-rw-r--r--main/src/cgeo/geocaching/connector/capability/ISearchByViewPort.java8
-rw-r--r--main/src/cgeo/geocaching/connector/gc/AbstractSearchThread.java (renamed from main/src/cgeo/geocaching/cgSearchThread.java)25
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConnector.java49
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConstants.java30
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCMap.java (renamed from main/src/cgeo/geocaching/connector/gc/GCBase.java)414
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java46
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Login.java8
-rw-r--r--main/src/cgeo/geocaching/connector/gc/SearchHandler.java (renamed from main/src/cgeo/geocaching/cgSearchHandler.java)9
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Tile.java50
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCApiConnector.java14
-rw-r--r--main/src/cgeo/geocaching/connector/ox/OXConnector.java22
-rw-r--r--main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java45
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java3
25 files changed, 499 insertions, 523 deletions
diff --git a/main/src/cgeo/geocaching/CacheCache.java b/main/src/cgeo/geocaching/CacheCache.java
index 1ada88c..bea8274 100644
--- a/main/src/cgeo/geocaching/CacheCache.java
+++ b/main/src/cgeo/geocaching/CacheCache.java
@@ -1,7 +1,7 @@
package cgeo.geocaching;
import cgeo.geocaching.cgData.StorageLocation;
-import cgeo.geocaching.connector.gc.GCBase;
+import cgeo.geocaching.connector.gc.Tile;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.utils.LeastRecentlyUsedMap;
@@ -108,7 +108,7 @@ public class CacheCache {
@Override
public void onRemove(cgCache removed) {
- GCBase.removeFromTileCache(removed);
+ Tile.Cache.removeFromTileCache(removed);
}
}
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index 885a6b5..7b9c147 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -7,7 +7,7 @@ import cgeo.geocaching.apps.cache.GeneralAppsFactory;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.IConnector;
-import cgeo.geocaching.connector.gc.GCParser;
+import cgeo.geocaching.connector.gc.GCConnector;
import cgeo.geocaching.enumerations.CacheAttribute;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
@@ -505,7 +505,7 @@ public class CacheDetailActivity extends AbstractActivity {
case CONTEXT_MENU_WAYPOINT_CACHES_AROUND: {
final cgWaypoint waypoint = cache.getWaypoint(index);
if (waypoint != null) {
- cgeocaches.startActivityCachesAround(this, waypoint.getCoords());
+ cgeocaches.startActivityCoordinates(this, waypoint.getCoords());
}
}
break;
@@ -561,7 +561,7 @@ public class CacheDetailActivity extends AbstractActivity {
cache.openInBrowser(this);
return true;
case MENU_CACHES_AROUND:
- cgeocaches.startActivityCachesAround(this, cache.getCoords());
+ cgeocaches.startActivityCoordinates(this, cache.getCoords());
return true;
case MENU_CALENDAR:
addToCalendarWithIntent();
@@ -1714,7 +1714,7 @@ public class CacheDetailActivity extends AbstractActivity {
@Override
public void run() {
- handler.sendEmptyMessage(GCParser.addToWatchlist(cache));
+ handler.sendEmptyMessage(GCConnector.addToWatchlist(cache));
}
}
@@ -1728,7 +1728,7 @@ public class CacheDetailActivity extends AbstractActivity {
@Override
public void run() {
- handler.sendEmptyMessage(GCParser.removeFromWatchlist(cache));
+ handler.sendEmptyMessage(GCConnector.removeFromWatchlist(cache));
}
}
diff --git a/main/src/cgeo/geocaching/SearchResult.java b/main/src/cgeo/geocaching/SearchResult.java
index 2e56c7c..d48f98c 100644
--- a/main/src/cgeo/geocaching/SearchResult.java
+++ b/main/src/cgeo/geocaching/SearchResult.java
@@ -14,6 +14,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
@@ -81,6 +82,18 @@ public class SearchResult implements Parcelable {
setTotal(in.readInt());
}
+ public SearchResult(cgCache cache) {
+ this();
+ addCache(cache);
+ }
+
+ public SearchResult(Collection<cgCache> caches) {
+ this();
+ for (cgCache cache : caches) {
+ addCache(cache);
+ }
+ }
+
@Override
public void writeToParcel(final Parcel out, final int flags) {
out.writeStringArray(geocodes.toArray(new String[geocodes.size()]));
diff --git a/main/src/cgeo/geocaching/cgCache.java b/main/src/cgeo/geocaching/cgCache.java
index bb6dffa..6373749 100644
--- a/main/src/cgeo/geocaching/cgCache.java
+++ b/main/src/cgeo/geocaching/cgCache.java
@@ -4,8 +4,10 @@ import cgeo.geocaching.cgData.StorageLocation;
import cgeo.geocaching.activity.IAbstractActivity;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.IConnector;
-import cgeo.geocaching.connector.gc.GCBase;
+import cgeo.geocaching.connector.capability.ISearchByCenter;
+import cgeo.geocaching.connector.capability.ISearchByGeocode;
import cgeo.geocaching.connector.gc.GCConnector;
+import cgeo.geocaching.connector.gc.GCConstants;
import cgeo.geocaching.connector.gc.Tile;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
@@ -480,7 +482,7 @@ public class cgCache implements ICache, IWaypoint {
}
public boolean supportsRefresh() {
- return getConnector().supportsRefreshCache(this);
+ return getConnector() instanceof ISearchByGeocode;
}
public boolean supportsWatchList() {
@@ -574,7 +576,7 @@ public class cgCache implements ICache, IWaypoint {
@Override
public String getCacheId() {
if (StringUtils.isBlank(cacheId) && getConnector().equals(GCConnector.getInstance())) {
- return String.valueOf(GCBase.gccodeToGCId(geocode));
+ return String.valueOf(GCConstants.gccodeToGCId(geocode));
}
return cacheId;
@@ -605,7 +607,7 @@ public class cgCache implements ICache, IWaypoint {
}
public boolean supportsCachesAround() {
- return getConnector().supportsCachesAround();
+ return getConnector() instanceof ISearchByCenter;
}
public void shareCache(Activity fromActivity, Resources res) {
@@ -1521,7 +1523,7 @@ public class cgCache implements ICache, IWaypoint {
return null;
}
- cgeoapplication app = cgeoapplication.getInstance();
+ final cgeoapplication app = cgeoapplication.getInstance();
if (!forceReload && listId == StoredList.TEMPORARY_LIST_ID && (app.isOffline(geocode, guid) || app.isThere(geocode, guid, true, true))) {
final SearchResult search = new SearchResult();
final String realGeocode = StringUtils.isNotBlank(geocode) ? geocode : app.getGeocode(guid);
@@ -1531,10 +1533,14 @@ public class cgCache implements ICache, IWaypoint {
// if we have no geocode, we can't dynamically select the handler, but must explicitly use GC
if (geocode == null && guid != null) {
- return GCConnector.getInstance().searchByGeocode(null, guid, app, handler);
+ return GCConnector.getInstance().searchByGeocode(null, guid, handler);
}
- return ConnectorFactory.getConnector(geocode).searchByGeocode(geocode, guid, app, handler);
+ final IConnector connector = ConnectorFactory.getConnector(geocode);
+ if (connector instanceof ISearchByGeocode) {
+ return ((ISearchByGeocode) connector).searchByGeocode(geocode, guid, handler);
+ }
+ return null;
}
}
diff --git a/main/src/cgeo/geocaching/cgeocaches.java b/main/src/cgeo/geocaching/cgeocaches.java
index 695af42..5231bf7 100644
--- a/main/src/cgeo/geocaching/cgeocaches.java
+++ b/main/src/cgeo/geocaching/cgeocaches.java
@@ -7,6 +7,8 @@ import cgeo.geocaching.activity.Progress;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.apps.cachelist.CacheListAppFactory;
import cgeo.geocaching.connector.gc.GCParser;
+import cgeo.geocaching.connector.gc.SearchHandler;
+import cgeo.geocaching.connector.gc.AbstractSearchThread;
import cgeo.geocaching.enumerations.CacheListType;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
@@ -438,7 +440,7 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
}
// reload history list
- (new LoadByHistoryThread(loadCachesHandler)).start();
+ (new LoadByHistoryThread()).start();
progress.dismiss();
}
@@ -500,7 +502,7 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
}
Thread threadPure;
- cgSearchThread thread;
+ AbstractSearchThread thread;
switch (type) {
case OFFLINE:
@@ -519,7 +521,7 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
showProgress(true);
setLoadingCaches();
- threadPure = new LoadByOfflineThread(loadCachesHandler, coords, listId);
+ threadPure = new LoadByOfflineThread(coords, listId);
threadPure.start();
break;
@@ -529,7 +531,7 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
showProgress(true);
setLoadingCaches();
- threadPure = new LoadByHistoryThread(loadCachesHandler);
+ threadPure = new LoadByHistoryThread();
threadPure.start();
break;
case NEAREST:
@@ -539,8 +541,8 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
showProgress(true);
setLoadingCaches();
- thread = new LoadByCoordsThread(loadCachesHandler, coords);
- thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread));
+ thread = new LoadByCoordsThread(coords);
+ thread.setRecaptchaHandler(new SearchHandler(this, res, thread));
thread.start();
break;
case COORDINATE:
@@ -550,8 +552,8 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
showProgress(true);
setLoadingCaches();
- thread = new LoadByCoordsThread(loadCachesHandler, coords);
- thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread));
+ thread = new LoadByCoordsThread(coords);
+ thread.setRecaptchaHandler(new SearchHandler(this, res, thread));
thread.start();
break;
case KEYWORD:
@@ -560,8 +562,8 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
showProgress(true);
setLoadingCaches();
- thread = new LoadByKeywordThread(loadCachesHandler, keyword);
- thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread));
+ thread = new LoadByKeywordThread(keyword);
+ thread.setRecaptchaHandler(new SearchHandler(this, res, thread));
thread.start();
break;
case ADDRESS:
@@ -578,8 +580,8 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
setLoadingCaches();
}
- thread = new LoadByCoordsThread(loadCachesHandler, coords);
- thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread));
+ thread = new LoadByCoordsThread(coords);
+ thread.setRecaptchaHandler(new SearchHandler(this, res, thread));
thread.start();
break;
case USERNAME:
@@ -588,8 +590,8 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
showProgress(true);
setLoadingCaches();
- thread = new LoadByUserNameThread(loadCachesHandler, username);
- thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread));
+ thread = new LoadByUserNameThread(username);
+ thread.setRecaptchaHandler(new SearchHandler(this, res, thread));
thread.start();
break;
case OWNER:
@@ -598,8 +600,8 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
showProgress(true);
setLoadingCaches();
- thread = new LoadByOwnerThread(loadCachesHandler, username);
- thread.setRecaptchaHandler(new cgSearchHandler(this, res, thread));
+ thread = new LoadByOwnerThread(username);
+ thread.setRecaptchaHandler(new SearchHandler(this, res, thread));
thread.start();
break;
case MAP:
@@ -1443,13 +1445,10 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
}
private class LoadByOfflineThread extends Thread {
-
- final private Handler handler;
final private Geopoint coords;
final private int listId;
- public LoadByOfflineThread(final Handler handlerIn, final Geopoint coordsIn, int listIdIn) {
- handler = handlerIn;
+ public LoadByOfflineThread(final Geopoint coordsIn, int listIdIn) {
coords = coordsIn;
listId = listIdIn;
}
@@ -1457,50 +1456,34 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
@Override
public void run() {
search = cgeoapplication.getInstance().getBatchOfStoredCaches(true, coords, Settings.getCacheType(), listId);
- handler.sendMessage(Message.obtain());
+ loadCachesHandler.sendMessage(Message.obtain());
}
}
private class LoadByHistoryThread extends Thread {
-
- final private Handler handler;
-
- public LoadByHistoryThread(Handler handlerIn) {
- handler = handlerIn;
- }
-
@Override
public void run() {
search = cgeoapplication.getInstance().getHistoryOfCaches(true, coords != null ? Settings.getCacheType() : CacheType.ALL);
- handler.sendMessage(Message.obtain());
+ loadCachesHandler.sendMessage(Message.obtain());
}
}
- private class LoadNextPageThread extends cgSearchThread {
-
- private final Handler handler;
-
- public LoadNextPageThread(Handler handlerIn) {
- handler = handlerIn;
+ private class LoadNextPageThread extends AbstractSearchThread {
+ public LoadNextPageThread() {
+ super(loadNextPageHandler);
}
@Override
- public void run() {
- search = GCParser.searchByNextPage(this, search, Settings.isShowCaptcha());
-
- handler.sendMessage(Message.obtain());
+ public void runSearch() {
+ search = GCParser.searchByNextPage(search, Settings.isShowCaptcha());
}
}
- private class LoadByCoordsThread extends cgSearchThread {
-
- final private Handler handler;
+ private class LoadByCoordsThread extends AbstractSearchThread {
final private Geopoint coords;
- public LoadByCoordsThread(final Handler handler, final Geopoint coords) {
- setPriority(Thread.MIN_PRIORITY);
-
- this.handler = handler;
+ public LoadByCoordsThread(final Geopoint coords) {
+ super(loadCachesHandler);
this.coords = coords;
if (coords == null) {
@@ -1511,22 +1494,16 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
}
@Override
- public void run() {
- search = GCParser.searchByCoords(this, coords, cacheType, Settings.isShowCaptcha());
-
- handler.sendMessage(Message.obtain());
+ public void runSearch() {
+ search = GCParser.searchByCoords(coords, cacheType, Settings.isShowCaptcha());
}
}
- private class LoadByKeywordThread extends cgSearchThread {
-
- final private Handler handler;
+ private class LoadByKeywordThread extends AbstractSearchThread {
final private String keyword;
- public LoadByKeywordThread(final Handler handler, final String keyword) {
- setPriority(Thread.MIN_PRIORITY);
-
- this.handler = handler;
+ public LoadByKeywordThread(final String keyword) {
+ super(loadCachesHandler);
this.keyword = keyword;
if (keyword == null) {
@@ -1537,21 +1514,16 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
}
@Override
- public void run() {
- search = GCParser.searchByKeyword(this, keyword, cacheType, Settings.isShowCaptcha());
- handler.sendMessage(Message.obtain());
+ public void runSearch() {
+ search = GCParser.searchByKeyword(keyword, cacheType, Settings.isShowCaptcha());
}
}
- private class LoadByUserNameThread extends cgSearchThread {
-
- final private Handler handler;
+ private class LoadByUserNameThread extends AbstractSearchThread {
final private String username;
- public LoadByUserNameThread(final Handler handler, final String username) {
- setPriority(Thread.MIN_PRIORITY);
-
- this.handler = handler;
+ public LoadByUserNameThread(final String username) {
+ super(loadCachesHandler);
this.username = username;
if (StringUtils.isBlank(username)) {
@@ -1562,21 +1534,16 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
}
@Override
- public void run() {
- search = GCParser.searchByUsername(this, username, cacheType, Settings.isShowCaptcha());
- handler.sendMessage(Message.obtain());
+ public void runSearch() {
+ search = GCParser.searchByUsername(username, cacheType, Settings.isShowCaptcha());
}
}
- private class LoadByOwnerThread extends cgSearchThread {
-
- final private Handler handler;
+ private class LoadByOwnerThread extends AbstractSearchThread {
final private String username;
- public LoadByOwnerThread(final Handler handler, final String username) {
- setPriority(Thread.MIN_PRIORITY);
-
- this.handler = handler;
+ public LoadByOwnerThread(final String username) {
+ super(loadCachesHandler);
this.username = username;
if (StringUtils.isBlank(username)) {
@@ -1587,9 +1554,8 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
}
@Override
- public void run() {
- search = GCParser.searchByOwner(this, username, cacheType, Settings.isShowCaptcha());
- handler.sendMessage(Message.obtain());
+ public void runSearch() {
+ search = GCParser.searchByOwner(username, cacheType, Settings.isShowCaptcha());
}
}
@@ -1645,7 +1611,6 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
}
Log.i("Waiting for next cache " + delay + " ms");
- sleep(delay);
} catch (Exception e) {
Log.e("cgeocaches.LoadDetailsThread.sleep: " + e.toString());
}
@@ -1849,9 +1814,8 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
setLoadingCaches();
listFooter.setOnClickListener(null);
- LoadNextPageThread thread;
- thread = new LoadNextPageThread(loadNextPageHandler);
- thread.setRecaptchaHandler(new cgSearchHandler(cgeocaches.this, res, thread));
+ final LoadNextPageThread thread = new LoadNextPageThread();
+ thread.setRecaptchaHandler(new SearchHandler(cgeocaches.this, res, thread));
thread.start();
}
}
@@ -1908,7 +1872,7 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
private class MoveHandler extends Handler {
@Override
public void handleMessage(Message msg) {
- Thread threadPure = new LoadByOfflineThread(loadCachesHandler, coords, msg.what);
+ Thread threadPure = new LoadByOfflineThread(coords, msg.what);
threadPure.start();
}
}
@@ -2038,16 +2002,6 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
context.startActivity(cachesIntent);
}
- public static void startActivityCachesAround(final AbstractActivity context, final Geopoint coords) {
- cgeocaches cachesActivity = new cgeocaches();
-
- Intent cachesIntent = new Intent(context, cachesActivity.getClass());
- cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.COORDINATE);
- cachesIntent.putExtra(EXTRAS_COORDS, coords);
-
- context.startActivity(cachesIntent);
- }
-
public static void startActivityOwner(final AbstractActivity context, final String userName) {
final Intent cachesIntent = new Intent(context, cgeocaches.class);
@@ -2121,7 +2075,7 @@ public class cgeocaches extends AbstractListActivity implements IObserver<Object
}
public static void startActivityAddress(final Context context, final Geopoint coords, final String address) {
- Intent addressIntent = new Intent(context, cgeocaches.class);
+ final Intent addressIntent = new Intent(context, cgeocaches.class);
addressIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.ADDRESS);
addressIntent.putExtra(EXTRAS_COORDS, coords);
addressIntent.putExtra("address", address);
diff --git a/main/src/cgeo/geocaching/cgeopopup.java b/main/src/cgeo/geocaching/cgeopopup.java
index dd9be5b..05383f1 100644
--- a/main/src/cgeo/geocaching/cgeopopup.java
+++ b/main/src/cgeo/geocaching/cgeopopup.java
@@ -2,7 +2,7 @@ package cgeo.geocaching;
import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
-import cgeo.geocaching.connector.ConnectorFactory;
+import cgeo.geocaching.connector.gc.GCMap;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
@@ -236,7 +236,7 @@ public class cgeopopup extends AbstractActivity {
if ( CacheType.UNKNOWN == cache.getType() ) {
Set<String> geocodes = new HashSet<String>();
geocodes.add(geocode);
- SearchResult search = ConnectorFactory.searchByGeocodes(geocodes);
+ SearchResult search = GCMap.searchByGeocodes(geocodes);
cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_ONLY);
}
@@ -515,7 +515,7 @@ public class cgeopopup extends AbstractActivity {
return;
}
- cgeocaches.startActivityCachesAround(this, cache.getCoords());
+ cgeocaches.startActivityCoordinates(this, cache.getCoords());
finish();
}
diff --git a/main/src/cgeo/geocaching/cgeowaypoint.java b/main/src/cgeo/geocaching/cgeowaypoint.java
index ca3182d..61f44b9 100644
--- a/main/src/cgeo/geocaching/cgeowaypoint.java
+++ b/main/src/cgeo/geocaching/cgeowaypoint.java
@@ -240,7 +240,7 @@ public class cgeowaypoint extends AbstractActivity implements IObserver<IGeoData
showToast(res.getString(R.string.err_location_unknown));
}
- cgeocaches.startActivityCachesAround(this, waypoint.getCoords());
+ cgeocaches.startActivityCoordinates(this, waypoint.getCoords());
finish();
}
diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java
index 248ca23..f1d00fa 100644
--- a/main/src/cgeo/geocaching/connector/AbstractConnector.java
+++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java
@@ -2,12 +2,7 @@ package cgeo.geocaching.connector;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgeoapplication;
-import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Viewport;
-import cgeo.geocaching.utils.CancellableHandler;
-
-import java.util.Set;
public abstract class AbstractConnector implements IConnector {
@@ -17,11 +12,6 @@ public abstract class AbstractConnector implements IConnector {
}
@Override
- public boolean supportsRefreshCache(cgCache cache) {
- return false;
- }
-
- @Override
public boolean supportsWatchList() {
return false;
}
@@ -41,26 +31,6 @@ public abstract class AbstractConnector implements IConnector {
return false;
}
- @Override
- public boolean supportsCachesAround() {
- return false;
- }
-
- @Override
- public SearchResult searchByCoordinate(Geopoint center) {
- return null;
- }
-
- @Override
- public SearchResult searchByGeocode(String geocode, String guid, cgeoapplication app, CancellableHandler handler) {
- return null;
- }
-
- @Override
- public SearchResult searchByGeocodes(Set<String> geocodes) {
- return null;
- }
-
public SearchResult searchByViewport(Viewport viewport, String tokens[]) {
return null;
}
diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
index fc8ef45..784a54e 100644
--- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java
+++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java
@@ -6,13 +6,10 @@ import cgeo.geocaching.connector.gc.GCConnector;
import cgeo.geocaching.connector.oc.OCApiConnector;
import cgeo.geocaching.connector.oc.OCConnector;
import cgeo.geocaching.connector.ox.OXConnector;
-import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Viewport;
import org.apache.commons.lang3.StringUtils;
-import java.util.Set;
-
public final class ConnectorFactory {
private static final UnknownConnector UNKNOWN_CONNECTOR = new UnknownConnector();
private static final IConnector[] connectors = new IConnector[] {
@@ -70,13 +67,6 @@ public final class ConnectorFactory {
return StringUtils.isBlank(geocode) || !Character.isLetterOrDigit(geocode.charAt(0));
}
- /** @see IConnector#searchByCoordinate */
- public static SearchResult searchByCoordinate(final Geopoint center) {
- // We have only connector capable of doing a 'searchByCoordinate()'
- // If there is a second connector the information has to be collected from all collectors
- return GCConnector.getInstance().searchByCoordinate(center);
- }
-
/** @see IConnector#searchByViewport */
public static SearchResult searchByViewport(final Viewport viewport, final String[] tokens) {
// We have only connector capable of doing a 'searchByViewport()'
@@ -84,11 +74,4 @@ public final class ConnectorFactory {
return GCConnector.getInstance().searchByViewport(viewport, tokens);
}
- /** @see IConnector#searchByGeocodes */
- public static SearchResult searchByGeocodes(final Set<String> geocodes) {
- // We have only connector capable of doing a 'searchByViewport()'
- // If there is a second connector the information has to be collected from all collectors
- return GCConnector.getInstance().searchByGeocodes(geocodes);
- }
-
}
diff --git a/main/src/cgeo/geocaching/connector/IConnector.java b/main/src/cgeo/geocaching/connector/IConnector.java
index 28c21c8..4bc63fc 100644
--- a/main/src/cgeo/geocaching/connector/IConnector.java
+++ b/main/src/cgeo/geocaching/connector/IConnector.java
@@ -2,12 +2,7 @@ package cgeo.geocaching.connector;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgeoapplication;
-import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Viewport;
-import cgeo.geocaching.utils.CancellableHandler;
-
-import java.util.Set;
public interface IConnector {
/**
@@ -25,8 +20,6 @@ public interface IConnector {
*/
public boolean canHandle(final String geocode);
- public boolean supportsRefreshCache(final cgCache cache);
-
/**
* get browser URL for the given cache
*
@@ -72,25 +65,6 @@ public interface IConnector {
public boolean supportsUserActions();
/**
- * enable/disable "caches around" action in cache details
- *
- * @return
- */
- public boolean supportsCachesAround();
-
- public SearchResult searchByGeocode(final String geocode, final String guid, final cgeoapplication app, final CancellableHandler handler);
-
- public SearchResult searchByGeocodes(final Set<String> geocodes);
-
- /**
- * search caches by coordinate. must be implemented if {@link supportsCachesAround} returns <code>true</true>
- *
- * @param center
- * @return
- */
- public SearchResult searchByCoordinate(final Geopoint center);
-
- /**
* Search caches by viewport.
*
* @param viewport
diff --git a/main/src/cgeo/geocaching/connector/capability/ISearchByCenter.java b/main/src/cgeo/geocaching/connector/capability/ISearchByCenter.java
new file mode 100644
index 0000000..62645c2
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/capability/ISearchByCenter.java
@@ -0,0 +1,13 @@
+package cgeo.geocaching.connector.capability;
+
+import cgeo.geocaching.SearchResult;
+import cgeo.geocaching.geopoint.Geopoint;
+
+/**
+ * connector capability for online searching caches around a center coordinate, sorted by distance
+ *
+ */
+public interface ISearchByCenter {
+ public SearchResult searchByCenter(final Geopoint center);
+
+}
diff --git a/main/src/cgeo/geocaching/connector/capability/ISearchByGeocode.java b/main/src/cgeo/geocaching/connector/capability/ISearchByGeocode.java
new file mode 100644
index 0000000..c3d6bba
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/capability/ISearchByGeocode.java
@@ -0,0 +1,12 @@
+package cgeo.geocaching.connector.capability;
+
+import cgeo.geocaching.SearchResult;
+import cgeo.geocaching.utils.CancellableHandler;
+
+/**
+ * connector capability of searching online for a cache by geocode
+ *
+ */
+public interface ISearchByGeocode {
+ public SearchResult searchByGeocode(final String geocode, final String guid, final CancellableHandler handler);
+}
diff --git a/main/src/cgeo/geocaching/connector/capability/ISearchByViewPort.java b/main/src/cgeo/geocaching/connector/capability/ISearchByViewPort.java
new file mode 100644
index 0000000..316cf00
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/capability/ISearchByViewPort.java
@@ -0,0 +1,8 @@
+package cgeo.geocaching.connector.capability;
+
+import cgeo.geocaching.SearchResult;
+import cgeo.geocaching.geopoint.Viewport;
+
+public interface ISearchByViewPort {
+ public SearchResult searchByViewport(final Viewport viewport, final String[] tokens);
+}
diff --git a/main/src/cgeo/geocaching/cgSearchThread.java b/main/src/cgeo/geocaching/connector/gc/AbstractSearchThread.java
index ff73a66..33c8a92 100644
--- a/main/src/cgeo/geocaching/cgSearchThread.java
+++ b/main/src/cgeo/geocaching/connector/gc/AbstractSearchThread.java
@@ -1,13 +1,20 @@
-package cgeo.geocaching;
+package cgeo.geocaching.connector.gc;
import cgeo.geocaching.utils.Log;
import android.os.Handler;
+import android.os.Message;
-abstract public class cgSearchThread extends Thread {
+abstract public class AbstractSearchThread extends Thread {
private Handler recaptchaHandler = null;
private String recaptchaChallenge = null;
private String recaptchaText = null;
+ private final Handler handler;
+ private static AbstractSearchThread currentInstance;
+
+ public AbstractSearchThread(final Handler handler) {
+ this.handler = handler;
+ }
public void setRecaptchaHandler(Handler recaptchaHandlerIn) {
recaptchaHandler = recaptchaHandlerIn;
@@ -44,4 +51,18 @@ abstract public class cgSearchThread extends Thread {
public synchronized String getText() {
return recaptchaText;
}
+
+ @Override
+ final public void run() {
+ super.run();
+ currentInstance = this;
+ runSearch();
+ handler.sendMessage(Message.obtain());
+ }
+
+ protected abstract void runSearch();
+
+ public static AbstractSearchThread getCurrentInstance() {
+ return currentInstance;
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
index b461cc2..fbda5cd 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
@@ -6,7 +6,10 @@ import cgeo.geocaching.Settings;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.connector.AbstractConnector;
+import cgeo.geocaching.connector.capability.ISearchByCenter;
+import cgeo.geocaching.connector.capability.ISearchByGeocode;
import cgeo.geocaching.enumerations.StatusCode;
+import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.CancellableHandler;
@@ -15,10 +18,9 @@ import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import java.util.Set;
import java.util.regex.Pattern;
-public class GCConnector extends AbstractConnector {
+public class GCConnector extends AbstractConnector implements ISearchByGeocode, ISearchByCenter {
private static GCConnector instance;
private static final Pattern gpxZipFilePattern = Pattern.compile("\\d{7,}(_.+)?\\.zip", Pattern.CASE_INSENSITIVE);
@@ -43,11 +45,6 @@ public class GCConnector extends AbstractConnector {
}
@Override
- public boolean supportsRefreshCache(cgCache cache) {
- return true;
- }
-
- @Override
public String getCacheUrl(cgCache cache) {
// it would also be possible to use "http://www.geocaching.com/seek/cache_details.aspx?wp=" + cache.getGeocode();
return "http://coord.info/" + cache.getGeocode();
@@ -79,18 +76,7 @@ public class GCConnector extends AbstractConnector {
}
@Override
- public boolean supportsCachesAround() {
- return true;
- }
-
- @Override
- public SearchResult searchByGeocode(final String geocode, final String guid, final cgeoapplication app, final CancellableHandler handler) {
-
- if (app == null) {
- Log.e("cgeoBase.searchByGeocode: No application found");
- return null;
- }
-
+ public SearchResult searchByGeocode(final String geocode, final String guid, final CancellableHandler handler) {
final Parameters params = new Parameters("decrypt", "y");
if (StringUtils.isNotBlank(geocode)) {
params.put("wp", geocode);
@@ -106,11 +92,11 @@ public class GCConnector extends AbstractConnector {
if (StringUtils.isEmpty(page)) {
final SearchResult search = new SearchResult();
- if (app.isThere(geocode, guid, true, false)) {
+ if (cgeoapplication.getInstance().isThere(geocode, guid, true, false)) {
if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(guid)) {
Log.i("Loading old cache from cache.");
- search.addGeocode(app.getGeocode(guid));
+ search.addGeocode(cgeoapplication.getInstance().getGeocode(guid));
} else {
search.addGeocode(geocode);
}
@@ -134,13 +120,8 @@ public class GCConnector extends AbstractConnector {
}
@Override
- public SearchResult searchByGeocodes(Set<String> geocodes) {
- return GCBase.searchByGeocodes(geocodes);
- }
-
- @Override
public SearchResult searchByViewport(Viewport viewport, String[] tokens) {
- return GCBase.searchByViewport(viewport, tokens);
+ return GCMap.searchByViewport(viewport, tokens);
}
@Override
@@ -153,8 +134,18 @@ public class GCConnector extends AbstractConnector {
return cacheHasReliableLatLon;
}
+ public static int addToWatchlist(cgCache cache) {
+ return GCParser.addToWatchlist(cache);
+ }
+
+ public static int removeFromWatchlist(cgCache cache) {
+ return GCParser.removeFromWatchlist(cache);
+ }
+
@Override
- public String[] getTokens() {
- return GCBase.getTokens();
+ public SearchResult searchByCenter(Geopoint center) {
+ // TODO make search by coordinate use this method. currently it is just a marker that this connector supports search by center
+ return null;
}
+
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConstants.java b/main/src/cgeo/geocaching/connector/gc/GCConstants.java
index 083626d..21dde03 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConstants.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConstants.java
@@ -158,7 +158,37 @@ public final class GCConstants {
/** Number of logs to retrieve from GC.com */
public final static int NUMBER_OF_LOGS = 35;
+ private final static String SEQUENCE_GCID = "0123456789ABCDEFGHJKMNPQRTVWXYZ";
+ private final static long GC_BASE31 = 31;
+ private final static long GC_BASE16 = 16;
+
+ /**
+ * Convert GCCode (geocode) to (old) GCIds
+ *
+ * Based on http://www.geoclub.de/viewtopic.php?f=111&t=54859&start=40
+ * see http://support.groundspeak.com/index.php?pg=kb.printer.friendly&id=1#p221
+ */
+ public static long gccodeToGCId(final String gccode) {
+ long gcid = 0;
+ long base = GC_BASE31;
+ String geocodeWO = gccode.substring(2).toUpperCase();
+
+ if ((geocodeWO.length() < 4) || (geocodeWO.length() == 4 && SEQUENCE_GCID.indexOf(geocodeWO.charAt(0)) < 16)) {
+ base = GC_BASE16;
+ }
+
+ for (int p = 0; p < geocodeWO.length(); p++) {
+ gcid = base * gcid + SEQUENCE_GCID.indexOf(geocodeWO.charAt(p));
+ }
+
+ if (base == GC_BASE31) {
+ gcid += Math.pow(16, 4) - 16 * Math.pow(31, 3);
+ }
+ return gcid;
+ }
+
private GCConstants() {
// this class shall not have instances
}
+
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCBase.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java
index 64e5875..c7cb40f 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCBase.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java
@@ -1,6 +1,5 @@
package cgeo.geocaching.connector.gc;
-import cgeo.geocaching.ICoordinates;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
import cgeo.geocaching.cgCache;
@@ -13,16 +12,13 @@ import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.IConversion;
import cgeo.geocaching.geopoint.Viewport;
-import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.ui.Formatter;
-import cgeo.geocaching.utils.BaseUtils;
import cgeo.geocaching.utils.LeastRecentlyUsedMap;
import cgeo.geocaching.utils.Log;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import org.apache.http.HttpResponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -31,172 +27,80 @@ 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;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-/**
- * GC.com/Groundspeak (GS) specific stuff
- *
- * @author blafoo
- *
- */
-public class GCBase {
-
- protected final static String SEQUENCE_GCID = "0123456789ABCDEFGHJKMNPQRTVWXYZ";
- 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);
+public class GCMap {
private static Viewport lastSearchViewport = null;
- /**
- * Searches the view port on the live map with Strategy.AUTO
- *
- * @param viewport
- * Area to search
- * @param tokens
- * Live map tokens
- * @return
- */
- public static SearchResult searchByViewport(final Viewport viewport, final String[] tokens) {
- Strategy strategy = Settings.getLiveMapStrategy();
- if (strategy == Strategy.AUTO) {
- float speedNow = cgeoapplication.getInstance().currentGeo().getSpeed();
- strategy = speedNow >= 8 ? Strategy.FAST : Strategy.DETAILED; // 8 m/s = 30 km/h
- }
- // return searchByViewport(viewport, tokens, strategy);
-
- // testing purpose
- {
- SearchResult result = searchByViewport(viewport, tokens, strategy);
- String text = Formatter.SEPARATOR + strategy.getL10n() + Formatter.SEPARATOR;
- int speed = (int) cgeoapplication.getInstance().currentGeo().getSpeed();
- if (Settings.isUseMetricUnits()) {
- text += speed + " km/h";
- } else {
- text += speed / IConversion.MILES_TO_KILOMETER + " mph";
- }
- result.setUrl(result.getUrl() + text);
- return result;
- }
- }
-
- public static void removeFromTileCache(final ICoordinates point) {
- if (point != null) {
- Collection<Tile> tiles = new ArrayList<Tile>(tileCache.values());
- for (Tile tile : tiles) {
- if (tile.containsPoint(point)) {
- 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
- * searchByCoordinates query is issued.
- *
- * @param viewport
- * Area to search
- * @param tokens
- * Live map tokens
- * @param strategy
- * Strategy for data retrieval and parsing, @see Strategy
- * @return
- */
- private static SearchResult searchByViewport(final Viewport viewport, final String[] tokens, Strategy strategy) {
- Log.d("GCBase.searchByViewport" + viewport.toString());
-
- String referer = GCConstants.URL_LIVE_MAP;
-
- final SearchResult searchResult = new SearchResult();
- searchResult.setUrl(referer + "?ll=" + viewport.getCenter().getLatitude() + "," + viewport.getCenter().getLongitude());
+ public static SearchResult searchByGeocodes(Set<String> geocodes) {
+ final SearchResult result = new SearchResult();
- if (strategy.flags.contains(StrategyFlag.LOAD_TILES)) {
- final Set<Tile> tiles = getTilesForViewport(viewport);
+ final String geocodeList = StringUtils.join(geocodes.toArray(), "|");
+ final String referer = GCConstants.URL_LIVE_MAP_DETAILS;
- for (Tile tile : tiles) {
+ try {
+ final Parameters params = new Parameters("i", geocodeList, "_", String.valueOf(System.currentTimeMillis()));
+ final String data = StringUtils.defaultString(Tile.requestMapInfo(referer, params, referer));
- if (!tileCache.containsKey(tile.hashCode())) {
- final Parameters params = new Parameters(
- "x", String.valueOf(tile.getX()),
- "y", String.valueOf(tile.getY()),
- "z", String.valueOf(tile.getZoomlevel()),
- "ep", "1");
- if (tokens != null) {
- params.put("k", tokens[0], "st", tokens[1]);
- }
- if (Settings.isExcludeMyCaches()) {
- params.put("hf", "1", "hh", "1"); // hide found, hide hidden
- }
- if (Settings.getCacheType() == CacheType.TRADITIONAL) {
- params.put("ect", "9,5,3,6,453,13,1304,137,11,4,8,1858"); // 2 = tradi 3 = multi 8 = mystery
- } else if (Settings.getCacheType() == CacheType.MULTI) {
- params.put("ect", "9,5,2,6,453,13,1304,137,11,4,8,1858");
- } else if (Settings.getCacheType() == CacheType.MYSTERY) {
- params.put("ect", "9,5,3,6,453,13,1304,137,11,4,2,1858");
- }
- if (tile.getZoomlevel() != 14) {
- params.put("_", String.valueOf(System.currentTimeMillis()));
- }
- // TODO: other types t.b.d
+ // Example JSON information
+ // {"status":"success",
+ // "data":[{"name":"Mission: Impossible","gc":"GC1234","g":"34c2e609-5246-4f91-9029-d6c02b0f2a82","available":true,"archived":false,"subrOnly":false,"li":false,"fp":"5","difficulty":{"text":3.5,"value":"3_5"},"terrain":{"text":1.0,"value":"1"},"hidden":"7/23/2001","container":{"text":"Regular","value":"regular.gif"},"type":{"text":"Unknown Cache","value":8},"owner":{"text":"Ca$h_Cacher","value":"2db18e69-6877-402a-848d-6362621424f6"}},
+ // {"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"}}]
+ // }
- // 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, params, referer);
+ final JSONObject json = new JSONObject(data);
+ final String status = json.getString("status");
+ if (StringUtils.isBlank(status)) {
- // Check bitmap size
- if (bitmap != null && (bitmap.getWidth() != Tile.TILE_SIZE ||
- bitmap.getHeight() != Tile.TILE_SIZE)) {
- bitmap.recycle();
- bitmap = null;
- }
+ throw new JSONException("No status inside JSON");
+ }
+ if ("success".compareTo(status) != 0) {
+ throw new JSONException("Wrong status inside JSON");
+ }
+ final JSONArray dataArray = json.getJSONArray("data");
+ if (dataArray == null) {
+ throw new JSONException("No data inside JSON");
+ }
- String data = Tile.requestMapInfo(GCConstants.URL_MAP_INFO, params, referer);
- if (StringUtils.isEmpty(data)) {
- Log.e("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("GCBase.searchByViewport: No cache parsed for viewport " + viewport);
- }
- else {
- searchResult.addGeocodes(search.getGeocodes());
- }
- tileCache.put(tile.hashCode(), tile);
- }
+ for (int j = 0; j < dataArray.length(); j++) {
+ final cgCache cache = new cgCache();
- // release native bitmap memory
- if (bitmap != null) {
- bitmap.recycle();
- }
+ 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"));
+ // "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(Login.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.setOwner(ownerObj.getString("text"));
- }
- }
- }
+ result.addCache(cache);
- if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY)) {
- final Geopoint center = viewport.getCenter();
- if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) {
- SearchResult search = GCParser.searchByCoords(null, center, Settings.getCacheType(), false);
- if (search != null && !search.isEmpty()) {
- final Set<String> geocodes = search.getGeocodes();
- if (Settings.isPremiumMember()) {
- lastSearchViewport = cgeoapplication.getInstance().getBounds(geocodes);
- } else {
- lastSearchViewport = new Viewport(center, 0.01, 0.01);
- }
- searchResult.addGeocodes(geocodes);
- }
}
+ } catch (JSONException e) {
+ result.setError(StatusCode.UNKNOWN_ERROR);
+ } catch (ParseException e) {
+ result.setError(StatusCode.UNKNOWN_ERROR);
+ } catch (NumberFormatException e) {
+ result.setError(StatusCode.UNKNOWN_ERROR);
}
-
- return searchResult;
+ return result;
}
/**
@@ -313,125 +217,135 @@ public class GCBase {
return searchResult;
}
-
/**
- * Calculate needed tiles for the given viewport
- *
+ * Searches the view port on the live map with Strategy.AUTO
+ *
* @param viewport
+ * Area to search
+ * @param tokens
+ * Live map tokens
* @return
*/
- protected static Set<Tile> getTilesForViewport(final Viewport viewport) {
- Set<Tile> tiles = new HashSet<Tile>();
- int zoom = Math.min(Tile.calcZoomLon(viewport.bottomLeft, viewport.topRight),
- Tile.calcZoomLat(viewport.bottomLeft, viewport.topRight));
- tiles.add(new Tile(viewport.bottomLeft, zoom));
- tiles.add(new Tile(new Geopoint(viewport.getLatitudeMin(), viewport.getLongitudeMax()), zoom));
- tiles.add(new Tile(new Geopoint(viewport.getLatitudeMax(), viewport.getLongitudeMin()), zoom));
- tiles.add(new Tile(viewport.topRight, zoom));
- return tiles;
- }
-
- /**
- * Convert GCCode (geocode) to (old) GCIds
- *
- * Based on http://www.geoclub.de/viewtopic.php?f=111&t=54859&start=40
- * see http://support.groundspeak.com/index.php?pg=kb.printer.friendly&id=1#p221
- */
- public static long gccodeToGCId(final String gccode) {
- long gcid = 0;
- long base = GC_BASE31;
- String geocodeWO = gccode.substring(2).toUpperCase();
-
- if ((geocodeWO.length() < 4) || (geocodeWO.length() == 4 && SEQUENCE_GCID.indexOf(geocodeWO.charAt(0)) < 16)) {
- base = GC_BASE16;
- }
-
- for (int p = 0; p < geocodeWO.length(); p++) {
- gcid = base * gcid + SEQUENCE_GCID.indexOf(geocodeWO.charAt(p));
+ public static SearchResult searchByViewport(final Viewport viewport, final String[] tokens) {
+ Strategy strategy = Settings.getLiveMapStrategy();
+ if (strategy == Strategy.AUTO) {
+ float speedNow = cgeoapplication.getInstance().currentGeo().getSpeed();
+ strategy = speedNow >= 8 ? Strategy.FAST : Strategy.DETAILED; // 8 m/s = 30 km/h
}
+ // return searchByViewport(viewport, tokens, strategy);
- if (base == GC_BASE31) {
- gcid += Math.pow(16, 4) - 16 * Math.pow(31, 3);
+ // testing purpose
+ {
+ SearchResult result = searchByViewport(viewport, tokens, strategy);
+ String text = Formatter.SEPARATOR + strategy.getL10n() + Formatter.SEPARATOR;
+ int speed = (int) cgeoapplication.getInstance().currentGeo().getSpeed();
+ if (Settings.isUseMetricUnits()) {
+ text += speed + " km/h";
+ } else {
+ text += speed / IConversion.MILES_TO_KILOMETER + " mph";
+ }
+ result.setUrl(result.getUrl() + text);
+ return result;
}
- return gcid;
- }
-
- /** Get user session & session token from the Live Map. Needed for following requests */
- public static String[] getTokens() {
- final HttpResponse response = Network.getRequest(GCConstants.URL_LIVE_MAP);
- final String data = Network.getResponseData(response);
- String userSession = BaseUtils.getMatch(data, GCConstants.PATTERN_USERSESSION, "");
- String sessionToken = BaseUtils.getMatch(data, GCConstants.PATTERN_SESSIONTOKEN, "");
- return new String[] { userSession, sessionToken };
}
- public static SearchResult searchByGeocodes(final Set<String> geocodes) {
-
- final SearchResult result = new SearchResult();
+ /**
+ * Searches the view port on the live map for caches.
+ * The strategy dictates if only live map information is used or if an additional
+ * searchByCoordinates query is issued.
+ *
+ * @param viewport
+ * Area to search
+ * @param tokens
+ * Live map tokens
+ * @param strategy
+ * Strategy for data retrieval and parsing, @see Strategy
+ * @return
+ */
+ private static SearchResult searchByViewport(final Viewport viewport, final String[] tokens, Strategy strategy) {
+ Log.d("GCBase.searchByViewport" + viewport.toString());
- final String geocodeList = StringUtils.join(geocodes.toArray(), "|");
- final String referer = GCConstants.URL_LIVE_MAP_DETAILS;
+ final SearchResult searchResult = new SearchResult();
+ searchResult.setUrl(GCConstants.URL_LIVE_MAP + "?ll=" + viewport.getCenter().getLatitude() + "," + viewport.getCenter().getLongitude());
- try {
- final Parameters params = new Parameters("i", geocodeList, "_", String.valueOf(System.currentTimeMillis()));
- final String data = StringUtils.defaultString(Tile.requestMapInfo(referer, params, referer));
+ if (strategy.flags.contains(StrategyFlag.LOAD_TILES)) {
+ final Set<Tile> tiles = Tile.getTilesForViewport(viewport);
- // Example JSON information
- // {"status":"success",
- // "data":[{"name":"Mission: Impossible","gc":"GC1234","g":"34c2e609-5246-4f91-9029-d6c02b0f2a82","available":true,"archived":false,"subrOnly":false,"li":false,"fp":"5","difficulty":{"text":3.5,"value":"3_5"},"terrain":{"text":1.0,"value":"1"},"hidden":"7/23/2001","container":{"text":"Regular","value":"regular.gif"},"type":{"text":"Unknown Cache","value":8},"owner":{"text":"Ca$h_Cacher","value":"2db18e69-6877-402a-848d-6362621424f6"}},
- // {"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"}}]
- // }
+ for (Tile tile : tiles) {
- final JSONObject json = new JSONObject(data);
- final String status = json.getString("status");
- if (StringUtils.isBlank(status)) {
+ if (!Tile.Cache.contains(tile)) {
+ final Parameters params = new Parameters(
+ "x", String.valueOf(tile.getX()),
+ "y", String.valueOf(tile.getY()),
+ "z", String.valueOf(tile.getZoomlevel()),
+ "ep", "1");
+ if (tokens != null) {
+ params.put("k", tokens[0], "st", tokens[1]);
+ }
+ if (Settings.isExcludeMyCaches()) {
+ params.put("hf", "1", "hh", "1"); // hide found, hide hidden
+ }
+ if (Settings.getCacheType() == CacheType.TRADITIONAL) {
+ params.put("ect", "9,5,3,6,453,13,1304,137,11,4,8,1858"); // 2 = tradi 3 = multi 8 = mystery
+ } else if (Settings.getCacheType() == CacheType.MULTI) {
+ params.put("ect", "9,5,2,6,453,13,1304,137,11,4,8,1858");
+ } else if (Settings.getCacheType() == CacheType.MYSTERY) {
+ params.put("ect", "9,5,3,6,453,13,1304,137,11,4,2,1858");
+ }
+ if (tile.getZoomlevel() != 14) {
+ params.put("_", String.valueOf(System.currentTimeMillis()));
+ }
+ // TODO: other types t.b.d
- throw new JSONException("No status inside JSON");
- }
- if ("success".compareTo(status) != 0) {
- throw new JSONException("Wrong status inside JSON");
- }
- final JSONArray dataArray = json.getJSONArray("data");
- if (dataArray == null) {
- throw new JSONException("No data inside JSON");
- }
+ // The PNG must be requested first, otherwise the following request would always return with 204 - No Content
+ Bitmap bitmap = Tile.requestMapTile(params);
- for (int j = 0; j < dataArray.length(); j++) {
+ // Check bitmap size
+ if (bitmap != null && (bitmap.getWidth() != Tile.TILE_SIZE ||
+ bitmap.getHeight() != Tile.TILE_SIZE)) {
+ bitmap.recycle();
+ bitmap = null;
+ }
- cgCache cache = new cgCache();
+ String data = Tile.requestMapInfo(GCConstants.URL_MAP_INFO, params, GCConstants.URL_LIVE_MAP);
+ if (StringUtils.isEmpty(data)) {
+ Log.e("GCBase.searchByViewport: No data from server for tile (" + tile.getX() + "/" + tile.getY() + ")");
+ } else {
+ final SearchResult search = GCMap.parseMapJSON(data, tile, bitmap, strategy);
+ if (search == null || CollectionUtils.isEmpty(search.getGeocodes())) {
+ Log.e("GCBase.searchByViewport: No cache parsed for viewport " + viewport);
+ }
+ else {
+ searchResult.addGeocodes(search.getGeocodes());
+ }
+ Tile.Cache.add(tile);
+ }
- 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"));
- // "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(Login.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.setOwner(ownerObj.getString("text"));
+ // release native bitmap memory
+ if (bitmap != null) {
+ bitmap.recycle();
+ }
- result.addCache(cache);
+ }
+ }
+ }
+ if (strategy.flags.contains(StrategyFlag.SEARCH_NEARBY)) {
+ final Geopoint center = viewport.getCenter();
+ if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) {
+ SearchResult search = GCParser.searchByCoords(center, Settings.getCacheType(), false);
+ if (search != null && !search.isEmpty()) {
+ final Set<String> geocodes = search.getGeocodes();
+ if (Settings.isPremiumMember()) {
+ lastSearchViewport = cgeoapplication.getInstance().getBounds(geocodes);
+ } else {
+ lastSearchViewport = new Viewport(center, 0.01, 0.01);
+ }
+ searchResult.addGeocodes(geocodes);
+ }
}
- } catch (JSONException e) {
- result.setError(StatusCode.UNKNOWN_ERROR);
- } catch (ParseException e) {
- result.setError(StatusCode.UNKNOWN_ERROR);
- } catch (NumberFormatException e) {
- result.setError(StatusCode.UNKNOWN_ERROR);
}
- return result;
- }
+ return searchResult;
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index 9b397c9..3d2e994 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCParser.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -7,7 +7,6 @@ import cgeo.geocaching.Settings;
import cgeo.geocaching.TrackableLog;
import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgImage;
-import cgeo.geocaching.cgSearchThread;
import cgeo.geocaching.cgTrackable;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.cgeoapplication;
@@ -61,7 +60,7 @@ public abstract class GCParser {
private final static SimpleDateFormat dateTbIn1 = new SimpleDateFormat("EEEEE, dd MMMMM yyyy", Locale.ENGLISH); // Saturday, 28 March 2009
private final static SimpleDateFormat dateTbIn2 = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy", Locale.ENGLISH); // Saturday, March 28, 2009
- private static SearchResult parseSearch(final cgSearchThread thread, final String url, final String pageContent, final boolean showCaptcha) {
+ private static SearchResult parseSearch(final String url, final String pageContent, final boolean showCaptcha) {
if (StringUtils.isBlank(pageContent)) {
Log.e("cgeoBase.parseSearch: No page given");
return null;
@@ -77,6 +76,7 @@ public abstract class GCParser {
searchResult.viewstates = Login.getViewstates(page);
// recaptcha
+ AbstractSearchThread thread = AbstractSearchThread.getCurrentInstance();
if (showCaptcha) {
String recaptchaJsParam = BaseUtils.getMatch(page, GCConstants.PATTERN_SEARCH_RECAPTCHA, false, null);
@@ -305,7 +305,7 @@ public abstract class GCParser {
return searchResult;
}
- public static SearchResult parseCache(final String page, final CancellableHandler handler) {
+ static SearchResult parseCache(final String page, final CancellableHandler handler) {
final SearchResult searchResult = parseCacheFromText(page, handler);
if (searchResult != null && !searchResult.getGeocodes().isEmpty()) {
final cgCache cache = searchResult.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB);
@@ -710,7 +710,7 @@ public abstract class GCParser {
return searchResult;
}
- public static SearchResult searchByNextPage(cgSearchThread thread, final SearchResult search, boolean showCaptcha) {
+ public static SearchResult searchByNextPage(final SearchResult search, boolean showCaptcha) {
if (search == null) {
return search;
}
@@ -747,7 +747,7 @@ public abstract class GCParser {
return search;
}
- final SearchResult searchResult = parseSearch(thread, url, page, showCaptcha);
+ final SearchResult searchResult = parseSearch(url, page, showCaptcha);
if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) {
Log.e("cgeoBase.searchByNextPage: No cache parsed");
return search;
@@ -771,7 +771,7 @@ public abstract class GCParser {
* @param addF
* @return the original params if not null, maybe augmented with f=1, or a new Parameters with f=1 or null otherwise
*/
- public static Parameters addFToParams(final Parameters params, final boolean my, final boolean addF) {
+ private static Parameters addFToParams(final Parameters params, final boolean my, final boolean addF) {
if (!my && Settings.isExcludeMyCaches() && addF) {
if (params == null) {
return new Parameters("f", "1");
@@ -784,8 +784,6 @@ public abstract class GCParser {
}
/**
- * @param thread
- * thread to run the captcha if needed
* @param cacheType
* @param listId
* @param showCaptcha
@@ -793,7 +791,7 @@ public abstract class GCParser {
* the parameters to add to the request URI
* @return
*/
- private static SearchResult searchByAny(final cgSearchThread thread, final CacheType cacheType, final boolean my, final boolean showCaptcha, final Parameters params) {
+ private static SearchResult searchByAny(final CacheType cacheType, final boolean my, final boolean showCaptcha, final Parameters params) {
insertCacheType(params, cacheType);
final String uri = "http://www.geocaching.com/seek/nearest.aspx";
@@ -805,7 +803,7 @@ public abstract class GCParser {
return null;
}
- final SearchResult searchResult = parseSearch(thread, fullUri, page, showCaptcha);
+ final SearchResult searchResult = parseSearch(fullUri, page, showCaptcha);
if (searchResult == null || CollectionUtils.isEmpty(searchResult.getGeocodes())) {
Log.e("cgeoBase.searchByAny: No cache parsed");
return searchResult;
@@ -818,22 +816,22 @@ public abstract class GCParser {
return search;
}
- public static SearchResult searchByCoords(final cgSearchThread thread, final Geopoint coords, final CacheType cacheType, final boolean showCaptcha) {
+ public static SearchResult searchByCoords(final Geopoint coords, final CacheType cacheType, final boolean showCaptcha) {
final Parameters params = new Parameters("lat", Double.toString(coords.getLatitude()), "lng", Double.toString(coords.getLongitude()));
- return searchByAny(thread, cacheType, false, showCaptcha, params);
+ return searchByAny(cacheType, false, showCaptcha, params);
}
- public static SearchResult searchByKeyword(final cgSearchThread thread, final String keyword, final CacheType cacheType, final boolean showCaptcha) {
+ public static SearchResult searchByKeyword(final String keyword, final CacheType cacheType, final boolean showCaptcha) {
if (StringUtils.isBlank(keyword)) {
Log.e("cgeoBase.searchByKeyword: No keyword given");
return null;
}
final Parameters params = new Parameters("key", keyword);
- return searchByAny(thread, cacheType, false, showCaptcha, params);
+ return searchByAny(cacheType, false, showCaptcha, params);
}
- public static SearchResult searchByUsername(final cgSearchThread thread, final String userName, final CacheType cacheType, final boolean showCaptcha) {
+ public static SearchResult searchByUsername(final String userName, final CacheType cacheType, final boolean showCaptcha) {
if (StringUtils.isBlank(userName)) {
Log.e("cgeoBase.searchByUsername: No user name given");
return null;
@@ -847,17 +845,17 @@ public abstract class GCParser {
Log.i("cgBase.searchByUsername: Overriding users choice, downloading all caches.");
}
- return searchByAny(thread, cacheType, my, showCaptcha, params);
+ return searchByAny(cacheType, my, showCaptcha, params);
}
- public static SearchResult searchByOwner(final cgSearchThread thread, final String userName, final CacheType cacheType, final boolean showCaptcha) {
+ public static SearchResult searchByOwner(final String userName, final CacheType cacheType, final boolean showCaptcha) {
if (StringUtils.isBlank(userName)) {
Log.e("cgeoBase.searchByOwner: No user name given");
return null;
}
final Parameters params = new Parameters("u", userName);
- return searchByAny(thread, cacheType, false, showCaptcha, params);
+ return searchByAny(cacheType, false, showCaptcha, params);
}
public static cgTrackable searchTrackable(final String geocode, final String guid, final String id) {
@@ -885,7 +883,7 @@ public abstract class GCParser {
return trackable;
}
- trackable = parseTrackable(page, cgeoapplication.getInstance(), geocode);
+ trackable = parseTrackable(page, geocode);
if (trackable == null) {
Log.e("cgeoBase.searchTrackable: No trackable parsed");
return null;
@@ -1108,7 +1106,7 @@ public abstract class GCParser {
* the cache to add
* @return -1: error occured
*/
- public static int addToWatchlist(final cgCache cache) {
+ static int addToWatchlist(final cgCache cache) {
final String uri = "http://www.geocaching.com/my/watchlist.aspx?w=" + cache.getCacheId();
String page = Login.postRequestLogged(uri, null);
@@ -1134,7 +1132,7 @@ public abstract class GCParser {
* the cache to remove
* @return -1: error occured
*/
- public static int removeFromWatchlist(final cgCache cache) {
+ static int removeFromWatchlist(final cgCache cache) {
final String uri = "http://www.geocaching.com/my/watchlist.aspx?ds=1&action=rem&id=" + cache.getCacheId();
String page = Login.postRequestLogged(uri, null);
@@ -1170,7 +1168,7 @@ public abstract class GCParser {
* if not null, the application to use to save the trackable
* @return the parsed trackable, or null if none could be parsed
*/
- public static cgTrackable parseTrackable(final String page, final cgeoapplication app, final String possibleTrackingcode) {
+ static cgTrackable parseTrackable(final String page, final String possibleTrackingcode) {
if (StringUtils.isBlank(page)) {
Log.e("cgeoBase.parseTrackable: No page given");
return null;
@@ -1332,8 +1330,8 @@ public abstract class GCParser {
trackable.setTrackingcode(possibleTrackingcode);
}
- if (app != null) {
- app.saveTrackable(trackable);
+ if (cgeoapplication.getInstance() != null) {
+ cgeoapplication.getInstance().saveTrackable(trackable);
}
return trackable;
diff --git a/main/src/cgeo/geocaching/connector/gc/Login.java b/main/src/cgeo/geocaching/connector/gc/Login.java
index c39fcef..113f581 100644
--- a/main/src/cgeo/geocaching/connector/gc/Login.java
+++ b/main/src/cgeo/geocaching/connector/gc/Login.java
@@ -433,4 +433,12 @@ public abstract class Login {
return data;
}
+ /** Get user session & session token from the Live Map. Needed for following requests */
+ public static String[] getMapTokens() {
+ final HttpResponse response = Network.getRequest(GCConstants.URL_LIVE_MAP);
+ final String data = Network.getResponseData(response);
+ final String userSession = BaseUtils.getMatch(data, GCConstants.PATTERN_USERSESSION, "");
+ final String sessionToken = BaseUtils.getMatch(data, GCConstants.PATTERN_SESSIONTOKEN, "");
+ return new String[] { userSession, sessionToken };
+ }
}
diff --git a/main/src/cgeo/geocaching/cgSearchHandler.java b/main/src/cgeo/geocaching/connector/gc/SearchHandler.java
index 6d38ea1..45efff2 100644
--- a/main/src/cgeo/geocaching/cgSearchHandler.java
+++ b/main/src/cgeo/geocaching/connector/gc/SearchHandler.java
@@ -1,5 +1,6 @@
-package cgeo.geocaching;
+package cgeo.geocaching.connector.gc;
+import cgeo.geocaching.R;
import cgeo.geocaching.utils.Log;
import android.app.Activity;
@@ -20,10 +21,10 @@ import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
-public class cgSearchHandler extends Handler {
+public class SearchHandler extends Handler {
private Activity activity = null;
private Resources res = null;
- private cgSearchThread recaptchaThread = null;
+ private AbstractSearchThread recaptchaThread = null;
private ImageView imageView = null;
private Bitmap img = null;
@@ -40,7 +41,7 @@ public class cgSearchHandler extends Handler {
}
};
- public cgSearchHandler(Activity activityIn, Resources resIn, cgSearchThread recaptchaThreadIn) {
+ public SearchHandler(Activity activityIn, Resources resIn, AbstractSearchThread recaptchaThreadIn) {
activity = activityIn;
res = resIn;
recaptchaThread = recaptchaThreadIn;
diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java
index 692f28b..4747912 100644
--- a/main/src/cgeo/geocaching/connector/gc/Tile.java
+++ b/main/src/cgeo/geocaching/connector/gc/Tile.java
@@ -5,6 +5,7 @@ import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.LeastRecentlyUsedMap;
import cgeo.geocaching.utils.Log;
import org.apache.http.HttpResponse;
@@ -13,6 +14,10 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
/**
* All about tiles.
@@ -213,8 +218,8 @@ public class Tile {
}
/** Request .png image for a tile. */
- public static Bitmap requestMapTile(final String url, final Parameters params, final String referer) {
- final HttpResponse response = Network.getRequest(url, params, new Parameters("Referer", referer));
+ public static Bitmap requestMapTile(final Parameters params) {
+ final HttpResponse response = Network.getRequest(GCConstants.URL_MAP_TILE, params, new Parameters("Referer", GCConstants.URL_LIVE_MAP));
try {
return response != null ? BitmapFactory.decodeStream(response.getEntity().getContent()) : null;
} catch (IOException e) {
@@ -226,4 +231,45 @@ public class Tile {
public boolean containsPoint(final ICoordinates point) {
return viewPort.contains(point);
}
+
+ /**
+ * Calculate needed tiles for the given viewport
+ *
+ * @param viewport
+ * @return
+ */
+ protected static Set<Tile> getTilesForViewport(final Viewport viewport) {
+ Set<Tile> tiles = new HashSet<Tile>();
+ int zoom = Math.min(Tile.calcZoomLon(viewport.bottomLeft, viewport.topRight),
+ Tile.calcZoomLat(viewport.bottomLeft, viewport.topRight));
+ tiles.add(new Tile(viewport.bottomLeft, zoom));
+ tiles.add(new Tile(new Geopoint(viewport.getLatitudeMin(), viewport.getLongitudeMax()), zoom));
+ tiles.add(new Tile(new Geopoint(viewport.getLatitudeMax(), viewport.getLongitudeMin()), zoom));
+ tiles.add(new Tile(viewport.topRight, zoom));
+ return tiles;
+ }
+
+ public static class Cache {
+ private final static LeastRecentlyUsedMap<Integer, Tile> tileCache = new LeastRecentlyUsedMap.LruCache<Integer, Tile>(64);
+
+ public static void removeFromTileCache(final ICoordinates point) {
+ if (point != null) {
+ Collection<Tile> tiles = new ArrayList<Tile>(tileCache.values());
+ for (Tile tile : tiles) {
+ if (tile.containsPoint(point)) {
+ tileCache.remove(tile.hashCode());
+ }
+ }
+ }
+ }
+
+ public static boolean contains(final Tile tile) {
+ return tileCache.containsKey(tile.hashCode());
+ }
+
+ public static void add(final Tile tile) {
+ tileCache.put(tile.hashCode(), tile);
+ }
+ }
+
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java b/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
index f291065..508aab4 100644
--- a/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
+++ b/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
@@ -3,12 +3,12 @@ package cgeo.geocaching.connector.oc;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.connector.capability.ISearchByGeocode;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.CryptUtils;
-public class OCApiConnector extends OCConnector {
+public class OCApiConnector extends OCConnector implements ISearchByGeocode {
private final String cK;
@@ -28,18 +28,12 @@ public class OCApiConnector extends OCConnector {
}
@Override
- public boolean supportsRefreshCache(cgCache cache) {
- return true;
- }
-
- @Override
- public SearchResult searchByGeocode(final String geocode, final String guid, final cgeoapplication app, final CancellableHandler handler) {
+ public SearchResult searchByGeocode(final String geocode, final String guid, final CancellableHandler handler) {
final cgCache cache = OkapiClient.getCache(geocode);
if (cache == null) {
return null;
}
- final SearchResult searchResult = new SearchResult();
- searchResult.addCache(cache);
+ final SearchResult searchResult = new SearchResult(cache);
return searchResult.filterSearchResults(false, false, Settings.getCacheType());
}
}
diff --git a/main/src/cgeo/geocaching/connector/ox/OXConnector.java b/main/src/cgeo/geocaching/connector/ox/OXConnector.java
index c81011f..4c53361 100644
--- a/main/src/cgeo/geocaching/connector/ox/OXConnector.java
+++ b/main/src/cgeo/geocaching/connector/ox/OXConnector.java
@@ -3,17 +3,20 @@ package cgeo.geocaching.connector.ox;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.connector.AbstractConnector;
+import cgeo.geocaching.connector.capability.ISearchByCenter;
+import cgeo.geocaching.connector.capability.ISearchByGeocode;
+import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.utils.CancellableHandler;
+import java.util.Collection;
import java.util.regex.Pattern;
/**
* connector for OpenCaching.com
*
*/
-public class OXConnector extends AbstractConnector {
+public class OXConnector extends AbstractConnector implements ISearchByCenter, ISearchByGeocode {
private static final Pattern PATTERN_GEOCODE = Pattern.compile("OX[A-Z0-9]+", Pattern.CASE_INSENSITIVE);
@@ -44,13 +47,22 @@ public class OXConnector extends AbstractConnector {
}
@Override
- public SearchResult searchByGeocode(String geocode, String guid, cgeoapplication app, CancellableHandler handler) {
+ public SearchResult searchByGeocode(String geocode, String guid, CancellableHandler handler) {
final cgCache cache = OpenCachingApi.searchByGeoCode(geocode);
if (cache == null) {
return null;
}
- final SearchResult searchResult = new SearchResult();
- searchResult.addCache(cache);
+ final SearchResult searchResult = new SearchResult(cache);
+ return searchResult.filterSearchResults(false, false, Settings.getCacheType());
+ }
+
+ @Override
+ public SearchResult searchByCenter(Geopoint center) {
+ Collection<cgCache> caches = OpenCachingApi.searchByCenter(center);
+ if (caches == null) {
+ return null;
+ }
+ final SearchResult searchResult = new SearchResult(caches);
return searchResult.filterSearchResults(false, false, Settings.getCacheType());
}
}
diff --git a/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java b/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java
index 304429f..f06230e 100644
--- a/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java
+++ b/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java
@@ -5,6 +5,8 @@ import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.files.GPX10Parser;
+import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.GeopointFormatter;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.CryptUtils;
@@ -14,6 +16,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.http.HttpResponse;
import java.util.Collection;
+import java.util.Collections;
import java.util.EnumSet;
public class OpenCachingApi {
@@ -21,28 +24,54 @@ public class OpenCachingApi {
private static final String DEV_KEY = CryptUtils.rot13("PtqQnHo9RUTht3Np");
public static cgCache searchByGeoCode(final String geocode) {
- final HttpResponse response = Network.getRequest("http://www.opencaching.com/api/geocache/" + geocode + ".gpx", new Parameters("Authorization", DEV_KEY));
+ final HttpResponse response = Network.getRequest("http://www.opencaching.com/api/geocache/" + geocode + ".gpx",
+ new Parameters(
+ "Authorization", DEV_KEY,
+ "log_limit", "30",
+ "hint", "true",
+ "description", "html"));
+ final Collection<cgCache> caches = importCachesFromResponse(response, true);
+ if (CollectionUtils.isNotEmpty(caches)) {
+ return caches.iterator().next();
+ }
+ return null;
+ }
+
+ private static Collection<cgCache> importCachesFromResponse(final HttpResponse response, final boolean isDetailed) {
if (response == null) {
- return null;
+ return Collections.emptyList();
}
Collection<cgCache> caches = null;
try {
caches = new GPX10Parser(StoredList.STANDARD_LIST_ID).parse(response.getEntity().getContent(), null);
} catch (Exception e) {
Log.e("Error importing from OpenCaching.com", e);
+ return Collections.emptyList();
}
- if (caches != null && CollectionUtils.isNotEmpty(caches)) {
- final cgCache cache = caches.iterator().next();
+ for (cgCache cache : caches) {
cache.setUpdated(System.currentTimeMillis());
- cache.setDetailedUpdate(cache.getUpdated());
- cache.setDetailed(true);
+ if (isDetailed) {
+ cache.setDetailedUpdate(cache.getUpdated());
+ cache.setDetailed(true);
+ }
// save full detailed caches
cgeoapplication.getInstance().saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
- return cache;
}
+ return caches;
+ }
- return null;
+ public static Collection<cgCache> searchByCenter(final Geopoint center) {
+ final HttpResponse response = Network.getRequest("http://www.opencaching.com/api/geocache/.gpx",
+ new Parameters(
+ "Authorization", DEV_KEY,
+ "log_limit", "0",
+ "hint", "false",
+ "description", "none",
+ "limit", "10",
+ "center", center.format(GeopointFormatter.Format.LAT_LON_DECDEGREE_COMMA)));
+ return importCachesFromResponse(response, false);
}
+
}
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index 6b24ec9..03c8284 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -15,7 +15,6 @@ import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.cgeocaches;
import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.connector.ConnectorFactory;
-import cgeo.geocaching.connector.gc.GCBase;
import cgeo.geocaching.connector.gc.Login;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LiveMapStrategy.Strategy;
@@ -1133,7 +1132,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
do {
if (tokens == null) {
- tokens = GCBase.getTokens();
+ tokens = Login.getMapTokens();
if (noMapTokenHandler != null && tokens == null) {
noMapTokenHandler.sendEmptyMessage(0);
}