Esempio n. 1
0
  /**
   * Transform a raster to the target coordinate system.
   *
   * <p>This method transforms the whole raster into the target CRS of this RasterTransformer. The
   * size of the output raster will be calculated, so that the pixels keep the aspect ratio (i.e.
   * keep square pixels).
   *
   * <p>If the coordinate system of the source raster is <code>null</code> or equals the target crs,
   * the source raster will be returned unaltered.
   *
   * @param sourceRaster the raster to be transformed
   * @param interpolationType
   * @return the transformed raster
   * @throws IllegalArgumentException
   * @throws TransformationException
   * @throws UnknownCRSException
   */
  public AbstractRaster transform(AbstractRaster sourceRaster, InterpolationType interpolationType)
      throws IllegalArgumentException, TransformationException, UnknownCRSException {

    ICRS srcCRS = sourceRaster.getCoordinateSystem();
    if (srcCRS == null || srcCRS.equals(getTargetCRS())) {
      return sourceRaster;
    }

    GeometryTransformer gt = new GeometryTransformer(getTargetCRS());
    Envelope dstEnvelope = gt.transform(sourceRaster.getEnvelope(), srcCRS).getEnvelope();

    int srcWidth = sourceRaster.getColumns();
    int srcHeight = sourceRaster.getRows();

    // calculate the new size, consider the aspect ratio to get square pixels
    double deltaX = dstEnvelope.getSpan0();
    double deltaY = dstEnvelope.getSpan1();
    double diagSize = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
    // pixelSize for calculation of the new image size
    double pixelSize = diagSize / Math.sqrt(Math.pow(srcWidth, 2) + Math.pow(srcHeight, 2));
    int dstHeight = (int) (deltaY / pixelSize + 0.5);
    int dstWidth = (int) (deltaX / pixelSize + 0.5);

    return transform(sourceRaster, dstEnvelope, dstWidth, dstHeight, interpolationType);
  }
Esempio n. 2
0
  /**
   * Create a new raster that contains all data we need for the transformation.
   *
   * @throws IllegalArgumentException
   */
  private AbstractRaster getSubRaster(
      ICRS srcCRS, AbstractRaster sourceRaster, Envelope dstEnvelope)
      throws TransformationException, IllegalArgumentException {
    Envelope dataEnv = dstEnvelope;
    if (srcCRS != null && !srcCRS.equals(getTargetCRS())) {

      GeometryTransformer srcTransf = new GeometryTransformer(srcCRS);

      // the envelope from which we need data
      Envelope workEnv = srcTransf.transform(dstEnvelope, getTargetCRS());

      Envelope dataEnvelope = sourceRaster.getEnvelope();
      // the envelope from which we have data
      Geometry dataEnvGeom = workEnv.getIntersection(dataEnvelope);
      if (dataEnvGeom == null) {
        LOG.debug("no intersection for " + sourceRaster + " and " + dstEnvelope);
        // todo create subclass of TransformationException
        throw new TransformationException("no source data found");
      }
      dataEnv = dataEnvGeom.getEnvelope();
    }

    AbstractRaster source;
    try {
      source = sourceRaster.getSubRaster(dataEnv);
    } catch (IndexOutOfBoundsException ex) {
      throw new TransformationException("no source data found");
    }
    // if ( LOG.isDebugEnabled() ) {
    // debugRasterFile( source );
    // }
    return source;
  }
