001/* 002 * GeoAPI - Java interfaces for OGC/ISO standards 003 * Copyright © 2003-2023 Open Geospatial Consortium, Inc. 004 * http://www.geoapi.org 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.opengis.referencing.crs; 019 020import java.util.Map; 021import org.opengis.referencing.datum.Datum; 022import org.opengis.referencing.datum.DatumEnsemble; 023import org.opengis.referencing.cs.CoordinateSystem; 024import org.opengis.referencing.operation.Conversion; 025import org.opengis.annotation.UML; 026 027import static org.opengis.annotation.Obligation.MANDATORY; 028import static org.opengis.annotation.Specification.*; 029 030 031/** 032 * A <abbr>CRS</abbr> that is defined by applying a coordinate conversion to another preexisting <abbr>CRS</abbr>. 033 * The derived <abbr>CRS</abbr> inherits its datum (reference frame) or datum ensemble from its base <abbr>CRS</abbr>. 034 * A {@code DerivedCRS} instance may also implement one of the interfaces listed below, 035 * provided that the conditions in the right column are met: 036 * 037 * <table class="ogc"> 038 * <caption>Derived <abbr>CRS</abbr> types</caption> 039 * <tr><th>Type</th> <th>Conditions</th></tr> 040 * <tr><td>{@link ProjectedCRS}</td> <td>Base CRS is a {@link GeographicCRS} and conversion is a map projection.</td></tr> 041 * <tr><td>{@link GeodeticCRS}</td> <td>Base CRS is also a {@code GeodeticCRS}.</td></tr> 042 * <tr><td>{@link VerticalCRS}</td> <td>Base CRS is also a {@code VerticalCRS}.</td></tr> 043 * <tr><td>{@link TemporalCRS}</td> <td>Base CRS is also a {@code TemporalCRS}.</td></tr> 044 * <tr><td>{@link EngineeringCRS}</td> <td>Base CRS is a {@code GeodeticCRS}, {@code ProjectedCRS} or {@code EngineeringCRS}.</td></tr> 045 * </table> 046 * 047 * <h2>Projected <abbr>CRS</abbr></h2> 048 * In the special case where the <abbr>CRS</abbr> is derived from a base {@link GeographicCRS} by applying 049 * a coordinate conversion known as a map projection to latitude and longitude ellipsoidal coordinate values, 050 * the {@link ProjectedCRS} subtype should be used. Projected <abbr>CRS</abbr>s are modeled as a special case 051 * of derived <abbr>CRS</abbr> because of their importance in geographic information. 052 * 053 * <h2>Derived projected <abbr>CRS</abbr></h2> 054 * In the special case where the <abbr>CRS</abbr> is derived from a base {@link ProjectedCRS}, 055 * the coordinate system of the derived <abbr>CRS</abbr> is not necessarily Cartesian. 056 * But the derived <abbr>CRS</abbr> still inherit the distortion characteristics of the base projected <abbr>CRS</abbr>. 057 * 058 * @author OGC Topic 2 (for abstract model and documentation) 059 * @author Martin Desruisseaux (IRD, Geomatys) 060 * @version 3.1 061 * @since 1.0 062 * 063 * @see CRSAuthorityFactory#createDerivedCRS(String) 064 * @see CRSFactory#createDerivedCRS(Map, CoordinateReferenceSystem, Conversion, CoordinateSystem) 065 */ 066@SuppressWarnings("deprecation") 067@UML(identifier="DerivedCRS", specification=ISO_19111) 068public interface DerivedCRS extends GeneralDerivedCRS { 069 /** 070 * Returns the <abbr>CRS</abbr> that is the base for this derived <abbr>CRS</abbr>. 071 * This is the {@linkplain Conversion#getSourceCRS() source <abbr>CRS</abbr>} 072 * of the {@linkplain #getConversionFromBase() deriving conversion}. 073 * 074 * <div class="warning"><b>Upcoming API change — specialization</b><br> 075 * According ISO 19111, the return type should be {@link SingleCRS}. 076 * This change may be applied in GeoAPI 4.0. 077 * </div> 078 * 079 * @return the <abbr>CRS</abbr> that is the base for this derived <abbr>CRS</abbr>. 080 */ 081 @Override 082 @UML(identifier="baseCRS", obligation=MANDATORY, specification=ISO_19111) 083 CoordinateReferenceSystem getBaseCRS(); 084 085 /** 086 * Returns the conversion from the base <abbr>CRS</abbr> to this derived <abbr>CRS</abbr>. 087 * The source <abbr>CRS</abbr> of the conversion, if non null, shall be the {@linkplain #getBaseCRS() base <abbr>CRS</abbr>}. 088 * The target <abbr>CRS</abbr> of the conversion, if non-null, shall be this <abbr>CRS</abbr>. 089 * 090 * @return the conversion from the base <abbr>CRS</abbr> to this derived <abbr>CRS</abbr>. 091 * 092 * @departure rename 093 * Was {@code toBase} in OGC 01-009, {@code conversion} in ISO 19111:2007 094 * and {@code derivingConversion} in ISO 19111:2019. By analogy with 01-009, 095 * GeoAPI defines a method name which contains the "{@code FromBase}" words 096 * for making clear which <abbr>CRS</abbr> is the source or which one is the target. 097 */ 098 @Override 099 @UML(identifier="derivingConversion", obligation=MANDATORY, specification=ISO_19111) 100 Conversion getConversionFromBase(); 101 102 /** 103 * Returns the same datum as the base <abbr>CRS</abbr>. 104 * This property may be null if the base <abbr>CRS</abbr> is related to an object 105 * identified only by a {@linkplain #getDatumEnsemble() datum ensemble}. 106 * 107 * @return the datum of the base <abbr>CRS</abbr>, or {@code null} if the base is related to 108 * an object identified only by a {@linkplain #getDatumEnsemble() datum ensemble}. 109 */ 110 @Override 111 default Datum getDatum() { 112 final CoordinateReferenceSystem crs = getBaseCRS(); 113 return (crs instanceof SingleCRS) ? ((SingleCRS) getBaseCRS()).getDatum() : null; 114 } 115 116 /** 117 * Returns the same datum ensemble as the base <abbr>CRS</abbr>. 118 * This property may be null if the base <abbr>CRS</abbr> is related to an object 119 * identified only by a single {@linkplain #getDatum() datum}. 120 * 121 * @return the datum ensemble of the base <abbr>CRS</abbr>, or {@code null} if the base is 122 * related to an object identified only by a single {@linkplain #getDatum() datum}. 123 * 124 * @since 3.1 125 */ 126 @Override 127 default DatumEnsemble<?> getDatumEnsemble() { 128 final CoordinateReferenceSystem crs = getBaseCRS(); 129 return (crs instanceof SingleCRS) ? ((SingleCRS) getBaseCRS()).getDatumEnsemble() : null; 130 } 131}