private static void addFilterParams( final Map<String, String> valueMap, final OCApiConnector connector) { if (!Settings.isExcludeDisabledCaches()) { valueMap.put("status", "Available|Temporarily unavailable"); } if (Settings.isExcludeMyCaches() && connector.getSupportedAuthLevel() == OAuthLevel.Level3) { valueMap.put("exclude_my_own", "true"); valueMap.put("found_status", "notfound_only"); } if (Settings.getCacheType() != CacheType.ALL) { valueMap.put("type", getFilterFromType(Settings.getCacheType())); } }
private static List<Geocache> requestCaches( final OCApiConnector connector, final Parameters params, final Map<String, String> valueMap, final boolean my) { // if a global type filter is set, and OKAPI does not know that type, then return an empty list // instead of all caches if (Settings.getCacheType() != CacheType.ALL && StringUtils.isBlank(getFilterFromType())) { return Collections.emptyList(); } addFilterParams(valueMap, connector, my); try { params.add("search_params", JsonUtils.writer.writeValueAsString(valueMap)); } catch (final JsonProcessingException e) { Log.e("requestCaches", e); return Collections.emptyList(); } addRetrieveParams(params, connector); final ObjectNode data = request(connector, OkapiService.SERVICE_SEARCH_AND_RETRIEVE, params).data; if (data == null) { return Collections.emptyList(); } return parseCaches(data); }
protected void selectGlobalTypeFilter() { final List<CacheType> cacheTypes = new ArrayList<CacheType>(); // first add the most used types cacheTypes.add(CacheType.ALL); cacheTypes.add(CacheType.TRADITIONAL); cacheTypes.add(CacheType.MULTI); cacheTypes.add(CacheType.MYSTERY); // then add all other cache types sorted alphabetically final List<CacheType> sorted = new ArrayList<CacheType>(); sorted.addAll(Arrays.asList(CacheType.values())); sorted.removeAll(cacheTypes); Collections.sort( sorted, new Comparator<CacheType>() { @Override public int compare(final CacheType left, final CacheType right) { return left.getL10n().compareToIgnoreCase(right.getL10n()); } }); cacheTypes.addAll(sorted); int checkedItem = cacheTypes.indexOf(Settings.getCacheType()); if (checkedItem < 0) { checkedItem = 0; } final String[] items = new String[cacheTypes.size()]; for (int i = 0; i < cacheTypes.size(); i++) { items[i] = cacheTypes.get(i).getL10n(); } final Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.menu_filter); builder.setSingleChoiceItems( items, checkedItem, new DialogInterface.OnClickListener() { @Override public void onClick(final DialogInterface dialog, final int position) { final CacheType cacheType = cacheTypes.get(position); Settings.setCacheType(cacheType); setFilterTitle(); dialog.dismiss(); } }); builder.create().show(); }
private static String getFilterFromType() { switch (Settings.getCacheType()) { case EVENT: return "Event"; case MULTI: return "Multi"; case MYSTERY: return "Quiz"; case TRADITIONAL: return "Traditional"; case VIRTUAL: return "Virtual"; case WEBCAM: return "Webcam"; default: return ""; } }
private void download() { try { showProgress(); final SearchResult searchResult = DataStore.loadCachedInViewport(getViewport(), Settings.getCacheType()); if (Settings.isGCConnectorActive() && tokens == null) { tokens = GCLogin.getInstance().getMapTokens(); if (StringUtils.isEmpty(tokens.getUserSession()) || StringUtils.isEmpty(tokens.getSessionToken())) { tokens = null; // TODO: show missing map token toast // if (!noMapTokenShowed) { // ActivityMixin.showToast(activity, // res.getString(R.string.map_token_err)); // noMapTokenShowed = true; // } } } searchResult.addSearchResult( ConnectorFactory.searchByViewport(getViewport().resize(1.2), tokens)); final Set<Geocache> result = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); AbstractCachesOverlay.filter(result); // update the caches // first remove filtered out final Set<String> filteredCodes = searchResult.getFilteredGeocodes(); Log.d("Filtering out " + filteredCodes.size() + " caches: " + filteredCodes.toString()); DataStore.removeCaches(filteredCodes, EnumSet.of(RemoveFlag.CACHE)); Log.d(String.format(Locale.ENGLISH, "Live caches found: %d", result.size())); // render fill(result); } finally { hideProgress(); } }
private void setFilterTitle() { filterTitle.setText(Settings.getCacheType().getL10n()); }
/** * 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 */ @NonNull private static SearchResult searchByViewport( final Viewport viewport, final MapTokens tokens, final LivemapStrategy strategy) { Log.d("GCMap.searchByViewport" + viewport.toString()); final SearchResult searchResult = new SearchResult(); if (Settings.isDebug()) { searchResult.setUrl(viewport.getCenter().format(Format.LAT_LON_DECMINUTE)); } if (strategy.flags.contains(LivemapStrategy.Flag.LOAD_TILES)) { final Set<Tile> tiles = Tile.getTilesForViewport(viewport); if (Settings.isDebug()) { searchResult.setUrl( new StringBuilder() .append(tiles.iterator().next().getZoomLevel()) .append(Formatter.SEPARATOR) .append(searchResult.getUrl()) .toString()); } for (final Tile tile : tiles) { 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", "app", "cgeo"); if (tokens != null) { params.put("k", tokens.getUserSession(), "st", tokens.getSessionToken()); } if (Settings.isExcludeMyCaches()) { // works only for PM params.put("hf", "1", "hh", "1"); // hide found, hide hidden } // ect: exclude cache type (probably), comma separated list if (Settings.getCacheType() != CacheType.ALL) { params.put("ect", getCacheTypeFilter(Settings.getCacheType())); } if (tile.getZoomLevel() != 14) { params.put("_", String.valueOf(System.currentTimeMillis())); } // The PNG must be requested first, otherwise the following request would always return // with 204 - No Content final Single<Bitmap> bitmapObs = Tile.requestMapTile(params).onErrorResumeNext(Single.<Bitmap>just(null)); final Single<String> dataObs = Tile.requestMapInfo(GCConstants.URL_MAP_INFO, params, GCConstants.URL_LIVE_MAP) .onErrorResumeNext(Single.just("")); try { Single.zip( bitmapObs, dataObs, new Func2<Bitmap, String, Void>() { @Override public Void call(final Bitmap bitmap, final String data) { final boolean validBitmap = bitmap != null && bitmap.getWidth() == Tile.TILE_SIZE && bitmap.getHeight() == Tile.TILE_SIZE; if (StringUtils.isEmpty(data)) { Log.w( "GCMap.searchByViewport: No data from server for tile (" + tile.getX() + "/" + tile.getY() + ")"); } else { final SearchResult search = parseMapJSON(data, tile, validBitmap ? bitmap : null, strategy); if (CollectionUtils.isEmpty(search.getGeocodes())) { Log.e( "GCMap.searchByViewport: No cache parsed for viewport " + viewport); } else { synchronized (searchResult) { searchResult.addSearchResult(search); } } synchronized (Tile.cache) { Tile.cache.add(tile); } } // release native bitmap memory if (bitmap != null) { bitmap.recycle(); } return null; } }) .toBlocking() .value(); } catch (final Exception e) { Log.e("GCMap.searchByViewPort: connection error"); } } } // Check for vanished found caches if (tiles.iterator().next().getZoomLevel() >= Tile.ZOOMLEVEL_MIN_PERSONALIZED) { searchResult.addFilteredGeocodes( DataStore.getCachedMissingFromSearch( searchResult, tiles, GCConnector.getInstance(), Tile.ZOOMLEVEL_MIN_PERSONALIZED - 1)); } } if (strategy.flags.contains(Flag.SEARCH_NEARBY) && Settings.isGCPremiumMember()) { final Geopoint center = viewport.getCenter(); if ((lastSearchViewport == null) || !lastSearchViewport.contains(center)) { // FIXME We don't have a RecaptchaReceiver!? final SearchResult search = GCParser.searchByCoords(center, Settings.getCacheType(), false, null); if (search != null && !search.isEmpty()) { final Set<String> geocodes = search.getGeocodes(); lastSearchViewport = DataStore.getBounds(geocodes); searchResult.addGeocodes(geocodes); } } } return searchResult; }
/** * @param data Retrieved data. * @return SearchResult. Never null. */ public static SearchResult parseMapJSON( final String data, final Tile tile, final Bitmap bitmap, final LivemapStrategy strategy) { final SearchResult searchResult = new SearchResult(); try { final LeastRecentlyUsedMap<String, String> nameCache = new LeastRecentlyUsedMap.LruCache<>(2000); // JSON id, cache name if (StringUtils.isEmpty(data)) { throw new ParserException("No page given"); } // Example JSON information // {"grid":[....], // // "keys":["","55_55","55_54","17_25","55_53","17_27","17_26","57_53","57_55","3_62","3_61","57_54","3_60","15_27","15_26","15_25","4_60","4_61","4_62","16_25","16_26","16_27","2_62","2_60","2_61","56_53","56_54","56_55"], // "data":{"55_55":[{"i":"gEaR","n":"Spiel & Sport"}],"55_54":[{"i":"gEaR","n":"Spiel & // Sport"}],"17_25":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"55_53":[{"i":"gEaR","n":"Spiel & // Sport"}],"17_27":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"17_26":[{"i":"Rkzt","n":"EDSSW: // Rathaus "}],"57_53":[{"i":"gEaR","n":"Spiel & Sport"}],"57_55":[{"i":"gEaR","n":"Spiel & // Sport"}],"3_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was // -"}],"3_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was // -"}],"57_54":[{"i":"gEaR","n":"Spiel & Sport"}],"3_60":[{"i":"gOWz","n":"Baumarktserie - // Wer Wo Was -"}],"15_27":[{"i":"Rkzt","n":"EDSSW: Rathaus // "}],"15_26":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"15_25":[{"i":"Rkzt","n":"EDSSW: Rathaus // "}],"4_60":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was // -"}],"4_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was // -"}],"4_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was // -"}],"16_25":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"16_26":[{"i":"Rkzt","n":"EDSSW: // Rathaus "}],"16_27":[{"i":"Rkzt","n":"EDSSW: Rathaus // "}],"2_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was // -"}],"2_60":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was // -"}],"2_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was // -"}],"56_53":[{"i":"gEaR","n":"Spiel & Sport"}],"56_54":[{"i":"gEaR","n":"Spiel & // Sport"}],"56_55":[{"i":"gEaR","n":"Spiel & Sport"}]} // } final ObjectNode json = (ObjectNode) JsonUtils.reader.readTree(data); final ArrayNode grid = (ArrayNode) json.get("grid"); if (grid == null || grid.size() != (UTFGrid.GRID_MAXY + 1)) { throw new ParserException("No grid inside JSON"); } final ArrayNode keys = (ArrayNode) json.get("keys"); if (keys == null) { throw new ParserException("No keys inside JSON"); } final ObjectNode dataObject = (ObjectNode) json.get("data"); if (dataObject == null) { throw new ParserException("No data inside JSON"); } // iterate over the data and construct all caches in this tile final Map<String, List<UTFGridPosition>> positions = new HashMap<>(); // JSON id as key final Map<String, List<UTFGridPosition>> singlePositions = new HashMap<>(); // JSON id as key for (final JsonNode rawKey : keys) { final String key = rawKey.asText(); if (StringUtils.isNotBlank(key)) { // index 0 is empty final UTFGridPosition pos = UTFGridPosition.fromString(key); final ArrayNode dataForKey = (ArrayNode) dataObject.get(key); for (final JsonNode cacheInfo : dataForKey) { final String id = cacheInfo.get("i").asText(); nameCache.put(id, cacheInfo.get("n").asText()); List<UTFGridPosition> listOfPositions = positions.get(id); List<UTFGridPosition> singleListOfPositions = singlePositions.get(id); if (listOfPositions == null) { listOfPositions = new ArrayList<>(); positions.put(id, listOfPositions); singleListOfPositions = new ArrayList<>(); singlePositions.put(id, singleListOfPositions); } listOfPositions.add(pos); if (dataForKey.size() == 1) { singleListOfPositions.add(pos); } } } } final List<Geocache> caches = new ArrayList<>(); for (final Entry<String, List<UTFGridPosition>> entry : positions.entrySet()) { final String id = entry.getKey(); final List<UTFGridPosition> pos = entry.getValue(); final UTFGridPosition xy = UTFGrid.getPositionInGrid(pos); final Geocache cache = new Geocache(); cache.setDetailed(false); cache.setReliableLatLon(false); cache.setGeocode(id); cache.setName(nameCache.get(id)); cache.setCoords(tile.getCoord(xy), tile.getZoomLevel()); if (strategy.flags.contains(LivemapStrategy.Flag.PARSE_TILES) && bitmap != null) { for (final UTFGridPosition singlePos : singlePositions.get(id)) { if (IconDecoder.parseMapPNG(cache, bitmap, singlePos, tile.getZoomLevel())) { break; // cache parsed } } } else { cache.setType(CacheType.UNKNOWN, tile.getZoomLevel()); } boolean exclude = false; if (Settings.isExcludeMyCaches() && (cache.isFound() || cache.isOwner())) { // workaround for BM exclude = true; } if (Settings.isExcludeDisabledCaches() && cache.isDisabled()) { exclude = true; } if (!Settings.getCacheType().contains(cache) && cache.getType() != CacheType.UNKNOWN) { // workaround for BM exclude = true; } if (!exclude) { caches.add(cache); } } searchResult.addAndPutInCache(caches); Log.d("Retrieved " + searchResult.getCount() + " caches for tile " + tile.toString()); } catch (RuntimeException | ParserException | IOException e) { Log.e("GCMap.parseMapJSON", e); } return searchResult; }