Esempio n. 3
0
  /**
   * Returns new RasterGeoReference with the origin set to the min[0],max[1] of the envelope and the
   * OriginLocation to the given one. Other values are taken from this instance. Attention, the
   * resulting origin is snapped to the location (center/outer) of the underlying grid, so the
   * min[0] and max[1] values are only approximations to the new origin!
   *
   * @param targetLocation
   * @param envelope to get the origin from.
   * @return new RasterGeoReference or <code>null</code> if the envelope is <code>null</code>
   */
  public RasterGeoReference createRelocatedReference(
      OriginLocation targetLocation, Envelope envelope) {
    if (envelope != null) {
      OriginLocation tLoc = (targetLocation == null) ? location : targetLocation;
      Envelope transformedEnv = envelope;
      if (transformer != null) {
        try {
          transformedEnv = transformer.transform(envelope).getEnvelope();
        } catch (IllegalArgumentException e) {
          // just don't transform and go ahead without.
        } catch (TransformationException e) {
          // just don't transform and go ahead without.
        } catch (UnknownCRSException e) {
          // just don't transform and go ahead without.
        } catch (ReferenceResolvingException e) {
          // just don't transform and go ahead without.
        }
      }

      double[] min = transformedEnv.getMin().getAsArray();
      double[] max = transformedEnv.getMax().getAsArray();

      int[] rasterCoordinate = getRasterCoordinate(min[0], max[1]);
      // take the 'upper' left raster position as the new origin, thus add a half pixel.
      double raster0 = rasterCoordinate[0] + (tLoc == CENTER ? 0.5 : 0);
      double raster1 = rasterCoordinate[1] + (tLoc == CENTER ? 0.5 : 0);
      // if ( location == CENTER ) {
      // raster0 += 0.5;
      // raster1 += 0.5;
      // }
      // if ( tLoc != location ) {
      // if ( tLoc == OUTER ) {
      // // this location is center, the above subtracted 0.5 will get the raster location of the
      // centered
      // // view, but to get an OUTER view we need to subtract another half a pixel.
      // raster0 -= 0.5;
      // raster1 -= 0.5;
      // } else {
      // // this location is OUTER, add 0.5 to get the center location
      // raster0 += 0.5;
      // raster1 += 0.5;
      // }
      // }
      double[] worldCoordinate = getWorldCoordinate(raster0, raster1);

      return new RasterGeoReference(
          tLoc,
          this.getResolutionX(),
          this.getResolutionY(),
          this.getRotationX(),
          this.getRotationY(),
          worldCoordinate[0],
          worldCoordinate[1],
          this.crs);
    }
    return null;
  }
Esempio n. 4
0
  /**
   * Converts an envelope in world coordinates to raster coordinates, note the envelope in world
   * coordinates is defined over min/max (lower left/upper right), whereas a RasterRect is defined
   * as min(upperleft) with a width and height.
   *
   * @param envelope envelope in world coordinates
   * @return RasterRect
   */
  public RasterRect convertEnvelopeToRasterCRS(Envelope envelope) {
    RasterRect result = new RasterRect();
    if (envelope != null) {
      Envelope transformedEnv = envelope;
      if (transformer != null) {
        try {
          transformedEnv = transformer.transform(envelope).getEnvelope();
        } catch (IllegalArgumentException e) {
          // just don't transform and go ahead without.
        } catch (TransformationException e) {
          // just don't transform and go ahead without.
        } catch (UnknownCRSException e) {
          // just don't transform and go ahead without.
        }
      }

      double[] min = transformedEnv.getMin().getAsArray();
      double[] max = transformedEnv.getMax().getAsArray();

      // upper left point
      double ulX = min[0];
      double ulY = max[1];

      // lower right point
      double lrX = max[0];
      double lrY = min[1];

      // finding easting and northing ordinates is not necessary because the transform is aligned
      // with the defined
      // coordinatesystem.

      int[] rrUpperLeft = getRasterCoordinate(ulX, ulY);
      int[] rrLowerRight = getRasterCoordinate(lrX, lrY);

      // get the minimal raster x value.
      result.x = min(rrUpperLeft[0], rrLowerRight[0]);

      // and the minimal raster y value
      result.y = min(rrUpperLeft[1], rrLowerRight[1]);

      // find 'unrounded' location raster locations.
      double[] rrUL = getRasterCoordinateUnrounded(ulX, ulY);
      double[] rrLR = getRasterCoordinateUnrounded(lrX, lrY);

      // floor the unrounded min, ceil the unrounded max, this equals the outer representation, for
      // example the
      // point 1.1, 3.1 must result in a span of 1-4. (Draw it out :-) ) e.g a width of 3
      result.width = (int) abs(floor(rrUL[0]) - ceil(rrLR[0]));
      result.height = (int) abs(floor(rrUL[1]) - ceil(rrLR[1]));
    }
    return result;
  }
