예제 #1
0
  /**
   * Processes the given number of POIs.
   *
   * @param mapDataSink the callback which handles the extracted POIs.
   * @param numberOfPois how many POIs should be processed.
   * @return true if the POIs could be processed successfully, false otherwise.
   */
  private boolean processPOIs(ITileDataSink mapDataSink, int numberOfPois) {
    Tag[] poiTags = mTileSource.fileInfo.poiTags;
    MapElement e = mElem;

    int numTags = 0;

    for (int elementCounter = numberOfPois; elementCounter != 0; --elementCounter) {
      if (mDebugFile) {
        /* get and check the POI signature */
        mSignaturePoi = mReadBuffer.readUTF8EncodedString(SIGNATURE_LENGTH_POI);
        if (!mSignaturePoi.startsWith("***POIStart")) {
          log.warn("invalid POI signature: " + mSignaturePoi);
          log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
          return false;
        }
      }

      /* get the POI latitude offset (VBE-S) */
      int latitude = mTileLatitude + mReadBuffer.readSignedInt();
      /* get the POI longitude offset (VBE-S) */
      int longitude = mTileLongitude + mReadBuffer.readSignedInt();

      /* get the special byte which encodes multiple flags */
      byte specialByte = mReadBuffer.readByte();

      /* bit 1-4 represent the layer */
      byte layer = (byte) ((specialByte & POI_LAYER_BITMASK) >>> POI_LAYER_SHIFT);

      /* bit 5-8 represent the number of tag IDs */
      byte numberOfTags = (byte) (specialByte & POI_NUMBER_OF_TAGS_BITMASK);

      if (numberOfTags != 0) {
        if (!mReadBuffer.readTags(e.tags, poiTags, numberOfTags)) return false;

        numTags = numberOfTags;
      }

      /* reset to common tag position */
      e.tags.numTags = numTags;

      /* get the feature bitmask (1 byte) */
      byte featureByte = mReadBuffer.readByte();

      /* bit 1-3 enable optional features
       * check if the POI has a name */
      if ((featureByte & POI_FEATURE_NAME) != 0) {
        String str = mReadBuffer.readUTF8EncodedString();
        e.tags.add(new Tag(Tag.KEY_NAME, str, false));
      }

      /* check if the POI has a house number */
      if ((featureByte & POI_FEATURE_HOUSE_NUMBER) != 0) {
        // mReadBuffer.getPositionAndSkip();
        // String str =
        mReadBuffer.readUTF8EncodedString();
      }

      /* check if the POI has an elevation */
      if ((featureByte & POI_FEATURE_ELEVATION) != 0) {
        mReadBuffer.readSignedInt();
        // mReadBuffer.getPositionAndSkip();// tags.add(new
        // Tag(Tag.TAG_KEY_ELE,
        // Integer.toString(mReadBuffer.readSignedInt())));
      }
      mTileProjection.projectPoint(latitude, longitude, e);

      e.setLayer(layer);

      mapDataSink.process(e);
    }

    return true;
  }
