/** Test {@link cgBase#searchByOwner(String, String, int, boolean, CancellableHandler)} */
 @MediumTest
 public static void testSearchByOwner() {
   final SearchResult search = cgBase.searchByOwner(null, "blafoo", CacheType.MYSTERY, 0, false);
   assertNotNull(search);
   assertEquals(3, search.getGeocodes().size());
   assertTrue(search.getGeocodes().contains("GC36RT6"));
 }
Пример #2
0
  /**
   * @param excludeDisabled
   * @param excludeMine
   * @param cacheType
   * @return
   */
  public SearchResult filterSearchResults(
      final boolean excludeDisabled, final boolean excludeMine, final CacheType cacheType) {

    SearchResult result = new SearchResult(this);
    result.geocodes.clear();
    final ArrayList<Geocache> includedCaches = new ArrayList<Geocache>();
    final Set<Geocache> caches = DataStore.loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB);
    int excluded = 0;
    for (Geocache cache : caches) {
      // Is there any reason to exclude the cache from the list?
      final boolean excludeCache =
          (excludeDisabled && cache.isDisabled())
              || (excludeMine && (cache.isOwner() || cache.isFound()))
              || (!cacheType.contains(cache));
      if (excludeCache) {
        excluded++;
      } else {
        includedCaches.add(cache);
      }
    }
    result.addAndPutInCache(includedCaches);
    // decrease maximum number of caches by filtered ones
    result.setTotalCountGC(result.getTotalCountGC() - excluded);
    GCVote.loadRatings(includedCaches);
    return result;
  }
 /** Test {@link cgBase#searchByUsername(String, String, int, boolean, CancellableHandler)} */
 @MediumTest
 public static void testSearchByUsername() {
   final SearchResult search = cgBase.searchByUsername(null, "blafoo", CacheType.WEBCAM, 0, false);
   assertNotNull(search);
   assertEquals(3, search.totalCnt);
   assertTrue(search.getGeocodes().contains("GCP0A9"));
 }
  public void testImportGpxZipAttachment() {
    Uri uri = Uri.parse("android.resource://cgeo.geocaching.test/raw/pq7545915");

    GPXImporter.ImportGpxZipAttachmentThread importThread =
        new GPXImporter.ImportGpxZipAttachmentThread(
            uri,
            getInstrumentation().getContext().getContentResolver(),
            listId,
            importStepHandler,
            progressHandler);
    runImportThread(importThread);

    assertImportStepMessages(
        GPXImporter.IMPORT_STEP_START,
        GPXImporter.IMPORT_STEP_READ_FILE,
        GPXImporter.IMPORT_STEP_READ_WPT_FILE,
        GPXImporter.IMPORT_STEP_STORE_CACHES,
        GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,
        GPXImporter.IMPORT_STEP_FINISHED);
    SearchResult search = (SearchResult) importStepHandler.messages.get(5).obj;
    assertEquals(Collections.singletonList("GC31J2H"), new ArrayList<String>(search.getGeocodes()));

    cgCache cache = cgeoapplication.getInstance().loadCache("GC31J2H", LoadFlags.LOAD_CACHE_OR_DB);
    assertCacheProperties(cache);
    assertEquals(
        1,
        cache
            .getWaypoints()
            .size()); // this is the original pocket query result without test waypoint
  }
  public void testImportGpxZip() throws IOException {
    File pq7545915 = new File(tempDir, "7545915.zip");
    copyResourceToFile(R.raw.pq7545915, pq7545915);

    GPXImporter.ImportGpxZipFileThread importThread =
        new GPXImporter.ImportGpxZipFileThread(
            pq7545915, listId, importStepHandler, progressHandler);
    runImportThread(importThread);

    assertImportStepMessages(
        GPXImporter.IMPORT_STEP_START,
        GPXImporter.IMPORT_STEP_READ_FILE,
        GPXImporter.IMPORT_STEP_READ_WPT_FILE,
        GPXImporter.IMPORT_STEP_STORE_CACHES,
        GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,
        GPXImporter.IMPORT_STEP_FINISHED);
    SearchResult search = (SearchResult) importStepHandler.messages.get(5).obj;
    assertEquals(Collections.singletonList("GC31J2H"), new ArrayList<String>(search.getGeocodes()));

    cgCache cache = cgeoapplication.getInstance().loadCache("GC31J2H", LoadFlags.LOAD_CACHE_OR_DB);
    assertCacheProperties(cache);
    assertEquals(
        1,
        cache
            .getWaypoints()
            .size()); // this is the original pocket query result without test waypoint
  }
  public void testImportGpxAttachment() {
    Uri uri = Uri.parse("android.resource://cgeo.geocaching.test/raw/gc31j2h");

    GPXImporter.ImportGpxAttachmentThread importThread =
        new GPXImporter.ImportGpxAttachmentThread(
            uri,
            getInstrumentation().getContext().getContentResolver(),
            listId,
            importStepHandler,
            progressHandler);
    runImportThread(importThread);

    assertImportStepMessages(
        GPXImporter.IMPORT_STEP_START,
        GPXImporter.IMPORT_STEP_READ_FILE,
        GPXImporter.IMPORT_STEP_STORE_CACHES,
        GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,
        GPXImporter.IMPORT_STEP_FINISHED);
    SearchResult search = (SearchResult) importStepHandler.messages.get(4).obj;
    assertEquals(Collections.singletonList("GC31J2H"), new ArrayList<String>(search.getGeocodes()));

    cgCache cache = cgeoapplication.getInstance().loadCache("GC31J2H", LoadFlags.LOAD_CACHE_OR_DB);
    assertCacheProperties(cache);

    // can't assert, for whatever reason the waypoints are remembered in DB
    //        assertNull(cache.waypoints);
  }
 /** Test {@link cgBase#searchByCoords(cgSearchThread, Geopoint, String, int, boolean)} */
 @MediumTest
 public static void testSearchByCoords() {
   final SearchResult search =
       cgBase.searchByCoords(
           null, new Geopoint("N 52° 24.972 E 009° 35.647"), CacheType.MYSTERY, 0, false);
   assertNotNull(search);
   assertTrue(18 <= search.getGeocodes().size());
   assertTrue(search.getGeocodes().contains("GC1RMM2"));
 }
 /** Test {@link cgBase#searchByGeocode(String, String, int, boolean, CancellableHandler)} */
 @MediumTest
 public static cgCache testSearchByGeocode(final String geocode) {
   final SearchResult search = cgBase.searchByGeocode(geocode, null, 0, true, null);
   assertNotNull(search);
   if (Settings.isPremiumMember() || search.error == null) {
     assertEquals(1, search.getGeocodes().size());
     assertTrue(search.getGeocodes().contains(geocode));
     return cgeoapplication.getInstance().loadCache(geocode, LoadFlags.LOADCACHEORDB);
   }
   assertEquals(0, search.getGeocodes().size());
   return null;
 }
