org.opengis.referencing.cs.CoordinateSystem Java Examples

The following examples show how to use org.opengis.referencing.cs.CoordinateSystem. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CoordinateSystemsTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests {@link CoordinateSystems#swapAndScaleAxes(CoordinateSystem, CoordinateSystem)} for (λ,φ,h) ↔ (φ,λ,h).
 * This very common conversion is of critical importance to Apache SIS.
 *
 * @throws IncommensurableException if a conversion between incompatible units was attempted.
 */
@Test
@DependsOnMethod("testSwapAndScaleAxes2D")
public void testSwapAndScaleAxes3D() throws IncommensurableException {
    final CoordinateSystem λφh = new DefaultEllipsoidalCS(singletonMap(NAME_KEY, "(λ,φ,h)"),
            HardCodedAxes.GEODETIC_LONGITUDE,
            HardCodedAxes.GEODETIC_LATITUDE,
            HardCodedAxes.ELLIPSOIDAL_HEIGHT);
    final CoordinateSystem φλh = new DefaultEllipsoidalCS(singletonMap(NAME_KEY, "(φ,λ,h)"),
            HardCodedAxes.GEODETIC_LATITUDE,
            HardCodedAxes.GEODETIC_LONGITUDE,
            HardCodedAxes.ELLIPSOIDAL_HEIGHT);
    final Matrix expected = Matrices.create(4, 4, new double[] {
            0, 1, 0, 0,
            1, 0, 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1});
    assertTrue(swapAndScaleAxes(λφh, λφh).isIdentity());
    assertTrue(swapAndScaleAxes(φλh, φλh).isIdentity());
    assertMatrixEquals("(λ,φ,h) → (φ,λ,h)", expected, swapAndScaleAxes(λφh, φλh), STRICT);
    assertMatrixEquals("(φ,λ,h) → (λ,φ,h)", expected, swapAndScaleAxes(φλh, λφh), STRICT);
}
 
Example #2
Source File: DefaultCompoundCRSTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests construction and serialization of a {@link DefaultCompoundCRS}.
 */
@Test
public void testConstructionAndSerialization() {
    final DefaultGeographicCRS crs2 = HardCodedCRS.WGS84;
    final DefaultCompoundCRS   crs3 = new DefaultCompoundCRS(singletonMap(NAME_KEY, "3D"), crs2, HEIGHT);
    final DefaultCompoundCRS   crs4 = new DefaultCompoundCRS(singletonMap(NAME_KEY, "4D"), crs3, TIME);
    Validators.validate(crs4);
    /*
     * Verifies the coordinate system axes.
     */
    final CoordinateSystem cs = crs4.getCoordinateSystem();
    assertInstanceOf("coordinateSystem", DefaultCompoundCS.class, cs);
    assertEquals("dimension", 4, cs.getDimension());
    assertSame(HardCodedAxes.GEODETIC_LONGITUDE,     cs.getAxis(0));
    assertSame(HardCodedAxes.GEODETIC_LATITUDE,      cs.getAxis(1));
    assertSame(HardCodedAxes.GRAVITY_RELATED_HEIGHT, cs.getAxis(2));
    assertSame(HardCodedAxes.TIME,                   cs.getAxis(3));
    /*
     * Verifies the list of components, including after serialization
     * since readObject(ObjectInputStream) is expected to recreate it.
     */
    verifyComponents(crs2, crs3, crs4);
    verifyComponents(crs2, crs3, assertSerializedEquals(crs4));
}
 
Example #3
Source File: CodesTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Compares the axis directions and units with EPSG definitions.
 *
 * @throws Exception if an error occurred while fetching the codes or querying the database.
 */
@Test
@SuppressWarnings("unchecked")
public void verify() throws Exception {
    final CSAuthorityFactory factory = TestFactorySource.getSharedFactory();
    final Field field = Codes.class.getDeclaredField("EPSG");
    field.setAccessible(true);
    for (final Codes c : ((Map<Codes,?>) field.get(null)).keySet()) {
        final CoordinateSystem cs = factory.createCoordinateSystem(String.valueOf(c.epsg));
        final Unit<?> unit = cs.getAxis(0).getUnit();
        final AxisDirection[] directions = new AxisDirection[cs.getDimension()];
        for (int i=0; i<directions.length; i++) {
            assertEquals(i < 2 ? unit : VERTICAL_UNIT, cs.getAxis(i).getUnit());
            directions[i] = cs.getAxis(i).getDirection();
        }
        assertEquals("Codes.lookpup(…)", c.epsg, Codes.lookup(unit, directions));
    }
}
 
Example #4
Source File: DefaultDerivedCRS.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a derived CRS from a math transform and a type inferred from the given arguments.
 * This method expects the same arguments and performs the same work than the
 * {@linkplain #DefaultDerivedCRS(Map, SingleCRS, CoordinateReferenceSystem, OperationMethod, MathTransform,
 * CoordinateSystem) above constructor},
 * except that the {@code DerivedCRS} instance returned by this method may additionally implement
 * the {@link GeodeticCRS}, {@link VerticalCRS}, {@link TemporalCRS}, {@link ParametricCRS} or
 * {@link EngineeringCRS} interface.
 * See the class javadoc for more information.
 *
 * @param  properties        the properties to be given to the {@link DefaultConversion} object
 *                           (with keys prefixed by {@code "conversion."}) and to the new derived CRS object.
 * @param  baseCRS           coordinate reference system to base the derived CRS on.
 * @param  interpolationCRS  the CRS of additional coordinates needed for the operation, or {@code null} if none.
 * @param  method            the coordinate operation method (mandatory in all cases).
 * @param  baseToDerived     transform from positions in the base CRS to positions in this target CRS.
 * @param  derivedCS         the coordinate system for the derived CRS.
 * @return the newly created derived CRS, potentially implementing an additional CRS interface.
 * @throws IllegalArgumentException if at least one argument has an incompatible number of dimensions.
 *
 * @see #DefaultDerivedCRS(Map, SingleCRS, CoordinateReferenceSystem, OperationMethod, MathTransform, CoordinateSystem)
 */
