Search in sources :

Example 26 with FactoryException

use of org.opengis.util.FactoryException in project sis by apache.

the class MathTransformContext method getMatrix.

/**
 * Returns the normalization or denormalization matrix.
 */
@Override
@SuppressWarnings("fallthrough")
public Matrix getMatrix(final MatrixRole role) throws FactoryException {
    final CoordinateSystem cs;
    boolean inverse = false;
    double rotation;
    switch(role) {
        default:
            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "role", role));
        // Fall through
        case INVERSE_NORMALIZATION:
            inverse = true;
        case NORMALIZATION:
            rotation = sourceMeridian;
            cs = getSourceCS();
            break;
        // Fall through
        case INVERSE_DENORMALIZATION:
            inverse = true;
        case DENORMALIZATION:
            inverse = !inverse;
            rotation = targetMeridian;
            cs = getTargetCS();
            break;
    }
    Matrix matrix = super.getMatrix(role);
    if (rotation != 0) {
        if (inverse)
            rotation = -rotation;
        MatrixSIS cm = MatrixSIS.castOrCopy(matrix);
        if (cs instanceof CartesianCS) {
            rotation = Math.toRadians(rotation);
            final Matrix4 rot = new Matrix4();
            rot.m00 = rot.m11 = Math.cos(rotation);
            rot.m01 = -(rot.m10 = Math.sin(rotation));
            if (inverse) {
                // Apply the rotation after denormalization.
                matrix = Matrices.multiply(rot, cm);
            } else {
                // Apply the rotation before normalization.
                matrix = cm.multiply(rot);
            }
        } else if (cs == null || cs instanceof EllipsoidalCS || cs instanceof SphericalCS) {
            final Double value = rotation;
            if (inverse) {
                // Longitude is the first axis in normalized CS.
                cm.convertBefore(0, null, value);
            } else {
                cm.convertAfter(0, null, value);
            }
            matrix = cm;
        } else {
            throw new FactoryException(Errors.format(Errors.Keys.UnsupportedCoordinateSystem_1, cs.getName()));
        }
    }
    return matrix;
}
Also used : CartesianCS(org.opengis.referencing.cs.CartesianCS) SphericalCS(org.opengis.referencing.cs.SphericalCS) Matrix(org.opengis.referencing.operation.Matrix) FactoryException(org.opengis.util.FactoryException) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS) MatrixSIS(org.apache.sis.referencing.operation.matrix.MatrixSIS) Matrix4(org.apache.sis.referencing.operation.matrix.Matrix4)

Example 27 with FactoryException

use of org.opengis.util.FactoryException in project sis by apache.

the class LocalizationGridBuilder method create.

/**
 * Creates a transform from the source points to the target points.
 * This method assumes that source points are precise and all uncertainty is in the target points.
 * If this transform is close enough to an affine transform, then an instance of {@link LinearTransform} is returned.
 *
 * @param  factory  the factory to use for creating the transform, or {@code null} for the default factory.
 *                  The {@link MathTransformFactory#createAffineTransform(Matrix)} method of that factory
 *                  shall return {@link LinearTransform} instances.
 * @return the transform from source to target points.
 * @throws FactoryException if the transform can not be created,
 *         for example because the target points have not be specified.
 */
