Search in sources :

Example 36 with ProjectedCRS

use of org.opengis.referencing.crs.ProjectedCRS in project sis by apache.

the class DefaultProjectedCRSTest method testWKT1.

/**
 * Tests WKT 1 formatting.
 *
 * @throws FactoryException if the CRS creation failed.
 */
@Test
@DependsOnMethod("testConstructor")
public void testWKT1() throws FactoryException {
    final ProjectedCRS crs = create(HardCodedCRS.NTF);
    assertWktEquals(Convention.WKT1, "PROJCS[“NTF (Paris) / Lambert zone II”,\n" + "  GEOGCS[“NTF (Paris)”,\n" + "    DATUM[“Nouvelle Triangulation Francaise”,\n" + "      SPHEROID[“NTF”, 6378249.2, 293.4660212936269]],\n" + "      PRIMEM[“Paris”, 2.5969213],\n" + "    UNIT[“grad”, 0.015707963267948967],\n" + "    AXIS[“Longitude”, EAST],\n" + "    AXIS[“Latitude”, NORTH]],\n" + "  PROJECTION[“Lambert_Conformal_Conic_1SP”, AUTHORITY[“EPSG”, “9801”]],\n" + // In grads
    "  PARAMETER[“latitude_of_origin”, 52.0],\n" + "  PARAMETER[“central_meridian”, 0.0],\n" + "  PARAMETER[“scale_factor”, 0.99987742],\n" + "  PARAMETER[“false_easting”, 600000.0],\n" + "  PARAMETER[“false_northing”, 2200000.0],\n" + "  UNIT[“metre”, 1],\n" + "  AXIS[“Easting”, EAST],\n" + "  AXIS[“Northing”, NORTH],\n" + "  AUTHORITY[“EPSG”, “27572”]]", crs);
}
Also used : ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Example 37 with ProjectedCRS

use of org.opengis.referencing.crs.ProjectedCRS in project sis by apache.

the class DefaultProjectedCRSTest method testConstructor.

/**
 * Creates a projected CRS and verifies its parameters.
 * Verifies also that the constructor does not accept invalid base CRS.
 *
 * @throws FactoryException if the CRS creation failed.
 */
@Test
public void testConstructor() throws FactoryException {
    final ProjectedCRS crs = create(HardCodedCRS.NTF);
    verifyParameters(crs.getConversionFromBase().getParameterValues());
    try {
        create(HardCodedCRS.WGS84_3D);
        fail("Should not accept a three-dimensional base geodetic CRS.");
    } catch (InvalidGeodeticParameterException e) {
        final String message = e.getMessage();
        assertTrue(message, message.contains("Lambert Conic Conformal (1SP)"));
    }
}
Also used : InvalidGeodeticParameterException(org.apache.sis.referencing.factory.InvalidGeodeticParameterException) ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) Test(org.junit.Test)

Example 38 with ProjectedCRS

use of org.opengis.referencing.crs.ProjectedCRS in project sis by apache.

the class Proj4 method definition.

/**
 * Infers a {@literal Proj.4} definition from the given projected, geographic or geocentric coordinate reference system.
 * This method does not need the Proj.4 native library; it can be used in a pure Java application.
 * However the returned definition string may differ depending on whether the Proj.4 library is available or not.
 *
 * @param  crs  the coordinate reference system for which to create a Proj.4 definition.
 * @return the definition of the given CRS in a Proj.4 format.
 * @throws FactoryException if the Proj.4 definition string can not be created from the given CRS.
 */
