Search in sources :

Example 16 with GeographicCRS

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

the class TransformTestCase method testAxisRangeChange.

/**
 * Tests a transformation where only the range of longitude axis is changed.
 *
 * @throws FactoryException if an error occurred while creating the operation.
 * @throws TransformException if an error occurred while transforming the envelope.
 *
 * @since 0.8
 */
@Test
public final void testAxisRangeChange() throws FactoryException, TransformException {
    final GeographicCRS sourceCRS = HardCodedCRS.WGS84;
    final GeographicCRS targetCRS = HardCodedCRS.WGS84.forConvention(AxesConvention.POSITIVE_RANGE);
    final G rectangle = createFromExtremums(sourceCRS, -178, -70, 165, 80);
    final G expected = createFromExtremums(targetCRS, 182, -70, 165, 80);
    final G actual = transform(CRS.findOperation(sourceCRS, targetCRS, null), rectangle);
    assertGeometryEquals(expected, actual, STRICT, STRICT);
}
Also used : GeographicCRS(org.opengis.referencing.crs.GeographicCRS) Test(org.junit.Test)

Example 17 with GeographicCRS

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

the class TransformTestCase method testTransformNotOverPole.

/**
 * Tests conversions of an envelope or rectangle which is <strong>not</strong> over a pole,
 * but was wrongly considered as over a pole before SIS-329 fix.
 *
 * @throws FactoryException if an error occurred while creating the operation.
 * @throws TransformException if an error occurred while transforming the envelope.
 *
 * @see <a href="https://issues.apache.org/jira/browse/SIS-329">SIS-329</a>
 */
@Test
@DependsOnMethod("testTransform")
public final void testTransformNotOverPole() throws FactoryException, TransformException {
    final ProjectedCRS sourceCRS = CommonCRS.WGS84.universal(10, -3.5);
    final GeographicCRS targetCRS = sourceCRS.getBaseCRS();
    final Conversion conversion = inverse(sourceCRS.getConversionFromBase());
    final G rectangle = createFromExtremums(sourceCRS, 199980, 4490220, 309780, 4600020);
    final G expected = createFromExtremums(targetCRS, // Computed by SIS (not validated by external authority).
    40.50846282536367, // Computed by SIS (not validated by external authority).
    -6.594124551832373, 41.52923550023067, -5.246186118392847);
    final G actual = transform(conversion, rectangle);
    assertGeometryEquals(expected, actual, ANGULAR_TOLERANCE, ANGULAR_TOLERANCE);
}
Also used : ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) GeographicCRS(org.opengis.referencing.crs.GeographicCRS) DefaultConversion(org.apache.sis.referencing.operation.DefaultConversion) Conversion(org.opengis.referencing.operation.Conversion) Test(org.junit.Test) DependsOnMethod(org.apache.sis.test.DependsOnMethod)

Example 18 with GeographicCRS

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

the class CommonAuthorityFactory method createAuto.

/**
 * Creates a projected CRS from parameters in the {@code AUTO(2)} namespace.
 *
 * @param  code        the user-specified code, used only for error reporting.
 * @param  projection  the projection code (e.g. 42001).
 * @param  isLegacy    {@code true} if the code was found in {@code "AUTO"} or {@code "AUTO1"} namespace.
 * @param  factor      the multiplication factor for the unit of measurement.
 * @param  longitude   a longitude in the desired projection zone.
 * @param  latitude    a latitude in the desired projection zone.
 * @return the projected CRS for the given projection and parameters.
 */
