001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: *
005: * (C) 2004-2006, Geotools Project Managment Committee (PMC)
006: * (C) 2000, Frank Warmerdam
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Lesser General Public
010: * License as published by the Free Software Foundation; either
011: * version 2.1 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Lesser General Public License for more details.
017: *
018: * This package contains formulas from the PROJ package of USGS.
019: * USGS's work is fully acknowledged here. This derived work has
020: * been relicensed under LGPL with Frank Warmerdam's permission.
021: */
022: package org.geotools.referencing.operation.projection;
023:
024: // OpenGIS dependencies
025: import org.opengis.parameter.ParameterDescriptor;
026: import org.opengis.parameter.ParameterDescriptorGroup;
027: import org.opengis.parameter.ParameterNotFoundException;
028: import org.opengis.parameter.ParameterValueGroup;
029: import org.opengis.referencing.FactoryException;
030: import org.opengis.referencing.operation.MathTransform;
031: import org.opengis.referencing.operation.PlanarProjection;
032:
033: // Geotools dependencies
034: import org.geotools.metadata.iso.citation.Citations;
035: import org.geotools.referencing.NamedIdentifier;
036: import org.geotools.resources.i18n.VocabularyKeys;
037: import org.geotools.resources.i18n.Vocabulary;
038: import org.geotools.resources.i18n.ErrorKeys;
039: import org.geotools.resources.i18n.Errors;
040:
041: /**
042: * Orthographic Projection. This is a perspective azimuthal (planar) projection
043: * that is neither conformal nor equal-area. It resembles a globe and only
044: * one hemisphere can be seen at a time, since it is
045: * a perspectiove projection from infinite distance. While not useful for
046: * accurate measurements, this projection is useful for pictorial views of the
047: * world. Only the spherical form is given here.
048: * <p>
049: *
050: * NOTE: formulae used below are from a port, to java, of the
051: * 'proj' package of the USGS survey. USGS work is acknowledged here.
052: * <p>
053: *
054: * <strong>References:</strong><ul>
055: * <li> Proj-4.4.7 available at <A HREF="http://www.remotesensing.org/proj">www.remotesensing.org/proj</A><br>
056: * Relevant files are: {@code PJ_ortho.c}, {@code pj_fwd.c} and {@code pj_inv.c}.</li>
057: * <li> John P. Snyder (Map Projections - A Working Manual,
058: * U.S. Geological Survey Professional Paper 1395, 1987)</li>
059: * </ul>
060: *
061: * @see <A HREF="http://mathworld.wolfram.com/OrthographicProjection.html">Orthographic projection on mathworld.wolfram.com</A>
062: * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/orthographic.html">"Orthographic" on www.remotesensing.org</A>
063: *
064: * @since 2.1
065: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/Orthographic.java $
066: * @version $Id: Orthographic.java 24578 2007-02-24 00:57:19Z desruisseaux $
067: * @author Rueben Schulz
068: */
069: public abstract class Orthographic extends MapProjection {
070: /**
071: * Maximum difference allowed when comparing real numbers.
072: */
073: private static final double EPSILON = 1E-6;
074:
075: /**
076: * Creates a transform from the specified group of parameter values.
077: *
078: * @param parameters The group of parameter values.
079: * @throws ParameterNotFoundException if a required parameter was not found.
080: *
081: * @since 2.4
082: */
083: protected Orthographic(final ParameterValueGroup parameters)
084: throws ParameterNotFoundException {
085: // Fetch parameters
086: super (parameters);
087: }
088:
089: /**
090: * {@inheritDoc}
091: */
092: public ParameterDescriptorGroup getParameterDescriptors() {
093: return Provider.PARAMETERS;
094: }
095:
096: /**
097: * Compares the specified object with this map projection for equality.
098: */
099: public boolean equals(final Object object) {
100: if (object == this ) {
101: // Slight optimization
102: return true;
103: }
104: // Relevant parameters are already compared in MapProjection
105: return super .equals(object);
106: }
107:
108: //////////////////////////////////////////////////////////////////////////////////////////
109: //////////////////////////////////////////////////////////////////////////////////////////
110: //////// ////////
111: //////// PROVIDERS ////////
112: //////// ////////
113: //////////////////////////////////////////////////////////////////////////////////////////
114: //////////////////////////////////////////////////////////////////////////////////////////
115:
116: /**
117: * The {@linkplain org.geotools.referencing.operation.MathTransformProvider math transform
118: * provider} for a {@linkplain Orthographic Orthographic} projection.
119: *
120: * @since 2.1
121: * @version $Id: Orthographic.java 24578 2007-02-24 00:57:19Z desruisseaux $
122: * @author Rueben Schulz
123: *
124: * @see org.geotools.referencing.operation.DefaultMathTransformFactory
125: */
126: public static final class Provider extends AbstractProvider {
127: /**
128: * The parameters group.
129: */
130: static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(
131: new NamedIdentifier[] {
132: new NamedIdentifier(Citations.OGC,
133: "Orthographic"),
134: new NamedIdentifier(Citations.GEOTIFF,
135: "CT_Orthographic"),
136: new NamedIdentifier(Citations.ESRI,
137: "Orthographic"),
138: new NamedIdentifier(
139: Citations.GEOTOOLS,
140: Vocabulary
141: .formatInternational(VocabularyKeys.ORTHOGRAPHIC_PROJECTION)) },
142: new ParameterDescriptor[] { SEMI_MAJOR, SEMI_MINOR,
143: CENTRAL_MERIDIAN, LATITUDE_OF_ORIGIN,
144: SCALE_FACTOR, FALSE_EASTING, FALSE_NORTHING });
145:
146: /**
147: * Constructs a new provider.
148: */
149: public Provider() {
150: super (PARAMETERS);
151: }
152:
153: /**
154: * Returns the operation type for this map projection.
155: */
156: public Class getOperationType() {
157: return PlanarProjection.class;
158: }
159:
160: /**
161: * Creates a transform from the specified group of parameter values.
162: *
163: * @param parameters The group of parameter values.
164: * @return The created math transform.
165: * @throws ParameterNotFoundException if a required parameter was not found.
166: */
167: protected MathTransform createMathTransform(
168: final ParameterValueGroup parameters)
169: throws ParameterNotFoundException, FactoryException {
170: // Values here are in radians (the standard units for the map projection package)
171: final double latitudeOfOrigin = Math.abs(doubleValue(
172: LATITUDE_OF_ORIGIN, parameters));
173: if (isSpherical(parameters)) {
174: // Polar case.
175: if (Math.abs(latitudeOfOrigin - Math.PI / 2) < EPSILON) {
176: return new PolarOrthographic(parameters);
177: }
178: // Equatorial case.
179: else if (latitudeOfOrigin < EPSILON) {
180: return new EquatorialOrthographic(parameters);
181: }
182: // Generic (oblique) case.
183: else {
184: return new ObliqueOrthographic(parameters);
185: }
186: } else {
187: throw new FactoryException(Errors
188: .format(ErrorKeys.ELLIPTICAL_NOT_SUPPORTED));
189: }
190: }
191: }
192: }
|