public static DefaultDerivedCRS create(final Map<String,?>             properties,
                                       final SingleCRS                 baseCRS,
                                       final CoordinateReferenceSystem interpolationCRS,
                                       final OperationMethod           method,
                                       final MathTransform             baseToDerived,
                                       final CoordinateSystem          derivedCS)
{
    if (baseCRS != null && derivedCS != null) {
        final String type = getType(baseCRS, derivedCS);
        if (type != null) switch (type) {
            case WKTKeywords.GeodeticCRS:   return new Geodetic  (properties, (GeodeticCRS)   baseCRS, interpolationCRS, method, baseToDerived,                derivedCS);
            case WKTKeywords.VerticalCRS:   return new Vertical  (properties, (VerticalCRS)   baseCRS, interpolationCRS, method, baseToDerived,  (VerticalCS)  derivedCS);
            case WKTKeywords.TimeCRS:       return new Temporal  (properties, (TemporalCRS)   baseCRS, interpolationCRS, method, baseToDerived,      (TimeCS)  derivedCS);
            case WKTKeywords.ParametricCRS: return new Parametric(properties, (ParametricCRS) baseCRS, interpolationCRS, method, baseToDerived, (DefaultParametricCS) derivedCS);
            case WKTKeywords.EngineeringCRS: {
                if (baseCRS instanceof EngineeringCRS) {
                    // See the comment in create(Map, SingleCRS, Conversion, CoordinateSystem)
                    return new Engineering(properties, (EngineeringCRS) baseCRS, interpolationCRS, method, baseToDerived, derivedCS);
                }
                break;
            }
        }
    }
    return new DefaultDerivedCRS(properties, baseCRS, interpolationCRS, method, baseToDerived, derivedCS);
}
 
Example #5
Source File: DefaultCompoundCS.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns all axes in the given sequence of components.
 */
@SuppressWarnings("ForLoopReplaceableByForEach")
private static CoordinateSystemAxis[] getAxes(final CoordinateSystem[] components) {
    int count = 0;
    for (int i=0; i<components.length; i++) {
        count += components[i].getDimension();
    }
    final CoordinateSystemAxis[] axis = new CoordinateSystemAxis[count];
    count = 0;
    for (final CoordinateSystem c : components) {
        final int dim = c.getDimension();
        for (int j=0; j<dim; j++) {
            axis[count++] = c.getAxis(j);
        }
    }
    assert count == axis.length;
    return axis;
}
 
Example #6
Source File: AxisDirections.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Finds the dimension of an axis having the given direction or its opposite.
 * If more than one axis has the given direction, only the first occurrence is returned.
 * If both the given direction and its opposite exist, then the dimension for the given
 * direction has precedence over the opposite direction.
 *
 * @param  cs         the coordinate system to inspect, or {@code null}.
 * @param  direction  the direction of the axis to search.
 * @return the dimension of the axis using the given direction or its opposite, or -1 if none.
 */
public static int indexOfColinear(final CoordinateSystem cs, final AxisDirection direction) {
    int fallback = -1;
    if (cs != null) {
        final int dimension = cs.getDimension();
        for (int i=0; i<dimension; i++) {
            final AxisDirection d = cs.getAxis(i).getDirection();
            if (direction.equals(d)) {
                return i;
            }
            if (fallback < 0 && d.equals(opposite(direction))) {
                fallback = i;
            }
        }
    }
    return fallback;
}
 
Example #7
Source File: AxisDirections.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the angular unit of the specified coordinate system.
 * The preference will be given to the longitude axis, if found.
 *
 * @param  cs        the coordinate system from which to get the angular unit, or {@code null}.
 * @param  fallback  the default unit to return if no angular unit is found.
 * @return the angular unit, of {@code unit} if no angular unit was found.
 *
 * @see org.apache.sis.internal.referencing.ReferencingUtilities#getUnit(CoordinateSystem)
 *
 * @since 0.6
 */