public static String definition(final CoordinateReferenceSystem crs) throws FactoryException {
    ArgumentChecks.ensureNonNull("crs", crs);
    /*
         * If the given CRS object is associated to a Proj.4 structure, let Proj.4 formats itself
         * the definition string. Note that this operation may fail if there is no Proj.4 library
         * in the current system, or no JNI bindings to that library.
         */
    try {
        for (final Identifier id : crs.getIdentifiers()) {
            if (id instanceof PJ) {
                return ((PJ) id).getCode();
            }
        }
    } catch (UnsatisfiedLinkError e) {
        // Thrown the first time that we try to use the library.
        Logging.unexpectedException(Logging.getLogger(Modules.GDAL), Proj4.class, "definition", e);
    } catch (NoClassDefFoundError e) {
        // Thrown on all attempts after the first one.
        Logging.recoverableException(Logging.getLogger(Modules.GDAL), Proj4.class, "definition", e);
    }
    /*
         * If we found no Proj.4 structure, formats the definition string ourself. The string may differ from
         * what Proj.4 would have given. In particular, we do not provide "+init=" or "+datum=" parameter.
         * But the definition should still be semantically equivalent.
         */
    final String method;
    final GeodeticDatum datum;
    final ParameterValueGroup parameters;
    final CoordinateSystem cs = crs.getCoordinateSystem();
    if (crs instanceof GeodeticCRS) {
        if (cs instanceof EllipsoidalCS) {
            method = "latlon";
        } else if (cs instanceof CartesianCS) {
            method = "geocent";
        } else {
            throw new FactoryException(Errors.format(Errors.Keys.UnsupportedCoordinateSystem_1, cs.getClass()));
        }
        datum = ((GeodeticCRS) crs).getDatum();
        parameters = null;
    } else if (crs instanceof ProjectedCRS) {
        Projection c = ((ProjectedCRS) crs).getConversionFromBase();
        datum = ((ProjectedCRS) crs).getDatum();
        method = name(c.getMethod());
        parameters = c.getParameterValues();
    } else {
        throw new FactoryException(Errors.format(Errors.Keys.UnsupportedType_1, crs.getClass()));
    }
    /*
         * Append the map projection parameters. Those parameters may include axis lengths (a and b),
         * but not necessarily. If axis lengths are specified, then we will ignore the Ellipsoid instance
         * associated to the CRS.
         */
    final StringBuilder definition = new StringBuilder(100);
    definition.append(Proj4Factory.PROJ_PARAM).append(method);
    boolean hasSemiMajor = false;
    boolean hasSemiMinor = false;
    if (parameters != null) {
        definition.append(Proj4Factory.STANDARD_OPTIONS);
        for (final GeneralParameterValue parameter : parameters.values()) {
            if (parameter instanceof ParameterValue<?>) {
                final ParameterValue<?> pv = (ParameterValue<?>) parameter;
                final Object value;
                Unit<?> unit = pv.getUnit();
                if (unit != null) {
                    unit = Units.isAngular(unit) ? Units.DEGREE : unit.getSystemUnit();
                    // Always in metres or degrees.
                    value = pv.doubleValue(unit);
                } else {
                    value = pv.getValue();
                    if (value == null) {
                        continue;
                    }
                }
                final String pn = name(parameter.getDescriptor());
                hasSemiMajor |= pn.equals("a");
                hasSemiMinor |= pn.equals("b");
                definition.append(" +").append(pn).append('=').append(value);
            }
        }
    }
    /*
         * Append datum information: axis lengths if they were not part of the parameters, then prime meridian.
         */
    final Ellipsoid ellipsoid = datum.getEllipsoid();
    if (!hasSemiMajor)
        definition.append(" +a=").append(ellipsoid.getSemiMajorAxis());
    if (!hasSemiMinor)
        definition.append(" +b=").append(ellipsoid.getSemiMinorAxis());
    final PrimeMeridian pm = datum.getPrimeMeridian();
    if (pm != null) {
        double lon = pm.getGreenwichLongitude();
        final Unit<Angle> unit = pm.getAngularUnit();
        if (unit != null) {
            lon = unit.getConverterTo(Units.DEGREE).convert(lon);
        }
        definition.append(" +pm=").append(lon);
    }
    /*
         * Appends axis directions. This method always format a vertical direction (up or down)
         * even if the coordinate system is two-dimensional, because Proj.4 seems to require it.
         * Also extract axis units in the process.
         */
    // Horizontal at index 0, vertical at index 1.
    final Unit<?>[] units = new Unit<?>[2];
    boolean validCS = true;
    definition.append(' ').append(Proj4Factory.AXIS_ORDER_PARAM);
    final int dimension = Math.min(cs.getDimension(), 3);
    boolean hasVertical = false;
    for (int i = 0; i < dimension; i++) {
        final CoordinateSystemAxis axis = cs.getAxis(i);
        final AxisDirection dir = axis.getDirection();
        int unitIndex = 0;
        if (!AxisDirections.isCardinal(dir)) {
            if (!AxisDirections.isVertical(dir)) {
                throw new FactoryException(Errors.format(Errors.Keys.UnsupportedAxisDirection_1, dir));
            }
            hasVertical = true;
            unitIndex = 1;
        }
        final Unit<?> old = units[unitIndex];
        units[unitIndex] = axis.getUnit();
        validCS &= (old == null || old.equals(units[unitIndex]));
        definition.appendCodePoint(Character.toLowerCase(dir.name().codePointAt(0)));
    }
    if (!hasVertical && dimension < 3) {
        // Add a UP direction if not already present.
        definition.append('u');
    }
    /*
         * Append units of measurement, then verify the coordinate system validity.
         */
    for (int i = 0; i < units.length; i++) {
        final Unit<?> unit = units[i];
        if (unit != null && !unit.equals(Units.DEGREE) && !unit.equals(Units.METRE)) {
            validCS &= Units.isLinear(unit);
            definition.append(" +");
            // "+vto_meter" parameter.
            if (i == 1)
                definition.append('v');
            definition.append("to_meter=").append(Units.toStandardUnit(unit));
        }
    }
    /*
         * Append the "+towgs84" element if any. This is the last piece of information.
         * Note that the use of a "+towgs84" parameter is an "early binding" approach,
         * which is usually not recommended. But Proj4 works that way.
         */
    if (validCS) {
        if (datum instanceof DefaultGeodeticDatum) {
            for (final BursaWolfParameters bwp : ((DefaultGeodeticDatum) datum).getBursaWolfParameters()) {
                if (Utilities.equalsIgnoreMetadata(CommonCRS.WGS84.datum(), bwp.getTargetDatum())) {
                    definition.append(" +towgs84=").append(bwp.tX).append(',').append(bwp.tY).append(',').append(bwp.tZ);
                    if (!bwp.isTranslation()) {
                        definition.append(',').append(bwp.rX).append(',').append(bwp.rY).append(',').append(bwp.rZ).append(',').append(bwp.dS);
                    }
                    break;
                }
            }
        }
        return definition.toString();
    }
    /*
         * If we reach this point, we detected a coordinate system that we can not format as a
         * Proj.4 definition string. Format an error message with axis directions and units.
         */
    definition.setLength(0);
    definition.append('(');
    for (int i = 0; i < units.length; i++) {
        final CoordinateSystemAxis axis = cs.getAxis(i);
        if (i != 0)
            definition.append(", ");
        definition.append(axis.getUnit()).append(' ').append(Types.getCodeName(axis.getDirection()));
    }
    throw new FactoryException(Errors.format(Errors.Keys.IllegalCoordinateSystem_1, definition.append(')')));
}
Also used : ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) UnavailableFactoryException(org.apache.sis.referencing.factory.UnavailableFactoryException) FactoryException(org.opengis.util.FactoryException) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) Projection(org.opengis.referencing.operation.Projection) CoordinateSystemAxis(org.opengis.referencing.cs.CoordinateSystemAxis) Unit(javax.measure.Unit) Identifier(org.opengis.metadata.Identifier) AxisDirection(org.opengis.referencing.cs.AxisDirection) EllipsoidalCS(org.opengis.referencing.cs.EllipsoidalCS) CartesianCS(org.opengis.referencing.cs.CartesianCS) GeneralParameterValue(org.opengis.parameter.GeneralParameterValue) ParameterValue(org.opengis.parameter.ParameterValue) GeneralParameterValue(org.opengis.parameter.GeneralParameterValue) GeodeticDatum(org.opengis.referencing.datum.GeodeticDatum) DefaultGeodeticDatum(org.apache.sis.referencing.datum.DefaultGeodeticDatum) GeodeticCRS(org.opengis.referencing.crs.GeodeticCRS) PrimeMeridian(org.opengis.referencing.datum.PrimeMeridian) ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) Angle(javax.measure.quantity.Angle) DefaultGeodeticDatum(org.apache.sis.referencing.datum.DefaultGeodeticDatum) IdentifiedObject(org.opengis.referencing.IdentifiedObject) BursaWolfParameters(org.apache.sis.referencing.datum.BursaWolfParameters) Ellipsoid(org.opengis.referencing.datum.Ellipsoid)

