Exemple #1
0
  public static Tile calculateTile(
      final Tile tile, final int srcZoom, final int dstZoom, final int tilesize) {
    final TMSUtils.Bounds bounds = TMSUtils.tileBounds(tile.tx, tile.ty, srcZoom, tilesize);

    return TMSUtils.latLonToTile(bounds.s, bounds.w, dstZoom, tilesize);
  }
  /**
   * BoundsCropper takes an image (actually, its metadata), a list of user bounds to crop, and a
   * zoom level, and gives back the metadata corresponding to the cropped image with the maximum
   * zoom level set to the one provided.
   *
   * <p>Additional details:
   *
   * <p>If there is only one user bounds, then the cropped image bounds corresponds to that
   * singleton bounds. If there is a list of user bounds, then the cropped image bounds corresponds
   * to an envelope around the list of user bounds.
   *
   * <p>The new image bounds are computed from the old using the following two transformations -
   * first, the user bounds are capped to the nearest tile boundaries. - second, the bounds from
   * above are then intersected with the original image boundaries
   *
   * <p>The new tile bounds are computed from the new image bounds.
   *
   * <p>If the user bounds are outside the image bounds (i.e., they have no overlap), then an
   * exception is thrown
   *
   * <p>If the provided zoom level is different from the maximum zoom level in the input metadata,
   * then care is taken to set the maximum zoom level of the returned data to the provided zoom
   * level.
   *
   * @param origMetadata
   * @param userBounds
   * @param zoomLevel
   * @return
   */
  public static MrsPyramidMetadata getCroppedMetadata(
      MrsPyramidMetadata origMetadata, List<Bounds> userBounds, int zoomLevel) {

    double minX = Double.POSITIVE_INFINITY, minY = Double.POSITIVE_INFINITY;
    double maxX = Double.NEGATIVE_INFINITY, maxY = Double.NEGATIVE_INFINITY;

    // if there is a list of user bounds, find the envelope surrounding it
    for (Bounds bounds : userBounds) {
      if (bounds.w < minX) minX = bounds.w;
      if (bounds.s < minY) minY = bounds.s;
      if (bounds.e > maxX) maxX = bounds.e;
      if (bounds.n > maxY) maxY = bounds.n;
    }

    Bounds cropBounds = new Bounds(minX, minY, maxX, maxY);

    // now cap it to the nearest outside tile boundaries
    Bounds cropTileBounds = TMSUtils.tileBounds(cropBounds, zoomLevel, origMetadata.getTilesize());

    // get the original image bounds
    Bounds imageBounds = Bounds.convertOldToNewBounds(origMetadata.getBounds());

    // complain if the user bounds has no overlap with
    if (!imageBounds.intersect(cropTileBounds)) {
      throw new IllegalArgumentException(
          String.format(
              "Oops - cropped bounds and image bounds "
                  + "do not overlap: cropped bounds=%s, image bounds=%s",
              cropTileBounds, imageBounds));
    }

    // now find the intersection of the cropped bounds and image bounds - this becomes the new
    // image bounds
    Bounds newImageBounds =
        new Bounds(
            Math.max(cropTileBounds.w, imageBounds.w),
            Math.max(cropTileBounds.s, imageBounds.s),
            Math.min(cropTileBounds.e, imageBounds.e),
            Math.min(cropTileBounds.n, imageBounds.n));

    // find the tile bounds corresponding to the new image bounds - this becomes the new tile bounds
    TMSUtils.TileBounds newTileBounds =
        TMSUtils.boundsToTile(newImageBounds, zoomLevel, origMetadata.getTilesize());

    final TMSUtils.Pixel lowerPx =
        TMSUtils.latLonToPixels(
            newImageBounds.s, newImageBounds.w, zoomLevel, origMetadata.getTilesize());
    final TMSUtils.Pixel upperPx =
        TMSUtils.latLonToPixels(
            newImageBounds.n, newImageBounds.e, zoomLevel, origMetadata.getTilesize());

    final LongRectangle pixelBounds =
        new LongRectangle(0, 0, upperPx.px - lowerPx.px, upperPx.py - lowerPx.py);

    // time to create the new metadata
    MrsPyramidMetadata croppedMetadata = new MrsPyramidMetadata();
    croppedMetadata.setPyramid(origMetadata.getPyramid());
    croppedMetadata.setBounds(Bounds.convertNewToOldBounds(newImageBounds));
    croppedMetadata.setTilesize(origMetadata.getTilesize());
    croppedMetadata.setTileType(origMetadata.getTileType());
    croppedMetadata.setBands(1);
    croppedMetadata.setDefaultValues(origMetadata.getDefaultValues());
    // max zoom should be input zoom not origMetadata.getMaxZoomLevel
    croppedMetadata.setMaxZoomLevel(zoomLevel);
    croppedMetadata.setName(zoomLevel, "" + zoomLevel);
    croppedMetadata.setTileBounds(zoomLevel, TileBounds.convertToLongRectangle(newTileBounds));
    croppedMetadata.setPixelBounds(zoomLevel, pixelBounds);
    croppedMetadata.setProtectionLevel(origMetadata.getProtectionLevel());
    return croppedMetadata;
  }