@SuppressWarnings("null")
private ProjectedCRS createAuto(final String code, final int projection, final boolean isLegacy, final double factor, final double longitude, final double latitude) throws FactoryException {
    Boolean isUTM = null;
    String method = null;
    String param = null;
    switch(projection) {
        /*
             * 42001: Universal Transverse Mercator   —   central meridian must be in the center of a UTM zone.
             * 42002: Transverse Mercator             —   like 42001 except that central meridian can be anywhere.
             * 42003: WGS 84 / Auto Orthographic      —   defined by "Central_Meridian" and "Latitude_of_Origin".
             * 42004: WGS 84 / Auto Equirectangular   —   defined by "Central_Meridian" and "Standard_Parallel_1".
             * 42005: WGS 84 / Auto Mollweide         —   defined by "Central_Meridian" only.
             */
        case 42001:
            isUTM = true;
            break;
        case 42002:
            isUTM = (latitude == 0) && (Zoner.UTM.centralMeridian(Zoner.UTM.zone(0, longitude)) == longitude);
            break;
        case 42003:
            method = "Orthographic";
            param = Constants.LATITUDE_OF_ORIGIN;
            break;
        case 42004:
            method = "Equirectangular";
            param = Constants.STANDARD_PARALLEL_1;
            break;
        case 42005:
            method = "Mollweide";
            break;
        default:
            throw noSuchAuthorityCode(String.valueOf(projection), code, null);
    }
    /*
         * For the (Universal) Transverse Mercator case (AUTO:42001 and 42002), we delegate to the CommonCRS
         * enumeration if possible because CommonCRS will itself delegate to the EPSG factory if possible.
         * The Math.signum(latitude) instruction is for preventing "AUTO:42001" to handle the UTM special cases
         * (Norway and Svalbard) or to switch on the Universal Polar Stereographic projection for high latitudes,
         * because the WMS specification does not said that we should.
         */
    final CommonCRS datum = CommonCRS.WGS84;
    // To be set, directly or indirectly, to WGS84.geographic().
    final GeographicCRS baseCRS;
    // Temporary UTM projection, for extracting other properties.
    final ProjectedCRS crs;
    // Coordinate system with (E,N) axes in metres.
    CartesianCS cs;
    try {
        if (isUTM != null && isUTM) {
            crs = datum.universal(Math.signum(latitude), longitude);
            if (factor == (isLegacy ? Constants.EPSG_METRE : 1)) {
                return crs;
            }
            baseCRS = crs.getBaseCRS();
            cs = crs.getCoordinateSystem();
        } else {
            cs = projectedCS;
            if (cs == null) {
                crs = datum.universal(Math.signum(latitude), longitude);
                projectedCS = cs = crs.getCoordinateSystem();
                baseCRS = crs.getBaseCRS();
            } else {
                crs = null;
                baseCRS = datum.geographic();
            }
        }
        /*
             * At this point we got a coordinate system with axes in metres.
             * If the user asked for another unit of measurement, change the axes now.
             */
        Unit<Length> unit;
        if (isLegacy) {
            unit = createUnitFromEPSG(factor).asType(Length.class);
        } else {
            unit = Units.METRE;
            if (factor != 1)
                unit = unit.multiply(factor);
        }
        if (!Units.METRE.equals(unit)) {
            cs = (CartesianCS) CoordinateSystems.replaceLinearUnit(cs, unit);
        }
        /*
             * Set the projection name, operation method and parameters. The parameters for the Transverse Mercator
             * projection are a little bit more tedious to set, so we use a convenience method for that.
             */
        final GeodeticObjectBuilder builder = new GeodeticObjectBuilder();
        if (isUTM != null) {
            if (isUTM && crs != null) {
                builder.addName(crs.getName());
            }
            // else default to the conversion name, which is "Transverse Mercator".
            builder.setTransverseMercator(isUTM ? Zoner.UTM : Zoner.ANY, latitude, longitude);
        } else {
            builder.setConversionMethod(method).addName(PROJECTION_NAMES[projection - FIRST_PROJECTION_CODE]).setParameter(Constants.CENTRAL_MERIDIAN, longitude, Units.DEGREE);
            if (param != null) {
                builder.setParameter(param, latitude, Units.DEGREE);
            }
        }
        return builder.createProjectedCRS(baseCRS, cs);
    } catch (IllegalArgumentException e) {
        throw noSuchAuthorityCode(String.valueOf(projection), code, e);
    }
}
Also used : CartesianCS(org.opengis.referencing.cs.CartesianCS) ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) Length(javax.measure.quantity.Length) GeodeticObjectBuilder(org.apache.sis.internal.referencing.GeodeticObjectBuilder) InternationalString(org.opengis.util.InternationalString) SimpleInternationalString(org.apache.sis.util.iso.SimpleInternationalString) CommonCRS(org.apache.sis.referencing.CommonCRS) GeographicCRS(org.opengis.referencing.crs.GeographicCRS)

Example 19 with GeographicCRS

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

the class DefaultCoordinateOperationFactory method createSingleOperation.

