aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/connector/gc
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo/geocaching/connector/gc')
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConnector.java6
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCMap.java24
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java362
-rw-r--r--main/src/cgeo/geocaching/connector/gc/IconDecoder.java2
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Tile.java5
5 files changed, 222 insertions, 177 deletions
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
index 925f6f0..294e969 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
@@ -50,7 +50,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
private static final String CACHE_URL_SHORT = "http://coord.info/";
// Double slash is used to force open in browser
- private static final String CACHE_URL_LONG = "http://www.geocaching.com//seek/cache_details.aspx?wp=";
+ private static final String CACHE_URL_LONG = "http://www.geocaching.com/seek/cache_details.aspx?wp=";
/**
* Pocket queries downloaded from the website use a numeric prefix. The pocket query creator Android app adds a
* verbatim "pocketquery" prefix.
@@ -192,8 +192,8 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
@Override
public boolean isOwner(final ICache cache) {
- return StringUtils.equalsIgnoreCase(cache.getOwnerUserId(), Settings.getUsername());
-
+ final String user = Settings.getUsername();
+ return StringUtils.isNotEmpty(user) && StringUtils.equalsIgnoreCase(cache.getOwnerUserId(), user);
}
@Override
diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java
index dc2408f..dd81507 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCMap.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java
@@ -146,30 +146,6 @@ public class GCMap {
throw new JSONException("No data inside JSON");
}
- /*
- * Optimization: the grid can get ignored. The keys are the grid position in the format x_y
- * It's not used at the moment due to optimizations
- * But maybe we need it some day...
- *
- * // attach all keys with the cache positions in the tile
- * Map<String, UTFGridPosition> keyPositions = new HashMap<String, UTFGridPosition>(); // JSON key, (x/y) in
- * grid
- * for (int y = 0; y < grid.length(); y++) {
- * String rowUTF8 = grid.getString(y);
- * if (rowUTF8.length() != (UTFGrid.GRID_MAXX + 1)) {
- * throw new JSONException("Grid has wrong size");
- * }
- *
- * for (int x = 0; x < UTFGrid.GRID_MAXX; x++) {
- * char c = rowUTF8.charAt(x);
- * if (c != ' ') {
- * short id = UTFGrid.getUTFGridId(c);
- * keyPositions.put(keys.getString(id), new UTFGridPosition(x, y));
- * }
- * }
- * }
- */
-
// iterate over the data and construct all caches in this tile
Map<String, List<UTFGridPosition>> positions = new HashMap<String, List<UTFGridPosition>>(); // JSON id as key
Map<String, List<UTFGridPosition>> singlePositions = new HashMap<String, List<UTFGridPosition>>(); // JSON id as key
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index 5422c11..4ae03bf 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCParser.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -47,6 +47,14 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import rx.Observable;
+import rx.Observable.OnSubscribe;
+import rx.Subscriber;
+import rx.functions.Action1;
+import rx.functions.Func0;
+import rx.functions.Func2;
+import rx.schedulers.Schedulers;
+
import android.net.Uri;
import android.text.Html;
@@ -136,7 +144,6 @@ public abstract class GCParser {
while (matcherGuidAndDisabled.find()) {
if (matcherGuidAndDisabled.groupCount() > 0) {
- //cache.setGuid(matcherGuidAndDisabled.group(1));
if (matcherGuidAndDisabled.group(2) != null) {
cache.setName(Html.fromHtml(matcherGuidAndDisabled.group(2).trim()).toString());
}
@@ -335,32 +342,50 @@ public abstract class GCParser {
}
static SearchResult parseCache(final String page, final CancellableHandler handler) {
- final SearchResult searchResult = parseCacheFromText(page, handler);
+ final ImmutablePair<StatusCode, Geocache> parsed = parseCacheFromText(page, handler);
// attention: parseCacheFromText already stores implicitly through searchResult.addCache
- if (searchResult != null && !searchResult.getGeocodes().isEmpty()) {
- final Geocache cache = searchResult.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB);
- if (cache == null) {
- return null;
- }
- getExtraOnlineInfo(cache, page, handler);
- // too late: it is already stored through parseCacheFromText
- cache.setDetailedUpdatedNow();
- if (CancellableHandler.isCancelled(handler)) {
- return null;
- }
+ if (parsed.left != StatusCode.NO_ERROR) {
+ return new SearchResult(parsed.left);
+ }
+
+ final Geocache cache = parsed.right;
+ getExtraOnlineInfo(cache, page, handler);
+ // too late: it is already stored through parseCacheFromText
+ cache.setDetailedUpdatedNow();
+ if (CancellableHandler.isCancelled(handler)) {
+ return null;
+ }
- // save full detailed caches
- CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_cache);
- DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
+ // save full detailed caches
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_cache);
+ DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
- // update progress message so user knows we're still working. This is more of a place holder than
- // actual indication of what the program is doing
- CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_render);
+ // update progress message so user knows we're still working. This is more of a place holder than
+ // actual indication of what the program is doing
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_render);
+ return new SearchResult(cache);
+ }
+
+ static SearchResult parseAndSaveCacheFromText(final String page, @Nullable final CancellableHandler handler) {
+ final ImmutablePair<StatusCode, Geocache> parsed = parseCacheFromText(page, handler);
+ final SearchResult result = new SearchResult(parsed.left);
+ if (parsed.left == StatusCode.NO_ERROR) {
+ result.addAndPutInCache(Collections.singletonList(parsed.right));
+ DataStore.saveLogsWithoutTransaction(parsed.right.getGeocode(), getLogsFromDetails(page).toBlockingObservable().toIterable());
}
- return searchResult;
+ return result;
}
- static SearchResult parseCacheFromText(final String pageIn, final CancellableHandler handler) {
+ /**
+ * Parse cache from text and return either an error code or a cache object in a pair. Note that inline logs are
+ * not parsed nor saved, while the cache itself is.
+ *
+ * @param pageIn the page text to parse
+ * @param handler the handler to send the progress notifications to
+ * @return a pair, with a {@link StatusCode} on the left, and a non-nulll cache objet on the right
+ * iff the status code is {@link StatusCode.NO_ERROR}.
+ */
+ static private ImmutablePair<StatusCode, Geocache> parseCacheFromText(final String pageIn, @Nullable final CancellableHandler handler) {
CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_details);
if (StringUtils.isBlank(pageIn)) {
@@ -368,22 +393,17 @@ public abstract class GCParser {
return null;
}
- final SearchResult searchResult = new SearchResult();
-
if (pageIn.contains(GCConstants.STRING_UNPUBLISHED_OTHER) || pageIn.contains(GCConstants.STRING_UNPUBLISHED_FROM_SEARCH)) {
- searchResult.setError(StatusCode.UNPUBLISHED_CACHE);
- return searchResult;
+ return ImmutablePair.of(StatusCode.UNPUBLISHED_CACHE, null);
}
if (pageIn.contains(GCConstants.STRING_PREMIUMONLY_1) || pageIn.contains(GCConstants.STRING_PREMIUMONLY_2)) {
- searchResult.setError(StatusCode.PREMIUM_ONLY);
- return searchResult;
+ return ImmutablePair.of(StatusCode.PREMIUM_ONLY, null);
}
final String cacheName = Html.fromHtml(TextUtils.getMatch(pageIn, GCConstants.PATTERN_NAME, true, "")).toString();
if (GCConstants.STRING_UNKNOWN_ERROR.equalsIgnoreCase(cacheName)) {
- searchResult.setError(StatusCode.UNKNOWN_ERROR);
- return searchResult;
+ return ImmutablePair.of(StatusCode.UNKNOWN_ERROR, null);
}
// first handle the content with line breaks, then trim everything for easier matching and reduced memory consumption in parsed fields
@@ -726,14 +746,11 @@ public abstract class GCParser {
// last check for necessary cache conditions
if (StringUtils.isBlank(cache.getGeocode())) {
- searchResult.setError(StatusCode.UNKNOWN_ERROR);
- return searchResult;
+ return ImmutablePair.of(StatusCode.UNKNOWN_ERROR, null);
}
cache.setDetailedUpdatedNow();
- searchResult.addAndPutInCache(Collections.singletonList(cache));
- DataStore.saveLogsWithoutTransaction(cache.getGeocode(), getLogsFromDetails(page, false));
- return searchResult;
+ return ImmutablePair.of(StatusCode.NO_ERROR, cache);
}
private static String getNumberString(final String numberWithPunctuation) {
@@ -1622,116 +1639,142 @@ public abstract class GCParser {
*
* @param page
* the text of the details page
- * @param friends
- * return friends logs only (will require a network request)
- * @return a list of log entries or <code>null</code> if the logs could not be retrieved
+ * @return a list of log entries which will be empty if the logs could not be retrieved
*
*/
- @Nullable
- private static List<LogEntry> getLogsFromDetails(final String page, final boolean friends) {
- String rawResponse;
+ @NonNull
+ private static Observable<LogEntry> getLogsFromDetails(final String page) {
+ // extract embedded JSON data from page
+ return parseLogs(false, TextUtils.getMatch(page, GCConstants.PATTERN_LOGBOOK, ""));
+ }
- if (friends) {
- final MatcherWrapper userTokenMatcher = new MatcherWrapper(GCConstants.PATTERN_USERTOKEN, page);
- if (!userTokenMatcher.find()) {
- Log.e("GCParser.loadLogsFromDetails: unable to extract userToken");
- return null;
- }
+ private enum SpecialLogs {
+ FRIENDS("sf"),
+ OWN("sp");
- final String userToken = userTokenMatcher.group(1);
- final Parameters params = new Parameters(
- "tkn", userToken,
- "idx", "1",
- "num", String.valueOf(GCConstants.NUMBER_OF_LOGS),
- "decrypt", "true",
- // "sp", Boolean.toString(personal), // personal logs
- "sf", Boolean.toString(friends));
+ final String paramName;
- final HttpResponse response = Network.getRequest("http://www.geocaching.com/seek/geocache.logbook", params);
- if (response == null) {
- Log.e("GCParser.loadLogsFromDetails: cannot log logs, response is null");
- return null;
- }
- final int statusCode = response.getStatusLine().getStatusCode();
- if (statusCode != 200) {
- Log.e("GCParser.loadLogsFromDetails: error " + statusCode + " when requesting log information");
- return null;
- }
- rawResponse = Network.getResponseData(response);
- if (rawResponse == null) {
- Log.e("GCParser.loadLogsFromDetails: unable to read whole response");
- return null;
- }
- } else {
- // extract embedded JSON data from page
- rawResponse = TextUtils.getMatch(page, GCConstants.PATTERN_LOGBOOK, "");
+ SpecialLogs(String paramName) {
+ this.paramName = paramName;
}
- return parseLogs(friends, rawResponse);
+ private String getParamName() {
+ return this.paramName;
+ }
}
- private static List<LogEntry> parseLogs(final boolean friends, String rawResponse) {
- final List<LogEntry> logs = new ArrayList<LogEntry>();
-
- // for non logged in users the log book is not shown
- if (StringUtils.isBlank(rawResponse)) {
- return logs;
- }
+ /**
+ * Extract special logs (friends, own) through seperate request.
+ *
+ * @param page
+ * The page to extrat userToken from
+ * @param logType
+ * The logType to request
+ * @return Observable<LogEntry> The logs
+ */
+ private static Observable<LogEntry> getSpecialLogs(final String page, final SpecialLogs logType) {
+ return Observable.defer(new Func0<Observable<? extends LogEntry>>() {
+ @Override
+ public Observable<? extends LogEntry> call() {
+ final MatcherWrapper userTokenMatcher = new MatcherWrapper(GCConstants.PATTERN_USERTOKEN, page);
+ if (!userTokenMatcher.find()) {
+ Log.e("GCParser.loadLogsFromDetails: unable to extract userToken");
+ return Observable.empty();
+ }
- try {
- final JSONObject resp = new JSONObject(rawResponse);
- if (!resp.getString("status").equals("success")) {
- Log.e("GCParser.loadLogsFromDetails: status is " + resp.getString("status"));
- return null;
+ final String userToken = userTokenMatcher.group(1);
+ final Parameters params = new Parameters(
+ "tkn", userToken,
+ "idx", "1",
+ "num", String.valueOf(GCConstants.NUMBER_OF_LOGS),
+ logType.getParamName(), Boolean.toString(Boolean.TRUE),
+ "decrypt", "true");
+ final HttpResponse response = Network.getRequest("http://www.geocaching.com/seek/geocache.logbook", params);
+ if (response == null) {
+ Log.e("GCParser.loadLogsFromDetails: cannot log logs, response is null");
+ return Observable.empty();
+ }
+ final int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != 200) {
+ Log.e("GCParser.loadLogsFromDetails: error " + statusCode + " when requesting log information");
+ return Observable.empty();
+ }
+ String rawResponse = Network.getResponseData(response);
+ if (rawResponse == null) {
+ Log.e("GCParser.loadLogsFromDetails: unable to read whole response");
+ return Observable.empty();
+ }
+ return parseLogs(true, rawResponse);
}
+ }).subscribeOn(Schedulers.io());
+ }
- final JSONArray data = resp.getJSONArray("data");
+ private static Observable<LogEntry> parseLogs(final boolean markAsFriendsLog, final String rawResponse) {
+ return Observable.create(new OnSubscribe<LogEntry>() {
+ @Override
+ public void call(final Subscriber<? super LogEntry> subscriber) {
+ // for non logged in users the log book is not shown
+ if (StringUtils.isBlank(rawResponse)) {
+ subscriber.onCompleted();
+ return;
+ }
- for (int index = 0; index < data.length(); index++) {
- final JSONObject entry = data.getJSONObject(index);
+ try {
+ final JSONObject resp = new JSONObject(rawResponse);
+ if (!resp.getString("status").equals("success")) {
+ Log.e("GCParser.loadLogsFromDetails: status is " + resp.getString("status"));
+ subscriber.onCompleted();
+ return;
+ }
- // FIXME: use the "LogType" field instead of the "LogTypeImage" one.
- final String logIconNameExt = entry.optString("LogTypeImage", ".gif");
- final String logIconName = logIconNameExt.substring(0, logIconNameExt.length() - 4);
+ final JSONArray data = resp.getJSONArray("data");
- long date = 0;
- try {
- date = GCLogin.parseGcCustomDate(entry.getString("Visited")).getTime();
- } catch (final ParseException e) {
- Log.e("GCParser.loadLogsFromDetails: failed to parse log date.");
- }
+ for (int index = 0; index < data.length(); index++) {
+ final JSONObject entry = data.getJSONObject(index);
- // TODO: we should update our log data structure to be able to record
- // proper coordinates, and make them clickable. In the meantime, it is
- // better to integrate those coordinates into the text rather than not
- // display them at all.
- final String latLon = entry.getString("LatLonString");
- final String logText = (StringUtils.isEmpty(latLon) ? "" : (latLon + "<br/><br/>")) + TextUtils.removeControlCharacters(entry.getString("LogText"));
- final LogEntry logDone = new LogEntry(
- TextUtils.removeControlCharacters(entry.getString("UserName")),
- date,
- LogType.getByIconName(logIconName),
- logText);
- logDone.found = entry.getInt("GeocacheFindCount");
- logDone.friend = friends;
-
- final JSONArray images = entry.getJSONArray("Images");
- for (int i = 0; i < images.length(); i++) {
- final JSONObject image = images.getJSONObject(i);
- final String url = "http://imgcdn.geocaching.com/cache/log/large/" + image.getString("FileName");
- final String title = TextUtils.removeControlCharacters(image.getString("Name"));
- final Image logImage = new Image(url, title);
- logDone.addLogImage(logImage);
- }
+ // FIXME: use the "LogType" field instead of the "LogTypeImage" one.
+ final String logIconNameExt = entry.optString("LogTypeImage", ".gif");
+ final String logIconName = logIconNameExt.substring(0, logIconNameExt.length() - 4);
- logs.add(logDone);
- }
- } catch (final JSONException e) {
- // failed to parse logs
- Log.w("GCParser.loadLogsFromDetails: Failed to parse cache logs", e);
- }
+ long date = 0;
+ try {
+ date = GCLogin.parseGcCustomDate(entry.getString("Visited")).getTime();
+ } catch (final ParseException e) {
+ Log.e("GCParser.loadLogsFromDetails: failed to parse log date.");
+ }
- return logs;
+ // TODO: we should update our log data structure to be able to record
+ // proper coordinates, and make them clickable. In the meantime, it is
+ // better to integrate those coordinates into the text rather than not
+ // display them at all.
+ final String latLon = entry.getString("LatLonString");
+ final String logText = (StringUtils.isEmpty(latLon) ? "" : (latLon + "<br/><br/>")) + TextUtils.removeControlCharacters(entry.getString("LogText"));
+ final LogEntry logDone = new LogEntry(
+ TextUtils.removeControlCharacters(entry.getString("UserName")),
+ date,
+ LogType.getByIconName(logIconName),
+ logText);
+ logDone.found = entry.getInt("GeocacheFindCount");
+ logDone.friend = markAsFriendsLog;
+
+ final JSONArray images = entry.getJSONArray("Images");
+ for (int i = 0; i < images.length(); i++) {
+ final JSONObject image = images.getJSONObject(i);
+ final String url = "http://imgcdn.geocaching.com/cache/log/large/" + image.getString("FileName");
+ final String title = TextUtils.removeControlCharacters(image.getString("Name"));
+ final Image logImage = new Image(url, title);
+ logDone.addLogImage(logImage);
+ }
+
+ subscriber.onNext(logDone);
+ }
+ } catch (final JSONException e) {
+ // failed to parse logs
+ Log.w("GCParser.loadLogsFromDetails: Failed to parse cache logs", e);
+ }
+ subscriber.onCompleted();
+ }
+ });
}
@NonNull
@@ -1823,32 +1866,39 @@ public abstract class GCParser {
}
private static void getExtraOnlineInfo(final Geocache cache, final String page, final CancellableHandler handler) {
+ // This method starts the page parsing for logs in the background, as well as retrieve the friends and own logs
+ // if requested. It merges them and stores them in the background, while the rating is retrieved if needed and
+ // stored. Then we wait for the log merging and saving to be completed before returning.
if (CancellableHandler.isCancelled(handler)) {
return;
}
- //cache.setLogs(loadLogsFromDetails(page, cache, false));
+ final Observable<LogEntry> logs = getLogsFromDetails(page).subscribeOn(Schedulers.computation());
+ Observable<LogEntry> specialLogs;
if (Settings.isFriendLogsWanted()) {
CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs);
- final List<LogEntry> friendLogs = getLogsFromDetails(page, true);
- if (friendLogs != null && !friendLogs.isEmpty()) {
- // create new list, as the existing log list is immutable
- ArrayList<LogEntry> mergedLogs = new ArrayList<LogEntry>(cache.getLogs());
- for (final LogEntry log : friendLogs) {
- if (mergedLogs.contains(log)) {
- mergedLogs.get(mergedLogs.indexOf(log)).friend = true;
- } else {
- mergedLogs.add(log);
+ specialLogs = Observable.merge(getSpecialLogs(page, SpecialLogs.FRIENDS),
+ getSpecialLogs(page, SpecialLogs.OWN));
+ } else {
+ CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs);
+ specialLogs = Observable.empty();
+ }
+ final Observable<List<LogEntry>> mergedLogs = Observable.zip(logs.toList(), specialLogs.toList(),
+ new Func2<List<LogEntry>, List<LogEntry>, List<LogEntry>>() {
+ @Override
+ public List<LogEntry> call(final List<LogEntry> logEntries, final List<LogEntry> specialLogEntries) {
+ mergeFriendsLogs(logEntries, specialLogEntries);
+ return logEntries;
}
- }
- DataStore.saveLogsWithoutTransaction(cache.getGeocode(), mergedLogs);
- }
- }
-
- if (Settings.isRatingWanted()) {
- if (CancellableHandler.isCancelled(handler)) {
- return;
- }
+ }).cache();
+ mergedLogs.subscribe(new Action1<List<LogEntry>>() {
+ @Override
+ public void call(final List<LogEntry> logEntries) {
+ DataStore.saveLogsWithoutTransaction(cache.getGeocode(), logEntries);
+ }
+ });
+
+ if (Settings.isRatingWanted() && !CancellableHandler.isCancelled(handler)) {
CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_gcvote);
final GCVoteRating rating = GCVote.getRating(cache.getGuid(), cache.getGeocode());
if (rating != null) {
@@ -1857,6 +1907,28 @@ public abstract class GCParser {
cache.setMyVote(rating.getMyVote());
}
}
+
+ // Wait for completion of logs parsing, retrieving and merging
+ mergedLogs.toBlockingObservable().last();
+ }
+
+ /**
+ * Merge log entries and mark them as friends logs (personal and friends) to identify
+ * them on friends/personal logs tab.
+ *
+ * @param mergedLogs
+ * the list to merge logs with
+ * @param logsToMerge
+ * the list of logs to merge
+ */
+ private static void mergeFriendsLogs(final List<LogEntry> mergedLogs, final Iterable<LogEntry> logsToMerge) {
+ for (final LogEntry log : logsToMerge) {
+ if (mergedLogs.contains(log)) {
+ mergedLogs.get(mergedLogs.indexOf(log)).friend = true;
+ } else {
+ mergedLogs.add(log);
+ }
+ }
}
public static boolean uploadModifiedCoordinates(Geocache cache, Geopoint wpt) {
diff --git a/main/src/cgeo/geocaching/connector/gc/IconDecoder.java b/main/src/cgeo/geocaching/connector/gc/IconDecoder.java
index c7b470a..c6a2afc 100644
--- a/main/src/cgeo/geocaching/connector/gc/IconDecoder.java
+++ b/main/src/cgeo/geocaching/connector/gc/IconDecoder.java
@@ -35,7 +35,7 @@ public abstract class IconDecoder {
return false; //out of image position
}
- int numberOfDetections = 7; //for level 12 and 13;
+ int numberOfDetections = 7; //for level 12 and 13
if (zoomlevel < 12) {
numberOfDetections = 5;
}
diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java
index ca70111..d7b3a48 100644
--- a/main/src/cgeo/geocaching/connector/gc/Tile.java
+++ b/main/src/cgeo/geocaching/connector/gc/Tile.java
@@ -9,6 +9,7 @@ import cgeo.geocaching.utils.LeastRecentlyUsedSet;
import cgeo.geocaching.utils.Log;
import ch.boye.httpclientandroidlib.HttpResponse;
+
import org.eclipse.jdt.annotation.NonNull;
import android.graphics.Bitmap;
@@ -88,10 +89,6 @@ public class Tile {
*
*/
private static int calcY(final Geopoint origin, final int zoomlevel) {
-
- // double latRad = Math.toRadians(origin.getLatitude());
- // return (int) ((1 - (Math.log(Math.tan(latRad) + (1 / Math.cos(latRad))) / Math.PI)) / 2 * numberOfTiles);
-
// Optimization from Bing
double sinLatRad = Math.sin(Math.toRadians(origin.getLatitude()));
// The cut of the fractional part instead of rounding to the nearest integer is intentional and part of the algorithm