public static Unit<Angle> getAngularUnit(final CoordinateSystem cs, Unit<Angle> fallback) {
    if (cs != null) {
        for (int i = cs.getDimension(); --i>=0;) {
            final CoordinateSystemAxis axis = cs.getAxis(i);
            if (axis != null) {                                                     // Paranoiac check.
                final Unit<?> candidate = axis.getUnit();
                if (Units.isAngular(candidate)) {
                    fallback = candidate.asType(Angle.class);
                    if (AxisDirection.EAST.equals(absolute(axis.getDirection()))) {
                        break;                                                      // Found the longitude axis.
                    }
                }
            }
        }
    }
    return fallback;
}
 
Example #8
Source File: DefaultCompoundCRS.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a compound coordinate system for the specified array of CRS objects.
 *
 * @param  properties  the properties given to the constructor, or {@code null} if unknown.
 * @param  components  the CRS components, usually singles but not necessarily.
 * @return the coordinate system for the given components.
 */
private static CoordinateSystem createCoordinateSystem(final Map<String,?> properties,
        final CoordinateReferenceSystem[] components)
{
    ArgumentChecks.ensureNonNull("components", components);
    verify(properties, components);
    if (components.length < 2) {
        throw new IllegalArgumentException(Errors.getResources(properties).getString(
                Errors.Keys.TooFewArguments_2, 2, components.length));
    }
    final CoordinateSystem[] cs = new CoordinateSystem[components.length];
    for (int i=0; i<components.length; i++) {
        final CoordinateReferenceSystem crs = components[i];
        ArgumentChecks.ensureNonNullElement("components", i, crs);
        cs[i] = crs.getCoordinateSystem();
    }
    return new DefaultCompoundCS(cs);
}
 
Example #9
Source File: GeometryUtils.java    From geowave with Apache License 2.0 6 votes vote down vote up
/**
 * This is perhaps a brain dead approach to do this, but it does handle wrap around cases. Also
 * supports cases where the wrap around occurs many times.
 *
 * @param val the value
 * @param crs
 * @param axis the coordinate axis
 * @return the adjusted coordinate dimension
 */
public static double adjustCoordinateDimensionToRange(
    final double val,
    final CoordinateReferenceSystem crs,
    final int axis) {
  final CoordinateSystem coordinateSystem = crs.getCoordinateSystem();
  if (coordinateSystem.getDimension() > axis) {
    final double lowerBound = coordinateSystem.getAxis(axis).getMinimumValue();
    final double bound = coordinateSystem.getAxis(axis).getMaximumValue() - lowerBound;
    final double sign = sign(val);
    // re-scale to 0 to n, then determine how many times to 'loop
    // around'
    final double mult = Math.floor(Math.abs((val + (sign * (-1.0 * lowerBound))) / bound));
    return val + (mult * bound * sign * (-1.0));
  }
  return val;
}
 
