001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-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.io.PrintWriter;
020: import java.io.StringWriter;
021: import java.util.Arrays;
022: import java.util.Collection;
023: import java.util.Collections;
024: import java.util.Iterator;
025: import java.util.Map;
026: import javax.units.NonSI;
027: import javax.units.SI;
028: import javax.units.Unit;
029:
030: // JUnit dependencies
031: import junit.framework.Test;
032: import junit.framework.TestCase;
033: import junit.framework.TestSuite;
034:
035: // OpenGIS dependencies
036: import org.opengis.parameter.ParameterValueGroup;
037: import org.opengis.referencing.FactoryException;
038: import org.opengis.referencing.crs.CRSFactory;
039: import org.opengis.referencing.crs.CoordinateReferenceSystem;
040: import org.opengis.referencing.crs.GeographicCRS;
041: import org.opengis.referencing.crs.ProjectedCRS;
042: import org.opengis.referencing.cs.AxisDirection;
043: import org.opengis.referencing.cs.CSFactory;
044: import org.opengis.referencing.cs.CartesianCS;
045: import org.opengis.referencing.cs.EllipsoidalCS;
046: import org.opengis.referencing.datum.DatumFactory;
047: import org.opengis.referencing.datum.Ellipsoid;
048: import org.opengis.referencing.datum.GeodeticDatum;
049: import org.opengis.referencing.datum.PrimeMeridian;
050: import org.opengis.referencing.operation.Conversion;
051: import org.opengis.referencing.operation.MathTransform;
052: import org.opengis.referencing.operation.MathTransformFactory;
053: import org.opengis.referencing.operation.OperationMethod;
054: import org.opengis.referencing.operation.Projection;
055: import org.opengis.util.GenericName;
056: import org.opengis.util.ScopedName;
057:
058: // Geotools dependencies
059: import org.geotools.factory.Hints;
060: import org.geotools.referencing.factory.DatumAliases;
061: import org.geotools.referencing.factory.GeotoolsFactory;
062: import org.geotools.referencing.factory.ReferencingFactoryContainer;
063: import org.geotools.referencing.cs.DefaultCartesianCS;
064: import org.geotools.referencing.cs.DefaultEllipsoidalCS;
065: import org.geotools.referencing.datum.DefaultEllipsoid;
066: import org.geotools.referencing.datum.DefaultPrimeMeridian;
067: import org.geotools.referencing.crs.DefaultGeographicCRS;
068: import org.geotools.referencing.crs.DefaultProjectedCRS;
069: import org.geotools.referencing.operation.projection.MapProjection;
070: import org.geotools.resources.Arguments;
071:
072: /**
073: * Tests the creation of {@link CoordinateReferenceSystem} objects and dependencies through
074: * factories (not authority factories).
075: *
076: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/test/java/org/geotools/referencing/FactoriesTest.java $
077: * @version $Id: FactoriesTest.java 25943 2007-06-20 13:29:28Z desruisseaux $
078: */
079: public final class FactoriesTest extends TestCase {
080: /**
081: * The output stream. Will be overwriten by the {@link #main}
082: * if the test is run from the command line.
083: */
084: private static PrintWriter out = new PrintWriter(new StringWriter());
085:
086: /**
087: * Returns the test suite.
088: */
089: public static Test suite() {
090: return new TestSuite(FactoriesTest.class);
091: }
092:
093: /**
094: * Creates a new instance of <code>FactoriesTest</code>
095: */
096: public FactoriesTest(final String name) {
097: super (name);
098: }
099:
100: /**
101: * Convenience method creating a map with only the "name" property.
102: * This is the only mandatory property for object creation.
103: */
104: private static Map name(final String name) {
105: return Collections.singletonMap("name", name);
106: }
107:
108: /**
109: * Tests the creation of new coordinate reference systems.
110: *
111: * @throws FactoryException if a coordinate reference system can't be created.
112: */
113: public void testCreation() throws FactoryException {
114: out.println();
115: out.println("Testing CRS creations");
116: out.println("---------------------");
117: out.println();
118: out.println("create Coodinate Reference System....1: ");
119: final DatumFactory datumFactory = ReferencingFactoryFinder
120: .getDatumFactory(null);
121: final CSFactory csFactory = ReferencingFactoryFinder
122: .getCSFactory(null);
123: final CRSFactory crsFactory = ReferencingFactoryFinder
124: .getCRSFactory(null);
125: final MathTransformFactory mtFactory = ReferencingFactoryFinder
126: .getMathTransformFactory(null);
127:
128: final Ellipsoid airy1830;
129: final Unit meters = SI.METER;
130: airy1830 = datumFactory.createEllipsoid(name("Airy1830"),
131: 6377563.396, 6356256.910, meters);
132: out.println();
133: out.println("create Coodinate Reference System....2: ");
134: out.println(airy1830.toWKT());
135:
136: final PrimeMeridian greenwich;
137: final Unit degrees = NonSI.DEGREE_ANGLE;
138: greenwich = datumFactory.createPrimeMeridian(name("Greenwich"),
139: 0, degrees);
140: out.println();
141: out.println("create Coodinate Reference System....3: ");
142: out.println(greenwich.toWKT());
143:
144: // NOTE: we could use the following pre-defined constant instead:
145: // DefaultPrimeMeridian.GREENWICH;
146: final GeodeticDatum datum;
147: datum = datumFactory.createGeodeticDatum(name("Airy1830"),
148: airy1830, greenwich);
149: out.println();
150: out.println("create Coodinate Reference System....4: ");
151: out.println(datum.toWKT());
152:
153: // NOTE: we could use the following pre-defined constant instead:
154: // DefaultEllipsoidalCS.GEODETIC_2D;
155: final EllipsoidalCS ellCS;
156: ellCS = csFactory.createEllipsoidalCS(name("Ellipsoidal"),
157: csFactory.createCoordinateSystemAxis(name("Longitude"),
158: "long", AxisDirection.EAST, degrees), csFactory
159: .createCoordinateSystemAxis(name("Latitude"),
160: "lat", AxisDirection.NORTH, degrees));
161: out.println();
162: out.println("create Coodinate Reference System....5: ");
163: out.println(ellCS); // No WKT for coordinate systems
164:
165: final GeographicCRS geogCRS;
166: geogCRS = crsFactory.createGeographicCRS(name("Airy1830"),
167: datum, ellCS);
168: out.println();
169: out.println("create Coodinate Reference System....6: ");
170: out.println(geogCRS.toWKT());
171:
172: final MathTransform p;
173: final ParameterValueGroup param = mtFactory
174: .getDefaultParameters("Transverse_Mercator");
175: param.parameter("semi_major").setValue(
176: airy1830.getSemiMajorAxis());
177: param.parameter("semi_minor").setValue(
178: airy1830.getSemiMinorAxis());
179: param.parameter("central_meridian").setValue(49);
180: param.parameter("latitude_of_origin").setValue(-2);
181: param.parameter("false_easting").setValue(400000);
182: param.parameter("false_northing").setValue(-100000);
183: out.println();
184: out.println("create Coodinate System....7: ");
185: out.println(param);
186:
187: // NOTE: we could use the following pre-defined constant instead:
188: // DefaultCartesianCS.PROJECTED;
189: final CartesianCS cartCS;
190: cartCS = csFactory.createCartesianCS(name("Cartesian"),
191: csFactory.createCoordinateSystemAxis(name("Easting"),
192: "x", AxisDirection.EAST, meters), csFactory
193: .createCoordinateSystemAxis(name("Northing"),
194: "y", AxisDirection.NORTH, meters));
195: out.println();
196: out.println("create Coodinate Reference System....8: ");
197: out.println(cartCS); // No WKT for coordinate systems
198:
199: final Hints hints = new Hints(null);
200: hints.put(Hints.DATUM_FACTORY, datumFactory);
201: hints.put(Hints.CS_FACTORY, csFactory);
202: hints.put(Hints.CRS_FACTORY, crsFactory);
203: hints.put(Hints.MATH_TRANSFORM_FACTORY, mtFactory);
204:
205: final ReferencingFactoryContainer container = new ReferencingFactoryContainer(
206: hints);
207: assertSame(datumFactory, container.getDatumFactory());
208: assertSame(csFactory, container.getCSFactory());
209: assertSame(crsFactory, container.getCRSFactory());
210: assertSame(mtFactory, container.getMathTransformFactory());
211:
212: final ProjectedCRS projCRS = container.createProjectedCRS(
213: name("Great_Britian_National_Grid"), geogCRS, null,
214: param, cartCS);
215: out.println();
216: out.println("create Coodinate System....9: ");
217: out.println(projCRS.toWKT());
218: }
219:
220: /**
221: * Tests all map projection creation.
222: */
223: public void testMapProjections() throws FactoryException {
224: out.println();
225: out.println("Testing classification names");
226: out.println("----------------------------");
227: final MathTransformFactory mtFactory = ReferencingFactoryFinder
228: .getMathTransformFactory(null);
229: final Collection methods = mtFactory
230: .getAvailableMethods(Projection.class);
231: for (final Iterator it = methods.iterator(); it.hasNext();) {
232: final OperationMethod method = (OperationMethod) it.next();
233: final String classification = method.getName().getCode();
234: final ParameterValueGroup param = mtFactory
235: .getDefaultParameters(classification);
236: try {
237: param.parameter("semi_major").setValue(6377563.396);
238: param.parameter("semi_minor").setValue(
239: 6356256.909237285);
240: } catch (IllegalArgumentException e) {
241: // Above parameters do not exists. Ignore.
242: }
243: final MathTransform mt;
244: try {
245: mt = mtFactory.createParameterizedTransform(param);
246: } catch (FactoryException e) {
247: // Probably not a map projection. This test is mostly about projection, so ignore.
248: continue;
249: } catch (UnsupportedOperationException e) {
250: continue;
251: }
252: if (mt instanceof MapProjection) {
253: /*
254: * Tests map projection properties. Some tests are ommitted for south-oriented
255: * map projections, since they are implemented as a concatenation of their North-
256: * oriented variants with an affine transform.
257: */
258: out.println(classification);
259: final boolean skip = classification
260: .equalsIgnoreCase("Transverse Mercator (South Orientated)")
261: || classification
262: .equalsIgnoreCase("Equidistant_Cylindrical");
263: if (!skip) {
264: assertEquals(classification, ((MapProjection) mt)
265: .getParameterDescriptors().getName()
266: .getCode());
267: }
268: final ProjectedCRS projCRS = new DefaultProjectedCRS(
269: "Test", method, DefaultGeographicCRS.WGS84, mt,
270: DefaultCartesianCS.PROJECTED);
271: final Conversion conversion = projCRS
272: .getConversionFromBase();
273: assertSame(mt, conversion.getMathTransform());
274: final OperationMethod projMethod = conversion
275: .getMethod();
276: assertEquals(classification, projMethod.getName()
277: .getCode());
278: }
279: }
280: }
281:
282: /**
283: * Tests datum aliases. Note: ellipsoid and prime meridian are dummy values just
284: * (not conform to the usage in real world) just for testing purpose.
285: */
286: public void testDatumAliases() throws FactoryException {
287: final String name0 = "Nouvelle Triangulation Francaise (Paris)";
288: final String name1 = "Nouvelle_Triangulation_Francaise_Paris";
289: final String name2 = "NTF (Paris meridian)";
290: final Ellipsoid ellipsoid = DefaultEllipsoid.WGS84;
291: final PrimeMeridian meridian = DefaultPrimeMeridian.GREENWICH;
292: DatumFactory factory = new GeotoolsFactory();
293: final Map properties = Collections.singletonMap("name", name1);
294: GeodeticDatum datum = factory.createGeodeticDatum(properties,
295: ellipsoid, meridian);
296: assertTrue(datum.getAlias().isEmpty());
297:
298: for (int i = 0; i < 3; i++) {
299: switch (i) {
300: case 0:
301: factory = new DatumAliases(factory);
302: break;
303: case 1:
304: factory = ReferencingFactoryFinder
305: .getDatumFactory(null);
306: break;
307: case 2:
308: ((DatumAliases) factory).freeUnused();
309: break;
310: default:
311: throw new AssertionError(); // Should not occurs.
312: }
313: final String pass = "Pass #" + i;
314: datum = factory.createGeodeticDatum(properties, ellipsoid,
315: meridian);
316: final GenericName[] aliases = (GenericName[]) datum
317: .getAlias().toArray(new GenericName[0]);
318: assertEquals(pass, 3, aliases.length);
319: assertEquals(pass, name0, aliases[0].asLocalName()
320: .toString());
321: assertEquals(pass, name1, aliases[1].asLocalName()
322: .toString());
323: assertEquals(pass, name2, aliases[2].asLocalName()
324: .toString());
325: assertTrue(pass, aliases[0] instanceof ScopedName);
326: assertTrue(pass, aliases[1] instanceof ScopedName);
327: assertTrue(pass, aliases[2] instanceof ScopedName);
328: }
329:
330: datum = factory.createGeodeticDatum(Collections.singletonMap(
331: "name", "Tokyo"), ellipsoid, meridian);
332: Collection/*<GenericName>*/aliases = datum.getAlias();
333: assertEquals(4, aliases.size());
334:
335: ((DatumAliases) factory).freeUnused();
336: datum = factory.createGeodeticDatum(Collections.singletonMap(
337: "name", "_toKyo _"), ellipsoid, meridian);
338: assertEquals(4, datum.getAlias().size());
339: assertTrue(aliases.equals(datum.getAlias()));
340:
341: datum = factory.createGeodeticDatum(Collections.singletonMap(
342: "name", "D_Tokyo"), ellipsoid, meridian);
343: assertEquals(4, datum.getAlias().size());
344:
345: datum = factory.createGeodeticDatum(Collections.singletonMap(
346: "name", "Luxembourg 1930"), ellipsoid, meridian);
347: assertEquals(3, datum.getAlias().size());
348:
349: datum = factory.createGeodeticDatum(Collections.singletonMap(
350: "name", "Dummy"), ellipsoid, meridian);
351: assertTrue("Non existing datum should have no alias.", datum
352: .getAlias().isEmpty());
353:
354: datum = factory.createGeodeticDatum(Collections.singletonMap(
355: "name", "WGS 84"), ellipsoid, meridian);
356: assertTrue(AbstractIdentifiedObject
357: .nameMatches(datum, "WGS 84"));
358: assertTrue(AbstractIdentifiedObject.nameMatches(datum,
359: "WGS_1984"));
360: assertTrue(AbstractIdentifiedObject.nameMatches(datum,
361: "World Geodetic System 1984"));
362: assertFalse(AbstractIdentifiedObject.nameMatches(datum,
363: "WGS 72"));
364: }
365:
366: /**
367: * Run the test from the command line.
368: * Options: {@code -verbose}.
369: *
370: * @param args the command line arguments.
371: */
372: public static void main(final String[] args) {
373: final Arguments arguments = new Arguments(args);
374: if (arguments.getFlag("-verbose"))
375: try {
376: out = arguments.out;
377: final FactoriesTest test = new FactoriesTest(null);
378: test.testCreation();
379: test.testMapProjections();
380: } catch (FactoryException exception) {
381: exception.printStackTrace(arguments.err);
382: }
383: else {
384: junit.textui.TestRunner.run(suite());
385: }
386: }
387: }
|