/**
   * Transforms the referenced envelope to the specified coordinate reference system using the
   * specified amount of points.
   *
   * <p>This method can handle the case where the envelope contains the North or South pole, or when
   * it cross the &plusmn;180� longitude.
   *
   * @param targetCRS The target coordinate reference system.
   * @param lenient {@code true} if datum shift should be applied even if there is insuffisient
   *     information. Otherwise (if {@code false}), an exception is thrown in such case.
   * @param numPointsForTransformation The number of points to use for sampling the envelope.
   * @return The transformed envelope.
   * @throws FactoryException if the math transform can't be determined.
   * @throws TransformException if at least one coordinate can't be transformed.
   * @see CRS#transform(CoordinateOperation, org.opengis.geometry.Envelope)
   * @since 2.3
   */
  public ReferencedEnvelope transform(
      final CoordinateReferenceSystem targetCRS,
      final boolean lenient,
      final int numPointsForTransformation)
      throws TransformException, FactoryException {
    if (crs == null) {
      if (isEmpty()) {
        // We don't have a CRS yet because we are still empty, being empty is
        // something we can represent in the targetCRS
        return new ReferencedEnvelope(targetCRS);
      } else {
        // really this is a the code that created this ReferencedEnvelope
        throw new NullPointerException(
            "Unable to transform referenced envelope, crs has not yet been provided.");
      }
    }
    if (getDimension() != targetCRS.getCoordinateSystem().getDimension()) {
      if (lenient) {
        return JTS.transformTo3D(this, targetCRS, lenient, numPointsForTransformation);
      } else {
        throw new MismatchedDimensionException(
            Errors.format(
                ErrorKeys.MISMATCHED_DIMENSION_$3,
                crs.getName().getCode(),
                new Integer(getDimension()),
                new Integer(targetCRS.getCoordinateSystem().getDimension())));
      }
    }
    /*
     * Gets a first estimation using an algorithm capable to take singularity in account
     * (North pole, South pole, 180� longitude). We will expand this initial box later.
     */
    CoordinateOperationFactory coordinateOperationFactory =
        CRS.getCoordinateOperationFactory(lenient);

    final CoordinateOperation operation =
        coordinateOperationFactory.createOperation(crs, targetCRS);
    final GeneralEnvelope transformed = CRS.transform(operation, this);
    transformed.setCoordinateReferenceSystem(targetCRS);

    /*
     * Now expands the box using the usual utility methods.
     */
    final ReferencedEnvelope target = new ReferencedEnvelope(transformed);
    final MathTransform transform = operation.getMathTransform();
    JTS.transform(this, target, transform, numPointsForTransformation);

    return target;
  }
  /** {@inheritDoc } */
  @Override
  public double[] getResolution(final CoordinateReferenceSystem crs) {
    if (CRS.equalsIgnoreMetadata(objectiveCRS, crs)) {
      return getResolution();
    } else {
      final double[] res = new double[crs.getCoordinateSystem().getDimension()];

      final Envelope env;
      try {
        env = CRS.transform(canvasObjectiveBBox2D, crs);
        final Rectangle2D canvasCRSBounds =
            new Rectangle2D.Double(0, 0, env.getSpan(0), env.getSpan(1));
        res[0] = Math.abs(canvasCRSBounds.getWidth() / canvasDisplaybounds.getWidth());
        res[1] = Math.abs(canvasCRSBounds.getHeight() / canvasDisplaybounds.getHeight());
        for (int i = 2; i < res.length; i++) {
          // other dimension are likely to be the temporal and elevation one.
          // we set a hug resolution to ensure that only one slice of data will be retrived.
          res[i] = Double.MAX_VALUE;
        }
      } catch (TransformException ex) {
        LOGGER.log(Level.WARNING, null, ex);
      } catch (IllegalArgumentException ex) {
        LOGGER.log(Level.WARNING, null, ex);
      } catch (Exception ex) {
        LOGGER.log(Level.WARNING, null, ex);
      }

      return adjustResolutionWithDPI(res);
    }
  }
  /**
   * Utility method to create a ReferencedEnvelope from an JTS Envelope class, supporting 2d as well
   * as 3d envelopes (returning the right class).
   *
   * @param env The JTS Envelope object
   * @return ReferencedEnvelope, ReferencedEnvelope3D if it is 3d,<br>
   *     results in a null/an empty envelope, if input envelope was a null/an empty envelope
   */
  public static ReferencedEnvelope create(Envelope env, CoordinateReferenceSystem crs) {
    if (env == null) {
      return null;
    }
    if (crs.getCoordinateSystem().getDimension() >= 3) {
      if (env.isNull()) {
        return new ReferencedEnvelope3D(crs);
      } else {
        return new ReferencedEnvelope3D(
            env.getMinX(),
            env.getMaxX(),
            env.getMinY(),
            env.getMaxY(),
            Double.NaN,
            Double.NaN,
            crs);
      }
    }

    if (env.isNull()) {
      return new ReferencedEnvelope(crs);
    } else {
      return new ReferencedEnvelope(env, crs);
    }
  }
  /** {@inheritDoc} */
  @Override
  public CoordinateReferenceSystem getResponseCRS() throws FactoryException {
    if (output == null
        || output.getGridCRS() == null
        || output.getGridCRS().getSrsName() == null
        || output.getGridCRS().getSrsName().getValue() == null) {
      return null;
    }
    final CoordinateReferenceSystem objCrs =
        CRS.forCode(output.getGridCRS().getSrsName().getValue());
    final BoundingBoxType boundingBox = domainSubset.getBoundingBox().getValue();

    /*
     * If the bounding box contains at least 3 dimensions and the CRS specified is just
     * a 2D one, then we have to add a VerticalCRS to the one gotten by the crs decoding step.
     * Otherwise the CRS decoded is already fine, and we just return it.
     */
    if (boundingBox.getDimensions().intValue() > 2
        && objCrs.getCoordinateSystem().getDimension() < 3) {
      final VerticalCRS verticalCRS = CommonCRS.Vertical.ELLIPSOIDAL.crs();
      return new GeodeticObjectBuilder()
          .addName(objCrs.getName().getCode() + " (3D)")
          .createCompoundCRS(objCrs, verticalCRS);
    } else {
      return objCrs;
    }
  }
  /** {@inheritDoc} */
  @Override
  public CoordinateReferenceSystem getCRS() throws FactoryException {
    if (domainSubset == null || domainSubset.getBoundingBox() == null) {
      return null;
    }
    final BoundingBoxType boundingBox = domainSubset.getBoundingBox().getValue();
    final CoordinateReferenceSystem objCrs =
        AbstractCRS.castOrCopy(CRS.forCode(boundingBox.getCrs()))
            .forConvention(AxesConvention.RIGHT_HANDED);

    // final List<DirectPositionType> positions =
    // domainSubset.getSpatialSubSet().getEnvelope().getPos();

    /*
     * If the bounding box contains at least 3 dimensions and the CRS specified is just
     * a 2D one, then we have to add a VerticalCRS to the one gotten by the crs decoding step.
     * Otherwise the CRS decoded is already fine, and we just return it.
     */
    if (boundingBox.getUpperCorner().size() > 2
        && objCrs.getCoordinateSystem().getDimension() < 3) {
      final VerticalCRS verticalCRS = CommonCRS.Vertical.ELLIPSOIDAL.crs();
      return new GeodeticObjectBuilder()
          .addName(objCrs.getName().getCode() + " (3D)")
          .createCompoundCRS(objCrs, verticalCRS);
    } else {
      return objCrs;
    }
  }