/**
 * Creates a transformation or conversion from the given properties.
 * This method infers by itself if the operation to create is a
 * {@link Transformation}, a {@link Conversion} or a {@link Projection} sub-type
 * ({@link CylindricalProjection}, {@link ConicProjection} or {@link PlanarProjection})
 * using the {@linkplain DefaultOperationMethod#getOperationType() information provided by the given method}.
 *
 * <p>The properties given in argument follow the same rules than for the
 * {@linkplain AbstractCoordinateOperation#AbstractCoordinateOperation(Map, CoordinateReferenceSystem,
 * CoordinateReferenceSystem, CoordinateReferenceSystem, MathTransform) coordinate operation} constructor.
 * The following table is a reminder of main (not all) properties:</p>
 *
 * <table class="sis">
 *   <caption>Recognized properties (non exhaustive list)</caption>
 *   <tr>
 *     <th>Property name</th>
 *     <th>Value type</th>
 *     <th>Returned by</th>
 *   </tr>
 *   <tr>
 *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
 *     <td>{@link org.opengis.metadata.Identifier} or {@link String}</td>
 *     <td>{@link DefaultConversion#getName()}</td>
 *   </tr>
 *   <tr>
 *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
 *     <td>{@link org.opengis.metadata.Identifier} (optionally as array)</td>
 *     <td>{@link DefaultConversion#getIdentifiers()}</td>
 *   </tr>
 *   <tr>
 *     <td>{@value org.opengis.referencing.operation.CoordinateOperation#DOMAIN_OF_VALIDITY_KEY}</td>
 *     <td>{@link org.opengis.metadata.extent.Extent}</td>
 *     <td>{@link DefaultConversion#getDomainOfValidity()}</td>
 *   </tr>
 * </table>
 *
 * @param  properties        the properties to be given to the identified object.
 * @param  sourceCRS         the source CRS.
 * @param  targetCRS         the target CRS.
 * @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  transform         transform from positions in the source CRS to positions in the target CRS.
 * @return the coordinate operation created from the given arguments.
 * @throws FactoryException if the object creation failed.
 *
 * @see DefaultOperationMethod#getOperationType()
 * @see DefaultTransformation
 * @see DefaultConversion
 */