Esempio n. 5
0
  /**
   * Relocates the given minimum and maximum points of the given envelope to the target origin
   * location definition. This method does nothing if the given location equals this {@link
   * RasterGeoReference}'s origin location. This method effectively adds or subtracts half a
   * resolution of the ordinates of the given Envelope. Different CRS's are supported.
   *
   * @param targetLocation the preferred location of the origin. *
   * @param envelope to relocate.
   * @return a new Envelope which is aligned with the target location or <code>null</code> if the
   *     envelope is <code>null</code>
   */
  public Envelope relocateEnvelope(OriginLocation targetLocation, Envelope envelope) {
    if (envelope == null) {
      return null;
    }
    if (targetLocation == location) {
      return envelope;
    }
    // rb: the envelope will not create copies, neither does the geometryfactory ;-)
    double[] orig = envelope.getMin().getAsArray();
    double[] nMin = new double[orig.length];
    System.arraycopy(orig, 0, nMin, 0, orig.length);
    orig = envelope.getMax().getAsArray();
    double[] nMax = new double[orig.length];
    System.arraycopy(orig, 0, nMax, 0, orig.length);
    Envelope transformedEnv =
        geomFactory.createEnvelope(nMin, nMax, envelope.getCoordinateSystem());
    if (targetLocation != location) {
      if (transformer != null && envelope.getCoordinateSystem() != null) {
        try {
          transformedEnv = transformer.transform(envelope).getEnvelope();
        } catch (IllegalArgumentException e) {
          // just don't transform and go ahead without.
        } catch (TransformationException e) {
          // just don't transform and go ahead without.
        } catch (UnknownCRSException e) {
          // just don't transform and go ahead without.
        } catch (ReferenceResolvingException e) {
          // just don't transform and go ahead without.
        }
      }
      double[] min = transformedEnv.getMin().getAsArray();
      double[] max = transformedEnv.getMax().getAsArray();

      double[] rasterCoordinateMin = getRasterCoordinateUnrounded(min[0], min[1]);
      double[] rasterCoordinateMax = getRasterCoordinateUnrounded(max[0], max[1]);

      double world0Min = rasterCoordinateMin[0];
      double world1Min = rasterCoordinateMin[1];

      double world0Max = rasterCoordinateMax[0];
      double world1Max = rasterCoordinateMax[1];

      if (location == CENTER) {
        // the targetlocation is OUTER
        // take the 'upper' left raster position as the new origin.
        world0Min -= 0.5;
        world1Min -= 0.5;
        world0Max -= 0.5;
        world1Max -= 0.5;
      } else {
        // the targetlocation is CENTER
        world0Min += 0.5;
        world1Min += 0.5;
        world0Max += 0.5;
        world1Max += 0.5;
      }
      double[] worldMinCoordinate = getWorldCoordinate(world0Min, world1Min);
      double[] worldMaxCoordinate = getWorldCoordinate(world0Max, world1Max);

      nMin[0] = worldMinCoordinate[0];
      nMin[1] = worldMinCoordinate[1];
      nMax[0] = worldMaxCoordinate[0];
      nMax[1] = worldMaxCoordinate[1];
      transformedEnv = geomFactory.createEnvelope(nMin, nMax, transformedEnv.getCoordinateSystem());

      // no convert back to the requested crs
      if (transformer != null && envelope.getCoordinateSystem() != null) {
        try {
          GeometryTransformer invTrans = new GeometryTransformer(envelope.getCoordinateSystem());
          transformedEnv = invTrans.transform(transformedEnv).getEnvelope();
        } catch (IllegalArgumentException e) {
          // just don't transform and go ahead without.
        } catch (TransformationException e) {
          // just don't transform and go ahead without.
        } catch (UnknownCRSException e) {
          // just don't transform and go ahead without.
        } catch (ReferenceResolvingException e) {
          // just don't transform and go ahead without.
        }
      }
    }
    return transformedEnv;
  }
