Search in sources :

Example 11 with Extent

use of org.opengis.metadata.extent.Extent in project sis by apache.

the class ReferencingFunctions method getGeographicArea.

/**
 * Returns the domain of validity as a geographic bounding box for an identified object.
 * This method returns a 2×2 matrix:
 * the first row contains the latitude and longitude of upper left corner,
 * and the second row contains the latitude and longitude of bottom right corner.
 * Units are degrees.
 *
 * @param  codeOrPath  the code allocated by an authority, or the path to a file.
 * @return the object bounding box.
 */
@Override
public double[][] getGeographicArea(final String codeOrPath) {
    final CacheKey<GeographicBoundingBox> key = new CacheKey<>(GeographicBoundingBox.class, codeOrPath, null, null);
    GeographicBoundingBox area = key.peek();
    if (area == null) {
        final Cache.Handler<GeographicBoundingBox> handler = key.lock();
        try {
            area = handler.peek();
            if (area == null)
                try {
                    final IdentifiedObject object = getIdentifiedObject(codeOrPath, null);
                    final Object domain = IdentifiedObjects.getProperties(object).get(ReferenceSystem.DOMAIN_OF_VALIDITY_KEY);
                    if (domain instanceof Extent) {
                        area = Extents.getGeographicBoundingBox((Extent) domain);
                    }
                } catch (Exception exception) {
                    reportException("getGeographicArea", exception);
                }
        } finally {
            handler.putAndUnlock(area);
        }
    }
    if (area == null) {
        return new double[][] {};
    }
    return new double[][] { new double[] { area.getNorthBoundLatitude(), area.getWestBoundLongitude() }, new double[] { area.getSouthBoundLatitude(), area.getEastBoundLongitude() } };
}
Also used : Extent(org.opengis.metadata.extent.Extent) IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) GeographicBoundingBox(org.opengis.metadata.extent.GeographicBoundingBox) IdentifiedObject(org.opengis.referencing.IdentifiedObject) AbstractIdentifiedObject(org.apache.sis.referencing.AbstractIdentifiedObject) DataStoreException(org.apache.sis.storage.DataStoreException) IllegalArgumentException(com.sun.star.lang.IllegalArgumentException) FactoryException(org.opengis.util.FactoryException) Cache(org.apache.sis.util.collection.Cache)

Example 12 with Extent

use of org.opengis.metadata.extent.Extent in project sis by apache.

the class DefaultConcatenatedOperation method initialize.

/**
 * Performs the part of {@code DefaultConcatenatedOperations} construction that requires an iteration over
 * the sequence of coordinate operations. This method performs the following processing:
 *
 * <ul>
 *   <li>Verify the validity of the {@code operations} argument.</li>
 *   <li>Add the single operations in the {@code flattened} array.</li>
 *   <li>Set the {@link #transform} field to the concatenated transform.</li>
 *   <li>Set the {@link #coordinateOperationAccuracy} field, but only if {@code setAccuracy} is {@code true}.</li>
 * </ul>
 *
 * This method invokes itself recursively if there is nested {@code ConcatenatedOperation} instances
 * in the given list. This should not happen according ISO 19111 standard, but we try to be safe.
 *
 * <div class="section">How coordinate operation accuracy is determined</div>
 * If {@code setAccuracy} is {@code true}, then this method copies accuracy information found in the single
 * {@link Transformation} instance. This method ignores instances of other kinds for the following reason:
 * some {@link Conversion} instances declare an accuracy, which is typically close to zero. If a concatenated
 * operation contains such conversion together with a transformation with unknown accuracy, then we do not want
 * to declare "0 meter" as the concatenated operation accuracy; it would be a false information.
 * An other reason is that a concatenated operation typically contains an arbitrary amount of conversions,
 * but only one transformation. So considering only transformations usually means to pickup only one operation
 * in the given {@code operations} list, which make things clearer.
 *
 * <div class="note"><b>Note:</b>
 * according ISO 19111, the accuracy attribute is allowed only for transformations. However this restriction
 * is not enforced everywhere. For example the EPSG database declares an accuracy of 0 meter for conversions,
 * which is conceptually exact. In this class we are departing from strict interpretation of the specification
 * since we are adding accuracy informations to a concatenated operation. This departure should be considered
 * as a convenience feature only; accuracies are really relevant in transformations only.</div>
 *
 * @param  properties   the properties specified at construction time, or {@code null} if unknown.
 * @param  operations   the operations to concatenate.
 * @param  flattened    the destination list in which to add the {@code SingleOperation} instances.
 * @param  mtFactory    the math transform factory to use, or {@code null} for not performing concatenation.
 * @param  setSource    {@code true} for setting the {@link #sourceCRS} on the very first CRS (regardless if null or not).
 * @param  setAccuracy  {@code true} for setting the {@link #coordinateOperationAccuracy} field.
 * @param  setDomain    {@code true} for setting the {@link #domainOfValidity} field.
 * @return the last target CRS, regardless if null or not.
 * @throws FactoryException if the factory can not concatenate the math transforms.
 */