public SingleOperation createSingleOperation(final Map<String, ?> properties, final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS, final CoordinateReferenceSystem interpolationCRS, final OperationMethod method, MathTransform transform) throws FactoryException {
    ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
    ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
    ArgumentChecks.ensureNonNull("method", method);
    /*
         * Undocumented (for now) feature: if the 'transform' argument is null but parameters are
         * found in the given properties, create the MathTransform instance from those parameters.
         * This is needed for WKT parsing of CoordinateOperation[…] among others.
         */
    if (transform == null) {
        final ParameterValueGroup parameters = Containers.property(properties, ReferencingServices.PARAMETERS_KEY, ParameterValueGroup.class);
        if (parameters == null) {
            throw new NullArgumentException(Errors.format(Errors.Keys.NullArgument_1, "transform"));
        }
        transform = getMathTransformFactory().createBaseToDerived(sourceCRS, parameters, targetCRS.getCoordinateSystem());
    }
    /*
         * The "operationType" property is currently undocumented. The intent is to help this factory method in
         * situations where the given operation method is not an Apache SIS implementation or does not override
         * getOperationType(), or the method is ambiguous (e.g. "Affine" can be used for both a transformation
         * or a conversion).
         *
         * If we have both a 'baseType' and a Method.getOperationType(), take the most specific type.
         * An exception will be thrown if the two types are incompatible.
         */
    Class<?> baseType = Containers.property(properties, ReferencingServices.OPERATION_TYPE_KEY, Class.class);
    if (baseType == null) {
        baseType = SingleOperation.class;
    }
    if (method instanceof DefaultOperationMethod) {
        final Class<? extends SingleOperation> c = ((DefaultOperationMethod) method).getOperationType();
        if (c != null) {
            // Paranoiac check (above method should not return null).
            if (baseType.isAssignableFrom(c)) {
                baseType = c;
            } else if (!c.isAssignableFrom(baseType)) {
                throw new IllegalArgumentException(Errors.format(Errors.Keys.IncompatiblePropertyValue_1, ReferencingServices.OPERATION_TYPE_KEY));
            }
        }
    }
    /*
         * If the base type is still abstract (probably because it was not specified neither in the given OperationMethod
         * or in the properties), then try to find a concrete type using the following rules derived from the definitions
         * given in ISO 19111:
         *
         *   - If the two CRS uses the same datum (ignoring metadata), assume that we have a Conversion.
         *   - Otherwise we have a datum change, which implies that we have a Transformation.
         *
         * In the case of Conversion, we can specialize one step more if the conversion is going from a geographic CRS
         * to a projected CRS. It may seems that we should check if ProjectedCRS.getBaseCRS() is equals (ignoring meta
         * data) to source CRS. But we already checked the datum, which is the important part. The axis order and unit
         * could be different, which we want to allow.
         */
    if (baseType == SingleOperation.class) {
        if (isConversion(sourceCRS, targetCRS)) {
            if (interpolationCRS == null && sourceCRS instanceof GeographicCRS && targetCRS instanceof ProjectedCRS) {
                baseType = Projection.class;
            } else {
                baseType = Conversion.class;
            }
        } else {
            baseType = Transformation.class;
        }
    }
    /*
         * Now create the coordinate operation of the requested type. If we can not find a concrete class for the
         * requested type, we will instantiate a SingleOperation in last resort.  The later action is a departure
         * from ISO 19111 since 'SingleOperation' is conceptually abstract.  But we do that as a way to said that
         * we are missing this important piece of information but still go ahead.
         *
         * It is inconvenient to guarantee that the created operation is an instance of 'baseType' since the user
         * could have specified an implementation class or a custom sub-interface. We will perform the type check
         * only after object creation.
         */
    final AbstractSingleOperation op;
    if (Transformation.class.isAssignableFrom(baseType)) {
        op = new DefaultTransformation(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
    } else if (Projection.class.isAssignableFrom(baseType)) {
        ArgumentChecks.ensureCanCast("sourceCRS", GeographicCRS.class, sourceCRS);
        ArgumentChecks.ensureCanCast("targetCRS", ProjectedCRS.class, targetCRS);
        if (interpolationCRS != null) {
            throw new IllegalArgumentException(Errors.format(Errors.Keys.ForbiddenAttribute_2, "interpolationCRS", baseType));
        }
        final GeographicCRS baseCRS = (GeographicCRS) sourceCRS;
        final ProjectedCRS crs = (ProjectedCRS) targetCRS;
        if (CylindricalProjection.class.isAssignableFrom(baseType)) {
            op = new DefaultCylindricalProjection(properties, baseCRS, crs, method, transform);
        } else if (ConicProjection.class.isAssignableFrom(baseType)) {
            op = new DefaultConicProjection(properties, baseCRS, crs, method, transform);
        } else if (PlanarProjection.class.isAssignableFrom(baseType)) {
            op = new DefaultPlanarProjection(properties, baseCRS, crs, method, transform);
        } else {
            op = new DefaultProjection(properties, baseCRS, crs, method, transform);
        }
    } else if (Conversion.class.isAssignableFrom(baseType)) {
        op = new DefaultConversion(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
    } else {
        // See above comment about this last-resort fallback.
        op = new AbstractSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
    }
    if (!baseType.isInstance(op)) {
        throw new FactoryException(Resources.format(Resources.Keys.CanNotCreateObjectAsInstanceOf_2, baseType, op.getName()));
    }
    return pool.unique(op);
}
Also used : ParameterValueGroup(org.opengis.parameter.ParameterValueGroup) FactoryException(org.opengis.util.FactoryException) NullArgumentException(org.apache.sis.util.NullArgumentException) ProjectedCRS(org.opengis.referencing.crs.ProjectedCRS) GeographicCRS(org.opengis.referencing.crs.GeographicCRS)

Example 20 with GeographicCRS

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

the class LocationFormat method format.

/**
 * Writes a textual representation of the given location in the given stream or buffer.
 *
 * <div class="warning"><b>Upcoming API change — generalization</b><br>
 * in a future SIS version, the type of {@code location} parameter may be generalized
 * to the {@code org.opengis.referencing.gazetteer.Location} interface.
 * This change is pending GeoAPI revision.</div>
 *
 * @param  location    the location to format.
 * @param  toAppendTo  where to format the location.
 * @throws IOException if an error occurred while writing to the given appendable.
 */
@Override
@SuppressWarnings({ "fallthrough", "null" })
public void format(final AbstractLocation location, final Appendable toAppendTo) throws IOException {
    ArgumentChecks.ensureNonNull("location", location);
    final Locale locale = getLocale(Locale.Category.DISPLAY);
    final Vocabulary vocabulary = Vocabulary.getResources(locale);
    final TableAppender table = new TableAppender(toAppendTo, "│ ", columnSeparator, " │");
    table.setMultiLinesCells(true);
    /*
         * Location type.
         */
    table.appendHorizontalSeparator();
    final AbstractLocationType type = location.type();
    if (type != null) {
        append(table, vocabulary, Vocabulary.Keys.LocationType, toString(type.getName(), locale));
    }
    /*
         * Geographic identifier and alternative identifiers, if any.
         */
    append(table, vocabulary, Vocabulary.Keys.GeographicIdentifier, toString(location.getGeographicIdentifier(), locale));
    final Collection<? extends InternationalString> alt = location.getAlternativeGeographicIdentifiers();
    if (alt != null && !alt.isEmpty()) {
        boolean isFirst = true;
        vocabulary.appendLabel(Vocabulary.Keys.AlternativeIdentifiers, table);
        nextColumn(table);
        for (final InternationalString id : alt) {
            if (!isFirst) {
                isFirst = false;
                table.append(lineSeparator);
            }
            table.append(id);
        }
        table.nextLine();
    }
    /*
         * Extents (temporal and geographic). If an envelope exists and the CRS is not geographic,
         * then the envelope bounds will be appended on the same lines than the geographic bounds.
         * But before writing the bounding box and/or the envelope, check if they are redundant.
         * We may also need to change axis order (but not unit) of the envelope in order to match
         * the axis order of the geographic bounding box.
         */
    final Extent extent = new DefaultExtent(null, location.getGeographicExtent(), null, location.getTemporalExtent());
    final Range<Date> time = Extents.getTimeRange(extent);
    if (time != null) {
        append(table, vocabulary, Vocabulary.Keys.StartDate, toString(time.getMinValue()));
        append(table, vocabulary, Vocabulary.Keys.EndDate, toString(time.getMaxValue()));
    }
    GeographicBoundingBox bbox = Extents.getGeographicBoundingBox(extent);
    Envelope envelope = location.getEnvelope();
    DirectPosition position = position(location.getPosition());
    // Position in geographic CRS.
    DirectPosition geopos = null;
    // Envelope Coordinate Reference System.
    CoordinateReferenceSystem crs = null;
    // CRS in conventional (x,y) axis order.
    CoordinateReferenceSystem normCRS = null;
    // If failed to transform envelope.
    Exception warning = null;
    try {
        if (envelope != null) {
            normCRS = normalize(crs = envelope.getCoordinateReferenceSystem());
            if (normCRS != crs) {
                // Should only change order and sign.
                envelope = Envelopes.transform(envelope, normCRS);
            }
        }
        if (position != null) {
            /*
                 * If only one of the envelope or the position objects specify a CRS, assume that the other object
                 * use the same CRS. If both the envelope and the position objects specify a CRS, the envelope CRS
                 * will have precedence and the "representative position" will be projected to that CRS.
                 */
            final CoordinateReferenceSystem posCRS = position.getCoordinateReferenceSystem();
            if (normCRS == null) {
                normCRS = normalize(crs = posCRS);
                if (normCRS != crs) {
                    // Should only change order and sign.
                    envelope = Envelopes.transform(envelope, normCRS);
                }
            }
            if (bbox != null) {
                // Compute geographic position only if there is a geographic bounding box.
                GeographicCRS geogCRS = ReferencingUtilities.toNormalizedGeographicCRS(posCRS);
                if (geogCRS != null) {
                    geopos = transform(position, posCRS, geogCRS);
                }
            }
            position = transform(position, posCRS, normCRS);
        }
    } catch (FactoryException | TransformException e) {
        envelope = null;
        position = null;
        warning = e;
    }
    /*
         * At this point we got the final geographic bounding box and/or envelope to write.
         * Since we will write the projected and geographic coordinates side-by-side in the same cells,
         * we need to format them in advance so we can compute their width for internal right-alignment.
         * We do the alignment ourselves instead than using TableAppender.setCellAlignment(ALIGN_RIGHT)
         * because we do not want (projected geographic) tuple to appear far on the right side if other
         * cells have long texts.
         */
    if (bbox != null || envelope != null) {
        final CoordinateSystem cs = (crs != null) ? crs.getCoordinateSystem() : null;
        String[] geographic = null;
        String[] projected = null;
        String[] unitSymbol = null;
        AngleFormat geogFormat = null;
        NumberFormat projFormat = null;
        UnitFormat unitFormat = null;
        int maxGeogLength = 0;
        int maxProjLength = 0;
        int maxUnitLength = 0;
        boolean showProj = false;
        if (bbox != null || geopos != null) {
            geogFormat = (AngleFormat) getFormat(Angle.class);
            geographic = new String[BOUND_KEY.length];
            Arrays.fill(geographic, "");
        }
        if (envelope != null || position != null) {
            projFormat = (NumberFormat) getFormat(Number.class);
            unitFormat = (UnitFormat) getFormat(Unit.class);
            projected = new String[BOUND_KEY.length];
            unitSymbol = new String[BOUND_KEY.length];
            Arrays.fill(projected, "");
            Arrays.fill(unitSymbol, "");
        }
        for (int i = 0; i < BOUND_KEY.length; i++) {
            RoundingMode rounding = RoundingMode.FLOOR;
            double g = Double.NaN;
            double p = Double.NaN;
            int dimension = 0;
            switch(i) {
                case 0:
                    if (bbox != null)
                        g = bbox.getWestBoundLongitude();
                    if (envelope != null)
                        p = envelope.getMinimum(0);
                    break;
                case 2:
                    if (bbox != null)
                        g = bbox.getEastBoundLongitude();
                    if (envelope != null)
                        p = envelope.getMaximum(0);
                    rounding = RoundingMode.CEILING;
                    break;
                case 3:
                    if (bbox != null)
                        g = bbox.getSouthBoundLatitude();
                    if (envelope != null)
                        p = envelope.getMinimum(1);
                    dimension = 1;
                    break;
                case 5:
                    if (bbox != null)
                        g = bbox.getNorthBoundLatitude();
                    if (envelope != null)
                        p = envelope.getMaximum(1);
                    rounding = RoundingMode.CEILING;
                    dimension = 1;
                    break;
                // Fall through
                case 4:
                    dimension = 1;
                case 1:
                    if (geopos != null)
                        g = geopos.getOrdinate(dimension);
                    if (position != null)
                        p = position.getOrdinate(dimension);
                    rounding = RoundingMode.HALF_EVEN;
                    break;
            }
            if (!Double.isNaN(p)) {
                showProj |= (g != p);
                if (cs != null) {
                    final Unit<?> unit = cs.getAxis(dimension).getUnit();
                    if (unit != null) {
                        final int length = (unitSymbol[i] = unitFormat.format(unit)).length();
                        if (length > maxUnitLength) {
                            maxUnitLength = length;
                        }
                    }
                }
                try {
                    projFormat.setRoundingMode(rounding);
                } catch (UnsupportedOperationException e) {
                // Ignore.
                }
                final int length = (projected[i] = projFormat.format(p)).length();
                if (length > maxProjLength) {
                    maxProjLength = length;
                }
            }
            if (!Double.isNaN(g)) {
                geogFormat.setRoundingMode(rounding);
                final Angle angle = (dimension == 0) ? new Longitude(g) : new Latitude(g);
                final int length = (geographic[i] = geogFormat.format(angle)).length();
                if (length > maxGeogLength) {
                    maxGeogLength = length;
                }
            }
        }
        if (!showProj) {
            // All projected coordinates are identical to geographic ones.
            projected = null;
            unitSymbol = null;
            maxProjLength = 0;
            maxUnitLength = 0;
        } else if (maxProjLength != 0) {
            if (maxUnitLength != 0) {
                maxUnitLength++;
            }
            // Arbitrary space between projected and geographic coordinates.
            maxGeogLength += 4;
        }
        /*
             * At this point all coordinates have been formatted in advance.
             */
        final String separator = (projected != null && geographic != null) ? "    —" : "";
        for (int i = 0; i < BOUND_KEY.length; i++) {
            final String p = (projected != null) ? projected[i] : "";
            final String u = (unitSymbol != null) ? unitSymbol[i] : "";
            final String g = (geographic != null) ? geographic[i] : "";
            if (!p.isEmpty() || !g.isEmpty()) {
                vocabulary.appendLabel(BOUND_KEY[i], table);
                nextColumn(table);
                table.append(CharSequences.spaces(maxProjLength - p.length())).append(p);
                table.append(CharSequences.spaces(maxUnitLength - u.length())).append(u).append(separator);
                table.append(CharSequences.spaces(maxGeogLength - g.length())).append(g);
                table.nextLine();
            }
        }
    }
    if (crs != null) {
        append(table, vocabulary, Vocabulary.Keys.CoordinateRefSys, IdentifiedObjects.getName(crs, null));
    }
    /*
         * Organization responsible for defining the characteristics of the location instance.
         */
    final AbstractParty administrator = location.getAdministrator();
    if (administrator != null) {
        append(table, vocabulary, Vocabulary.Keys.Administrator, toString(administrator.getName(), locale));
    }
    table.appendHorizontalSeparator();
    table.flush();
    if (warning != null) {
        vocabulary.appendLabel(Vocabulary.Keys.Warnings, toAppendTo);
        toAppendTo.append(warning.toString()).append(lineSeparator);
    }
}
Also used : Locale(java.util.Locale) Vocabulary(org.apache.sis.util.resources.Vocabulary) DirectPosition(org.opengis.geometry.DirectPosition) DefaultExtent(org.apache.sis.metadata.iso.extent.DefaultExtent) Extent(org.opengis.metadata.extent.Extent) FactoryException(org.opengis.util.FactoryException) CoordinateSystem(org.opengis.referencing.cs.CoordinateSystem) UnitFormat(org.apache.sis.measure.UnitFormat) RoundingMode(java.math.RoundingMode) TableAppender(org.apache.sis.io.TableAppender) Latitude(org.apache.sis.measure.Latitude) GeographicBoundingBox(org.opengis.metadata.extent.GeographicBoundingBox) InternationalString(org.opengis.util.InternationalString) AngleFormat(org.apache.sis.measure.AngleFormat) Envelope(org.opengis.geometry.Envelope) DefaultExtent(org.apache.sis.metadata.iso.extent.DefaultExtent) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) GeographicCRS(org.opengis.referencing.crs.GeographicCRS) AbstractParty(org.apache.sis.metadata.iso.citation.AbstractParty) TransformException(org.opengis.referencing.operation.TransformException) Longitude(org.apache.sis.measure.Longitude) Date(java.util.Date) ParseException(java.text.ParseException) TransformException(org.opengis.referencing.operation.TransformException) IOException(java.io.IOException) FactoryException(org.opengis.util.FactoryException) Angle(org.apache.sis.measure.Angle) InternationalString(org.opengis.util.InternationalString) NumberFormat(java.text.NumberFormat)

Aggregations

GeographicCRS (org.opengis.referencing.crs.GeographicCRS)40 Test (org.junit.Test)27 DependsOnMethod (org.apache.sis.test.DependsOnMethod)15 ProjectedCRS (org.opengis.referencing.crs.ProjectedCRS)10 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)9 Conversion (org.opengis.referencing.operation.Conversion)6 CoordinateOperation (org.opengis.referencing.operation.CoordinateOperation)6 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)5 DefaultConversion (org.apache.sis.referencing.operation.DefaultConversion)4 GeographicBoundingBox (org.opengis.metadata.extent.GeographicBoundingBox)4 CartesianCS (org.opengis.referencing.cs.CartesianCS)4 DefaultGeographicBoundingBox (org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox)3 DefaultGeographicCRS (org.apache.sis.referencing.crs.DefaultGeographicCRS)3 ParameterValueGroup (org.opengis.parameter.ParameterValueGroup)3 VerticalCRS (org.opengis.referencing.crs.VerticalCRS)3 EllipsoidalCS (org.opengis.referencing.cs.EllipsoidalCS)3 TransformException (org.opengis.referencing.operation.TransformException)3 HashMap (java.util.HashMap)2 Angle (javax.measure.quantity.Angle)2 Length (javax.measure.quantity.Length)2