Esempio n. 6
0
  /**
   * Returns an Envelope for a raster with given size and given x,y raster location.
   *
   * <p>The calculation considers the origin and resolution of the raster.
   *
   * @param targetLocation of the origin, specifies if the the newly created envelope should
   *     consider the origin located at the OUTER or CENTER of a pixel.
   * @param rasterRect defining the x,y raster coordinates (as integers) as well as the width and
   *     height of the raster.
   * @param crs the coordinate system for the envelope
   * @return the calculated envelope
   */
  public Envelope getEnvelope(OriginLocation targetLocation, RasterRect rasterRect, ICRS crs) {
    // if the targetlocation must be center, we add half a pixel, because we need to get the world
    // coordinate of the
    // center of the pixel.
    double nullX = rasterRect.x + (targetLocation == CENTER ? 0.5 : 0);
    double nullY = rasterRect.y + (targetLocation == CENTER ? 0.5 : 0);
    double tw = nullX + rasterRect.width;
    double th = nullY + rasterRect.height;

    // double tw = rasterRect.width;
    // double th = rasterRect.height;

    // if ( location == CENTER ) {
    // // if the targetlocation must be center, we add half a pixel, because we need to get the
    // world coordinate of
    // // the center of the pixel.
    // tw += 0.5;
    // th += 0.5;
    // }
    //
    // if ( location != targetLocation ) {
    // if ( targetLocation == OUTER ) {
    // // this location is center, the target location is outer, subtract 0.5 pixel from the
    // width|height.
    // // tw -= 0.5;
    // // th -= 0.5;
    // pixelAddUp -= 0.5;
    // } else {
    // // this location is outer, the target location is center, add 0.5 pixel to the width|height
    // // tw += 0.5;
    // // th += 0.5;
    // pixelAddUp += 0.5;
    // }
    // }

    // nullX += pixelAddUp;
    // nullY += pixelAddUp;
    // tw += pixelAddUp;
    // th += pixelAddUp;

    double[] widthHeightPos = getWorldCoordinate(tw, th);
    double[] origin = getWorldCoordinate(nullX, nullY);
    // double[] origin = getOrigin();
    // if ( location != targetLocation ) {
    // if ( targetLocation == OUTER ) {
    // // this location is center, the target location is outer, subtract 0.5 res to the origin.
    // origin[0] -= resX * 0.5;
    // origin[1] -= resY * 0.5;
    // } else {
    // // this location is outer, the target location is center, add 0.5 resolution to the origin
    // origin[0] += resX * 0.5;
    // origin[1] += resY * 0.5;
    // }
    // }

    // convert to lower-left and upper-right for the envelope
    double min0 = min(widthHeightPos[0], origin[0]);
    double min1 = min(widthHeightPos[1], origin[1]);
    double max0 = max(widthHeightPos[0], origin[0]);
    double max1 = max(widthHeightPos[1], origin[1]);

    // coordinates are in the crs, so axis order is available.
    Envelope result = geomFactory.createEnvelope(min0, min1, max0, max1, this.crs);
    if (crs != null && this.crs != null) {
      GeometryTransformer trans = new GeometryTransformer(crs);
      try {
        result = trans.transform(result).getEnvelope();
      } catch (Throwable e) {
        // let the envelope be.
      }
    }
    return result;
  }