@Override
public MathTransform create(final MathTransformFactory factory) throws FactoryException {
    final LinearTransform gridToCoord = linear.create(factory);
    /*
         * Make a first check about whether the result of above LinearTransformBuilder.create() call
         * can be considered a good fit. If true, then we may return the linear transform directly.
         */
    boolean isExact = true;
    boolean isLinear = true;
    for (final double c : linear.correlation()) {
        isExact &= (c == 1);
        if (c < 0.9999) {
            // Empirical threshold (may need to be revisited).
            isLinear = false;
            break;
        }
    }
    if (isExact) {
        return MathTransforms.concatenate(sourceToGrid, gridToCoord);
    }
    final int width = linear.gridSize(0);
    final int height = linear.gridSize(1);
    final int tgtDim = gridToCoord.getTargetDimensions();
    final double[] residual = new double[tgtDim * linear.gridLength];
    final double[] point = new double[tgtDim + 1];
    double gridPrecision = precision;
    try {
        /*
             * If the user specified a precision, we need to convert it from source units to grid units.
             * We convert each dimension separately, then retain the largest magnitude of vector results.
             */
        if (gridPrecision > 0 && !sourceToGrid.isIdentity()) {
            final double[] vector = new double[sourceToGrid.getSourceDimensions()];
            final double[] offset = new double[sourceToGrid.getTargetDimensions()];
            double converted = 0;
            for (int i = 0; i < vector.length; i++) {
                vector[i] = precision;
                sourceToGrid.deltaTransform(vector, 0, offset, 0, 1);
                final double length = MathFunctions.magnitude(offset);
                if (length > converted)
                    converted = length;
                vector[i] = 0;
            }
            gridPrecision = converted;
        }
        /*
             * Compute the residuals, i.e. the differences between the coordinates that we get by a linear
             * transformation and the coordinates that we want to get. If at least one residual is greater
             * than the desired precision,  then the returned MathTransform will need to apply corrections
             * after linear transforms. Those corrections will be done by InterpolatedTransform.
             */
        final MatrixSIS coordToGrid = MatrixSIS.castOrCopy(gridToCoord.inverse().getMatrix());
        final DirectPosition2D src = new DirectPosition2D();
        point[tgtDim] = 1;
        for (int k = 0, y = 0; y < height; y++) {
            src.y = y;
            tmp[1] = y;
            for (int x = 0; x < width; x++) {
                src.x = x;
                tmp[0] = x;
                // Expected position.
                linear.getControlPoint2D(tmp, point);
                // As grid coordinate.
                double[] grid = coordToGrid.multiply(point);
                isLinear &= (residual[k++] = grid[0] - x) <= gridPrecision;
                isLinear &= (residual[k++] = grid[1] - y) <= gridPrecision;
            }
        }
    } catch (TransformException e) {
        // Should never happen.
        throw new FactoryException(e);
    }
    if (isLinear) {
        return MathTransforms.concatenate(sourceToGrid, gridToCoord);
    }
    return InterpolatedTransform.createGeodeticTransformation(nonNull(factory), new ResidualGrid(sourceToGrid, gridToCoord, width, height, tgtDim, residual, (gridPrecision > 0) ? gridPrecision : DEFAULT_PRECISION));
}
Also used : FactoryException(org.opengis.util.FactoryException) NoninvertibleTransformException(org.opengis.referencing.operation.NoninvertibleTransformException) TransformException(org.opengis.referencing.operation.TransformException) LinearTransform(org.apache.sis.referencing.operation.transform.LinearTransform) DirectPosition2D(org.apache.sis.geometry.DirectPosition2D) MatrixSIS(org.apache.sis.referencing.operation.matrix.MatrixSIS)

Example 28 with FactoryException

use of org.opengis.util.FactoryException in project sis by apache.

the class Proj4Factory method createCRS.

/**
 * Creates a coordinate reference system from the given {@literal Proj.4} wrapper.
 * The given {@code pj} will be stored as the CRS identifier.
 *
 * @param  pj          the Proj.4 object to wrap.
 * @param  withHeight  whether to include a height axis.
 * @throws IllegalArgumentException if a Proj.4 parameter value can not be parsed or assigned.
 * @throws ParserException if a unit symbol can not be parsed.
 */