Пример #9
0
 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());
   }
 }
  /** Test {@link cgBase#searchByViewport(String, Viewport)} */
  @MediumTest
  public static void testSearchByViewport() {

    if (LIVEMAPENABLED) {
      GC2JVEH cache = new GC2JVEH();

      final String token = cgBase.getMapUserToken(new Handler());
      final Viewport viewport = new Viewport(cache.getCoords(), 0.003, 0.003);
      final SearchResult search = cgBase.searchByViewport(token, viewport);

      // GC2JVEH is a premium members only cache. It can't be "found" by non-premium members
      if (Settings.isPremiumMember()) {
        assertNotNull(search);
        // coords are identical... if the user is logged in
        if (search.error != null) {
          if (search.getGeocodes().contains(cache.getGeocode())) {
            assertFalse(
                cache
                    .getCoords()
                    .isEqualTo(
                        cgeoapplication
                            .getInstance()
                            .loadCache(cache.getGeocode(), LoadFlags.LOADCACHEORDB)
                            .getCoords()));
            assertFalse(
                cgeoapplication
                    .getInstance()
                    .loadCache(cache.getGeocode(), LoadFlags.LOADCACHEORDB)
                    .isReliableLatLon());
          }
        } else {
          assertTrue(search.getGeocodes().contains(cache.getGeocode()));
          assertEquals(
              cache.getCoords().toString(),
              cgeoapplication
                  .getInstance()
                  .loadCache(cache.getGeocode(), LoadFlags.LOADCACHEORDB)
                  .getCoords()
                  .toString());
          assertTrue(
              cgeoapplication
                  .getInstance()
                  .loadCache(cache.getGeocode(), LoadFlags.LOADCACHEORDB)
                  .isReliableLatLon());
        }
      }
    }
  }
