001: /**
002: * This tutorial code was developed and tested with the geotools 2.2.x svn.
003: * If using geotools 2.1, note that referenging.jar is not needed (it was part of main.jar)
004: * and some geotools referencing classes were renamed to Default* in geotools 2.2.x.
005: *
006: * Geotools dependancies:
007: * main-2.2.x.jar
008: * referencing-2.2.x.jar
009: * epsg-wkt-2.2.x.jar or epsg-hsql-2.2.x.jar or epsg-access-2.2.x
010: *
011: * Other dependancies:
012: * geoapi-2.0.jar
013: * units-0.01.jar
014: * vecmath-1.3.jar
015: * hsqldb-1.8.0.1.jar (if using epsg-hsql-2.2.x.jar)
016: */package org.geotools.demo.referencing;
017:
018: //J2SE dependancies
019: import java.util.Collections;
020: import java.util.HashMap;
021: import java.util.Map;
022: import java.util.Iterator;
023: import java.util.Set;
024:
025: import javax.units.NonSI;
026: import javax.units.SI;
027:
028: //GeoAPI dependencies
029: import org.opengis.referencing.FactoryException;
030: import org.opengis.referencing.crs.*;
031: import org.opengis.referencing.operation.*;
032: import org.opengis.referencing.cs.AxisDirection;
033: import org.opengis.referencing.cs.CSFactory;
034: import org.opengis.referencing.cs.CartesianCS;
035: import org.opengis.referencing.cs.CoordinateSystemAxis;
036: import org.opengis.referencing.cs.EllipsoidalCS;
037: import org.opengis.referencing.datum.DatumFactory;
038: import org.opengis.referencing.datum.Ellipsoid;
039: import org.opengis.referencing.datum.GeodeticDatum;
040: import org.opengis.referencing.datum.PrimeMeridian;
041: import org.opengis.spatialschema.geometry.DirectPosition;
042: import org.opengis.spatialschema.geometry.MismatchedDimensionException;
043: import org.opengis.parameter.ParameterValueGroup;
044: import org.opengis.referencing.IdentifiedObject;
045: import org.opengis.metadata.Identifier;
046: import org.opengis.util.GenericName;
047:
048: // Geotools dependencies
049: import org.geotools.factory.Hints;
050: import org.geotools.geometry.GeneralDirectPosition;
051: import org.geotools.referencing.CRS;
052: import org.geotools.referencing.FactoryFinder;
053: import org.geotools.referencing.factory.FactoryGroup;
054: import org.geotools.referencing.datum.DefaultGeodeticDatum;
055: import org.geotools.referencing.datum.BursaWolfParameters;
056:
057: /**
058: *
059: * Code for the geotools coordinate transformation services tutorial:
060: * http://docs.codehaus.org/display/GEOTOOLS/Coordinate+Transformation+Services+for+Geotools+2.1
061: *
062: * The following code is made up of many, short methods used for discussion in the tutorial,
063: * and does not create a coherent program.
064: *
065: * These examples cover the following topics:
066: * <ul>
067: * <li>creating coordinate reference systems (CRS) by hand</li>
068: * <li>creating CRS's from well known text (WKT) strings</li>
069: * <li>creating CRS's from authority codes </li>
070: * <li>creating math transforms between CRS's </li>
071: * <li>creating math transforms by hand </li>
072: * <li> </li>
073: * </ul>
074: *
075: * START SNIPPET and END SNIPPET comments are used by the wiki to display code snippets from svn.
076: * Factory creation is repeated below so that it shows up in the tutorial code snippets.
077: *
078: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/demo/referencing/src/main/java/org/geotools/demo/referencing/CTSTutorial.java $
079: * @version $Id: CTSTutorial.java 21780 2006-10-03 21:06:21Z desruisseaux $
080: * @author Rueben Schulz
081: *
082: * TODO using the auto crs factory
083: */
084: public class CTSTutorial {
085:
086: /** CRS stored for latter use in createMathTransformBetweenCRSs() */
087: private CoordinateReferenceSystem nad27CRS = null;
088: /** CRS stored for latter use in createMathTransformBetweenCRSs() */
089: private CoordinateReferenceSystem utm10NCRS = null;
090:
091: CTSTutorial() {
092: try {
093: creatCRSFromWKT();
094: createFromEPSGCode();
095: createCRSByHand1();
096: createCRSByHand2();
097: //createCRSByHand3();
098: createMathTransformBetweenCRSs();
099: //transformUsingCRSUtility();
100: createAndUseMathTransform();
101: hintExample();
102: //createTransformFromAuthorityCode();
103: } catch (Exception e) {
104: e.printStackTrace();
105: }
106: }
107:
108: /**
109: * A method with some examples of premade static objects.
110: */
111: void premadeObjects() {
112: // START SNIPPET: premadeObjects
113: GeographicCRS geoCRS = org.geotools.referencing.crs.DefaultGeographicCRS.WGS84;
114: GeodeticDatum wgs84Datum = org.geotools.referencing.datum.DefaultGeodeticDatum.WGS84;
115: PrimeMeridian greenwichMeridian = org.geotools.referencing.datum.DefaultPrimeMeridian.GREENWICH;
116: CartesianCS cartCS = org.geotools.referencing.cs.DefaultCartesianCS.GENERIC_2D;
117: CoordinateSystemAxis latAxis = org.geotools.referencing.cs.DefaultCoordinateSystemAxis.GEODETIC_LATITUDE;
118: // END SNIPPET: premadeObjects
119: }
120:
121: /**
122: * An example of creating a CRS from a WKT string. Additonal examples of WKT strings
123: * can be found in
124: * http://svn.geotools.org/geotools/trunk/gt/module/referencing/test/org/geotools/referencing/test-data/
125: *
126: * TODO Brief description of what a CRS is (and what it is composed of)
127: *
128: * @throws Exception
129: */
130: void creatCRSFromWKT() throws Exception {
131: System.out
132: .println("------------------------------------------");
133: System.out.println("Creating a CRS from a WKT string:");
134: // START SNIPPET: crsFromWKT
135: CRSFactory crsFactory = FactoryFinder.getCRSFactory(null);
136: String wkt = "PROJCS[\"UTM_Zone_10N\", " + "GEOGCS[\"WGS84\", "
137: + "DATUM[\"WGS84\", "
138: + "SPHEROID[\"WGS84\", 6378137.0, 298.257223563]], "
139: + "PRIMEM[\"Greenwich\", 0.0], "
140: + "UNIT[\"degree\",0.017453292519943295], "
141: + "AXIS[\"Longitude\",EAST], "
142: + "AXIS[\"Latitude\",NORTH]], "
143: + "PROJECTION[\"Transverse_Mercator\"], "
144: + "PARAMETER[\"semi_major\", 6378137.0], "
145: + "PARAMETER[\"semi_minor\", 6356752.314245179], "
146: + "PARAMETER[\"central_meridian\", -123.0], "
147: + "PARAMETER[\"latitude_of_origin\", 0.0], "
148: + "PARAMETER[\"scale_factor\", 0.9996], "
149: + "PARAMETER[\"false_easting\", 500000.0], "
150: + "PARAMETER[\"false_northing\", 0.0], "
151: + "UNIT[\"metre\",1.0], " + "AXIS[\"x\",EAST], "
152: + "AXIS[\"y\",NORTH]]";
153:
154: CoordinateReferenceSystem crs = crsFactory.createFromWKT(wkt);
155: // END SNIPPET: crsFromWKT
156: System.out.println(" CRS: " + crs.toWKT());
157: System.out.println("Identified CRS object:");
158: printIdentifierStuff(crs);
159: System.out.println("Identified Datum object:");
160: printIdentifierStuff(((ProjectedCRS) crs).getDatum());
161: System.out
162: .println("------------------------------------------");
163: }
164:
165: /**
166: * Creates a CRS from an EPSG code. There are a few different EPSG authority
167: * factories in geotools that do roughly the same thing:
168: *
169: * <ul>
170: * <li>gt2-epsg-access.jar is backed by the official EPSG MS Access
171: * database (only works on MS Windows, therefore I have not shown how to
172: * configure it here).</li>
173: * <li>gt2-epsg-hsql.jar provides an embeded hsql database created from the
174: * EPSG SQL scripts. This contains the same information as the MS Arcess
175: * database.</li>
176: * <li>other factories allow the EPSG information to be in an external
177: * database (postgresql, mysql, oracle)</li>
178: * <li>gt2-epsg-wkt.jar is a simple properties file with WKT descriptions
179: * for EPSG defined CRS codes. This file does not derive directly from the
180: * official EPSG database, so its should be used with caution. It provides a
181: * very simple method of creating a new authority factory and named objects.</li>
182: * </ul>
183: *
184: * The specific authority factory returned by getCRSAuthorityFactory is
185: * dependent on the different factories on your classpath (ie WKT or Access
186: * or HSQL) and the hints you provide. By default the "better" authority
187: * factory should be used if more than one is available.
188: *
189: * TODO check on the use of hints
190: * TODO expand on how to use EPSG data in a
191: * postgres db (this may be a 2.2 feature, but FactoryUsingANSISQL may work)
192: *
193: */
194: void createFromEPSGCode() throws Exception {
195: System.out
196: .println("------------------------------------------");
197: System.out.println("Creating a CRS from an authority factory:");
198: // START SNIPPET: crsFromCode
199: String code = "26910";
200: CoordinateReferenceSystem crs = FactoryFinder
201: .getCRSAuthorityFactory("EPSG", null)
202: .createCoordinateReferenceSystem(code);
203: // END SNIPPET: crsFromCode
204: System.out.println(" CRS: " + crs.toWKT());
205: System.out.println("Identified CRS object:");
206: printIdentifierStuff(crs);
207: System.out
208: .println("------------------------------------------");
209: }
210:
211: /**
212: * Creates a WGS 84/UTM Zone 10N CRS mostly (uses some premade objects) by
213: * hand. Uses the higher level FactoryGroup instead of the lower level
214: * MathTransformFactory (commented out).
215: *
216: * @throws Exception
217: */
218: void createCRSByHand1() throws Exception {
219: System.out
220: .println("------------------------------------------");
221: System.out.println("Creating a CRS by hand:");
222: // START SNIPPET: UTM10NcrsByHand
223: MathTransformFactory mtFactory = FactoryFinder
224: .getMathTransformFactory(null);
225: FactoryGroup factories = new FactoryGroup();
226:
227: GeographicCRS geoCRS = org.geotools.referencing.crs.DefaultGeographicCRS.WGS84;
228: CartesianCS cartCS = org.geotools.referencing.cs.DefaultCartesianCS.GENERIC_2D;
229:
230: ParameterValueGroup parameters = mtFactory
231: .getDefaultParameters("Transverse_Mercator");
232: parameters.parameter("central_meridian").setValue(-111.0);
233: parameters.parameter("latitude_of_origin").setValue(0.0);
234: parameters.parameter("scale_factor").setValue(0.9996);
235: parameters.parameter("false_easting").setValue(500000.0);
236: parameters.parameter("false_northing").setValue(0.0);
237:
238: Map properties = Collections.singletonMap("name",
239: "WGS 84 / UTM Zone 12N");
240: ProjectedCRS projCRS = factories.createProjectedCRS(properties,
241: geoCRS, null, parameters, cartCS);
242: // END SNIPPET: UTM10NcrsByHand
243:
244: //parameters.parameter("semi_major").setValue(((GeodeticDatum)geoCRS.getDatum()).getEllipsoid().getSemiMajorAxis());
245: //parameters.parameter("semi_minor").setValue(((GeodeticDatum)geoCRS.getDatum()).getEllipsoid().getSemiMinorAxis());
246:
247: //MathTransform trans = mtFactory.createParameterizedTransform(parameters);
248: //ProjectedCRS projCRS = crsFactory.createProjectedCRS(
249: // Collections.singletonMap("name", "WGS 84 / UTM Zone 12N"),
250: // new org.geotools.referencing.operation.OperationMethod(trans),
251: // geoCRS, trans, cartCS);
252: System.out.println(" Projected CRS: " + projCRS.toWKT());
253: System.out
254: .println("------------------------------------------");
255:
256: // save for later use in createMathTransformBetweenCRSs()
257: this .utm10NCRS = projCRS;
258: }
259:
260: /**
261: * Creates a NAD 27 geographic CRS. Notice that the datum factory
262: * automatically adds aliase names to the datum (because "North American
263: * Datum 1927" has an entry in
264: * http://svn.geotools.org/geotools/trunk/gt/module/referencing/src/org/geotools/referencing/factory/DatumAliasesTable.txt ).
265: * Also notice that toWGS84 information (used in a datum transform) was
266: * also added to the datum.
267: */
268: void createCRSByHand2() throws Exception {
269: System.out
270: .println("------------------------------------------");
271: System.out.println("Creating a CRS by hand:");
272: // START SNIPPET: nad27crsByHand
273: CRSFactory crsFactory = FactoryFinder.getCRSFactory(null);
274: DatumFactory datumFactory = FactoryFinder.getDatumFactory(null);
275: CSFactory csFactory = FactoryFinder.getCSFactory(null);
276:
277: Map map = new HashMap();
278: map.put("name", "Clarke 1866");
279:
280: Ellipsoid clark1866ellipse = datumFactory
281: .createFlattenedSphere(map, 6378206.4,
282: 294.978698213901, SI.METER);
283:
284: PrimeMeridian greenwichMeridian = org.geotools.referencing.datum.DefaultPrimeMeridian.GREENWICH;
285:
286: final BursaWolfParameters toWGS84 = new BursaWolfParameters(
287: DefaultGeodeticDatum.WGS84);
288: toWGS84.dx = -3.0;
289: toWGS84.dy = 142;
290: toWGS84.dz = 183;
291:
292: map.clear();
293: map.put("name", "North American Datum 1927");
294: map.put(DefaultGeodeticDatum.BURSA_WOLF_KEY, toWGS84);
295:
296: GeodeticDatum clark1866datum = datumFactory
297: .createGeodeticDatum(map, clark1866ellipse,
298: greenwichMeridian);
299: System.out.println(clark1866datum.toWKT());
300: // notice all of the lovely datum aliases (used to determine if two
301: // datums are the same)
302: System.out.println("Identified Datum object:");
303: printIdentifierStuff(clark1866datum);
304:
305: map.clear();
306: map.put("name", "<lat>, <long>");
307: CoordinateSystemAxis latAxis = org.geotools.referencing.cs.DefaultCoordinateSystemAxis.GEODETIC_LATITUDE;
308: CoordinateSystemAxis longAxis = org.geotools.referencing.cs.DefaultCoordinateSystemAxis.GEODETIC_LONGITUDE;
309: EllipsoidalCS ellipsCS = csFactory.createEllipsoidalCS(map,
310: latAxis, longAxis);
311:
312: map.clear();
313: map.put("name", "NAD 27");
314: map.put("authority", "9999");
315: // TODO add an authority code here (should be an identifier)
316: GeographicCRS nad27CRS = crsFactory.createGeographicCRS(map,
317: clark1866datum, ellipsCS);
318: System.out.println(nad27CRS.toWKT());
319: // END SNIPPET: nad27crsByHand
320: System.out.println("Identified CRS object:");
321: printIdentifierStuff(nad27CRS);
322:
323: System.out
324: .println("------------------------------------------");
325:
326: // save for latter use in createMathTransformBetweenCRSs()
327: this .nad27CRS = nad27CRS;
328: }
329:
330: /**
331: * Creates two coordinate reference system by hand without using any of the
332: * GT2 APIs (except FactoryFinder to get things started). It does not use
333: * any of the static objects available in geotools implementations. The
334: * following example creates a CRS to represent the Airy 1830 ellipsoid with
335: * the incoming data in the order of (long,lat,height) and a geocentric CRS
336: * with (x,y,z) axises.
337: *
338: * TODO the Airy CRS described below is actually wgs84, FIX this.
339: *
340: * @throws FactoryException
341: */
342: void createCRSByHand3() throws FactoryException {
343: System.out
344: .println("------------------------------------------");
345: System.out.println("Creating two CRSs by hand:");
346: CRSFactory crsFactory = FactoryFinder.getCRSFactory(null);
347: DatumFactory datumFactory = FactoryFinder.getDatumFactory(null);
348: CSFactory csFactory = FactoryFinder.getCSFactory(null);
349: Map map = new HashMap();
350:
351: //
352: // Create a datum used for each CRS
353: //
354: map.clear();
355: map.put("name", "Greenwich Meridian");
356: PrimeMeridian greenwichMeridian = datumFactory
357: .createPrimeMeridian(map, 0, NonSI.DEGREE_ANGLE);
358:
359: map.clear();
360: map.put("name", "WGS 84 Ellipsoid Datum");
361: Ellipsoid wgs84Ellipsoid = datumFactory.createFlattenedSphere(
362: map, 6378137, 298.257223563, SI.METER);
363:
364: map.clear();
365: map.put("name", "WGS84 Height Datum");
366: GeodeticDatum wgs84Datum = datumFactory.createGeodeticDatum(
367: map, wgs84Ellipsoid, greenwichMeridian);
368:
369: //
370: //Create a geocentric CRS
371: //
372: // Create a collection of axes for the coordinate system.
373: map.clear();
374: map.put("name", "Cartesian X axis");
375: CoordinateSystemAxis xAxis = csFactory
376: .createCoordinateSystemAxis(map, "X",
377: AxisDirection.GEOCENTRIC_X, SI.METER);
378:
379: map.clear();
380: map.put("name", "Cartesian Y axis");
381: CoordinateSystemAxis yAxis = csFactory
382: .createCoordinateSystemAxis(map, "Y",
383: AxisDirection.GEOCENTRIC_Y, SI.METER);
384:
385: map.clear();
386: map.put("name", "Cartesian Z axis");
387: CoordinateSystemAxis zAxis = csFactory
388: .createCoordinateSystemAxis(map, "Z",
389: AxisDirection.GEOCENTRIC_Z, SI.METER);
390:
391: map.clear();
392: map.put("name", "Rendered Cartesian CS");
393: CartesianCS worldCS = csFactory.createCartesianCS(map, xAxis,
394: yAxis, zAxis);
395:
396: // Now, the geocentric coordinate reference system that we'd use for output - eg to a 3D renderer
397: map.clear();
398: map.put("name", "Output Cartesian CS");
399: CoordinateReferenceSystem geocentricCRS = crsFactory
400: .createGeocentricCRS(map, wgs84Datum, worldCS);
401: System.out.println("Geocentric CRS: " + geocentricCRS.toWKT());
402:
403: //
404: // Create a geograyhic CRS for the Airy 1830 ellipsoid
405: //map.clear();
406: //map.put("name", "Airy 1830");
407: //Ellipsoid airyEllipse =
408: // datumFactory.createFlattenedSphere(map, 6377563.396, 299.3249646, SI.METER);
409:
410: map.clear();
411: map.put("name", "Geodetic North axis");
412: CoordinateSystemAxis northAxis = csFactory
413: .createCoordinateSystemAxis(map, "N",
414: AxisDirection.NORTH, NonSI.DEGREE_ANGLE);
415:
416: map.clear();
417: map.put("name", "Geodetic East axis");
418: CoordinateSystemAxis eastAxis = csFactory
419: .createCoordinateSystemAxis(map, "E",
420: AxisDirection.EAST, NonSI.DEGREE_ANGLE);
421:
422: map.clear();
423: map.put("name", "Geodetic Height axis");
424: CoordinateSystemAxis heightAxis = csFactory
425: .createCoordinateSystemAxis(map, "Up",
426: AxisDirection.UP, SI.METER);
427:
428: map.clear();
429: map.put("name", "<long>,<lat> Airy 1830 geodetic");
430: EllipsoidalCS airyCS = csFactory.createEllipsoidalCS(map,
431: eastAxis, northAxis, heightAxis);
432:
433: // finally create the source geographic CRS
434: CoordinateReferenceSystem airyCRS = crsFactory
435: .createGeographicCRS(map, wgs84Datum, airyCS);
436: //TODO crs.toWKT() throws exceptions here (.toString() works)
437: System.out.println("Geographic CRS: " + airyCRS.toString());
438:
439: System.out.println("Identified CRS object:");
440: printIdentifierStuff(airyCRS);
441: System.out.println("Identified Datum object:");
442: printIdentifierStuff(((GeographicCRS) airyCRS).getDatum());
443:
444: // you could now use these two CRS's to create a transform between them
445: // as done below in createMathTransformBetweenCRSs(). The transform can
446: // be used to convert points from lat,long to geocentric x,y,z.
447: System.out
448: .println("------------------------------------------");
449: }
450:
451: /**
452: * Creates a math transform between the CRS's created in createCRSByHand2()
453: * and createCRSByHand1(). The resulting transformation is a concatenation
454: * of the following transforms:
455: *
456: * <ul>
457: * <li>Affine - to switch axis order from (latitude,longitude) to (longitude,latitude)</li>
458: * <li>Molodenski - to preform a datum shift between NAD27 and WGS84,
459: * using the NAD 27 CRS BursaWolfParameters parameters </li>
460: * <li>Transverse Mercator - to convert from geographic to projected UTM coordinates</li>
461: * </ul>
462: *
463: * @throws Exception
464: */
465: void createMathTransformBetweenCRSs() throws Exception {
466: System.out
467: .println("------------------------------------------");
468: System.out
469: .println("Creating a math transform between two CRSs:");
470:
471: // START SNIPPET: mathTransformBetweenCRSs
472: CoordinateOperationFactory coFactory = FactoryFinder
473: .getCoordinateOperationFactory(null);
474:
475: // Nad 27 geographic (lat,long)
476: CoordinateReferenceSystem sourceCRS = nad27CRS;
477: // UTM Zone 10N, WGS 84 (x,y)
478: CoordinateReferenceSystem targetCRS = utm10NCRS;
479:
480: CoordinateOperation op = coFactory.createOperation(sourceCRS,
481: targetCRS);
482: MathTransform trans = op.getMathTransform();
483: System.out.println("Math Transform: " + trans.toWKT());
484:
485: // transform some points
486: DirectPosition pt = new GeneralDirectPosition(45.1, -120.0);
487: System.out.println("Input point: " + pt);
488: pt = trans.transform(pt, null);
489: System.out.println("Output point: " + pt);
490: System.out.println("Inverse of output point: "
491: + trans.inverse().transform(pt, null));
492: // END SNIPPET: mathTransformBetweenCRSs
493: System.out
494: .println("------------------------------------------");
495: }
496:
497: /**
498: * Uses the CRS utility class to create two CRSs and a tranformation between them.
499: */
500: void transformUsingCRSUtility() throws Exception {
501: System.out
502: .println("------------------------------------------");
503: System.out
504: .println("Using the CRS utility to create a math transform between two CRSs:");
505:
506: CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4978"); //WGS84 geocentrique
507: CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4979"); //WGS84 geographique 3D
508: System.out.println("Source CRS: "
509: + sourceCRS.getName().getCode());
510: System.out.println("Target CRS: "
511: + targetCRS.getName().getCode());
512:
513: MathTransform mathTransform = CRS.findMathTransform(sourceCRS,
514: targetCRS);
515: System.out.println("MT: " + mathTransform.toWKT());
516: DirectPosition pt = new GeneralDirectPosition(4089881.3,
517: -4874130.7, 441946.6); //x,y,z
518: System.out.println("Input point: " + pt);
519: pt = mathTransform.transform(pt, null);
520: System.out.println("Output point: " + pt); //longitude,latitude,height
521:
522: System.out
523: .println("------------------------------------------");
524: }
525:
526: /**
527: * Creates a low level math transform by hand. This is essentially just an equation (with some parameters)
528: * used to transform input to output points.
529: *
530: * @throws TransformException
531: * @throws MismatchedDimensionException
532: */
533: void createAndUseMathTransform() throws FactoryException,
534: MismatchedDimensionException, TransformException {
535: System.out
536: .println("------------------------------------------");
537: System.out.println("Creating a math transform by hand:");
538: // START SNIPPET: mathTransformByHand
539: MathTransformFactory mtFactory = FactoryFinder
540: .getMathTransformFactory(null);
541:
542: ParameterValueGroup params = mtFactory
543: .getDefaultParameters("Hotine_Oblique_Mercator");
544: params.parameter("semi_major").setValue(6377298.556);
545: params.parameter("semi_minor").setValue(6356097.5503009);
546: params.parameter("longitude_of_center").setValue(115.0);
547: params.parameter("latitude_of_center").setValue(4.0);
548: params.parameter("azimuth").setValue(53.315820472222200);
549: params.parameter("rectified_grid_angle").setValue(
550: 53.130102361111100);
551: params.parameter("scale_factor").setValue(0.99984);
552: params.parameter("false_easting").setValue(0.0);
553: params.parameter("false_northing").setValue(0.0);
554: MathTransform trans = mtFactory
555: .createParameterizedTransform(params);
556: System.out.println("Math Transform: " + trans.toWKT());
557:
558: //transform some points
559: DirectPosition pt = new GeneralDirectPosition(120.0, 6.0);
560: System.out.println("Input point: " + pt);
561: pt = trans.transform(pt, null);
562: System.out.println("Output point: " + pt);
563: System.out.println("Inverse of output point: "
564: + trans.inverse().transform(pt, null));
565: // END SNIPPET: mathTransformByHand
566: System.out
567: .println("------------------------------------------");
568: }
569:
570: /*
571: * An example of using a hint to turn off datum shifts
572: */
573: void hintExample() throws Exception {
574: System.out
575: .println("------------------------------------------");
576: System.out
577: .println("Using hints to create a transform without a datum shift:");
578: // Source CRS: Belge 1972 / Belge Lambert 72
579: String sourceCode = "31300";
580: // Target CRS: NTF (Paris) / Nord France
581: String targetCode = "27591";
582: Hints hints = new Hints(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);
583: // This instructs Geotools to be tolerant to missing Bursa-Wolf parameters.
584: // However, you may get one kilometer error in such case if a datum shift
585: // is applied without such parameters.
586: CRSAuthorityFactory crsFactory = FactoryFinder
587: .getCRSAuthorityFactory("EPSG", hints);
588: CoordinateReferenceSystem sourceCRS = crsFactory
589: .createCoordinateReferenceSystem(sourceCode);
590: CoordinateReferenceSystem targetCRS = crsFactory
591: .createCoordinateReferenceSystem(targetCode);
592:
593: CoordinateOperationFactory opFactory = FactoryFinder
594: .getCoordinateOperationFactory(hints);
595: MathTransform mt = opFactory.createOperation(sourceCRS,
596: targetCRS).getMathTransform();
597: System.out.println("Math Transform: " + mt.toWKT());
598: System.out
599: .println("------------------------------------------");
600: }
601:
602: /**
603: *
604: * @since 2.2
605: * @throws Exception
606: */
607: //also want to play with the new operation authority factory (especially the nad shift case)
608: void createOperationFromAuthorityCode() throws Exception {
609: //This is only on head, not in geotools 2.1rc
610: CoordinateOperationAuthorityFactory coaf = FactoryFinder
611: .getCoordinateOperationAuthorityFactory("EPSG", null);
612: CoordinateOperation co = coaf.createCoordinateOperation("");
613: //TODO find an operation code
614: }
615:
616: /**
617: *
618: * @since 2.2
619: * @throws Exception
620: */
621: void createTransformFromAuthorityCode() throws Exception {
622: //This is only on head, not in geotools 2.1rc
623: CoordinateOperationAuthorityFactory coaf = FactoryFinder
624: .getCoordinateOperationAuthorityFactory("EPSG", null);
625: Set coordOperations = coaf
626: .createFromCoordinateReferenceSystemCodes("EPSG:4267",
627: "EPSG:4269");
628: //TODO it seems that no operations are being returned here, figure out why
629: for (Iterator it = coordOperations.iterator(); it.hasNext();) {
630: CoordinateOperation co = (CoordinateOperation) it.next();
631: System.out.println(" " + co.toWKT());
632:
633: }
634: }
635:
636: /**
637: * Print out information about an identified object
638: */
639: // START SNIPPET: identifiedObject
640: void printIdentifierStuff(IdentifiedObject identObj) {
641: System.out.println(" getName().getCode() - "
642: + identObj.getName().getCode());
643: System.out.println(" getName().getAuthority() - "
644: + identObj.getName().getAuthority());
645: System.out.println(" getRemarks() - " + identObj.getRemarks());
646: System.out.println(" getAliases():");
647: //GenericName[]
648: Iterator aliases = identObj.getAlias().iterator();
649: if (!aliases.hasNext()) {
650: System.out.println(" no aliases");
651: } else {
652: for (int i = 0; aliases.hasNext(); i++) {
653: System.out.println(" alias(" + i + "): "
654: + (GenericName) aliases.next());
655: }
656: }
657:
658: System.out.println(" getIdentifiers():");
659: //Identifier[]
660: Iterator idents = identObj.getIdentifiers().iterator();
661: if (!idents.hasNext()) {
662: System.out.println(" no extra identifiers");
663: } else {
664: for (int i = 0; idents.hasNext(); i++) {
665: Identifier ident = (Identifier) idents.next();
666: System.out.println(" identifier(" + i
667: + ").getCode() - " + ident.getCode());
668: System.out.println(" identifier(" + i
669: + ").getAuthority() - " + ident.getAuthority());
670: }
671: }
672: }
673:
674: // END SNIPPET: identifiedObject
675:
676: public static void main(String[] args) {
677: new CTSTutorial();
678: }
679: }
|