| /* |
| * 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.factory; |
| |
| import java.util.Date; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.HashMap; |
| import java.util.Collections; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import java.util.logging.LogRecord; |
| import java.util.concurrent.atomic.AtomicReference; |
| import java.lang.reflect.Constructor; |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| import javax.measure.Unit; |
| import javax.measure.quantity.Angle; |
| import javax.measure.quantity.Length; |
| import javax.xml.bind.JAXBException; |
| import org.opengis.util.GenericName; |
| import org.opengis.util.FactoryException; |
| import org.opengis.util.InternationalString; |
| import org.opengis.metadata.Identifier; |
| import org.opengis.metadata.extent.Extent; |
| import org.opengis.referencing.*; |
| import org.opengis.referencing.cs.*; |
| import org.opengis.referencing.crs.*; |
| import org.opengis.referencing.datum.*; |
| import org.opengis.referencing.operation.*; |
| import org.opengis.parameter.ParameterNotFoundException; |
| import org.apache.sis.referencing.cs.*; |
| import org.apache.sis.referencing.crs.*; |
| import org.apache.sis.referencing.datum.*; |
| import org.apache.sis.referencing.NamedIdentifier; |
| import org.apache.sis.referencing.IdentifiedObjects; |
| import org.apache.sis.referencing.AbstractReferenceSystem; |
| import org.apache.sis.referencing.AbstractIdentifiedObject; |
| import org.apache.sis.internal.referencing.ReferencingFactoryContainer; |
| import org.apache.sis.internal.referencing.MergedProperties; |
| import org.apache.sis.internal.system.DefaultFactories; |
| import org.apache.sis.internal.system.Loggers; |
| import org.apache.sis.internal.util.CollectionsExt; |
| import org.apache.sis.util.collection.WeakHashSet; |
| import org.apache.sis.util.iso.AbstractFactory; |
| import org.apache.sis.util.resources.Messages; |
| import org.apache.sis.util.resources.Errors; |
| import org.apache.sis.util.logging.Logging; |
| import org.apache.sis.util.ArgumentChecks; |
| import org.apache.sis.io.wkt.Parser; |
| import org.apache.sis.util.Exceptions; |
| import org.apache.sis.xml.XML; |
| |
| |
| /** |
| * Creates {@linkplain org.apache.sis.referencing.crs.AbstractCRS Coordinate Reference System} (CRS) implementations, |
| * with their {@linkplain org.apache.sis.referencing.cs.AbstractCS Coordinate System} (CS) |
| * and {@linkplain org.apache.sis.referencing.datum.AbstractDatum Datum} components. |
| * This factory serves two purposes: |
| * |
| * <ul> |
| * <li><b>For users</b>, allows the creation of complex objects that can not be created by the authority factories, |
| * without explicit dependency to Apache SIS (when using the GeoAPI interfaces implemented by this class).</li> |
| * <li><b>For providers</b>, allows <cite>inversion of control</cite> by overriding methods in this class, |
| * then specifying the customized instance to other services that consume {@code CRSFactory} (for example |
| * authority factories or {@linkplain org.apache.sis.io.wkt.WKTFormat WKT parsers}).</li> |
| * </ul> |
| * |
| * This {@code GeodeticObjectFactory} class is not easy to use directly. |
| * Users are encouraged to use an authority factory instead |
| * (or the {@link org.apache.sis.referencing.CRS#forCode(String)} convenience method) |
| * when the CRS object to construct can be identified by a code in the namespace of an authority (typically EPSG). |
| * |
| * <div class="section">Object properties</div> |
| * Most factory methods expect a {@link Map Map<String,?>} argument, often followed by explicit arguments. |
| * Unless otherwise noticed, information provided in the {@code properties} map are considered ignorable metadata |
| * while information provided in explicit arguments have an impact on coordinate transformation results. |
| * |
| * <p>The following table lists the keys recognized by the {@code GeodeticObjectFactory} default implementation, |
| * together with the type of values associated to those keys. |
| * A value for the {@code "name"} key is mandatory for all objects, while all other properties are optional. |
| * {@code GeodeticObjectFactory} methods ignore all unknown 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 Identifier} or {@link String}</td> |
| * <td>{@link AbstractIdentifiedObject#getName()}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.opengis.metadata.Identifier#AUTHORITY_KEY}</td> |
| * <td>{@link String} or {@link org.opengis.metadata.citation.Citation}</td> |
| * <td>{@link NamedIdentifier#getAuthority()} on the {@linkplain AbstractIdentifiedObject#getName() name}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.opengis.metadata.Identifier#CODE_KEY}</td> |
| * <td>{@link String}</td> |
| * <td>{@link NamedIdentifier#getCode()} on the {@linkplain AbstractIdentifiedObject#getName() name}</td> |
| * </tr> |
| * <tr> |
| * <td>"codespace"</td> |
| * <td>{@link String}</td> |
| * <td>{@link NamedIdentifier#getCodeSpace()} on the {@linkplain AbstractIdentifiedObject#getName() name}</td> |
| * </tr> |
| * <tr> |
| * <td>"version"</td> |
| * <td>{@link String}</td> |
| * <td>{@link NamedIdentifier#getVersion()} on the {@linkplain AbstractIdentifiedObject#getName() name}</td> |
| * </tr> |
| * <tr> |
| * <td>"description"</td> |
| * <td>{@link String}</td> |
| * <td>{@link NamedIdentifier#getDescription()} on the {@linkplain AbstractIdentifiedObject#getName() name}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.opengis.referencing.IdentifiedObject#ALIAS_KEY}</td> |
| * <td>{@link GenericName} or {@link CharSequence} (optionally as array)</td> |
| * <td>{@link AbstractIdentifiedObject#getAlias()}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td> |
| * <td>{@link Identifier} (optionally as array)</td> |
| * <td>{@link AbstractIdentifiedObject#getIdentifiers()}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.opengis.referencing.ReferenceSystem#DOMAIN_OF_VALIDITY_KEY}</td> |
| * <td>{@link Extent}</td> |
| * <td>{@link AbstractReferenceSystem#getDomainOfValidity()}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.opengis.referencing.ReferenceSystem#SCOPE_KEY}</td> |
| * <td>{@link String} or {@link InternationalString}</td> |
| * <td>{@link AbstractReferenceSystem#getScope()}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.opengis.referencing.datum.Datum#ANCHOR_POINT_KEY}</td> |
| * <td>{@link InternationalString} or {@link String}</td> |
| * <td>{@link AbstractDatum#getAnchorPoint()}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.opengis.referencing.datum.Datum#REALIZATION_EPOCH_KEY}</td> |
| * <td>{@link Date}</td> |
| * <td>{@link AbstractDatum#getRealizationEpoch()}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.opengis.referencing.IdentifiedObject#REMARKS_KEY}</td> |
| * <td>{@link InternationalString} or {@link String}</td> |
| * <td>{@link AbstractIdentifiedObject#getRemarks()}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.apache.sis.referencing.AbstractIdentifiedObject#DEPRECATED_KEY}</td> |
| * <td>{@link Boolean}</td> |
| * <td>{@link AbstractIdentifiedObject#isDeprecated()}</td> |
| * </tr> |
| * <tr> |
| * <td>{@value org.apache.sis.referencing.AbstractIdentifiedObject#LOCALE_KEY}</td> |
| * <td>{@link Locale}</td> |
| * <td>(none)</td> |
| * </tr> |
| * </table> |
| * |
| * <div class="section">Localization</div> |
| * All localizable attributes like {@code "remarks"} may have a language and country code suffix. |
| * For example the {@code "remarks_fr"} property stands for remarks in {@linkplain Locale#FRENCH French} and |
| * the {@code "remarks_fr_CA"} property stands for remarks in {@linkplain Locale#CANADA_FRENCH French Canadian}. |
| * They are convenience properties for building the {@code InternationalString} value. |
| * |
| * <p>The {@code "locale"} property applies only in case of exception for formatting the error message, and |
| * is used only on a <cite>best effort</cite> basis. The locale is discarded after successful construction |
| * since localizations are applied by the {@link InternationalString#toString(Locale)} method.</p> |
| * |
| * @author Martin Desruisseaux (IRD, Geomatys) |
| * @author Guilhem Legal (Geomatys) |
| * @author Johann Sorel (Geomatys) |
| * @version 0.8 |
| * @since 0.6 |
| * @module |
| */ |
| public class GeodeticObjectFactory extends AbstractFactory implements CRSFactory, CSFactory, DatumFactory, Parser { |
| /** |
| * The logger to use for reporting object creations. |
| */ |
| private static final Logger LOGGER = Logging.getLogger(Loggers.CRS_FACTORY); |
| |
| /** |
| * The constructor for WKT parsers, fetched when first needed. The WKT parser is defined in the |
| * same module than this class, so we will hopefully not have security issues. But we have to |
| * use reflection because the parser class is not yet public (because we do not want to commit |
| * its API yet). |
| */ |
| private static volatile Constructor<? extends Parser> parserConstructor; |
| |
| /** |
| * The default properties, or an empty map if none. This map shall not change after construction in |
| * order to allow usage without synchronization in multi-thread context. But we do not need to wrap |
| * in a unmodifiable map since {@code GeodeticObjectFactory} does not provide public access to it. |
| */ |
| private final Map<String,?> defaultProperties; |
| |
| /** |
| * The math transform factory. Will be created only when first needed. |
| * This is normally not needed by this factory, except when constructing derived and projected CRS. |
| * |
| * @see #getMathTransformFactory() |
| */ |
| private volatile MathTransformFactory mtFactory; |
| |
| /** |
| * Weak references to existing objects (CRS, CS, Datum, Ellipsoid or PrimeMeridian). |
| * This set is used in order to return a pre-existing object instead of creating a new one. |
| */ |
| private final WeakHashSet<AbstractIdentifiedObject> pool; |
| |
| /** |
| * The <cite>Well Known Text</cite> parser for {@code CoordinateReferenceSystem} instances. |
| * This parser is not thread-safe, so we need to prevent two threads from using the same instance in same time. |
| */ |
| private final AtomicReference<Parser> parser; |
| |
| /** |
| * Constructs a factory with no default properties. |
| */ |
| public GeodeticObjectFactory() { |
| this(null); |
| } |
| |
| /** |
| * Constructs a factory with the given default properties. |
| * {@code GeodeticObjectFactory} will fallback on the map given to this constructor for any property |
| * not present in the map provided to a {@code createFoo(Map<String,?>, …)} method. |
| * |
| * @param properties the default properties, or {@code null} if none. |
| */ |
| public GeodeticObjectFactory(Map<String,?> properties) { |
| if (properties == null || properties.isEmpty()) { |
| properties = Collections.emptyMap(); |
| } else { |
| properties = CollectionsExt.compact(new HashMap<>(properties)); |
| } |
| defaultProperties = properties; |
| pool = new WeakHashSet<>(AbstractIdentifiedObject.class); |
| parser = new AtomicReference<>(); |
| } |
| |
| /** |
| * Returns the union of the given {@code properties} map with the default properties given at |
| * {@linkplain #GeodeticObjectFactory(Map) construction time}. Entries in the given properties |
| * map have precedence, even if their {@linkplain java.util.Map.Entry#getValue() value} is {@code null} |
| * (i.e. a null value "erase" the default property value). |
| * Entries with null value after the union will be omitted. |
| * |
| * <p>This method is invoked by all {@code createFoo(Map<String,?>, …)} methods.</p> |
| * |
| * @param properties the user-supplied properties. |
| * @return the union of the given properties with the default properties. |
| */ |
| protected Map<String,?> complete(final Map<String,?> properties) { |
| ArgumentChecks.ensureNonNull("properties", properties); |
| return new MergedProperties(properties, defaultProperties) { |
| /** |
| * Handles the {@code "mtFactory"} key in a special way since this is normally not needed for |
| * {@link GeodeticObjectFactory}, except when creating the SIS implementation of derived or |
| * projected CRS (because of the way we implemented derived CRS, but this is specific to SIS). |
| */ |
| @Override |
| protected Object invisibleEntry(final Object key) { |
| if (ReferencingFactoryContainer.MT_FACTORY.equals(key)) { |
| return getMathTransformFactory(); |
| } else { |
| return super.invisibleEntry(key); |
| } |
| } |
| }; |
| } |
| |
| /** |
| * Returns the math transform factory for internal usage only. |
| * The {@code MathTransformFactory} is normally not needed by {@code GeodeticObjectFactory}, |
| * except when constructing the Apache SIS implementation of derived and projected CRS. |
| * For this reason, we will fetch this dependency only if really requested. |
| */ |
| final MathTransformFactory getMathTransformFactory() { |
| MathTransformFactory factory = mtFactory; |
| if (factory == null) { |
| mtFactory = factory = DefaultFactories.forBuildin(MathTransformFactory.class); |
| } |
| return factory; |
| } |
| |
| /** |
| * Returns a unique instance of the given object. If this method recycles an existing object, |
| * then the existing instance is returned silently. Otherwise this method logs a message at |
| * {@link Level#FINE} telling that a new object has been created. |
| */ |
| private <T extends AbstractIdentifiedObject> T unique(final String caller, final T object) { |
| final T c = pool.unique(object); |
| if (c == object && LOGGER.isLoggable(Level.FINE)) { |
| final String id = IdentifiedObjects.toString(IdentifiedObjects.getIdentifier(c, null)); |
| final LogRecord record = Messages.getResources(null).getLogRecord(Level.FINE, |
| (id != null) ? Messages.Keys.CreatedIdentifiedObject_3 |
| : Messages.Keys.CreatedNamedObject_2, |
| c.getInterface(), c.getName().getCode(), id); |
| record.setSourceClassName(GeodeticObjectFactory.class.getCanonicalName()); |
| record.setSourceMethodName(caller); |
| record.setLoggerName(LOGGER.getName()); |
| LOGGER.log(record); |
| } |
| return c; |
| } |
| |
| /** |
| * Creates a geocentric coordinate reference system from a {@linkplain CartesianCS Cartesian coordinate system}. |
| * Geocentric CRS have their origin at the approximate centre of mass of the earth. |
| * An {@linkplain #createGeocentricCRS(Map, GeodeticDatum, SphericalCS) alternate method} allows creation of the |
| * same kind of CRS with spherical coordinate system instead than a Cartesian one. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * <li>{@link #createCartesianCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)}</li> |
| * <li>One of:<ul> |
| * <li>{@link #createEllipsoid(Map, double, double, Unit)}</li> |
| * <li>{@link #createFlattenedSphere(Map, double, double, Unit)}</li> |
| * </ul></li> |
| * <li>{@link #createPrimeMeridian(Map, double, Unit)}</li> |
| * <li>{@link #createGeodeticDatum(Map, Ellipsoid, PrimeMeridian)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultGeocentricCRS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param datum the geodetic datum to use in created CRS. |
| * @param cs the three-dimensional Cartesian coordinate system for the created CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see GeodeticAuthorityFactory#createGeocentricCRS(String) |
| * @see DefaultGeocentricCRS#DefaultGeocentricCRS(Map, GeodeticDatum, CartesianCS) |
| */ |
| @Override |
| public GeocentricCRS createGeocentricCRS(final Map<String,?> properties, |
| final GeodeticDatum datum, final CartesianCS cs) throws FactoryException |
| { |
| final DefaultGeocentricCRS crs; |
| try { |
| crs = new DefaultGeocentricCRS(complete(properties), datum, cs); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createGeocentricCRS", crs); |
| } |
| |
| /** |
| * Creates a three-dimensional Cartesian coordinate system from the given set of axis. |
| * This coordinate system can be used with geocentric, engineering and derived CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultCartesianCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis (e.g. “Geocentric X”). |
| * @param axis1 the second axis (e.g. “Geocentric Y”). |
| * @param axis2 the third axis (e.g. “Geocentric Z”). |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultCartesianCS#DefaultCartesianCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis) |
| * @see GeodeticAuthorityFactory#createCartesianCS(String) |
| */ |
| @Override |
| public CartesianCS createCartesianCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1, |
| final CoordinateSystemAxis axis2) throws FactoryException |
| { |
| final DefaultCartesianCS cs; |
| try { |
| cs = new DefaultCartesianCS(complete(properties), axis0, axis1, axis2); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createCartesianCS", cs); |
| } |
| |
| /** |
| * Creates a geocentric coordinate reference system from a {@linkplain SphericalCS spherical coordinate system}. |
| * Geocentric CRS have their origin at the approximate centre of mass of the earth. |
| * An {@linkplain #createGeocentricCRS(Map, GeodeticDatum, CartesianCS) alternate method} allows creation of the |
| * same kind of CRS with Cartesian coordinate system instead than a spherical one. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * <li>{@link #createSphericalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)}</li> |
| * <li>One of:<ul> |
| * <li>{@link #createEllipsoid(Map, double, double, Unit)}</li> |
| * <li>{@link #createFlattenedSphere(Map, double, double, Unit)}</li> |
| * </ul></li> |
| * <li>{@link #createPrimeMeridian(Map, double, Unit)}</li> |
| * <li>{@link #createGeodeticDatum(Map, Ellipsoid, PrimeMeridian)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultGeocentricCRS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param datum geodetic datum to use in created CRS. |
| * @param cs the spherical coordinate system for the created CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultGeocentricCRS#DefaultGeocentricCRS(Map, GeodeticDatum, SphericalCS) |
| * @see GeodeticAuthorityFactory#createGeocentricCRS(String) |
| */ |
| @Override |
| public GeocentricCRS createGeocentricCRS(final Map<String,?> properties, |
| final GeodeticDatum datum, final SphericalCS cs) throws FactoryException |
| { |
| final DefaultGeocentricCRS crs; |
| try { |
| crs = new DefaultGeocentricCRS(complete(properties), datum, cs); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createGeocentricCRS", crs); |
| } |
| |
| /** |
| * Creates a spherical coordinate system from the given set of axis. |
| * This coordinate system can be used with geocentric, engineering and derived CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultSphericalCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis (e.g. “Spherical latitude”). |
| * @param axis1 the second axis (e.g. “Spherical longitude”). |
| * @param axis2 the third axis (e.g. “Geocentric radius”). |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultSphericalCS#DefaultSphericalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis) |
| * @see GeodeticAuthorityFactory#createSphericalCS(String) |
| */ |
| @Override |
| public SphericalCS createSphericalCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1, |
| final CoordinateSystemAxis axis2) throws FactoryException |
| { |
| final DefaultSphericalCS cs; |
| try { |
| cs = new DefaultSphericalCS(complete(properties), axis0, axis1, axis2); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createSphericalCS", cs); |
| } |
| |
| /** |
| * Creates a geographic coordinate reference system. It can be (<var>latitude</var>, <var>longitude</var>) |
| * or (<var>longitude</var>, <var>latitude</var>), optionally with an ellipsoidal height. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * <li>One of:<ul> |
| * <li>{@link #createEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)}</li> |
| * <li>{@link #createEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis)}</li> |
| * </ul></li> |
| * <li>One of:<ul> |
| * <li>{@link #createEllipsoid(Map, double, double, Unit)}</li> |
| * <li>{@link #createFlattenedSphere(Map, double, double, Unit)}</li> |
| * </ul></li> |
| * <li>{@link #createPrimeMeridian(Map, double, Unit)}</li> |
| * <li>{@link #createGeodeticDatum(Map, Ellipsoid, PrimeMeridian)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultGeographicCRS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param datum geodetic datum to use in created CRS. |
| * @param cs the two- or three-dimensional ellipsoidal coordinate system for the created CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultGeographicCRS#DefaultGeographicCRS(Map, GeodeticDatum, EllipsoidalCS) |
| * @see GeodeticAuthorityFactory#createGeographicCRS(String) |
| */ |
| @Override |
| public GeographicCRS createGeographicCRS(final Map<String,?> properties, |
| final GeodeticDatum datum, final EllipsoidalCS cs) throws FactoryException |
| { |
| final DefaultGeographicCRS crs; |
| try { |
| crs = new DefaultGeographicCRS(complete(properties), datum, cs); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createGeographicCRS", crs); |
| } |
| |
| /** |
| * Creates geodetic datum from ellipsoid and (optionally) Bursa-Wolf parameters. |
| * Geodetic datum defines the location and orientation of an ellipsoid that approximates the shape of the earth. |
| * This datum can be used with geographic, geocentric and engineering CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>One of:<ul> |
| * <li>{@link #createEllipsoid(Map, double, double, Unit)}</li> |
| * <li>{@link #createFlattenedSphere(Map, double, double, Unit)}</li> |
| * </ul></li> |
| * <li>{@link #createPrimeMeridian(Map, double, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultGeodeticDatum} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param ellipsoid the ellipsoid to use in new geodetic datum. |
| * @param primeMeridian the prime meridian to use in new geodetic datum. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultGeodeticDatum#DefaultGeodeticDatum(Map, Ellipsoid, PrimeMeridian) |
| * @see GeodeticAuthorityFactory#createGeodeticDatum(String) |
| */ |
| @Override |
| public GeodeticDatum createGeodeticDatum(final Map<String,?> properties, |
| final Ellipsoid ellipsoid, final PrimeMeridian primeMeridian) throws FactoryException |
| { |
| final DefaultGeodeticDatum datum; |
| try { |
| datum = new DefaultGeodeticDatum(complete(properties), ellipsoid, primeMeridian); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createGeodeticDatum", datum); |
| } |
| |
| /** |
| * Creates a prime meridian, relative to Greenwich. |
| * Defines the origin from which longitude values are determined. |
| * |
| * <p>The default implementation creates a {@link DefaultPrimeMeridian} instance.</p> |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param longitude the longitude of prime meridian in supplied angular units East of Greenwich. |
| * @param angularUnit the angular units of longitude. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultPrimeMeridian#DefaultPrimeMeridian(Map, double, Unit) |
| * @see GeodeticAuthorityFactory#createPrimeMeridian(String) |
| */ |
| @Override |
| public PrimeMeridian createPrimeMeridian(final Map<String,?> properties, |
| final double longitude, final Unit<Angle> angularUnit) throws FactoryException |
| { |
| final DefaultPrimeMeridian meridian; |
| try { |
| meridian = new DefaultPrimeMeridian(complete(properties), longitude, angularUnit); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createPrimeMeridian", meridian); |
| } |
| |
| /** |
| * Creates an ellipsoidal coordinate system without ellipsoidal height. |
| * It can be (<var>latitude</var>, <var>longitude</var>) or (<var>longitude</var>, <var>latitude</var>). |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultEllipsoidalCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis (e.g. “Geodetic latitude”). |
| * @param axis1 the second axis (e.g. “Geodetic longitude”). |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultEllipsoidalCS#DefaultEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis) |
| * @see GeodeticAuthorityFactory#createEllipsoidalCS(String) |
| */ |
| @Override |
| public EllipsoidalCS createEllipsoidalCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1) throws FactoryException |
| { |
| final DefaultEllipsoidalCS cs; |
| try { |
| cs = new DefaultEllipsoidalCS(complete(properties), axis0, axis1); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createEllipsoidalCS", cs); |
| } |
| |
| /** |
| * Creates an ellipsoidal coordinate system with ellipsoidal height. |
| * It can be (<var>latitude</var>, <var>longitude</var>, <var>height</var>) |
| * or (<var>longitude</var>, <var>latitude</var>, <var>height</var>). |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultEllipsoidalCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis (e.g. “Geodetic latitude”). |
| * @param axis1 the second axis (e.g. “Geodetic longitude”). |
| * @param axis2 the third axis (e.g. “Ellipsoidal height”). |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultEllipsoidalCS#DefaultEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis) |
| * @see GeodeticAuthorityFactory#createEllipsoidalCS(String) |
| */ |
| @Override |
| public EllipsoidalCS createEllipsoidalCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1, |
| final CoordinateSystemAxis axis2) throws FactoryException |
| { |
| final DefaultEllipsoidalCS cs; |
| try { |
| cs = new DefaultEllipsoidalCS(complete(properties), axis0, axis1, axis2); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createEllipsoidalCS", cs); |
| } |
| |
| /** |
| * Creates an ellipsoid from semi-axis length values. |
| * The default implementation creates a {@link DefaultEllipsoid} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param semiMajorAxis the equatorial radius in supplied linear units. |
| * @param semiMinorAxis the polar radius in supplied linear units. |
| * @param unit the linear units of ellipsoid axes. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultEllipsoid#createEllipsoid(Map, double, double, Unit) |
| * @see GeodeticAuthorityFactory#createEllipsoid(String) |
| */ |
| @Override |
| public Ellipsoid createEllipsoid(final Map<String,?> properties, |
| final double semiMajorAxis, final double semiMinorAxis, |
| final Unit<Length> unit) throws FactoryException |
| { |
| final DefaultEllipsoid ellipsoid; |
| try { |
| ellipsoid = DefaultEllipsoid.createEllipsoid(complete(properties), semiMajorAxis, semiMinorAxis, unit); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createEllipsoid", ellipsoid); |
| } |
| |
| /** |
| * Creates an ellipsoid from a major semi-axis length and inverse flattening. |
| * The default implementation creates a {@link DefaultEllipsoid} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param semiMajorAxis the equatorial radius in supplied linear units. |
| * @param inverseFlattening the eccentricity of ellipsoid. |
| * @param unit the linear units of major axis. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultEllipsoid#createFlattenedSphere(Map, double, double, Unit) |
| * @see GeodeticAuthorityFactory#createEllipsoid(String) |
| */ |
| @Override |
| public Ellipsoid createFlattenedSphere(final Map<String,?> properties, |
| final double semiMajorAxis, final double inverseFlattening, |
| final Unit<Length> unit) throws FactoryException |
| { |
| final DefaultEllipsoid ellipsoid; |
| try { |
| ellipsoid = DefaultEllipsoid.createFlattenedSphere(complete(properties), semiMajorAxis, inverseFlattening, unit); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createFlattenedSphere", ellipsoid); |
| } |
| |
| /** |
| * Creates a projected coordinate reference system from a conversion. |
| * Projected CRS are used to approximate the shape of the earth on a planar surface in such a way |
| * that the distortion that is inherent to the approximation is controlled and known. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * <li>{@link #createCartesianCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)}</li> |
| * <li>{@link #createEllipsoidalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis)}</li> |
| * <li>One of:<ul> |
| * <li>{@link #createEllipsoid(Map, double, double, Unit)}</li> |
| * <li>{@link #createFlattenedSphere(Map, double, double, Unit)}</li> |
| * </ul></li> |
| * <li>{@link #createPrimeMeridian(Map, double, Unit)}</li> |
| * <li>{@link #createGeodeticDatum(Map, Ellipsoid, PrimeMeridian)}</li> |
| * <li>{@link #createGeographicCRS(Map, GeodeticDatum, EllipsoidalCS)}</li> |
| * <li>{@link org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory#createDefiningConversion(Map, OperationMethod, ParameterValueGroup)}</li> |
| * </ol></div> |
| * |
| * The supplied {@code conversion} argument shall <strong>not</strong> includes the operation steps |
| * for performing {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes unit |
| * conversions and change of axis order} since those operations will be inferred by this constructor. |
| * |
| * <p>The default implementation creates a {@link DefaultProjectedCRS} instance.</p> |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param baseCRS the geographic coordinate reference system to base projection on. |
| * @param conversion the defining conversion from a {@linkplain org.apache.sis.referencing.cs.AxesConvention#NORMALIZED |
| * normalized} base to a normalized derived CRS. |
| * @param derivedCS the coordinate system for the projected CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultProjectedCRS#DefaultProjectedCRS(Map, GeographicCRS, Conversion, CartesianCS) |
| * @see GeodeticAuthorityFactory#createProjectedCRS(String) |
| */ |
| @Override |
| public ProjectedCRS createProjectedCRS(final Map<String,?> properties, |
| final GeographicCRS baseCRS, final Conversion conversion, |
| final CartesianCS derivedCS) throws FactoryException |
| { |
| final DefaultProjectedCRS crs; |
| try { |
| crs = new DefaultProjectedCRS(complete(properties), baseCRS, conversion, derivedCS); |
| } catch (IllegalArgumentException exception) { |
| final Throwable cause = exception.getCause(); |
| if (cause instanceof FactoryException) { |
| throw (FactoryException) cause; // Must be propagated for allowing caller to catch NoSuchIdentifierException. |
| } |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createProjectedCRS", crs); |
| } |
| |
| /** |
| * Creates a two-dimensional Cartesian coordinate system from the given pair of axis. |
| * This coordinate system can be used with projected, engineering and derived CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultCartesianCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis (e.g. “Easting”). |
| * @param axis1 the second axis (e.g. “Northing”). |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultCartesianCS#DefaultCartesianCS(Map, CoordinateSystemAxis, CoordinateSystemAxis) |
| * @see GeodeticAuthorityFactory#createCartesianCS(String) |
| */ |
| @Override |
| public CartesianCS createCartesianCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1) throws FactoryException |
| { |
| final DefaultCartesianCS cs; |
| try { |
| cs = new DefaultCartesianCS(complete(properties), axis0, axis1); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createCartesianCS", cs); |
| } |
| |
| /** |
| * Creates a derived coordinate reference system from a conversion. |
| * The derived CRS returned by this method may also implement the {@link GeodeticCRS}, {@link VerticalCRS}, |
| * {@link TemporalCRS} or {@link EngineeringCRS} interface depending on the type of the base CRS and the |
| * coordinate system. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * <li>A {@code createFooCS(…)} method for Cartesian, spherical, ellipsoidal, vertical, temporal, linear, affine, polar, cylindrical or user-defined CS.</li> |
| * <li>An other {@code createFooCRS(…)} method for geocentric, geographic, vertical, temporal or engineering CRS.</li> |
| * <li>{@link org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory#createDefiningConversion(Map, OperationMethod, ParameterValueGroup)}</li> |
| * </ol></div> |
| * |
| * The supplied {@code conversion} argument shall <strong>not</strong> includes the operation steps |
| * for performing {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes unit |
| * conversions and change of axis order} since those operations will be inferred by this constructor. |
| * |
| * <p>The default implementation creates a {@link DefaultDerivedCRS} instance.</p> |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param baseCRS the coordinate reference system to base projection on. Shall be an instance of {@link SingleCRS}. |
| * @param conversion the defining conversion from a {@linkplain org.apache.sis.referencing.cs.AxesConvention#NORMALIZED |
| * normalized} base to a normalized derived CRS. |
| * @param derivedCS the coordinate system for the derived CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultDerivedCRS#create(Map, SingleCRS, Conversion, CoordinateSystem) |
| * @see GeodeticAuthorityFactory#createDerivedCRS(String) |
| */ |
| @Override |
| public DerivedCRS createDerivedCRS(final Map<String,?> properties, |
| final CoordinateReferenceSystem baseCRS, final Conversion conversion, |
| final CoordinateSystem derivedCS) throws FactoryException |
| { |
| ArgumentChecks.ensureCanCast("baseCRS", SingleCRS.class, baseCRS); |
| final DefaultDerivedCRS crs; |
| try { |
| crs = DefaultDerivedCRS.create(complete(properties), (SingleCRS) baseCRS, conversion, derivedCS); |
| } catch (IllegalArgumentException exception) { |
| final Throwable cause = exception.getCause(); |
| if (cause instanceof FactoryException) { |
| throw (FactoryException) cause; // Must be propagated for allowing caller to catch NoSuchIdentifierException. |
| } |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createDerivedCRS", crs); |
| } |
| |
| /** |
| * Creates a vertical coordinate reference system. |
| * Vertical CRSs make use of the direction of gravity to define the concept of height or depth, |
| * but the relationship with gravity may not be straightforward. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * <li>{@link #createVerticalCS(Map, CoordinateSystemAxis)}</li> |
| * <li>{@link #createVerticalDatum(Map, VerticalDatumType)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultVerticalCRS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param datum the vertical datum to use in created CRS. |
| * @param cs the vertical coordinate system for the created CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultVerticalCRS#DefaultVerticalCRS(Map, VerticalDatum, VerticalCS) |
| * @see GeodeticAuthorityFactory#createVerticalCRS(String) |
| */ |
| @Override |
| public VerticalCRS createVerticalCRS(final Map<String,?> properties, |
| final VerticalDatum datum, final VerticalCS cs) throws FactoryException |
| { |
| final DefaultVerticalCRS crs; |
| try { |
| crs = new DefaultVerticalCRS(complete(properties), datum, cs); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createVerticalCRS", crs); |
| } |
| |
| /** |
| * Creates a vertical datum from an enumerated type value. |
| * The default implementation creates a {@link DefaultVerticalDatum} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param type the type of this vertical datum (often geoidal). |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultVerticalDatum#DefaultVerticalDatum(Map, VerticalDatumType) |
| * @see GeodeticAuthorityFactory#createVerticalDatum(String) |
| */ |
| @Override |
| public VerticalDatum createVerticalDatum(final Map<String,?> properties, |
| final VerticalDatumType type) throws FactoryException |
| { |
| final DefaultVerticalDatum datum; |
| try { |
| datum = new DefaultVerticalDatum(complete(properties), type); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createVerticalDatum", datum); |
| } |
| |
| /** |
| * Creates a vertical coordinate system. |
| * This coordinate system can be used with vertical and derived CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultVerticalCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis the single axis (e.g. “height” or “depth”). |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultVerticalCS#DefaultVerticalCS(Map, CoordinateSystemAxis) |
| * @see GeodeticAuthorityFactory#createVerticalCS(String) |
| */ |
| @Override |
| public VerticalCS createVerticalCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis) throws FactoryException |
| { |
| final DefaultVerticalCS cs; |
| try { |
| cs = new DefaultVerticalCS(complete(properties), axis); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createVerticalCS", cs); |
| } |
| |
| /** |
| * Creates a temporal coordinate reference system. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * <li>{@link #createTimeCS(Map, CoordinateSystemAxis)}</li> |
| * <li>{@link #createTemporalDatum(Map, Date)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultTemporalCRS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param datum the temporal datum to use in created CRS. |
| * @param cs the temporal coordinate system for the created CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultTemporalCRS#DefaultTemporalCRS(Map, TemporalDatum, TimeCS) |
| * @see GeodeticAuthorityFactory#createTemporalCRS(String) |
| */ |
| @Override |
| public TemporalCRS createTemporalCRS(final Map<String,?> properties, |
| final TemporalDatum datum, final TimeCS cs) throws FactoryException |
| { |
| final DefaultTemporalCRS crs; |
| try { |
| crs = new DefaultTemporalCRS(complete(properties), datum, cs); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createTemporalCRS", crs); |
| } |
| |
| /** |
| * Creates a temporal datum from an enumerated type value. |
| * The default implementation creates a {@link DefaultTemporalDatum} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param origin the date and time origin of this temporal datum. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultTemporalDatum#DefaultTemporalDatum(Map, Date) |
| * @see GeodeticAuthorityFactory#createTemporalDatum(String) |
| */ |
| @Override |
| public TemporalDatum createTemporalDatum(final Map<String,?> properties, |
| final Date origin) throws FactoryException |
| { |
| final DefaultTemporalDatum datum; |
| try { |
| datum = new DefaultTemporalDatum(complete(properties), origin); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createTemporalDatum", datum); |
| } |
| |
| /** |
| * Creates a temporal coordinate system. |
| * This coordinate system can be used with temporal and derived CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultTimeCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis the single axis. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultTimeCS#DefaultTimeCS(Map, CoordinateSystemAxis) |
| * @see GeodeticAuthorityFactory#createTimeCS(String) |
| */ |
| @Override |
| public TimeCS createTimeCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis) throws FactoryException |
| { |
| final DefaultTimeCS cs; |
| try { |
| cs = new DefaultTimeCS(complete(properties), axis); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createTimeCS", cs); |
| } |
| |
| /** |
| * Creates a parametric coordinate reference system. |
| * Parametric CRS can be used for physical properties or functions that vary monotonically with height. |
| * A typical example is the pressure in meteorological applications. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * <li>{@link #createParametricCS(Map, CoordinateSystemAxis)}</li> |
| * <li>{@link #createParametricDatum(Map)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultParametricCRS} instance. |
| * |
| * <div class="warning"><b>Warning:</b> in a future SIS version, the parameter types may be changed to |
| * {@code org.opengis.referencing.datum.ParametricDatum} and {@code org.opengis.referencing.cs.ParametricCS}, |
| * and the return type may be changed to {@code org.opengis.referencing.crs.ParametricCRS}. |
| * Those change are pending GeoAPI revision.</div> |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param datum the parametric datum to use in created CRS. |
| * @param cs the parametric coordinate system for the created CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultParametricCRS#DefaultParametricCRS(Map, DefaultParametricDatum, DefaultParametricCS) |
| * @see GeodeticAuthorityFactory#createParametricCRS(String) |
| */ |
| public DefaultParametricCRS createParametricCRS(final Map<String,?> properties, |
| final DefaultParametricDatum datum, final DefaultParametricCS cs) throws FactoryException |
| { |
| final DefaultParametricCRS crs; |
| try { |
| crs = new DefaultParametricCRS(complete(properties), datum, cs); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createParametricCRS", crs); |
| } |
| |
| /** |
| * Creates a parametric datum. |
| * The default implementation creates a {@link DefaultParametricDatum} instance. |
| * |
| * <div class="warning"><b>Warning:</b> in a future SIS version, the return type may be changed |
| * to {@code org.opengis.referencing.datum.ParametricDatum}. This change is pending GeoAPI revision.</div> |
| * |
| * @param properties name and other properties to give to the new object. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultParametricDatum#DefaultParametricDatum(Map) |
| * @see GeodeticAuthorityFactory#createParametricDatum(String) |
| */ |
| public DefaultParametricDatum createParametricDatum(final Map<String,?> properties) |
| throws FactoryException |
| { |
| final DefaultParametricDatum datum; |
| try { |
| datum = new DefaultParametricDatum(complete(properties)); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createParametricDatum", datum); |
| } |
| |
| /** |
| * Creates a parametric coordinate system. |
| * This coordinate system can be used only with parametric CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultParametricCS} instance. |
| * |
| * <div class="warning"><b>Warning:</b> in a future SIS version, the return type may be changed |
| * to {@code org.opengis.referencing.cs.ParametricCS}. This change is pending GeoAPI revision.</div> |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis the single axis. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultParametricCS#DefaultParametricCS(Map, CoordinateSystemAxis) |
| * @see GeodeticAuthorityFactory#createParametricCS(String) |
| */ |
| public DefaultParametricCS createParametricCS(Map<String, ?> properties, CoordinateSystemAxis axis) throws FactoryException { |
| final DefaultParametricCS cs; |
| try { |
| cs = new DefaultParametricCS(complete(properties), axis); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createParametricCS", cs); |
| } |
| |
| /** |
| * Creates a compound coordinate reference system from an ordered list of CRS components. |
| * Apache SIS is permissive on the order of components that can be used in a compound CRS. |
| * However for better inter-operability, users are encouraged to follow the order mandated by ISO 19162: |
| * |
| * <ol> |
| * <li>A mandatory horizontal CRS (only one of two-dimensional {@code GeographicCRS} or {@code ProjectedCRS} or {@code EngineeringCRS}).</li> |
| * <li>Optionally followed by a {@code VerticalCRS} or a {@code ParametricCRS} (but not both).</li> |
| * <li>Optionally followed by a {@code TemporalCRS}.</li> |
| * </ol> |
| * |
| * The default implementation creates a {@link DefaultCompoundCRS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param components the sequence of coordinate reference systems making the compound CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultCompoundCRS#DefaultCompoundCRS(Map, CoordinateReferenceSystem...) |
| * @see GeodeticAuthorityFactory#createCompoundCRS(String) |
| * @see org.apache.sis.referencing.CRS#compound(CoordinateReferenceSystem...) |
| */ |
| @Override |
| public CompoundCRS createCompoundCRS(final Map<String,?> properties, |
| final CoordinateReferenceSystem... components) throws FactoryException |
| { |
| final DefaultCompoundCRS crs; |
| try { |
| crs = new DefaultCompoundCRS(complete(properties), components); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createCompoundCRS", crs); |
| } |
| |
| /** |
| * Creates an image coordinate reference system. |
| * The default implementation creates a {@link DefaultImageCRS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param datum the image datum to use in created CRS. |
| * @param cs the Cartesian or oblique Cartesian coordinate system for the created CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultImageCRS#DefaultImageCRS(Map, ImageDatum, AffineCS) |
| * @see GeodeticAuthorityFactory#createImageCRS(String) |
| */ |
| @Override |
| public ImageCRS createImageCRS(final Map<String,?> properties, |
| final ImageDatum datum, final AffineCS cs) throws FactoryException |
| { |
| final DefaultImageCRS crs; |
| try { |
| crs = new DefaultImageCRS(complete(properties), datum, cs); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createImageCRS", crs); |
| } |
| |
| /** |
| * Creates an image datum. |
| * The default implementation creates a {@link DefaultImageDatum} instance. |
| * |
| * @param properties Name and other properties to give to the new object. |
| * @param pixelInCell Specification of the way the image grid is associated with the image data attributes. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultImageDatum#DefaultImageDatum(Map, PixelInCell) |
| * @see GeodeticAuthorityFactory#createImageDatum(String) |
| */ |
| @Override |
| public ImageDatum createImageDatum(final Map<String,?> properties, |
| final PixelInCell pixelInCell) throws FactoryException |
| { |
| final DefaultImageDatum datum; |
| try { |
| datum = new DefaultImageDatum(complete(properties), pixelInCell); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createImageDatum", datum); |
| } |
| |
| /** |
| * Creates a two-dimensional affine coordinate system from the given pair of axis. |
| * This coordinate system can be used with image and engineering CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultAffineCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis. |
| * @param axis1 the second axis. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultAffineCS#DefaultAffineCS(Map, CoordinateSystemAxis, CoordinateSystemAxis) |
| */ |
| @Override |
| public AffineCS createAffineCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1) throws FactoryException |
| { |
| final DefaultAffineCS cs; |
| try { |
| cs = new DefaultAffineCS(complete(properties), axis0, axis1); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createAffineCS", cs); |
| } |
| |
| /** |
| * Creates a engineering coordinate reference system. |
| * Engineering CRS can be divided into two broad categories: |
| * |
| * <ul> |
| * <li>earth-fixed systems applied to engineering activities on or near the surface of the earth;</li> |
| * <li>CRSs on moving platforms such as road vehicles, vessels, aircraft, or spacecraft.</li> |
| * </ul> |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * <li>A {@code createFooCS(…)} method for Cartesian, spherical, linear, affine, polar, cylindrical or user-defined CS.</li> |
| * <li>{@link #createEngineeringDatum(Map)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultEngineeringCRS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param datum the engineering datum to use in created CRS. |
| * @param cs the coordinate system for the created CRS. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultEngineeringCRS#DefaultEngineeringCRS(Map, EngineeringDatum, CoordinateSystem) |
| * @see GeodeticAuthorityFactory#createEngineeringCRS(String) |
| */ |
| @Override |
| public EngineeringCRS createEngineeringCRS(final Map<String,?> properties, |
| final EngineeringDatum datum, final CoordinateSystem cs) throws FactoryException |
| { |
| final DefaultEngineeringCRS crs; |
| try { |
| crs = new DefaultEngineeringCRS(complete(properties), datum, cs); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createEngineeringCRS", crs); |
| } |
| |
| /** |
| * Creates an engineering datum. |
| * The default implementation creates a {@link DefaultEngineeringDatum} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultEngineeringDatum#DefaultEngineeringDatum(Map) |
| * @see GeodeticAuthorityFactory#createEngineeringDatum(String) |
| */ |
| @Override |
| public EngineeringDatum createEngineeringDatum(final Map<String,?> properties) |
| throws FactoryException |
| { |
| final DefaultEngineeringDatum datum; |
| try { |
| datum = new DefaultEngineeringDatum(complete(properties)); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createEngineeringDatum", datum); |
| } |
| |
| /** |
| * Creates a three-dimensional affine coordinate system from the given set of axis. |
| * This coordinate system can be used with engineering CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultAffineCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis. |
| * @param axis1 the second axis. |
| * @param axis2 the third axis. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultAffineCS#DefaultAffineCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis) |
| */ |
| @Override |
| public AffineCS createAffineCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1, |
| final CoordinateSystemAxis axis2) throws FactoryException |
| { |
| final DefaultAffineCS cs; |
| try { |
| cs = new DefaultAffineCS(complete(properties), axis0, axis1, axis2); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createAffineCS", cs); |
| } |
| |
| /** |
| * Creates a cylindrical coordinate system from the given set of axis. |
| * This coordinate system can be used with engineering CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultCylindricalCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis. |
| * @param axis1 the second axis. |
| * @param axis2 the third axis. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultCylindricalCS#DefaultCylindricalCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis) |
| * @see GeodeticAuthorityFactory#createCylindricalCS(String) |
| */ |
| @Override |
| public CylindricalCS createCylindricalCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1, |
| final CoordinateSystemAxis axis2) throws FactoryException |
| { |
| final DefaultCylindricalCS cs; |
| try { |
| cs = new DefaultCylindricalCS(complete(properties), axis0, axis1, axis2); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createCylindricalCS", cs); |
| } |
| |
| /** |
| * Creates a polar coordinate system from the given pair of axis. |
| * This coordinate system can be used with engineering CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultPolarCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis. |
| * @param axis1 the second axis. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultPolarCS#DefaultPolarCS(Map, CoordinateSystemAxis, CoordinateSystemAxis) |
| * @see GeodeticAuthorityFactory#createPolarCS(String) |
| */ |
| @Override |
| public PolarCS createPolarCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1) throws FactoryException |
| { |
| final DefaultPolarCS cs; |
| try { |
| cs = new DefaultPolarCS(complete(properties), axis0, axis1); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createPolarCS", cs); |
| } |
| |
| /** |
| * Creates a linear coordinate system. |
| * This coordinate system can be used with engineering CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultLinearCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis the single axis. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultLinearCS#DefaultLinearCS(Map, CoordinateSystemAxis) |
| */ |
| @Override |
| public LinearCS createLinearCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis) throws FactoryException |
| { |
| final DefaultLinearCS cs; |
| try { |
| cs = new DefaultLinearCS(complete(properties), axis); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createLinearCS", cs); |
| } |
| |
| /** |
| * Creates a two-dimensional user defined coordinate system from the given pair of axis. |
| * This coordinate system can be used with engineering CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultUserDefinedCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis. |
| * @param axis1 the second axis. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultUserDefinedCS#DefaultUserDefinedCS(Map, CoordinateSystemAxis, CoordinateSystemAxis) |
| */ |
| @Override |
| public UserDefinedCS createUserDefinedCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1) throws FactoryException |
| { |
| final DefaultUserDefinedCS cs; |
| try { |
| cs = new DefaultUserDefinedCS(complete(properties), axis0, axis1); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createUserDefinedCS", cs); |
| } |
| |
| /** |
| * Creates a three-dimensional user defined coordinate system from the given set of axis. |
| * This coordinate system can be used with engineering CRS. |
| * |
| * <div class="note"><b>Dependencies:</b> |
| * the components needed by this method can be created by the following methods: |
| * <ol> |
| * <li>{@link #createCoordinateSystemAxis(Map, String, AxisDirection, Unit)}</li> |
| * </ol></div> |
| * |
| * The default implementation creates a {@link DefaultUserDefinedCS} instance. |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param axis0 the first axis. |
| * @param axis1 the second axis. |
| * @param axis2 the third axis. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultUserDefinedCS#DefaultUserDefinedCS(Map, CoordinateSystemAxis, CoordinateSystemAxis, CoordinateSystemAxis) |
| */ |
| @Override |
| public UserDefinedCS createUserDefinedCS(final Map<String,?> properties, |
| final CoordinateSystemAxis axis0, |
| final CoordinateSystemAxis axis1, |
| final CoordinateSystemAxis axis2) throws FactoryException |
| { |
| final DefaultUserDefinedCS cs; |
| try { |
| cs = new DefaultUserDefinedCS(complete(properties), axis0, axis1, axis2); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createUserDefinedCS", cs); |
| } |
| |
| /** |
| * Creates a coordinate system axis from an abbreviation and a unit. |
| * Note that the axis name is constrained by ISO 19111 depending on the coordinate reference system type. |
| * See the GeoAPI {@link CoordinateSystemAxis} javadoc for more information. |
| * |
| * <p>The default implementation creates a {@link DefaultCoordinateSystemAxis} instance.</p> |
| * |
| * @param properties name and other properties to give to the new object. |
| * @param abbreviation the coordinate axis abbreviation. |
| * @param direction the axis direction. |
| * @param unit the coordinate axis unit. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see DefaultCoordinateSystemAxis#DefaultCoordinateSystemAxis(Map, String, AxisDirection, Unit) |
| * @see GeodeticAuthorityFactory#createCoordinateSystemAxis(String) |
| */ |
| @Override |
| public CoordinateSystemAxis createCoordinateSystemAxis(final Map<String,?> properties, |
| final String abbreviation, final AxisDirection direction, |
| final Unit<?> unit) throws FactoryException |
| { |
| final DefaultCoordinateSystemAxis axis; |
| try { |
| axis = new DefaultCoordinateSystemAxis(complete(properties), abbreviation, direction, unit); |
| } catch (IllegalArgumentException exception) { |
| throw new InvalidGeodeticParameterException(exception); |
| } |
| return unique("createCoordinateSystemAxis", axis); |
| } |
| |
| /** |
| * Creates a coordinate reference system object from a XML string. |
| * Note that the given argument is the XML document itself, |
| * <strong>not</strong> a URL to a XML document. |
| * |
| * <p>The default implementation delegates to {@link XML#unmarshal(String)}</p> |
| * |
| * @param xml coordinate reference system encoded in XML format. |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see XML#unmarshal(String) |
| * @see org.apache.sis.referencing.CRS#fromXML(String) |
| */ |
| @Override |
| public CoordinateReferenceSystem createFromXML(final String xml) throws FactoryException { |
| final Object object; |
| try { |
| object = XML.unmarshal(xml); |
| } catch (JAXBException e) { |
| /* |
| * The JAXB exception if often a wrapper around other exceptions, sometime InvocationTargetException. |
| * The exception cause is called "linked exception" by JAXB, presumably because it predates standard |
| * chained exception mechanism introduced in Java 1.4. The JAXB linked exceptions do not propagate the |
| * error message, so we have to take it from the cause, skipping InvocationTargetException since they |
| * are wrapper for other causes. If the cause is a JAXBException, we will keep it as the declared cause |
| * for simplifying the stack trace. |
| */ |
| String message = e.getLocalizedMessage(); |
| Throwable cause = e.getCause(); |
| if (cause instanceof Exception) { |
| cause = Exceptions.unwrap((Exception) cause); |
| if (cause instanceof JAXBException) { |
| e = (JAXBException) cause; |
| } |
| if (message == null) { |
| message = cause.getLocalizedMessage(); |
| } |
| } |
| throw new FactoryException(message, e); |
| } |
| if (object instanceof CoordinateReferenceSystem) { |
| return (CoordinateReferenceSystem) object; |
| } else { |
| throw new FactoryException(Errors.getResources(defaultProperties).getString( |
| Errors.Keys.IllegalClass_2, CoordinateReferenceSystem.class, object.getClass())); |
| } |
| } |
| |
| /** |
| * Creates a Coordinate Reference System object from a <cite>Well Known Text</cite> (WKT). |
| * This method understands both version 1 (a.k.a. OGC 01-009) and version 2 (a.k.a. ISO 19162) |
| * of the WKT format. |
| * |
| * <div class="note"><b>Example:</b> below is a slightly simplified WKT 2 string for a Mercator projection. |
| * For making this example smaller, some optional {@code UNIT[…]} and {@code ORDER[…]} elements have been omitted. |
| * |
| * {@preformat wkt |
| * ProjectedCRS["SIRGAS 2000 / Brazil Mercator", |
| * BaseGeodCRS["SIRGAS 2000", |
| * Datum["Sistema de Referencia Geocentrico para las Americas 2000", |
| * Ellipsoid["GRS 1980", 6378137, 298.257222101]]], |
| * Conversion["Petrobras Mercator", |
| * Method["Mercator (variant B)", Id["EPSG",9805]], |
| * Parameter["Latitude of 1st standard parallel", -2], |
| * Parameter["Longitude of natural origin", -43], |
| * Parameter["False easting", 5000000], |
| * Parameter["False northing", 10000000]], |
| * CS[cartesian,2], |
| * Axis["easting (E)", east], |
| * Axis["northing (N)", north], |
| * LengthUnit["metre", 1], |
| * Id["EPSG",5641]] |
| * } |
| * </div> |
| * |
| * If the given text contains non-fatal anomalies |
| * (unknown or unsupported WKT elements, inconsistent unit definitions, unparsable axis abbreviations, <i>etc.</i>), |
| * warnings may be reported in a {@linkplain java.util.logging.Logger logger} named {@code "org.apache.sis.io.wkt"}. |
| * However this parser does not verify if the overall parsed object matches the EPSG (or other authority) definition, |
| * since this geodetic object factory is not an {@linkplain GeodeticAuthorityFactory authority factory}. |
| * For such verification, see the {@link org.apache.sis.referencing.CRS#fromWKT(String)} convenience method. |
| * |
| * <div class="section">Usage and performance considerations</div> |
| * The default implementation uses a shared instance of {@link org.apache.sis.io.wkt.WKTFormat} |
| * with the addition of thread-safety. This is okay for occasional use, |
| * but is sub-optimal if this method is extensively used in a multi-thread environment. |
| * Furthermore this method offers no control on the WKT {@linkplain org.apache.sis.io.wkt.Convention conventions} |
| * in use and on the handling of {@linkplain org.apache.sis.io.wkt.Warnings warnings}. |
| * Applications which need to parse a large amount of WKT strings should consider to use |
| * the {@link org.apache.sis.io.wkt.WKTFormat} class instead than this method. |
| * |
| * @param text coordinate system encoded in Well-Known Text format (version 1 or 2). |
| * @throws FactoryException if the object creation failed. |
| * |
| * @see org.apache.sis.io.wkt |
| * @see org.apache.sis.referencing.CRS#fromWKT(String) |
| * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a> |
| * @see <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">Legacy WKT 1</a> |
| */ |
| @Override |
| public CoordinateReferenceSystem createFromWKT(final String text) throws FactoryException { |
| Parser p = parser.getAndSet(null); |
| if (p == null) try { |
| Constructor<? extends Parser> c = parserConstructor; |
| if (c == null) { |
| c = Class.forName("org.apache.sis.io.wkt.GeodeticObjectParser").asSubclass(Parser.class) |
| .getConstructor(Map.class, ObjectFactory.class, MathTransformFactory.class); |
| final Constructor<?> cp = c; // For allowing use in inner class or lambda expression. |
| AccessController.doPrivileged((PrivilegedAction<Void>) () -> { |
| cp.setAccessible(true); |
| return null; |
| }); |
| parserConstructor = c; |
| } |
| p = c.newInstance(defaultProperties, this, getMathTransformFactory()); |
| } catch (ReflectiveOperationException e) { |
| throw new FactoryException(e); |
| } |
| final Object object; |
| try { |
| object = p.createFromWKT(text); |
| } catch (FactoryException e) { |
| /* |
| * In the case of map projection, the parsing may fail because a projection parameter is not known to SIS. |
| * If this happen, replace the generic exception thrown be the parser (which is FactoryException) by a |
| * more specific one. Note that InvalidGeodeticParameterException is defined only in this sis-referencing |
| * module, so we could not throw it from the sis-metadata module that contain the parser. |
| */ |
| Throwable cause = e.getCause(); |
| while (cause != null) { |
| if (cause instanceof ParameterNotFoundException) { |
| throw new InvalidGeodeticParameterException(e.getLocalizedMessage(), cause); |
| } |
| cause = cause.getCause(); |
| } |
| throw e; |
| } |
| parser.set(p); |
| if (object instanceof CoordinateReferenceSystem) { |
| return (CoordinateReferenceSystem) object; |
| } else { |
| throw new FactoryException(Errors.getResources(defaultProperties).getString( |
| Errors.Keys.IllegalClass_2, CoordinateReferenceSystem.class, object.getClass())); |
| } |
| } |
| } |