Package org.apache.sis.referencing.crs

Source Code of org.apache.sis.referencing.crs.DefaultGeodeticCRS

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sis.referencing.crs;

import java.util.Map;
import javax.measure.unit.Unit;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.opengis.referencing.cs.CartesianCS;
import org.opengis.referencing.cs.SphericalCS;
import org.opengis.referencing.cs.EllipsoidalCS;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.crs.GeodeticCRS;
import org.opengis.referencing.datum.GeodeticDatum;
import org.apache.sis.internal.referencing.Legacy;
import org.apache.sis.internal.referencing.WKTUtilities;
import org.apache.sis.referencing.AbstractReferenceSystem;
import org.apache.sis.io.wkt.Formatter;

import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
import static org.apache.sis.internal.referencing.WKTUtilities.toFormattable;


/**
* A 2D or 3D coordinate reference system based on a geodetic datum.
* The CRS is geographic if associated with an ellipsoidal coordinate system,
* or geocentric if associated with a spherical or Cartesian coordinate system.
*
* <p><b>Used with coordinate system types:</b>
*   {@linkplain org.apache.sis.referencing.cs.DefaultCartesianCS Cartesian},
*   {@linkplain org.apache.sis.referencing.cs.DefaultSphericalCS Spherical} or
*   {@linkplain org.apache.sis.referencing.cs.DefaultEllipsoidalCS Ellipsoidal}.
* </p>
*
* @author  Martin Desruisseaux (IRD, Geomatys)
* @since   0.4 (derived from geotk-1.2)
* @version 0.4
* @module
*/
@XmlType(name = "GeodeticCRSType", propOrder = {
    "ellipsoidalCS",
    "cartesianCS",
    "sphericalCS",
    "datum"
})
@XmlRootElement(name = "GeodeticCRS")
class DefaultGeodeticCRS extends AbstractCRS implements GeodeticCRS { // If made public, see comment in getDatum().
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = -6205678223972395910L;

    /**
     * The datum.
     */
    @XmlElement(name = "geodeticDatum")
    private final GeodeticDatum datum;

    /**
     * Constructs a new object in which every attributes are set to a null value.
     * <strong>This is not a valid object.</strong> This constructor is strictly
     * reserved to JAXB, which will assign values to the fields using reflexion.
     */
    DefaultGeodeticCRS() {
        datum = null;
    }

    /**
     * Creates a coordinate reference system from the given properties, datum and coordinate system.
     * The properties given in argument follow the same rules than for the
     * {@linkplain AbstractReferenceSystem#AbstractReferenceSystem(Map) super-class constructor}.
     *
     * <p>This constructor is not public because it does not verify the {@code cs} type.</p>
     *
     * @param properties The properties to be given to the coordinate reference system.
     * @param datum The datum.
     * @param cs The coordinate system.
     */
    DefaultGeodeticCRS(final Map<String,?> properties,
                       final GeodeticDatum datum,
                       final CoordinateSystem cs)
    {
        super(properties, cs);
        ensureNonNull("datum", datum);
        this.datum = datum;
    }

    /**
     * Constructs a new coordinate reference system with the same values than the specified one.
     * This copy constructor provides a way to convert an arbitrary implementation into a SIS one
     * or a user-defined one (as a subclass), usually in order to leverage some implementation-specific API.
     *
     * <p>This constructor performs a shallow copy, i.e. the properties are not cloned.</p>
     *
     * @param crs The coordinate reference system to copy.
     */
    protected DefaultGeodeticCRS(final GeodeticCRS crs) {
        super(crs);
        datum = crs.getDatum();
    }

    /**
     * Returns the GeoAPI interface implemented by this class.
     * The SIS implementation returns {@code GeodeticCRS.class}.
     * Subclasses implementing a more specific GeoAPI interface shall override this method.
     *
     * @return The coordinate reference system interface implemented by this class.
     */
    @Override
    public Class<? extends GeodeticCRS> getInterface() {
        return GeodeticCRS.class;
    }