private CoordinateReferenceSystem createCRS(final PJ pj, final boolean withHeight) throws FactoryException {
    final PJ.Type type = pj.getType();
    final boolean geographic = PJ.Type.GEOGRAPHIC.equals(type);
    final boolean geocentric = PJ.Type.GEOCENTRIC.equals(type);
    final Proj4Parser parser = new Proj4Parser(pj.getCode());
    final String dir = parser.value("axis", "enu");
    final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[geocentric | withHeight ? dir.length() : 2];
    for (int i = 0; i < axes.length; i++) {
        final char d = Character.toLowerCase(dir.charAt(i));
        char abbreviation = Character.toUpperCase(d);
        boolean vertical = false;
        final AxisDirection c;
        final String name;
        if (geocentric)
            switch(d) {
                case 'e':
                    c = AxisDirection.GEOCENTRIC_X;
                    name = "Geocentric X";
                    break;
                case 'n':
                    c = AxisDirection.GEOCENTRIC_Y;
                    name = "Geocentric Y";
                    break;
                case 'u':
                    c = AxisDirection.GEOCENTRIC_Z;
                    name = "Geocentric Z";
                    break;
                default:
                    c = AxisDirection.OTHER;
                    name = "Unknown";
                    break;
            }
        else
            switch(d) {
                case 'e':
                    c = AxisDirection.EAST;
                    name = geographic ? "Geodetic longitude" : "Easting";
                    break;
                case 'w':
                    c = AxisDirection.WEST;
                    name = geographic ? "Geodetic longitude" : "Westing";
                    break;
                case 'n':
                    c = AxisDirection.NORTH;
                    name = geographic ? "Geodetic latitude" : "Northing";
                    break;
                case 's':
                    c = AxisDirection.SOUTH;
                    name = geographic ? "Geodetic latitude" : "Southing";
                    break;
                case 'u':
                    c = AxisDirection.UP;
                    name = "Height";
                    vertical = true;
                    abbreviation = 'h';
                    break;
                case 'd':
                    c = AxisDirection.DOWN;
                    name = "Depth";
                    vertical = true;
                    break;
                default:
                    c = AxisDirection.OTHER;
                    name = "Unknown";
                    break;
            }
        if (geographic && AxisDirections.isCardinal(c)) {
            abbreviation = (d == 'e' || d == 'w') ? 'λ' : 'φ';
        }
        final Unit<?> unit = (vertical || !geographic) ? parser.unit(vertical) : Units.DEGREE;
        axes[i] = csFactory.createCoordinateSystemAxis(identifier(name), String.valueOf(abbreviation).intern(), c, unit);
    }
    /*
         * At this point we got the coordinate system axes. Now create the CRS. The given Proj.4 object
         * will be stored as the CRS identifier for allowing OperationFactory to get it back before to
         * attempt to create a new one for a given CRS.
         */
    final Map<String, Object> csName = identifier(UNNAMED);
    final Map<String, Object> name = new HashMap<>(identifier(parser.name(type == PJ.Type.PROJECTED)));
    name.put(CoordinateReferenceSystem.IDENTIFIERS_KEY, pj);
    switch(type) {
        case GEOGRAPHIC:
            {
                return crsFactory.createGeographicCRS(name, createDatum(pj, parser), withHeight ? csFactory.createEllipsoidalCS(csName, axes[0], axes[1], axes[2]) : csFactory.createEllipsoidalCS(csName, axes[0], axes[1]));
            }
        case GEOCENTRIC:
            {
                return crsFactory.createGeocentricCRS(name, createDatum(pj, parser), csFactory.createCartesianCS(csName, axes[0], axes[1], axes[2]));
            }
        case PROJECTED:
            {
                final PJ base = unique(new PJ(pj));
                final CoordinateReferenceSystem baseCRS = createCRS(base, withHeight);
                final Transform tr = new Transform(pj, withHeight, base, withHeight);
                /*
                 * Try to convert the Proj.4 parameters into OGC parameters in order to have a less opaque structure.
                 * Failure to perform this conversion will not cause a failure to create the ProjectedCRS. After all,
                 * maybe the user invokes this method for using a map projection not yet supported by Apache SIS.
                 * Instead, fallback on the more opaque Transform.METHOD description. Apache SIS will not be able to
                 * perform analysis on those parameters, but it will not prevent the Proj.4 transformation to work.
                 */
                OperationMethod method;
                ParameterValueGroup parameters;
                try {
                    method = parser.method(opFactory());
                    parameters = parser.parameters();
                } catch (IllegalArgumentException | FactoryException e) {
                    Logging.recoverableException(Logging.getLogger(Modules.GDAL), Proj4Factory.class, "createProjectedCRS", e);
                    method = Transform.METHOD;
                    // Will let Apache SIS infers the parameters from the Transform instance.
                    parameters = null;
                }
                final Conversion fromBase = new DefaultConversion(name, method, tr, parameters);
                return crsFactory.createProjectedCRS(name, (GeographicCRS) baseCRS, fromBase, withHeight ? csFactory.createCartesianCS(csName, axes[0], axes[1], axes[2]) : csFactory.createCartesianCS(csName, axes[0], axes[1]));
            }
        default:
            {
                throw new FactoryException(Errors.getResources(defaultProperties).getString(Errors.Keys.UnknownEnumValue_2, type, PJ.Type.class));
            }
    }
}
Also used : WeakValueHashMap(org.apache.sis.util.collection.WeakValueHashMap) HashMap(java.util.HashMap) ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) UnavailableFactoryException(org.apache.sis.referencing.factory.UnavailableFactoryException) FactoryException(org.opengis.util.FactoryException) DefaultConversion(org.apache.sis.referencing.operation.DefaultConversion) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) DefaultConversion(org.apache.sis.referencing.operation.DefaultConversion) IdentifiedObject(org.opengis.referencing.IdentifiedObject)

Example 29 with FactoryException

use of org.opengis.util.FactoryException in project sis by apache.

the class MTFactory method createFromWKT.

/**
 * Parses the given Well Known Text (version 1) into a math transform.
 */