예제 #2
0
  /**
   * Processes the given number of ways.
   *
   * @param queryParameters the parameters of the current query.
   * @param mapDataSink the callback which handles the extracted ways.
   * @param numberOfWays how many ways should be processed.
   * @return true if the ways could be processed successfully, false otherwise.
   */
  private boolean processWays(
      QueryParameters queryParameters, ITileDataSink mapDataSink, int numberOfWays) {

    Tag[] wayTags = mTileSource.fileInfo.wayTags;
    MapElement e = mElem;

    int numTags = 0;

    int wayDataBlocks;

    // skip string block
    int stringsSize = 0;
    stringOffset = 0;

    if (mTileSource.experimental) {
      stringsSize = mReadBuffer.readUnsignedInt();
      stringOffset = mReadBuffer.getBufferPosition();
      mReadBuffer.skipBytes(stringsSize);
    }

    // setTileClipping(queryParameters);

    for (int elementCounter = numberOfWays; elementCounter != 0; --elementCounter) {
      if (mDebugFile) {
        // get and check the way signature
        mSignatureWay = mReadBuffer.readUTF8EncodedString(SIGNATURE_LENGTH_WAY);
        if (!mSignatureWay.startsWith("---WayStart")) {
          log.warn("invalid way signature: " + mSignatureWay);
          log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
          return false;
        }
      }

      if (queryParameters.useTileBitmask) {
        elementCounter = mReadBuffer.skipWays(queryParameters.queryTileBitmask, elementCounter);

        if (elementCounter == 0) return true;

        if (elementCounter < 0) return false;

        if (mTileSource.experimental && mReadBuffer.lastTagPosition > 0) {
          int pos = mReadBuffer.getBufferPosition();
          mReadBuffer.setBufferPosition(mReadBuffer.lastTagPosition);

          byte numberOfTags = (byte) (mReadBuffer.readByte() & WAY_NUMBER_OF_TAGS_BITMASK);
          if (!mReadBuffer.readTags(e.tags, wayTags, numberOfTags)) return false;

          numTags = numberOfTags;

          mReadBuffer.setBufferPosition(pos);
        }
      } else {
        int wayDataSize = mReadBuffer.readUnsignedInt();
        if (wayDataSize < 0) {
          log.warn("invalid way data size: " + wayDataSize);
          if (mDebugFile) {
            log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock);
          }
          log.error("BUG way 2");
          return false;
        }

        /* ignore the way tile bitmask (2 bytes) */
        mReadBuffer.skipBytes(2);
      }

      /* get the special byte which encodes multiple flags */
      byte specialByte = mReadBuffer.readByte();

      /* bit 1-4 represent the layer */
      byte layer = (byte) ((specialByte & WAY_LAYER_BITMASK) >>> WAY_LAYER_SHIFT);
      /* bit 5-8 represent the number of tag IDs */
      byte numberOfTags = (byte) (specialByte & WAY_NUMBER_OF_TAGS_BITMASK);

      if (numberOfTags != 0) {

        if (!mReadBuffer.readTags(e.tags, wayTags, numberOfTags)) return false;

        numTags = numberOfTags;
      }

      /* get the feature bitmask (1 byte) */
      byte featureByte = mReadBuffer.readByte();

      /* bit 1-6 enable optional features */
      boolean featureWayDoubleDeltaEncoding =
          (featureByte & WAY_FEATURE_DOUBLE_DELTA_ENCODING) != 0;

      boolean hasName = (featureByte & WAY_FEATURE_NAME) != 0;
      boolean hasHouseNr = (featureByte & WAY_FEATURE_HOUSE_NUMBER) != 0;
      boolean hasRef = (featureByte & WAY_FEATURE_REF) != 0;

      e.tags.numTags = numTags;

      if (mTileSource.experimental) {
        if (hasName) {
          int textPos = mReadBuffer.readUnsignedInt();
          String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
          e.tags.add(new Tag(Tag.KEY_NAME, str, false));
        }
        if (hasHouseNr) {
          int textPos = mReadBuffer.readUnsignedInt();
          String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
          e.tags.add(new Tag(Tag.KEY_HOUSE_NUMBER, str, false));
        }
        if (hasRef) {
          int textPos = mReadBuffer.readUnsignedInt();
          String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos);
          e.tags.add(new Tag(Tag.KEY_REF, str, false));
        }
      } else {
        if (hasName) {
          String str = mReadBuffer.readUTF8EncodedString();
          e.tags.add(new Tag(Tag.KEY_NAME, str, false));
        }
        if (hasHouseNr) {
          String str = mReadBuffer.readUTF8EncodedString();
          e.tags.add(new Tag(Tag.KEY_HOUSE_NUMBER, str, false));
        }
        if (hasRef) {
          String str = mReadBuffer.readUTF8EncodedString();
          e.tags.add(new Tag(Tag.KEY_REF, str, false));
        }
      }
      if ((featureByte & WAY_FEATURE_LABEL_POSITION) != 0)
        // labelPosition =
        readOptionalLabelPosition();

      if ((featureByte & WAY_FEATURE_DATA_BLOCKS_BYTE) != 0) {
        wayDataBlocks = mReadBuffer.readUnsignedInt();

        if (wayDataBlocks < 1) {
          log.warn("invalid number of way data blocks: " + wayDataBlocks);
          logDebugSignatures();
          return false;
        }
      } else {
        wayDataBlocks = 1;
      }

      /* some guessing if feature is a line or a polygon */
      boolean linearFeature =
          e.tags.containsKey("highway")
              || e.tags.containsKey("boundary")
              || e.tags.containsKey("railway");
      if (linearFeature) {
        Tag areaTag = e.tags.get("area");
        if (areaTag != null && areaTag.value == Tag.VALUE_YES) linearFeature = false;
      }

      for (int wayDataBlock = 0; wayDataBlock < wayDataBlocks; wayDataBlock++) {
        e.clear();

        if (!processWayDataBlock(e, featureWayDoubleDeltaEncoding, linearFeature)) return false;

        /* drop invalid outer ring */
        if (e.isPoly() && e.index[0] < 6) {
          continue;
        }

        mTileProjection.project(e);

        if (!e.tags.containsKey("building"))
          if (!mTileClipper.clip(e)) {
            continue;
          }
        e.simplify(1, true);

        e.setLayer(layer);
        mapDataSink.process(e);
      }
    }

    return true;
  }
예제 #3
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);
  }