Beispiel #6
0
 /**
  * Determine the number of dimensions based on the CRS metadata.
  *
  * @return Number of dimensions expected based on metadata, default of 2
  */
 int getD() {
   CoordinateReferenceSystem crs =
       (CoordinateReferenceSystem) parameter.metadata.get(Parameter.CRS);
   if (crs == null) {
     return 2;
   } else {
     return crs.getCoordinateSystem().getDimension();
   }
 }
 /**
  * Convenience method for checking coordinate reference system validity.
  *
  * @param crs The coordinate reference system to check.
  * @param expected the dimension expected.
  * @throws MismatchedDimensionException if the CRS dimension is not valid.
  */
 static void checkCoordinateReferenceSystemDimension(
     final CoordinateReferenceSystem crs, final int expected) throws MismatchedDimensionException {
   if (crs != null) {
     final int dimension = crs.getCoordinateSystem().getDimension();
     if (dimension != expected) {
       throw new MismatchedDimensionException(
           Errors.format(
               ErrorKeys.MISMATCHED_DIMENSION_$3, crs.getName().getCode(), dimension, expected));
     }
   }
 }
 public void updatePixelUnit(CoordinateReferenceSystem crs) {
   final CoordinateSystem coordinateSystem = crs.getCoordinateSystem();
   final String unitX = coordinateSystem.getAxis(0).getUnit().toString();
   if (!unitX.equals(pixelXUnit.getText())) {
     pixelXUnit.setText(unitX);
     pixelSizeXField.setValue(unitMap.get(unitX));
   }
   final String unitY = coordinateSystem.getAxis(1).getUnit().toString();
   if (!unitY.equals(pixelYUnit.getText())) {
     pixelYUnit.setText(unitY);
     pixelSizeYField.setValue(unitMap.get(unitY));
   }
 }
