org.geotoolkit.internal.referencing.Identifier3D Maven / Gradle / Ivy
/*
* Geotoolkit.org - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2010-2012, Open Source Geospatial Foundation (OSGeo)
* (C) 2010-2012, Geomatys
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotoolkit.internal.referencing;
import java.util.Map;
import java.util.HashMap;
import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.datum.GeodeticDatum;
import org.opengis.referencing.ReferenceIdentifier;
import org.geotoolkit.util.Utilities;
import org.geotoolkit.referencing.DefaultReferenceIdentifier;
import static org.opengis.referencing.IdentifiedObject.NAME_KEY;
/**
* Identifier for a 3D CRS built from a 2D horizontal component and a 1D vertical component. This
* identifier is created by {@link org.geotoolkit.referencing.factory.ReferencingFactoryContainer}
* in order to allow the {@link org.geotoolkit.referencing.operation.AuthorityBackedFactory} class
* to find the original 2D component of a monolithic (not a compound) 3D CRS.
*
* This class is a hack. It exists for the following reasons:
*
*
* - We can not just rebuilt a new 2D CRS from a 3D one, because the EPSG code would be lost.
* We need the EPSG code of the 2D component for {@code AuthorityBackedFactory} work.
* - We can not let the 3D (horizontal + ellipsoidal height) CRS as a {@code ComponentCRS}
* because the {@code DefaultCoordinateOperationFactory} processing chain needs to pass
* those 3D CRS as monolithic objects. This is because some transformation steps need to
* process the three dimensions together; the ellipsoidal height shall never be separated
* from the geographical coordinates.
*
*
* This hack should not be visible in public API, and may change in incompatible way in any future
* version.
*
* @author Martin Desruisseaux (Geomatys)
* @version 3.16
*
* @see org.geotoolkit.referencing.operation.AuthorityBackedFactory#getHorizontalCRS
*
* @since 3.16
* @module
*/
public final class Identifier3D extends DefaultReferenceIdentifier {
/**
* For cross-version compatibility.
*/
private static final long serialVersionUID = -1799606724741505296L;
/**
* The horizontal component of the 3D CRS identified by this object.
* It must be a CRS backed by a geodetic datum.
*/
public final SingleCRS horizontalCRS;
/**
* Creates a new identifier with the same values than the given identifier,
* and store the given horizontal component for information purpose.
*
* @param identifier The identifier to copy.
* @param horizontalCRS The horizontal component of the 3D CRS.
*/
private Identifier3D(final ReferenceIdentifier identifier, final SingleCRS horizontalCRS) {
super(identifier);
this.horizontalCRS = horizontalCRS;
assert horizontalCRS.getDatum() instanceof GeodeticDatum : horizontalCRS;
}
/**
* Overridden for consistency with {@link #equals(Object)}.
*/
@Override
public int hashCode() {
return super.hashCode() + 31 * horizontalCRS.hashCode();
}
/**
* Compares this object with the given one for equality. This method needs to take
* the horizontal CRS in account, because CRS using this identifier may be stored
* in {@link org.geotoolkit.util.collection.WeakHashSet}.
*/
@Override
public boolean equals(final Object object) {
if (super.equals(object)) {
final Identifier3D other = (Identifier3D) object;
return Utilities.equals(horizontalCRS, other.horizontalCRS);
}
return false;
}
/**
* Given the properties of a CRS, replaces the value of the {@code "name"} key by an
* {@code Identifier3D} instance declaring the given horizontal CRS.
*
* @param properties The properties of a CRS.
* @param horizontalCRS The horizontal component of the 3D CRS.
* @return The properties with the given horizontal CRS injected in the name identifier.
*/
public static Map addHorizontalCRS(Map properties, final SingleCRS horizontalCRS) {
final Map copy = new HashMap(properties);
final ReferenceIdentifier id = (ReferenceIdentifier) copy.get(NAME_KEY);
copy.put(NAME_KEY, new Identifier3D(id, horizontalCRS));
return copy;
}
}