Пример #11
0
 /**
  * Copy a search result, for example to apply different filters on it.
  *
  * @param searchResult the original search result, which cannot be null
  */
 public SearchResult(final SearchResult searchResult) {
   geocodes = new HashSet<String>(searchResult.geocodes);
   filteredGeocodes = new HashSet<String>(searchResult.filteredGeocodes);
   error = searchResult.error;
   url = searchResult.url;
   viewstates = searchResult.viewstates;
   setTotalCountGC(searchResult.getTotalCountGC());
 }
Пример #12
0
  public void testImportLoc() throws IOException {
    File oc5952 = new File(tempDir, "oc5952.loc");
    copyResourceToFile(R.raw.oc5952_loc, oc5952);

    GPXImporter.ImportLocFileThread importThread =
        new GPXImporter.ImportLocFileThread(oc5952, listId, importStepHandler, progressHandler);
    runImportThread(importThread);

    assertImportStepMessages(
        GPXImporter.IMPORT_STEP_START,
        GPXImporter.IMPORT_STEP_READ_FILE,
        GPXImporter.IMPORT_STEP_STORE_CACHES,
        GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,
        GPXImporter.IMPORT_STEP_FINISHED);
    SearchResult search = (SearchResult) importStepHandler.messages.get(4).obj;
    assertEquals(Collections.singletonList("OC5952"), new ArrayList<String>(search.getGeocodes()));

    cgCache cache = cgeoapplication.getInstance().loadCache("OC5952", LoadFlags.LOAD_CACHE_OR_DB);
    assertCacheProperties(cache);
  }
Пример #13
0
  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();
    }
  }
Пример #14
0
 /** @see ISearchByViewPort#searchByViewport */
 @NonNull
 public static SearchResult searchByViewport(
     final @NonNull Viewport viewport, @NonNull final MapTokens tokens) {
   return SearchResult.parallelCombineActive(
       searchByViewPortConns,
       new Func1<ISearchByViewPort, SearchResult>() {
         @Override
         public SearchResult call(final ISearchByViewPort connector) {
           return connector.searchByViewport(viewport, tokens);
         }
       });
 }
Пример #15
0
  /**
   * Searches the view port on the live map with Strategy.AUTO
   *
   * @param viewport Area to search
   * @param tokens Live map tokens
   */
  @NonNull
  public static SearchResult searchByViewport(final Viewport viewport, final MapTokens tokens) {
    final int speed =
        (int) Sensors.getInstance().currentGeo().getSpeed() * 60 * 60 / 1000; // in km/h
    LivemapStrategy strategy = Settings.getLiveMapStrategy();
    if (strategy == LivemapStrategy.AUTO) {
      strategy = speed >= 30 ? LivemapStrategy.FAST : LivemapStrategy.DETAILED;
    }

    final SearchResult result = searchByViewport(viewport, tokens, strategy);

    if (Settings.isDebug()) {
      final StringBuilder text =
          new StringBuilder(Formatter.SEPARATOR)
              .append(strategy.getL10n())
              .append(Formatter.SEPARATOR)
              .append(Units.getSpeed(speed));
      result.setUrl(result.getUrl() + text);
    }

    return result;
  }
