public void addSearchResult(SearchResult other) { if (other == null) { return; } addGeocodes(other.geocodes); addFilteredGeocodes(other.filteredGeocodes); if (StringUtils.isBlank(url)) { url = other.url; } // copy the GC total search results number to be able to use "More caches" button if (getTotalCountGC() == 0 && other.getTotalCountGC() != 0) { setViewstates(other.getViewstates()); setTotalCountGC(other.getTotalCountGC()); } }
/** * 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; }