Ejemplo n.º 1
0
  private void processBlocks(
      IMapDatabaseCallback mapDatabaseCallback,
      QueryParameters queryParameters,
      SubFileParameter subFileParameter)
      throws IOException {
    boolean queryIsWater = true;
    // boolean queryReadWaterInfo = false;

    // read and process all blocks from top to bottom and from left to right
    for (long row = queryParameters.fromBlockY; row <= queryParameters.toBlockY; ++row) {
      for (long column = queryParameters.fromBlockX; column <= queryParameters.toBlockX; ++column) {

        // calculate the actual block number of the needed block in the
        // file
        long blockNumber = row * subFileParameter.blocksWidth + column;

        // get the current index entry
        long currentBlockIndexEntry =
            sDatabaseIndexCache.getIndexEntry(subFileParameter, blockNumber);

        // check if the current query would still return a water tile
        if (queryIsWater) {
          // check the water flag of the current block in its index
          // entry
          queryIsWater &= (currentBlockIndexEntry & BITMASK_INDEX_WATER) != 0;
          // queryReadWaterInfo = true;
        }

        // get and check the current block pointer
        long currentBlockPointer = currentBlockIndexEntry & BITMASK_INDEX_OFFSET;
        if (currentBlockPointer < 1 || currentBlockPointer > subFileParameter.subFileSize) {
          LOG.warning("invalid current block pointer: " + currentBlockPointer);
          LOG.warning("subFileSize: " + subFileParameter.subFileSize);
          return;
        }

        long nextBlockPointer;
        // check if the current block is the last block in the file
        if (blockNumber + 1 == subFileParameter.numberOfBlocks) {
          // set the next block pointer to the end of the file
          nextBlockPointer = subFileParameter.subFileSize;
        } else {
          // get and check the next block pointer
          nextBlockPointer =
              sDatabaseIndexCache.getIndexEntry(subFileParameter, blockNumber + 1)
                  & BITMASK_INDEX_OFFSET;
          if (nextBlockPointer < 1 || nextBlockPointer > subFileParameter.subFileSize) {
            LOG.warning("invalid next block pointer: " + nextBlockPointer);
            LOG.warning("sub-file size: " + subFileParameter.subFileSize);
            return;
          }
        }

        // calculate the size of the current block
        int currentBlockSize = (int) (nextBlockPointer - currentBlockPointer);
        if (currentBlockSize < 0) {
          LOG.warning("current block size must not be negative: " + currentBlockSize);
          return;
        } else if (currentBlockSize == 0) {
          // the current block is empty, continue with the next block
          continue;
        } else if (currentBlockSize > ReadBuffer.MAXIMUM_BUFFER_SIZE) {
          // the current block is too large, continue with the next
          // block
          LOG.warning("current block size too large: " + currentBlockSize);
          continue;
        } else if (currentBlockPointer + currentBlockSize > mFileSize) {
          LOG.warning("current block largher than file size: " + currentBlockSize);
          return;
        }

        // seek to the current block in the map file
        mInputFile.seek(subFileParameter.startAddress + currentBlockPointer);

        // read the current block into the buffer
        if (!mReadBuffer.readFromFile(currentBlockSize)) {
          // skip the current block
          LOG.warning("reading current block has failed: " + currentBlockSize);
          return;
        }

        // calculate the top-left coordinates of the underlying tile
        double tileLatitudeDeg =
            MercatorProjection.tileYToLatitude(
                subFileParameter.boundaryTileTop + row, subFileParameter.baseZoomLevel);
        double tileLongitudeDeg =
            MercatorProjection.tileXToLongitude(
                subFileParameter.boundaryTileLeft + column, subFileParameter.baseZoomLevel);
        mTileLatitude = (int) (tileLatitudeDeg * 1000000);
        mTileLongitude = (int) (tileLongitudeDeg * 1000000);

        try {
          processBlock(queryParameters, subFileParameter, mapDatabaseCallback);
        } catch (ArrayIndexOutOfBoundsException e) {
          LOG.log(Level.SEVERE, null, e);
        }
      }
    }

    // the query is finished, was the water flag set for all blocks?
    // if (queryIsWater && queryReadWaterInfo) {
    // Tag[] tags = new Tag[1];
    // tags[0] = TAG_NATURAL_WATER;
    //
    // System.arraycopy(WATER_TILE_COORDINATES, 0, mWayNodes,
    // mWayNodePosition, 8);
    // mWayNodePosition += 8;
    // mapDatabaseCallback.renderWaterBackground(tags, wayDataContainer);
    // }

  }
Ejemplo n.º 2
0
 /**
  * Get the GeoPoint for x,y in screen coordinates.
  *
  * @param x screen coordinate
  * @param y screen coordinate
  * @return the corresponding GeoPoint
  */
 public GeoPoint fromScreenPoint(float x, float y) {
   fromScreenPoint(x, y, mMovePoint);
   return new GeoPoint(
       MercatorProjection.toLatitude(mMovePoint.y), MercatorProjection.toLongitude(mMovePoint.x));
 }
Ejemplo n.º 3
0
 /**
  * Get the screen pixel for a GeoPoint
  *
  * @param geoPoint the GeoPoint
  * @param out Point projected to screen pixel relative to center
  */
 public void toScreenPoint(GeoPoint geoPoint, Point out) {
   MercatorProjection.project(geoPoint, out);
   toScreenPoint(out.x, out.y, out);
 }
Ejemplo n.º 4
0
  @Override
  public void query(MapTile tile, ITileDataSink sink) {

    if (mTileSource.fileHeader == null) {
      sink.completed(FAILED);
      return;
    }

    if (mIntBuffer == null) mIntBuffer = new int[MAXIMUM_WAY_NODES_SEQUENCE_LENGTH * 2];

    try {
      mTileProjection.setTile(tile);
      // mTile = tile;

      /* size of tile in map coordinates; */
      double size = 1.0 / (1 << tile.zoomLevel);

      /* simplification tolerance */
      int pixel = (tile.zoomLevel > 11) ? 1 : 2;

      int simplify = Tile.SIZE / pixel;

      /* translate screen pixel for tile to latitude and longitude
       * tolerance for point reduction before projection. */
      minDeltaLat =
          (int)
                  (Math.abs(
                          MercatorProjection.toLatitude(tile.y + size)
                              - MercatorProjection.toLatitude(tile.y))
                      * 1e6)
              / simplify;
      minDeltaLon =
          (int)
                  (Math.abs(
                          MercatorProjection.toLongitude(tile.x + size)
                              - MercatorProjection.toLongitude(tile.x))
                      * 1e6)
              / simplify;

      QueryParameters queryParameters = new QueryParameters();
      queryParameters.queryZoomLevel = mTileSource.fileHeader.getQueryZoomLevel(tile.zoomLevel);

      /* get and check the sub-file for the query zoom level */
      SubFileParameter subFileParameter =
          mTileSource.fileHeader.getSubFileParameter(queryParameters.queryZoomLevel);

      if (subFileParameter == null) {
        log.warn("no sub-file for zoom level: " + queryParameters.queryZoomLevel);

        sink.completed(FAILED);
        return;
      }

      QueryCalculations.calculateBaseTiles(queryParameters, tile, subFileParameter);
      QueryCalculations.calculateBlocks(queryParameters, subFileParameter);
      processBlocks(sink, queryParameters, subFileParameter);
    } catch (IOException e) {
      log.error(e.getMessage());
      sink.completed(FAILED);
      return;
    }

    sink.completed(SUCCESS);
  }