Example 39 with ProjectedCRS

use of org.opengis.referencing.crs.ProjectedCRS in project sis by apache.

the class Proj4FactoryTest method testTransform.

/**
 * Tests the transformation from {@code "+init=epsg:4326"} to {@code "+init=epsg:3395"}.
 *
 * @throws FactoryException if an error occurred while creating the CRS objects.
 * @throws TransformException if an error occurred while projecting a test point.
 */
@Test
public void testTransform() throws FactoryException, TransformException {
    final Proj4Factory factory = Proj4Factory.INSTANCE;
    final GeographicCRS sourceCRS = factory.createGeographicCRS("+init=epsg:4326");
    final ProjectedCRS targetCRS = factory.createProjectedCRS("+init=epsg:3395");
    final CoordinateOperation op = factory.createOperation(sourceCRS, targetCRS, true);
    assertInstanceOf("createOperation", Conversion.class, op);
    testMercatorProjection(op.getMathTransform());
}
Also used : ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) CoordinateOperation(org.opengis.referencing.operation.CoordinateOperation) GeographicCRS(org.opengis.referencing.crs.GeographicCRS) Test(org.junit.Test)

Example 40 with ProjectedCRS

use of org.opengis.referencing.crs.ProjectedCRS in project sis by apache.

the class LandsatReader method getMetadata.