    /**
     * Returns the datum.
     *
     * This method is overridden is subclasses for documentation purpose only, mostly for showing this method in
     * the appropriate position in javadoc (instead than at the bottom of the page). If {@code DefaultGeodeticCRS}
     * is made public in a future SIS version, then we should make this method final and remove the overridden methods.
     *
     * @return The datum.
     */
    @Override
    public GeodeticDatum getDatum() {
        return datum;
    }

    /**
     * Invoked by JAXB at marshalling time.
     */
    @XmlElement(name="cartesianCS")   private CartesianCS   getCartesianCS()   {return getCoordinateSystem(CartesianCS  .class);}
    @XmlElement(name="sphericalCS")   private SphericalCS   getSphericalCS()   {return getCoordinateSystem(SphericalCS  .class);}
    @XmlElement(name="ellipsoidalCS") private EllipsoidalCS getEllipsoidalCS() {return getCoordinateSystem(EllipsoidalCS.class);}

    /**
     * Invoked by JAXB at unmarshalling time.
     */
    private void setCartesianCS  (final CartesianCS   cs) {super.setCoordinateSystem("cartesianCS",   cs);}
    private void setSphericalCS  (final SphericalCS   cs) {super.setCoordinateSystem("sphericalCS",   cs);}
    private void setEllipsoidalCS(final EllipsoidalCS cs) {super.setCoordinateSystem("ellipsoidalCS", cs);}

    /**
     * Returns a coordinate reference system of the same type than this CRS but with different axes.
     * This method shall be overridden by all {@code DefaultGeodeticCRS} subclasses in this package.
     */
    @Override
    AbstractCRS createSameType(final Map<String,?> properties, final CoordinateSystem cs) {
        return new DefaultGeodeticCRS(properties, datum, cs);
    }

    /**
     * Formats this CRS as a <cite>Well Known Text</cite> {@code GeodeticCRS[…]} element.
     *
     * @return {@code "GeodeticCRS"} (WKT 2) or {@code "GeogCS"}/{@code "GeocCS"} (WKT 1).
     */
    @Override
    protected String formatTo(final Formatter formatter) {
        WKTUtilities.appendName(this, formatter, null);
        final boolean isWKT1  = formatter.getConvention().majorVersion() == 1;
        final Unit<?> unit    = getUnit();
        final Unit<?> oldUnit = formatter.addContextualUnit(unit);
        formatter.newLine();
        formatter.append(toFormattable(datum));
        formatter.newLine();
        formatter.indent(isWKT1 ? 0 : +1);
        formatter.append(toFormattable(datum.getPrimeMeridian()));
        formatter.indent(isWKT1 ? 0 : -1);
        formatter.newLine();
        CoordinateSystem cs = super.getCoordinateSystem();
        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);
            }
            /*
             * Replaces the given coordinate system by an instance conform to the conventions used in WKT 1.
             * Note that we can not delegate this task to subclasses, because XML unmarshalling of a geodetic
             * CRS will NOT create an instance of a subclass (because the distinction between geographic and
             * geocentric CRS is not anymore in ISO 19111:2007).
             */
            if (!(cs instanceof EllipsoidalCS)) { // Tested first because this is the most common case.
                if (cs instanceof CartesianCS) {
                    cs = Legacy.forGeocentricCRS((CartesianCS) cs, true);
                } else {
                    formatter.setInvalidWKT(cs, null);
                }
            }
        } else {
            formatter.append(toFormattable(cs)); // The concept of CoordinateSystem was not explicit in WKT 1.
            formatter.indent(+1);
        }
        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.removeContextualUnit(unit);
        formatter.addContextualUnit(oldUnit);
        formatter.newLine(); // For writing the ID[…] element on its own line.
        if (!isWKT1) {
            return "GeodeticCRS";
        }
        /*
         * For WKT1, the keyword depends on the subclass: "GeogCS" for GeographicCRS,
         * or 'GeocCS" for GeocentricCRS. However we can not rely on the subclass for
         * choosing the keyword, because in some situations (after XML unmarhaling)
         * we only have a GeodeticCRS. We need to make the choice here. The CS type
         * is a sufficient criterion.
         */
        return (cs instanceof EllipsoidalCS) ? "GeogCS" : "GeocCS";
    }
}
TOP

Related Classes of org.apache.sis.referencing.crs.DefaultGeodeticCRS

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.