Пример #16
0
  public void testImportGpxWithWaypoints() throws IOException {
    File gc31j2h = new File(tempDir, "gc31j2h.gpx");
    copyResourceToFile(R.raw.gc31j2h, gc31j2h);
    copyResourceToFile(R.raw.gc31j2h_wpts, new File(tempDir, "gc31j2h-wpts.gpx"));

    GPXImporter.ImportGpxFileThread importThread =
        new GPXImporter.ImportGpxFileThread(gc31j2h, listId, importStepHandler, progressHandler);
    runImportThread(importThread);

    assertImportStepMessages(
        GPXImporter.IMPORT_STEP_START,
        GPXImporter.IMPORT_STEP_READ_FILE,
        GPXImporter.IMPORT_STEP_READ_WPT_FILE,
        GPXImporter.IMPORT_STEP_STORE_CACHES,
        GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS,
        GPXImporter.IMPORT_STEP_FINISHED);
    SearchResult search = (SearchResult) importStepHandler.messages.get(5).obj;
    assertEquals(Collections.singletonList("GC31J2H"), new ArrayList<String>(search.getGeocodes()));

    cgCache cache = cgeoapplication.getInstance().loadCache("GC31J2H", LoadFlags.LOAD_CACHE_OR_DB);
    assertCacheProperties(cache);
    assertEquals(2, cache.getWaypoints().size());
  }
  /** Test {@link cgBase#searchByGeocode(String, String, int, boolean, CancellableHandler)} */
  @MediumTest
  public static void testSearchByGeocodeNotLoggedIn() {
    ImmutablePair<String, String> login = Settings.getLogin();

    try {
      // non premium cache
      MockedCache cache = new GC1ZXX2();

      deleteCacheFromDBAndLogout(cache.getGeocode());

      SearchResult search =
          cgBase.searchByGeocode(
              cache.getGeocode(), null, StoredList.TEMPORARY_LIST_ID, true, null);
      assertNotNull(search);
      assertEquals(1, search.getGeocodes().size());
      assertTrue(search.getGeocodes().contains(cache.getGeocode()));
      cgCache searchedCache = search.getFirstCacheFromResult(LoadFlags.LOADCACHEORDB);
      // coords must be null if the user is not logged in
      assertNull(searchedCache.getCoords());

      // premium cache. Not visible to guests
      cache = new GC2JVEH();

      deleteCacheFromDBAndLogout(cache.getGeocode());

      search =
          cgBase.searchByGeocode(
              cache.getGeocode(), null, StoredList.TEMPORARY_LIST_ID, true, null);
      assertNotNull(search);
      assertEquals(0, search.getGeocodes().size());

    } finally {
      // restore user and password
      Settings.setLogin(login.left, login.right);
      cgBase.login();
    }
  }
Пример #18
0
  public void testImportGpx() throws IOException {
    File gc31j2h = new File(tempDir, "gc31j2h.gpx");
    copyResourceToFile(R.raw.gc31j2h, gc31j2h);

    GPXImporter.ImportGpxFileThread importThread =
        new GPXImporter.ImportGpxFileThread(gc31j2h, listId, importStepHandler, progressHandler);
    runImportThread(importThread);

    assertEquals(5, importStepHandler.messages.size());
    Iterator<Message> iMsg = importStepHandler.messages.iterator();
    assertEquals(GPXImporter.IMPORT_STEP_START, iMsg.next().what);
    assertEquals(GPXImporter.IMPORT_STEP_READ_FILE, iMsg.next().what);
    assertEquals(GPXImporter.IMPORT_STEP_STORE_CACHES, iMsg.next().what);
    assertEquals(GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, iMsg.next().what);
    assertEquals(GPXImporter.IMPORT_STEP_FINISHED, iMsg.next().what);
    SearchResult search = (SearchResult) importStepHandler.messages.get(4).obj;
    assertEquals(Collections.singletonList("GC31J2H"), new ArrayList<String>(search.getGeocodes()));

    cgCache cache = cgeoapplication.getInstance().loadCache("GC31J2H", LoadFlags.LOAD_CACHE_OR_DB);
    assertCacheProperties(cache);

    // can't assert, for whatever reason the waypoints are remembered in DB
    //        assertNull(cache.waypoints);
  }
  /** Test {@link cgBase#searchByViewport(String, Viewport)} */
  @MediumTest
  public static void testSearchByViewportNotLoggedIn() {

    if (LIVEMAPENABLED) {
      ImmutablePair<String, String> login = Settings.getLogin();

      try {

        final String token = null; // without a valid token we are "logged off"

        // non premium cache
        MockedCache cache = new GC2CJPF();
        deleteCacheFromDBAndLogout(cache.getGeocode());

        Viewport viewport = new Viewport(cache.getCoords(), 0.003, 0.003);
        SearchResult search = cgBase.searchByViewport(token, viewport);

        assertNotNull(search);
        assertTrue(search.getGeocodes().contains(cache.getGeocode()));
        // coords differ
        Log.d(
            Settings.tag,
            "cgeoApplicationTest.testSearchByViewportNotLoggedIn: Coords expected = "
                + cache.getCoords());
        Log.d(
            Settings.tag,
            "cgeoApplicationTest.testSearchByViewportNotLoggedIn: Coords actual = "
                + cgeoapplication
                    .getInstance()
                    .loadCache(cache.getGeocode(), LoadFlags.LOADCACHEORDB)
                    .getCoords());
        assertFalse(
            cache
                .getCoords()
                .isEqualTo(
                    cgeoapplication
                        .getInstance()
                        .loadCache(cache.getGeocode(), LoadFlags.LOADCACHEORDB)
                        .getCoords(),
                    1e-3));
        assertFalse(
            cgeoapplication
                .getInstance()
                .loadCache(cache.getGeocode(), LoadFlags.LOADCACHEORDB)
                .isReliableLatLon());

        // premium cache
        cache = new GC2JVEH();
        deleteCacheFromDBAndLogout(cache.getGeocode());

        viewport = new Viewport(cache.getCoords(), 0.003, 0.003);
        search = cgBase.searchByViewport(token, viewport);

        assertNotNull(search);
        // It's a premium member cache only and thus not visible to guests
        assertFalse(search.getGeocodes().contains(cache.getGeocode()));

      } finally {
        // restore user and password
        Settings.setLogin(login.left, login.right);
        cgBase.login();
      }
    }
  }