private CoordinateReferenceSystem initialize(final Map<String, ?> properties, final CoordinateOperation[] operations, final List<CoordinateOperation> flattened, final MathTransformFactory mtFactory, boolean setSource, boolean setAccuracy, boolean setDomain) throws FactoryException {
    CoordinateReferenceSystem previous = null;
    for (int i = 0; i < operations.length; i++) {
        final CoordinateOperation op = operations[i];
        ArgumentChecks.ensureNonNullElement("operations", i, op);
        /*
             * Verify consistency of user argument: for each coordinate operation, the number of dimensions of the
             * source CRS shall be equals to the number of dimensions of the target CRS in the previous operation.
             */
        final CoordinateReferenceSystem next = op.getSourceCRS();
        if (previous != null && next != null) {
            final int dim1 = previous.getCoordinateSystem().getDimension();
            final int dim2 = next.getCoordinateSystem().getDimension();
            if (dim1 != dim2) {
                throw new IllegalArgumentException(Errors.getResources(properties).getString(Errors.Keys.MismatchedDimension_3, "operations[" + i + "].sourceCRS", dim1, dim2));
            }
        }
        if (setSource) {
            setSource = false;
            // Take even if null.
            sourceCRS = next;
        }
        // For next iteration cycle.
        previous = op.getTargetCRS();
        /*
             * Now that we have verified the CRS dimensions, we should be able to concatenate the transforms.
             * If an operation is a nested ConcatenatedOperation (not allowed by ISO 19111, but we try to be
             * safe), we will first try to use the ConcatenatedOperation.transform as a whole.  Only if that
             * concatenated operation does not provide a transform we will concatenate its components.  Note
             * however that we traverse nested concatenated operations unconditionally at least for checking
             * its consistency.
             */
        MathTransform step = op.getMathTransform();
        if (op instanceof ConcatenatedOperation) {
            final List<? extends CoordinateOperation> children = ((ConcatenatedOperation) op).getOperations();
            @SuppressWarnings("SuspiciousToArrayCall") final CoordinateOperation[] asArray = children.toArray(new CoordinateOperation[children.size()]);
            initialize(properties, asArray, flattened, (step == null) ? mtFactory : null, false, setAccuracy, setDomain);
        } else if (!step.isIdentity()) {
            flattened.add(op);
        }
        if (mtFactory != null && step != null) {
            transform = (transform != null) ? mtFactory.createConcatenatedTransform(transform, step) : step;
        }
        /*
             * Optionally copy the coordinate operation accuracy from the transformation (or from a concatenated
             * operation on the assumption that its accuracy was computed by the same algorithm than this method).
             * See javadoc for a rational about why we take only transformations in account. If more than one
             * transformation is found, clear the collection and abandon the attempt to set the accuracy information.
             * Instead the user will get a better result by invoking PositionalAccuracyConstant.getLinearAccuracy(…)
             * since that method conservatively computes the sum of all linear accuracy.
             */
        if (setAccuracy && (op instanceof Transformation || op instanceof ConcatenatedOperation) && (PositionalAccuracyConstant.getLinearAccuracy(op) != 0)) {
            if (coordinateOperationAccuracy == null) {
                coordinateOperationAccuracy = op.getCoordinateOperationAccuracy();
            } else {
                coordinateOperationAccuracy = null;
                setAccuracy = false;
            }
        }
        /*
             * Optionally copy the domain of validity, provided that it is the same for all component.
             * Current implementation does not try to compute the intersection of all components.
             */
        if (setDomain) {
            final Extent domain = op.getDomainOfValidity();
            if (domain != null) {
                if (domainOfValidity == null) {
                    domainOfValidity = domain;
                } else if (!domain.equals(domainOfValidity)) {
                    domainOfValidity = null;
                    setDomain = false;
                }
            }
        }
    }
    return previous;
}
Also used : Transformation(org.opengis.referencing.operation.Transformation) MathTransform(org.opengis.referencing.operation.MathTransform) Extent(org.opengis.metadata.extent.Extent) CoordinateOperation(org.opengis.referencing.operation.CoordinateOperation) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) ConcatenatedOperation(org.opengis.referencing.operation.ConcatenatedOperation)