/**
 * Returns the metadata about the resources described in the Landsat file.
 * The {@link #read(BufferedReader)} method must be invoked at least once before.
 *
 * @throws FactoryException if an error occurred while creating the Coordinate Reference System.
 */
final Metadata getMetadata() throws FactoryException {
    metadata.addLanguage(Locale.ENGLISH, MetadataBuilder.Scope.METADATA);
    metadata.addResourceScope(ScopeCode.valueOf("COVERAGE"), null);
    try {
        flushSceneTime();
    } catch (DateTimeException e) {
        // May happen if the SCENE_CENTER_TIME attribute was found without DATE_ACQUIRED.
        warning(null, null, e);
    }
    /*
         * Create the Coordinate Reference System. We normally have only one of UTM or Polar Stereographic,
         * but this block is nevertheless capable to take both (such metadata are likely to be invalid, but
         * we can not guess which of the two CRS is correct).
         */
    if (datum != null) {
        if (utmZone > 0) {
            metadata.addReferenceSystem(datum.universal(1, TransverseMercator.Zoner.UTM.centralMeridian(utmZone)));
        }
        if (projection != null) {
            final double sp = projection.parameter(Constants.STANDARD_PARALLEL_1).doubleValue();
            ProjectedCRS crs = (ProjectedCRS) CRS.forCode(Constants.EPSG + ":" + (// Standard parallel = 71°N
            sp >= 0 ? // Standard parallel = 71°N
            Constants.EPSG_ARCTIC_POLAR_STEREOGRAPHIC : // Standard parallel = 71°S
            Constants.EPSG_ANTARCTIC_POLAR_STEREOGRAPHIC));
            if (datum != CommonCRS.WGS84 || Math.abs(sp) != 71 || projection.parameter(Constants.FALSE_EASTING).doubleValue() != 0 || projection.parameter(Constants.FALSE_NORTHING).doubleValue() != 0 || projection.parameter(Constants.CENTRAL_MERIDIAN).doubleValue() != 0) {
                crs = ReferencingUtilities.createProjectedCRS(Collections.singletonMap(ProjectedCRS.NAME_KEY, "Polar stereographic"), datum.geographic(), projection, crs.getCoordinateSystem());
            }
            metadata.addReferenceSystem(crs);
        }
    }
    /*
         * Set information about envelope (or geographic area) and grid size.
         */
    if (toBoundingBox(GEOGRAPHIC)) {
        metadata.addExtent(corners, GEOGRAPHIC);
    }
    for (int i = 0; i < gridSizes.length; i += DIM) {
        final int width = gridSizes[i];
        final int height = gridSizes[i + 1];
        if (width != 0 || height != 0) {
            metadata.newGridRepresentation(MetadataBuilder.GridType.GEORECTIFIED);
            metadata.setAxisName(0, DimensionNameType.SAMPLE);
            metadata.setAxisName(1, DimensionNameType.LINE);
            metadata.setAxisLength(0, width);
            metadata.setAxisLength(1, height);
        }
    }
    /*
         * At this point we are done configuring he metadata builder. Creates the ISO 19115 metadata instance,
         * then continue adding some more specific metadata elements by ourself. For example information about
         * bands are splitted in 3 different AttributeGroups based on their grid size.
         */
    final DefaultMetadata result = metadata.build(false);
    if (result != null) {
        /*
             * Set information about all non-null bands. The bands are categorized in three groups:
             * PANCHROMATIC, REFLECTIVE and THERMAL. The group in which each band belong is encoded
             * in the BAND_GROUPS bitmask.
             */
        final DefaultCoverageDescription content = (DefaultCoverageDescription) singletonOrNull(result.getContentInfo());
        if (content != null) {
            final DefaultAttributeGroup[] groups = new DefaultAttributeGroup[NUM_GROUPS];
            for (int i = 0; i < bands.length; i++) {
                final DefaultBand band = bands[i];
                if (band != null) {
                    final int gi = (BAND_GROUPS >>> 2 * i) & 3;
                    DefaultAttributeGroup group = groups[gi];
                    if (group == null) {
                        group = new DefaultAttributeGroup(CoverageContentType.PHYSICAL_MEASUREMENT, null);
                        content.getAttributeGroups().add(group);
                        groups[gi] = group;
                    }
                    group.getAttributes().add(band);
                }
            }
        }
        result.setMetadataStandards(Citations.ISO_19115);
        result.freeze();
    }
    return result;
}
Also used : DateTimeException(java.time.DateTimeException) DefaultBand(org.apache.sis.metadata.iso.content.DefaultBand) ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) DefaultMetadata(org.apache.sis.metadata.iso.DefaultMetadata) DefaultCoverageDescription(org.apache.sis.metadata.iso.content.DefaultCoverageDescription) DefaultAttributeGroup(org.apache.sis.metadata.iso.content.DefaultAttributeGroup)