Пример #20
0
  /**
   * @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;
  }
Пример #21
0
  /**
   * 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;
  }
Пример #22
0
  public static SearchResult searchByGeocodes(final Set<String> geocodes) {
    final SearchResult result = new SearchResult();

    final Set<String> filteredGeocodes = GCConnector.getInstance().handledGeocodes(geocodes);
    if (filteredGeocodes.isEmpty()) {
      return result;
    }
    final String geocodeList = StringUtils.join(filteredGeocodes.toArray(), "|");

    try {
      final Parameters params =
          new Parameters("i", geocodeList, "_", String.valueOf(System.currentTimeMillis()));
      params.add("app", "cgeo");
      final String referer = GCConstants.URL_LIVE_MAP_DETAILS;
      final String data = Tile.requestMapInfo(referer, params, referer).toBlocking().value();

      // 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"}}]
      // }

      final ObjectNode json = (ObjectNode) JsonUtils.reader.readTree(data);
      final String status = json.path("status").asText();
      if (StringUtils.isBlank(status)) {
        throw new ParserException("No status inside JSON");
      }
      if ("success".compareTo(status) != 0) {
        throw new ParserException("Wrong status inside JSON");
      }
      final ArrayNode dataArray = (ArrayNode) json.get("data");
      if (dataArray == null) {
        throw new ParserException("No data inside JSON");
      }

      final List<Geocache> caches = new ArrayList<>();
      for (final JsonNode dataObject : dataArray) {
        final Geocache cache = new Geocache();
        cache.setName(dataObject.path("name").asText());
        cache.setGeocode(dataObject.path("gc").asText());
        cache.setGuid(dataObject.path("g").asText()); // 34c2e609-5246-4f91-9029-d6c02b0f2a82"
        cache.setDisabled(!dataObject.path("available").asBoolean());
        cache.setArchived(dataObject.path("archived").asBoolean());
        cache.setPremiumMembersOnly(dataObject.path("subrOnly").asBoolean());
        // "li" seems to be "false" always
        cache.setFavoritePoints(Integer.parseInt(dataObject.path("fp").asText()));
        cache.setDifficulty(
            Float.parseFloat(dataObject.path("difficulty").path("text").asText())); // 3.5
        cache.setTerrain(Float.parseFloat(dataObject.path("terrain").path("text").asText())); // 1.5
        cache.setHidden(
            GCLogin.parseGcCustomDate(
                dataObject.path("hidden").asText(), "MM/dd/yyyy")); // 7/23/2001
        cache.setSize(
            CacheSize.getById(dataObject.path("container").path("text").asText())); // Regular
        cache.setType(
            CacheType.getByPattern(
                dataObject.path("type").path("text").asText())); // Traditional Cache
        cache.setOwnerDisplayName(dataObject.path("owner").path("text").asText());

        caches.add(cache);
      }
      result.addAndPutInCache(caches);
    } catch (ParserException | ParseException | IOException | NumberFormatException ignored) {
      result.setError(StatusCode.UNKNOWN_ERROR);
    }
    return result;
  }