Example 13 with Extent

use of org.opengis.metadata.extent.Extent in project sis by apache.

the class StoreTest method testGetMetadata.

/**
 * Tests {@link Store#getMetadata()}.
 *
 * @throws DataStoreException if an error occurred while parsing the data.
 */
@Test
public void testGetMetadata() throws DataStoreException {
    final Metadata metadata;
    try (Store store = open()) {
        metadata = store.getMetadata();
    }
    final Extent extent = getSingleton(((AbstractIdentification) getSingleton(metadata.getIdentificationInfo())).getExtents());
    final GeographicBoundingBox bbox = (GeographicBoundingBox) getSingleton(extent.getGeographicElements());
    assertEquals("westBoundLongitude", 50.23, bbox.getWestBoundLongitude(), STRICT);
    assertEquals("eastBoundLongitude", 50.31, bbox.getEastBoundLongitude(), STRICT);
    assertEquals("southBoundLatitude", 9.23, bbox.getSouthBoundLatitude(), STRICT);
    assertEquals("northBoundLatitude", 9.27, bbox.getNorthBoundLatitude(), STRICT);
    assertTrue("Should not have a vertical extent.", extent.getVerticalElements().isEmpty());
}
Also used : Extent(org.opengis.metadata.extent.Extent) Metadata(org.opengis.metadata.Metadata) GeographicBoundingBox(org.opengis.metadata.extent.GeographicBoundingBox) Test(org.junit.Test)

Aggregations

Extent (org.opengis.metadata.extent.Extent)13 InternationalString (org.opengis.util.InternationalString)6 Test (org.junit.Test)4 GeographicBoundingBox (org.opengis.metadata.extent.GeographicBoundingBox)4 Locale (java.util.Locale)3 ResponsibleParty (org.opengis.metadata.citation.ResponsibleParty)3 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)3 FactoryException (org.opengis.util.FactoryException)3 IllegalArgumentException (com.sun.star.lang.IllegalArgumentException)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 CheckedArrayList (org.apache.sis.internal.util.CheckedArrayList)2 DefaultExtent (org.apache.sis.metadata.iso.extent.DefaultExtent)2 DefaultGeographicBoundingBox (org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox)2 DefaultDataIdentification (org.apache.sis.metadata.iso.identification.DefaultDataIdentification)2 AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)2 DataStoreException (org.apache.sis.storage.DataStoreException)2 SimpleInternationalString (org.apache.sis.util.iso.SimpleInternationalString)2 VerticalExtent (org.opengis.metadata.extent.VerticalExtent)2 CoordinateOperation (org.opengis.referencing.operation.CoordinateOperation)2