Example #10
Source File: CommonCRSTest.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Tests the {@link CommonCRS#normalizedGeographic()} method.
 */
@Test
@DependsOnMethod("testGeographic")
public void testNormalizedGeographic() {
    final GeographicCRS geographic = CommonCRS.WGS84.geographic();
    final GeographicCRS normalized = CommonCRS.WGS84.normalizedGeographic();
    Validators.validate(normalized);
    assertSame(geographic.getDatum(), normalized.getDatum());
    /*
     * Compare axes. Note that axes in different order have different EPSG codes.
     */
    final CoordinateSystem φλ = geographic.getCoordinateSystem();
    final CoordinateSystem λφ = normalized.getCoordinateSystem();
    assertEqualsIgnoreMetadata(φλ.getAxis(1), λφ.getAxis(0));       // Longitude
    assertEqualsIgnoreMetadata(φλ.getAxis(0), λφ.getAxis(1));       // Latitude
    assertSame("Cached value", normalized, CommonCRS.WGS84.normalizedGeographic());
}
 
Example #11
Source File: EllipsoidalHeightCombiner.java    From sis with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the coordinate system if the given CRS is a two-dimensional geographic or projected CRS,
 * or {@code null} otherwise. The returned coordinate system is either ellipsoidal or Cartesian;
 * no other type is returned.
 */
private static CoordinateSystem getCsIfHorizontal2D(final CoordinateReferenceSystem crs) {
    final boolean isProjected = (crs instanceof ProjectedCRS);
    if (isProjected || crs instanceof GeodeticCRS) {
        final CoordinateSystem cs = crs.getCoordinateSystem();
        if (cs.getDimension() == 2 && (isProjected || cs instanceof EllipsoidalCS)) {
            /*
             * ProjectedCRS are guaranteed to be associated to CartesianCS, so we do not test that.
             * GeodeticCRS may be associated to either CartesianCS or EllipsoidalCS, but this method
             * shall accept only EllipsoidalCS. Actually we should accept only GeographicCRS, but we
             * relax this condition by accepting GeodeticCRS with EllipsoidalCS.
             */
            return cs;
        }
    }
    return null;
}
 
Example #12
Source File: AbstractCRS.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Formats the given coordinate system.
 *
 * <p>In WKT 2 format, this method should not be invoked if {@link #isBaseCRS(Formatter)} returned {@code true}
 * because ISO 19162 excludes the coordinate system definition in base CRS. Note however that WKT 1 includes the
 * coordinate systems. The SIS-specific {@link Convention#INTERNAL} formats also those coordinate systems.</p>
 *
 * <div class="note"><b>Note:</b> the {@code unit} and {@code isWKT1} arguments could be computed by this method,
 * but are requested in order to avoid computing them twice, because the caller usually have them anyway.</div>
 *
 * @param  formatter  the formatter where to append the coordinate system.
 * @param  cs         the coordinate system to append.
 * @param  unit       the value of {@code ReferencingUtilities.getUnit(cs)}.
 * @param  isWKT1     {@code true} if formatting WKT 1, or {@code false} for WKT 2.
 */
final void formatCS(final Formatter formatter, final CoordinateSystem cs, final Unit<?> unit, final boolean isWKT1) {
    assert unit == ReferencingUtilities.getUnit(cs) : unit;
    assert (formatter.getConvention().majorVersion() == 1) == isWKT1 : isWKT1;
    assert isWKT1 || !isBaseCRS(formatter) || formatter.getConvention() == Convention.INTERNAL;    // Condition documented in javadoc.

    final Unit<?> oldUnit = formatter.addContextualUnit(unit);
    if (isWKT1) {                               // WKT 1 writes unit before axes, while WKT 2 writes them after axes.
        formatter.append(unit);
        if (unit == null) {
            formatter.setInvalidWKT(this, null);
        }
    } else {
        formatter.append(toFormattable(cs));    // WKT2 only, since the concept of CoordinateSystem was not explicit in WKT 1.
        formatter.indent(+1);
    }
    if (!isWKT1 || formatter.getConvention() != Convention.WKT1_IGNORE_AXES) {
        if (cs != null) {                       // Should never be null, except sometime temporarily during construction.
            final int dimension = cs.getDimension();
            for (int i=0; i<dimension; i++) {
                formatter.newLine();
                formatter.append(toFormattable(cs.getAxis(i)));
            }
        }
    }
    if (!isWKT1) {                              // WKT 2 writes unit after axes, while WKT 1 wrote them before axes.
        formatter.newLine();
        formatter.append(unit);
        formatter.indent(-1);
    }
    formatter.restoreContextualUnit(unit, oldUnit);
    formatter.newLine();                        // For writing the ID[…] element on its own line.
}
 
Example #13
Source File: GeoapiAssert.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Asserts that all axes in the given coordinate system are pointing toward the given directions, in the same order.
 *
 * @param message  Header of the exception message in case of failure, or {@code null} if none.
 * @param cs       The coordinate system to test.
 * @param expected The expected axis directions.
 */
public static void assertAxisDirectionsEqual(String message,
        final CoordinateSystem cs, final AxisDirection... expected)
{
    assertEquals(concat(message, "Wrong coordinate system dimension."), expected.length, cs.getDimension());
    message = concat(message, "Wrong axis direction.");
    for (int i=0; i<expected.length; i++) {
        assertEquals(message, expected[i], cs.getAxis(i).getDirection());
    }
}
 
Example #14
Source File: StandardDefinitions.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a coordinate system from hard-coded values for the given code.
 * The coordinate system names used by this method contains only the first
 * part of the names declared in the EPSG database.
 *
 * @param  code       the EPSG code.
 * @param  mandatory  whether to fail or return {@code null} if the given code is unknown.
 * @return the coordinate system for the given code.
 */
@SuppressWarnings("fallthrough")
static CoordinateSystem createCoordinateSystem(final short code, final boolean mandatory) {
    final String name;
    int type = 0;                   // 0= Cartesian (default), 1= Spherical, 2= Ellipsoidal
    int dim = 2;                    // Number of dimension, default to 2.
    short axisCode;                 // Code of first axis + dim (or code after the last axis).
    switch (code) {
        case ELLIPSOIDAL_2D: name = "Ellipsoidal 2D"; type = 2;          axisCode =  108; break;
        case ELLIPSOIDAL_3D: name = "Ellipsoidal 3D"; type = 2; dim = 3; axisCode =  111; break;
        case SPHERICAL:      name = "Spherical";      type = 1; dim = 3; axisCode =   63; break;
        case EARTH_CENTRED:  name = "Earth centred";            dim = 3; axisCode =  118; break;
        case CARTESIAN_2D:   name = "Cartesian 2D";                      axisCode =    3; break;
        case UPS_NORTH:      name = "Cartesian 2D for UPS north";        axisCode = 1067; break;
        case UPS_SOUTH:      name = "Cartesian 2D for UPS south";        axisCode = 1059; break;
        default:   if (!mandatory) return null;
                   throw new AssertionError(code);
    }
    final Map<String,?> properties = properties(code, name, null, false);
    CoordinateSystemAxis xAxis = null, yAxis = null, zAxis = null;
    switch (dim) {
        default: throw new AssertionError(dim);
        case 3:  zAxis = createAxis(--axisCode, true);
        case 2:  yAxis = createAxis(--axisCode, true);
        case 1:  xAxis = createAxis(--axisCode, true);
        case 0:  break;
    }
    switch (type) {
        default: throw new AssertionError(type);
        case 0:  return (zAxis != null) ? new DefaultCartesianCS  (properties, xAxis, yAxis, zAxis)
                                        : new DefaultCartesianCS  (properties, xAxis, yAxis);
        case 1:  return                   new DefaultSphericalCS  (properties, xAxis, yAxis, zAxis);
        case 2:  return (zAxis != null) ? new DefaultEllipsoidalCS(properties, xAxis, yAxis, zAxis)
                                        : new DefaultEllipsoidalCS(properties, xAxis, yAxis);
    }
}
 
Example #15
Source File: AbstractDirectPosition.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Ensures that the position is contained in the coordinate system domain.
 * For each dimension, this method compares the coordinate values against the
 * limits of the coordinate system axis for that dimension.
 * If some coordinates are out of range, then there is a choice depending on the
 * {@linkplain CoordinateSystemAxis#getRangeMeaning() axis range meaning}:
 *
 * <ul>
 *   <li>If {@link RangeMeaning#EXACT} (typically <em>latitudes</em> coordinates), then values
 *       greater than the {@linkplain CoordinateSystemAxis#getMaximumValue() axis maximal value}
 *       are replaced by the axis maximum, and values smaller than the
 *       {@linkplain CoordinateSystemAxis#getMinimumValue() axis minimal value}
 *       are replaced by the axis minimum.</li>
 *
 *   <li>If {@link RangeMeaning#WRAPAROUND} (typically <em>longitudes</em> coordinates), then
 *       a multiple of the axis range (e.g. 360° for longitudes) is added or subtracted.</li>
 * </ul>
 *
 * @return {@code true} if this position has been modified as a result of this method call,
 *         or {@code false} if no change has been done.
 *
 * @see GeneralEnvelope#normalize()
 */
public boolean normalize() {
    boolean changed = false;
    final CoordinateReferenceSystem crs = getCoordinateReferenceSystem();
    if (crs != null) {
        final int dimension = getDimension();
        final CoordinateSystem cs = crs.getCoordinateSystem();
        for (int i=0; i<dimension; i++) {
            double coordinate = getOrdinate(i);
            final CoordinateSystemAxis axis = cs.getAxis(i);
            final double  minimum = axis.getMinimumValue();
            final double  maximum = axis.getMaximumValue();
            final RangeMeaning rm = axis.getRangeMeaning();
            if (RangeMeaning.EXACT.equals(rm)) {
                     if (coordinate < minimum) coordinate = minimum;
                else if (coordinate > maximum) coordinate = maximum;
                else continue;
            } else if (RangeMeaning.WRAPAROUND.equals(rm)) {
                final double csSpan = maximum - minimum;
                final double shift  = Math.floor((coordinate - minimum) / csSpan) * csSpan;
                if (shift == 0) {
                    continue;
                }
                coordinate -= shift;
            }
            setOrdinate(i, coordinate);
            changed = true;
        }
    }
    return changed;
}
 
Example #16
Source File: ArgumentChecks.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Ensures that the given CRS, if non-null, has the expected number of dimensions.
 * This method does nothing if the given coordinate reference system is null.
 *
 * @param  name      the name of the argument to be checked. Used only if an exception is thrown.
 * @param  expected  the expected number of dimensions.
 * @param  crs       the coordinate reference system to check for its dimension, or {@code null}.
 * @throws MismatchedDimensionException if the given coordinate reference system is non-null
 *         and does not have the expected number of dimensions.
 */
public static void ensureDimensionMatches(final String name, final int expected,
        final CoordinateReferenceSystem crs) throws MismatchedDimensionException
{
    if (crs != null) {
        final CoordinateSystem cs = crs.getCoordinateSystem();
        if (cs != null) {                                       // Should never be null, but let be safe.
            final int dimension = cs.getDimension();
            if (dimension != expected) {
                throw new MismatchedDimensionException(Errors.format(
                        Errors.Keys.MismatchedDimension_3, name, expected, dimension));
            }
        }
    }
}
 
Example #17
Source File: Element.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a {@link ParseException} for an illegal coordinate system.
 *
 * <p>The given {@code cs} argument should never be null with Apache SIS implementation of
 * {@link org.opengis.referencing.cs.CSFactory}, but could be null with user-supplied implementation.
 * But it would be a {@code CSFactory} contract violation, so the user would get a {@link NullPointerException}
 * later. For making easier to trace the cause, we throw here an exception with a similar error message.</p>
 *
 * @param  cs  the illegal coordinate system.
 * @return the exception to be thrown.
 */
final ParseException illegalCS(final CoordinateSystem cs) {
    final short key;
    final String value;
    if (cs == null) {
        key   = Errors.Keys.NullArgument_1;   // See javadoc.
        value = "coordinateSystem";
    } else {
        key   = Errors.Keys.IllegalCoordinateSystem_1;
        value = cs.getName().getCode();
    }
    return new UnparsableObjectException(locale, key, new String[] {value}, offset);
}
 
Example #18
Source File: EPSGFactoryTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests the creation of CRS using name instead of primary key.
 *
 * @throws FactoryException if an error occurred while querying the factory.
 *
 * @see #testProjectedByName()
 */
@Test
public void testCreateByName() throws FactoryException {
    final EPSGFactory factory = TestFactorySource.factory;
    assumeNotNull(factory);
    assertSame   (factory.createUnit("9002"), factory.createUnit("foot"));
    assertNotSame(factory.createUnit("9001"), factory.createUnit("foot"));
    assertSame   (factory.createUnit("9202"), factory.createUnit("ppm"));       // Search in alias table.
    /*
     * Test a name with colons.
     */
    final CoordinateSystem cs = factory.createCoordinateSystem(
            "Ellipsoidal 2D CS. Axes: latitude, longitude. Orientations: north, east. UoM: degree");
    assertEpsgNameAndIdentifierEqual(
            "Ellipsoidal 2D CS. Axes: latitude, longitude. Orientations: north, east. UoM: degree", 6422, cs);
    /*
     * Tests with a unknown name. The exception should be NoSuchAuthorityCodeException
     * (some previous version wrongly threw a SQLException when using HSQL database).
     */
    try {
        factory.createGeographicCRS("WGS83");
        fail("Should not find a geographic CRS named “WGS83” (the actual name is “WGS 84”).");
    } catch (NoSuchAuthorityCodeException e) {
        // This is the expected exception.
        assertEquals("WGS83", e.getAuthorityCode());
    }
}
 
Example #19
Source File: AbstractEnvelope.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the axis of the given coordinate reference system for the given dimension,
 * or {@code null} if none.
 *
 * @param  crs        the envelope CRS, or {@code null}.
 * @param  dimension  the dimension for which to get the axis.
 * @return the axis at the given dimension, or {@code null}.
 */
static CoordinateSystemAxis getAxis(final CoordinateReferenceSystem crs, final int dimension) {
    if (crs != null) {
        final CoordinateSystem cs = crs.getCoordinateSystem();
        if (cs != null) {                                       // Paranoiac check (should never be null).
            return cs.getAxis(dimension);
        }
    }
    return null;
}
 
Example #20
Source File: GeoWaveRasterReader.java    From geowave with Apache License 2.0 5 votes vote down vote up
private static int indexOf(
    final CoordinateReferenceSystem crs,
    final Set<AxisDirection> direction) {
  final CoordinateSystem cs = crs.getCoordinateSystem();
  for (int index = 0; index < cs.getDimension(); index++) {
    final CoordinateSystemAxis axis = cs.getAxis(index);
    if (direction.contains(axis.getDirection())) {
      return index;
    }
  }
  return -1;
}
 
Example #21
Source File: AxisDirections.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
     * Returns the index of the first dimension in {@code cs} where axes are colinear with the {@code subCS} axes.
     * If no such dimension is found, returns -1. If more than one sequence of {@code cs} axes are colinear with
     * all {@code subCS} axes, then the following rules apply:
     *
     * <ol>
     *   <li>If a sequence of {@code cs} axes are equal to the {@code subCS} axes, that sequence has precedence.</li>
     *   <li>Otherwise if a sequence of {@code cs} axes have similar names than the {@code subCS} axes (as determined
     *       by {@linkplain org.apache.sis.referencing.IdentifiedObjects#isHeuristicMatchForName heuristic match},
     *       that sequence has precedence.</li>
     *   <li>Otherwise the index of the first sequence if returned, regardless axis names.</li>
     * </ol>
     *
     * Note that colinear axes are normally not allowed, except if the case of {@link org.opengis.referencing.crs.TemporalCRS}
     * when one time axis is the runtime (the date where a numerical model has been executed) and the other time axis is the
     * forecast time (the date at which a prevision is made).
     *
     * @param  cs     the coordinate system which contains all axes, or {@code null}.
     * @param  subCS  the coordinate system to search into {@code cs}.
     * @return the first dimension of a sequence of axes colinear with {@code subCS} axes, or {@code -1} if none.
     *
     * @since 0.5
     */
    public static int indexOfColinear(final CoordinateSystem cs, final CoordinateSystem subCS) {
        int fallback = -1;
        if (cs != null) {
            boolean fallbackMatches = false;
            final int subDim = subCS.getDimension();
            final int limit = cs.getDimension() - subDim;
next:       for (int i=0; i <= limit; i++) {
                boolean equal = true;
                boolean match = true;
                for (int j=0; j<subDim; j++) {
                    final CoordinateSystemAxis expected = subCS.getAxis(j);
                    final CoordinateSystemAxis actual = cs.getAxis(i + j);
                    if (!isColinear(expected.getDirection(), actual.getDirection())) {
                        continue next;
                    }
                    if (equal) {
                        equal = Utilities.deepEquals(expected, actual, ComparisonMode.BY_CONTRACT);
                        if (equal) continue;
                    }
                    if (match) {
                        match = NameToIdentifier.isHeuristicMatchForName(actual, expected.getName().getCode());
                    }
                }
                if (equal) {
                    return i;
                }
                if (fallback < 0 | (match & !fallbackMatches)) {
                    fallbackMatches = match;
                    fallback = i;
                }
            }
        }
        return fallback;
    }
 
Example #22
Source File: CRS.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * If the given CRS would qualify as horizontal except for its number of dimensions, returns that number.
 * Otherwise returns 0. The number of dimensions can only be 2 or 3.
 */
private static int horizontalCode(final CoordinateReferenceSystem crs) {
    /*
     * In order to determine if the CRS is geographic, checking the CoordinateSystem type is more reliable
     * then checking if the CRS implements the GeographicCRS interface.  This is because the GeographicCRS
     * type did not existed in ISO 19111:2007, so a CRS could be standard-compliant without implementing
     * the GeographicCRS interface.
     */
    boolean isEngineering = false;
    final boolean isGeodetic = (crs instanceof GeodeticCRS);
    if (isGeodetic || crs instanceof ProjectedCRS || (isEngineering = (crs instanceof EngineeringCRS))) {
        final CoordinateSystem cs = crs.getCoordinateSystem();
        final int dim = cs.getDimension();
        if ((dim & ~1) == 2 && (!isGeodetic || (cs instanceof EllipsoidalCS))) {
            if (isEngineering) {
                int n = 0;
                for (int i=0; i<dim; i++) {
                    if (AxisDirections.isCompass(cs.getAxis(i).getDirection())) n++;
                }
                // If we don't have exactly 2 east, north, etc. directions, consider as non-horizontal.
                if (n != 2) return 0;
            }
            return dim;
        }
    }
    return 0;
}
 
Example #23
Source File: DefaultGeocentricCRSTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Tests the {@link DefaultGeocentricCRS#forConvention(AxesConvention)} method
 * for {@link AxesConvention#RIGHT_HANDED}.
 *
 * @since 0.7
 */
@Test
public void testRightHanded() {
    final DefaultGeocentricCRS crs = DefaultGeocentricCRS.castOrCopy(HardCodedCRS.SPHERICAL);
    final DefaultGeocentricCRS normalized = crs.forConvention(AxesConvention.RIGHT_HANDED);
    assertNotSame(crs, normalized);
    final CoordinateSystem cs = normalized.getCoordinateSystem();
    final CoordinateSystem ref = crs.getCoordinateSystem();
    assertSame("longitude", ref.getAxis(1), cs.getAxis(0));
    assertSame("latitude",  ref.getAxis(0), cs.getAxis(1));
    assertSame("height",    ref.getAxis(2), cs.getAxis(2));
}
 
Example #24
Source File: SubTypes.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a SIS implementation for the given coordinate system.
 *
 * @see AbstractCS#castOrCopy(CoordinateSystem)
 */
static AbstractCS castOrCopy(final CoordinateSystem object) {
    if (object instanceof AffineCS) {
        return DefaultAffineCS.castOrCopy((AffineCS) object);
    }
    if (object instanceof SphericalCS) {
        return DefaultSphericalCS.castOrCopy((SphericalCS) object);
    }
    if (object instanceof EllipsoidalCS) {
        return DefaultEllipsoidalCS.castOrCopy((EllipsoidalCS) object);
    }
    if (object instanceof CylindricalCS) {
        return DefaultCylindricalCS.castOrCopy((CylindricalCS) object);
    }
    if (object instanceof PolarCS) {
        return DefaultPolarCS.castOrCopy((PolarCS) object);
    }
    if (object instanceof LinearCS) {
        return DefaultLinearCS.castOrCopy((LinearCS) object);
    }
    if (object instanceof VerticalCS) {
        return DefaultVerticalCS.castOrCopy((VerticalCS) object);
    }
    if (object instanceof TimeCS) {
        return DefaultTimeCS.castOrCopy((TimeCS) object);
    }
    if (object instanceof UserDefinedCS) {
        return DefaultUserDefinedCS.castOrCopy((UserDefinedCS) object);
    }
    /*
     * Intentionally check for AbstractCS after the interfaces because user may have defined his own
     * subclass implementing the interface. If we were checking for AbstractCS before the interfaces,
     * the returned instance could have been a user subclass without the JAXB annotations required
     * for XML marshalling.
     */
    if (object == null || object instanceof AbstractCS) {
        return (AbstractCS) object;
    }
    return new AbstractCS(object);
}
 
Example #25
Source File: AbstractCS.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the axes of the given coordinate system.
 */
private static CoordinateSystemAxis[] getAxes(final CoordinateSystem cs) {
    final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[cs.getDimension()];
    for (int i=0; i<axes.length; i++) {
        axes[i] = cs.getAxis(i);
    }
    return axes;
}
 
Example #26
Source File: Normalizer.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a coordinate system with the same axes than the given CS, except that the wraparound axes
 * are shifted to a range of positive values. This method can be used in order to shift between the
 * [-180 … +180]° and [0 … 360]° ranges of longitude values.
 *
 * <p>This method shifts the axis {@linkplain CoordinateSystemAxis#getMinimumValue() minimum} and
 * {@linkplain CoordinateSystemAxis#getMaximumValue() maximum} values by a multiple of half the range
 * (typically 180°). This method does not change the meaning of coordinate values. For example a longitude
 * of -60° still locate the same point in the old and the new coordinate system. But the preferred way to
 * locate that point become the 300° value if the longitude range has been shifted to positive values.</p>
 *
 * @return a coordinate system using the given kind of longitude range, or {@code null} if no change is needed.
 */
private static AbstractCS shiftAxisRange(final CoordinateSystem cs) {
    boolean changed = false;
    final CoordinateSystemAxis[] axes = new CoordinateSystemAxis[cs.getDimension()];
    for (int i=0; i<axes.length; i++) {
        CoordinateSystemAxis axis = cs.getAxis(i);
        if (RangeMeaning.WRAPAROUND.equals(axis.getRangeMeaning())) {
            double min = axis.getMinimumValue();
            if (min < 0) {
                double max = axis.getMaximumValue();
                double offset = (max - min) / 2;
                offset *= Math.floor(min/offset + Numerics.COMPARISON_THRESHOLD);
                min -= offset;
                max -= offset;
                if (min < max) { // Paranoiac check, but also a way to filter NaN values when offset is infinite.
                    axis = forRange(axis, min, max);
                    changed = true;
                }
            }
        }
        axes[i] = axis;
    }
    if (!changed) {
        return null;
    }
    return castOrCopy(cs).createForAxes(IdentifiedObjects.getProperties(cs, EXCLUDES), axes);
}
 
Example #27
Source File: Normalizer.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a coordinate system equivalent to the given one but with axes rearranged according the given convention.
 * If the given coordinate system is already compatible with the given convention, then returns {@code null}.
 *
 * @param  convention  the axes convention for which a coordinate system is desired.
 * @return a coordinate system compatible with the given convention, or {@code null} if no change is needed.
 *
 * @see AbstractCS#forConvention(AxesConvention)
 */
static AbstractCS forConvention(final CoordinateSystem cs, final AxesConvention convention) {
    switch (convention) {
        case NORMALIZED:              // Fall through
        case DISPLAY_ORIENTED: return normalize(cs, convention, true);
        case RIGHT_HANDED:            return normalize(cs, null, true);
        case POSITIVE_RANGE:          return shiftAxisRange(cs);
        default: throw new AssertionError(convention);
    }
}
 
Example #28
Source File: EPSGFactoryFallbackTest.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * Asserts that the result of {@link EPSGFactoryFallback#createObject(String)} is CS of the given CRS.
 * Contrarily to other kinds of objects, coordinate systems are currently not cached. Consequently we
 * can not assert that instances are the same.
 */
private static void verifyCreateCS(final CoordinateReferenceSystem crs, final String code) throws FactoryException {
    final CoordinateSystem expected = crs.getCoordinateSystem();
    final CoordinateSystem actual = EPSGFactoryFallback.INSTANCE.createCoordinateSystem(code);
    assertEquals(code, actual, EPSGFactoryFallback.INSTANCE.createObject(code));
    assertEqualsIgnoreMetadata(expected, actual);
}
 
Example #29
Source File: DefaultGeographicCRS.java    From sis with Apache License 2.0 5 votes vote down vote up
/**
 * For {@link SC_GeographicCRS} JAXB adapter only. This is needed because GML does not have "GeographicCRS" type.
 * Instead, the unmarshalling process will give us a "GeodeticCRS" object with the constraint that the coordinate
 * system shall be ellipsoidal. This constructor will be invoked for converting the GeodeticCRS instance to a
 * GeographicCRS instance.
 */
DefaultGeographicCRS(final GeodeticCRS crs) {
    super(crs);
    final CoordinateSystem cs = super.getCoordinateSystem();
    if (!(cs instanceof EllipsoidalCS)) {
        throw new IllegalArgumentException(Errors.format(
                Errors.Keys.IllegalClass_2, EllipsoidalCS.class, cs.getClass()));
    }
}
 
Example #30
Source File: DefaultDerivedCRS.java    From sis with Apache License 2.0 4 votes vote down vote up
/** Returns a coordinate reference system of the same type than this CRS but with different axes. */
@Override AbstractCRS createSameType(final Map<String,?> properties, final CoordinateSystem derivedCS) {
    final Conversion conversionFromBase = getConversionFromBase();
    return new Engineering(properties, (EngineeringCRS) conversionFromBase.getSourceCRS(), conversionFromBase, derivedCS);
}