001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.referencing;
017:
018: // J2SE dependencies and extensions
019: import java.awt.Shape;
020: import java.awt.geom.IllegalPathStateException;
021: import java.awt.geom.PathIterator;
022: import java.awt.geom.Point2D;
023: import javax.units.SI;
024:
025: // JUnit dependencies
026: import junit.framework.Test;
027: import junit.framework.TestCase;
028: import junit.framework.TestSuite;
029:
030: // OpenGIS dependencies
031: import org.opengis.referencing.FactoryException;
032: import org.opengis.referencing.crs.GeographicCRS;
033: import org.opengis.referencing.operation.TransformException;
034: import org.opengis.geometry.DirectPosition;
035:
036: // Geotools dependencies
037: import org.geotools.geometry.DirectPosition2D;
038: import org.geotools.referencing.crs.DefaultGeographicCRS;
039: import org.geotools.referencing.cs.DefaultEllipsoidalCS;
040: import org.geotools.referencing.cs.DefaultCoordinateSystemAxis;
041: import org.geotools.referencing.datum.DefaultEllipsoid;
042: import org.geotools.referencing.datum.DefaultGeodeticDatum;
043:
044: /**
045: * Tests the geodetic calculator.
046: *
047: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/test/java/org/geotools/referencing/GeodeticCalculatorTest.java $
048: * @version $Id: GeodeticCalculatorTest.java 24925 2007-03-27 20:12:08Z jgarnett $
049: */
050: public final class GeodeticCalculatorTest extends TestCase {
051: /**
052: * Run the test from the command line.
053: */
054: public static void main(final String[] args) {
055: junit.textui.TestRunner.run(suite());
056: }
057:
058: /**
059: * Returns the test suite.
060: */
061: public static Test suite() {
062: return new TestSuite(GeodeticCalculatorTest.class);
063: }
064:
065: /**
066: * Construct a new test case.
067: */
068: public GeodeticCalculatorTest(final String name) {
069: super (name);
070: }
071:
072: /**
073: * Tests some trivial azimuth directions.
074: */
075: public void testAzimuth() {
076: final double EPS = 2E-1;
077: final GeodeticCalculator calculator = new GeodeticCalculator();
078: assertTrue(calculator.getCoordinateReferenceSystem() instanceof GeographicCRS);
079: calculator.setStartingGeographicPoint(12, 20);
080: calculator.setDestinationGeographicPoint(13, 20);
081: assertEquals("East", 90, calculator.getAzimuth(), EPS);
082: calculator.setDestinationGeographicPoint(12, 21);
083: assertEquals("North", 0, calculator.getAzimuth(), EPS);
084: calculator.setDestinationGeographicPoint(11, 20);
085: assertEquals("West", -90, calculator.getAzimuth(), EPS);
086: calculator.setDestinationGeographicPoint(12, 19);
087: assertEquals("South", 180, calculator.getAzimuth(), EPS);
088: }
089:
090: /**
091: * Test path on the 45th parallel. Data for this test come from the
092: * <A HREF="http://www.univ-lemans.fr/~hainry/articles/loxonavi.html">Orthodromie et
093: * loxodromie</A> page.
094: */
095: public void testParallel45() {
096: // Column 1: Longitude difference in degrees.
097: // Column 2: Orthodromic distance in kilometers
098: // Column 3: Loxodromic distance in kilometers
099: final double[] DATA = { 0.00, 0, 0, 11.25, 883, 884, 22.50,
100: 1762, 1768, 33.75, 2632, 2652, 45.00, 3489, 3536,
101: 56.25, 4327, 4419, 67.50, 5140, 5303, 78.75, 5923,
102: 6187, 90.00, 6667, 7071, 101.25, 7363, 7955, 112.50,
103: 8002, 8839, 123.75, 8573, 9723, 135.00, 9064, 10607,
104: 146.25, 9463, 11490, 157.50, 9758, 12374, 168.75, 9939,
105: 13258, 180.00, 10000, 14142 };
106: final double R = 20000 / Math.PI;
107: final DefaultEllipsoid ellipsoid = DefaultEllipsoid
108: .createEllipsoid("Test", R, R, SI.KILO(SI.METER));
109: final GeodeticCalculator calculator = new GeodeticCalculator(
110: ellipsoid);
111: calculator.setStartingGeographicPoint(0, 45);
112: for (int i = 0; i < DATA.length; i += 3) {
113: calculator.setDestinationGeographicPoint(DATA[i], 45);
114: final double orthodromic = calculator
115: .getOrthodromicDistance();
116: // final double loxodromic = calculator. getLoxodromicDistance();
117: assertEquals("Orthodromic distance", DATA[i + 1],
118: orthodromic, 0.75);
119: // assertEquals( "Loxodromic distance", DATA[i+2], loxodromic, 0.75);
120: /*
121: * Test the orthodromic path. We compare its length with the expected length.
122: */
123: int count = 0;
124: double length = 0, lastX = Double.NaN, lastY = Double.NaN;
125: final Shape path = calculator.getGeodeticCurve(1000);
126: final PathIterator iterator = path.getPathIterator(null,
127: 0.1);
128: final double[] buffer = new double[6];
129: while (!iterator.isDone()) {
130: switch (iterator.currentSegment(buffer)) {
131: case PathIterator.SEG_LINETO: {
132: count++;
133: length += ellipsoid.orthodromicDistance(lastX,
134: lastY, buffer[0], buffer[1]);
135: // Fall through
136: }
137: case PathIterator.SEG_MOVETO: {
138: lastX = buffer[0];
139: lastY = buffer[1];
140: break;
141: }
142: default: {
143: throw new IllegalPathStateException();
144: }
145: }
146: iterator.next();
147: }
148: assertEquals("Segment count", 1000, count); // Implementation check; will no longer be
149: // valid when the path will contains curves.
150: assertEquals("Orthodromic path length", orthodromic,
151: length, 1E-4);
152: }
153: }
154:
155: /**
156: * Tests geodetic calculator involving a coordinate operation.
157: * Our test uses a simple geographic CRS with only the axis order interchanged.
158: */
159: public void testUsingTransform() throws FactoryException,
160: TransformException {
161: final GeographicCRS crs = new DefaultGeographicCRS("Test",
162: DefaultGeodeticDatum.WGS84, new DefaultEllipsoidalCS(
163: "Test", DefaultCoordinateSystemAxis.LATITUDE,
164: DefaultCoordinateSystemAxis.LONGITUDE));
165: final GeodeticCalculator calculator = new GeodeticCalculator(
166: crs);
167: assertSame(crs, calculator.getCoordinateReferenceSystem());
168:
169: final double x = 45;
170: final double y = 30;
171: calculator.setStartingPosition(new DirectPosition2D(x, y));
172: Point2D point = calculator.getStartingGeographicPoint();
173: assertEquals(y, point.getX(), 1E-5);
174: assertEquals(x, point.getY(), 1E-5);
175:
176: calculator.setDirection(10, 100);
177: DirectPosition position = calculator.getDestinationPosition();
178: point = calculator.getDestinationGeographicPoint();
179: assertEquals(point.getX(), position.getOrdinate(1), 1E-5);
180: assertEquals(point.getY(), position.getOrdinate(0), 1E-5);
181: }
182: }
|