Aggregations

ProjectedCRS (org.opengis.referencing.crs.ProjectedCRS)40 Test (org.junit.Test)31 DependsOnMethod (org.apache.sis.test.DependsOnMethod)23 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)11 GeographicCRS (org.opengis.referencing.crs.GeographicCRS)10 GeodeticCRS (org.opengis.referencing.crs.GeodeticCRS)5 CartesianCS (org.opengis.referencing.cs.CartesianCS)5 Conversion (org.opengis.referencing.operation.Conversion)5 DefaultConversion (org.apache.sis.referencing.operation.DefaultConversion)4 VerticalCRS (org.opengis.referencing.crs.VerticalCRS)4 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)4 EllipsoidalCS (org.opengis.referencing.cs.EllipsoidalCS)4 GeodeticObjectBuilder (org.apache.sis.internal.referencing.GeodeticObjectBuilder)3 DefaultProjectedCRS (org.apache.sis.referencing.crs.DefaultProjectedCRS)3 HashMap (java.util.HashMap)2 Ignore (org.junit.Ignore)2 DirectPosition (org.opengis.geometry.DirectPosition)2 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)2 EngineeringCRS (org.opengis.referencing.crs.EngineeringCRS)2 CoordinateSystemAxis (org.opengis.referencing.cs.CoordinateSystemAxis)2