@Override
public synchronized MathTransform createFromWKT(final String wkt) throws FactoryException {
    ArgumentChecks.ensureNonEmpty("wkt", wkt);
    if (parser == null) {
        parser = new WKTFormat(null, null);
        parser.setFactory(CRSAuthorityFactory.class, this);
        parser.setFactory(MathTransformFactory.class, this);
        parser.setFactory(CoordinateOperationFactory.class, this);
    }
    try {
        return (MathTransform) parser.parseObject(wkt);
    } catch (ParseException | ClassCastException e) {
        throw new FactoryException(e);
    }
}
Also used : MathTransform(org.opengis.referencing.operation.MathTransform) FactoryException(org.opengis.util.FactoryException) ParseException(java.text.ParseException) WKTFormat(org.apache.sis.io.wkt.WKTFormat)

Example 30 with FactoryException

use of org.opengis.util.FactoryException in project sis by apache.

the class GeoTiffStore method getMetadata.

/**
 * Returns information about the dataset as a whole. The returned metadata object can contain information
 * such as the spatiotemporal extent of the dataset, contact information about the creator or distributor,
 * data quality, usage constraints and more.
 *
 * @return information about the dataset.
 * @throws DataStoreException if an error occurred while reading the data.
 */
@Override
public synchronized Metadata getMetadata() throws DataStoreException {
    if (metadata == null) {
        final Reader reader = reader();
        final MetadataBuilder builder = reader.metadata;
        try {
            builder.setFormat(Constants.GEOTIFF);
        } catch (MetadataStoreException e) {
            warning(null, e);
        }
        builder.addEncoding(encoding, MetadataBuilder.Scope.METADATA);
        builder.addResourceScope(ScopeCode.valueOf("COVERAGE"), null);
        final Locale locale = getLocale();
        int n = 0;
        try {
            ImageFileDirectory dir;
            while ((dir = reader.getImageFileDirectory(n++)) != null) {
                dir.completeMetadata(builder, locale);
            }
        } catch (IOException e) {
            throw new DataStoreException(errors().getString(Errors.Keys.CanNotRead_1, reader.input.filename), e);
        } catch (FactoryException | ArithmeticException e) {
            throw new DataStoreContentException(getLocale(), Constants.GEOTIFF, reader.input.filename, null).initCause(e);
        }
        /*
             * Add the filename as an identifier only if the input was something convertible to URI (URL, File or Path),
             * otherwise reader.input.filename may not be useful; it may be just the InputStream classname. If the TIFF
             * file did not specified any ImageDescription tag, then we will had the filename as a title instead than an
             * identifier because the title is mandatory in ISO 19115 metadata.
             */
        if (location != null) {
            builder.addTitleOrIdentifier(IOUtilities.filenameWithoutExtension(reader.input.filename), MetadataBuilder.Scope.ALL);
        }
        metadata = builder.build(true);
    }
    return metadata;
}
Also used : Locale(java.util.Locale) MetadataStoreException(org.apache.sis.metadata.sql.MetadataStoreException) DataStoreException(org.apache.sis.storage.DataStoreException) MetadataBuilder(org.apache.sis.internal.storage.MetadataBuilder) DataStoreContentException(org.apache.sis.storage.DataStoreContentException) FactoryException(org.opengis.util.FactoryException) IOException(java.io.IOException)

Aggregations

FactoryException (org.opengis.util.FactoryException)84 TransformException (org.opengis.referencing.operation.TransformException)27 GeometryWrapper (org.apache.jena.geosparql.implementation.GeometryWrapper)21 MismatchedDimensionException (org.opengis.geometry.MismatchedDimensionException)19 ExprEvalException (org.apache.jena.sparql.expr.ExprEvalException)17 MathTransform (org.opengis.referencing.operation.MathTransform)15 DatatypeFormatException (org.apache.jena.datatypes.DatatypeFormatException)12 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)10 IdentifiedObject (org.opengis.referencing.IdentifiedObject)8 Envelope (org.locationtech.jts.geom.Envelope)7 ArrayList (java.util.ArrayList)6 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)6 NoninvertibleTransformException (org.opengis.referencing.operation.NoninvertibleTransformException)6 Literal (org.apache.jena.rdf.model.Literal)5 UnavailableFactoryException (org.apache.sis.referencing.factory.UnavailableFactoryException)5 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)5 ParseException (java.text.ParseException)4 AbstractIdentifiedObject (org.apache.sis.referencing.AbstractIdentifiedObject)4 BackingStoreException (org.apache.sis.util.collection.BackingStoreException)4 Test (org.junit.Test)4