Beispiel #9
0
 /**
  * Transforms the geometry to the storage EPSG code
  *
  * @param geometry Geometry to transform
  * @return Transformed geometry
  * @throws OwsExceptionReport
  */
 public Geometry transformToStorageEpsg(final Geometry geometry) throws OwsExceptionReport {
   if (geometry != null && !geometry.isEmpty()) {
     CoordinateReferenceSystem sourceCRS = getCRS(geometry.getSRID());
     int targetSRID;
     if (sourceCRS.getCoordinateSystem().getDimension() == 3) {
       targetSRID = getStorage3DEPSG();
     } else {
       targetSRID = getStorageEPSG();
     }
     return transform(geometry, targetSRID, sourceCRS, getCRS(targetSRID));
   }
   return geometry;
 }
 /**
  * Convenience method for checking coordinate reference system validity.
  *
  * @throws IllegalArgumentException if the CRS dimension is not valid.
  */
 protected void checkCoordinateReferenceSystemDimension() throws MismatchedDimensionException {
   if (crs != null) {
     final int expected = getDimension();
     final int dimension = crs.getCoordinateSystem().getDimension();
     if (dimension > expected) {
       // check dimensions and choose ReferencedEnvelope or ReferencedEnvelope3D
       // or the factory method ReferencedEnvelope.reference( CoordinateReferenceSystem )
       throw new MismatchedDimensionException(
           Errors.format(
               ErrorKeys.MISMATCHED_DIMENSION_$3,
               crs.getName().getCode(),
               new Integer(dimension),
               new Integer(expected)));
     }
   }
 }
 /**
  * Factory method to create the correct ReferencedEnvelope implementation for the provided
  * CoordinateReferenceSystem.
  *
  * @param crs CoordinateReferenceSystem used to select ReferencedEnvelope implementation
  * @return ReferencedEnvelope, ReferencedEnvelope3D if it is 3d
  */
 public static ReferencedEnvelope create(CoordinateReferenceSystem crs) {
   if (crs != null && crs.getCoordinateSystem().getDimension() > 2) {
     return new ReferencedEnvelope3D(crs);
   }
   return new ReferencedEnvelope(crs);
 }
    /**
     * Encodes the boundedBy element
     *
     * <p>e.g.:
     *
     * <pre>{@code
     * <gml:boundedBy>
     *    <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4326" axisLabels="Lat Long" uomLabels="deg deg" srsDimension="2">
     *       <gml:lowerCorner>1 1</gml:lowerCorner>
     *       <gml:upperCorner>5 3</gml:upperCorner>
     *    </gml:Envelope>
     * </gml:boundedBy>
     * }</pre>
     *
     * @param ci
     * @param gc2d
     * @param ePSGCode
     * @param axisSwap
     * @param srsName
     * @param axesNames
     * @param axisLabels
     * @throws IOException
     */
    public void handleBoundedBy(
        final GeneralEnvelope envelope,
        boolean axisSwap,
        String srsName,
        String axisLabels,
        WCSDimensionsHelper dimensionHelper)
        throws IOException {
      final CoordinateReferenceSystem crs = envelope.getCoordinateReferenceSystem();
      final CoordinateSystem cs = crs.getCoordinateSystem();

      // TODO time
      String uomLabels =
          extractUoM(crs, cs.getAxis(axisSwap ? 1 : 0).getUnit())
              + " "
              + extractUoM(crs, cs.getAxis(axisSwap ? 0 : 1).getUnit());

      // time and elevation dimensions management
      boolean hasElevation = false;
      boolean hasTime = false;
      if (dimensionHelper != null) {
        if (dimensionHelper.getElevationDimension() != null) {
          uomLabels = uomLabels + " m"; // TODO: Check elevation uom
          hasElevation = true;
        }
        if (dimensionHelper.getTimeDimension() != null) {
          uomLabels = uomLabels + " s";
          hasTime = true;
        }
      }
      final int srsDimension = cs.getDimension() + (hasElevation ? 1 : 0);

      // Setting up envelope bounds (including elevation)
      final String lower =
          new StringBuilder()
              .append(envelope.getLowerCorner().getOrdinate(axisSwap ? 1 : 0))
              .append(" ")
              .append(envelope.getLowerCorner().getOrdinate(axisSwap ? 0 : 1))
              .append(hasElevation ? " " + dimensionHelper.getBeginElevation() : "")
              .toString();

      final String upper =
          new StringBuilder()
              .append(envelope.getUpperCorner().getOrdinate(axisSwap ? 1 : 0))
              .append(" ")
              .append(envelope.getUpperCorner().getOrdinate(axisSwap ? 0 : 1))
              .append(hasElevation ? " " + dimensionHelper.getEndElevation() : "")
              .toString();

      // build the fragment
      final AttributesImpl envelopeAttrs = new AttributesImpl();
      envelopeAttrs.addAttribute("", "srsName", "srsName", "", srsName);
      envelopeAttrs.addAttribute("", "axisLabels", "axisLabels", "", axisLabels);
      envelopeAttrs.addAttribute("", "uomLabels", "uomLabels", "", uomLabels);
      envelopeAttrs.addAttribute(
          "", "srsDimension", "srsDimension", "", String.valueOf(srsDimension));
      start("gml:boundedBy");
      String envelopeName;
      if (dimensionHelper != null && (hasTime || hasElevation)) {
        envelopeName = "gml:EnvelopeWithTimePeriod";
      } else {
        envelopeName = "gml:Envelope";
      }
      start(envelopeName, envelopeAttrs);

      element("gml:lowerCorner", lower);
      element("gml:upperCorner", upper);

      if (dimensionHelper != null && hasTime) {
        element("gml:beginPosition", dimensionHelper.getBeginTime());
        element("gml:endPosition", dimensionHelper.getEndTime());
      }

      end(envelopeName);
      end("gml:boundedBy");
    }
 public CoordinateSystem getCoordinateSystem() {
   return base.getCoordinateSystem();
 }