001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2006, Adrian Custer, assigned to the PMC.
006: *
007: * This file is hereby placed into the Public Domain. This means anyone is
008: * free to do whatever they wish with this file. Use it well and enjoy!
009: */
010:
011: package org.example.geotools.base;
012:
013: import java.awt.Color;
014: import java.awt.Graphics2D;
015: import java.awt.Rectangle;
016: import java.awt.geom.AffineTransform;
017: import java.awt.image.BufferedImage;
018: import java.io.File;
019: import java.io.IOException;
020: import java.net.MalformedURLException;
021: import java.net.URI;
022: import java.net.URISyntaxException;
023: import java.net.URL;
024: import java.util.ArrayList;
025: import java.util.HashMap;
026: import java.util.Iterator;
027: import java.util.List;
028: import java.util.Map;
029:
030: import javax.imageio.ImageIO;
031: import javax.units.SI;
032:
033: import org.geotools.catalog.GeoResource;
034: import org.geotools.catalog.Service;
035: import org.geotools.catalog.defaults.DefaultServiceFinder;
036: import org.geotools.data.FeatureSource;
037: import org.geotools.data.postgis.PostgisDataStoreFactory;
038: import org.geotools.data.shapefile.ShapefileDataStoreFactory;
039: import org.geotools.data.wfs.WFSDataStoreFactory;
040: import org.geotools.demo.mappane.MapViewer;
041: import org.geotools.feature.AttributeType;
042: import org.geotools.feature.AttributeTypeFactory;
043: import org.geotools.feature.Feature;
044: import org.geotools.feature.FeatureCollection;
045: import org.geotools.feature.FeatureCollections;
046: import org.geotools.feature.FeatureType;
047: import org.geotools.feature.FeatureTypes;
048: import org.geotools.feature.GeometryAttributeType;
049: import org.geotools.feature.IllegalAttributeException;
050: import org.geotools.feature.SchemaException;
051: import org.geotools.geometry.jts.ReferencedEnvelope;
052: import org.geotools.map.DefaultMapLayer;
053: import org.geotools.map.MapLayer;
054: import org.geotools.referencing.FactoryFinder;
055: import org.geotools.referencing.crs.DefaultGeographicCRS;
056: import org.geotools.referencing.factory.FactoryGroup;
057: import org.geotools.referencing.operation.DefaultMathTransformFactory;
058: import org.geotools.referencing.operation.DefiningConversion;
059: import org.geotools.styling.Graphic;
060: import org.geotools.styling.Mark;
061: import org.geotools.styling.SLDParser;
062: import org.geotools.styling.Style;
063: import org.geotools.styling.StyleBuilder;
064: import org.geotools.styling.StyleFactory;
065: import org.geotools.styling.StyleFactoryFinder;
066: import org.geotools.styling.Symbolizer;
067: import org.opengis.parameter.ParameterValueGroup;
068: import org.opengis.referencing.FactoryException;
069: import org.opengis.referencing.IdentifiedObject;
070: import org.opengis.referencing.NoSuchIdentifierException;
071: import org.opengis.referencing.crs.CoordinateReferenceSystem;
072: import org.opengis.referencing.cs.AxisDirection;
073: import org.opengis.referencing.cs.CSFactory;
074: import org.opengis.referencing.cs.CartesianCS;
075: import org.opengis.referencing.cs.CoordinateSystemAxis;
076: import org.opengis.referencing.operation.Conversion;
077:
078: import com.vividsolutions.jts.geom.Coordinate;
079: import com.vividsolutions.jts.geom.Envelope;
080: import com.vividsolutions.jts.geom.GeometryFactory;
081: import com.vividsolutions.jts.geom.Point;
082:
083: /**
084: * DemoBase is the primary class of the three Demo* classes which combine into a
085: * demonstration application that introduces each of the major modules of the
086: * Geotools library. DemoBase creates an instance of each class and provides the
087: * methods which will control almost all of the action in the demonstration.
088: *
089: * WARNING: This is a work in progress and is incomplete.
090: *
091: *
092: * The Demo* classes are organized into a [data model / view / controller] split
093: * common to modern applications.
094: *
095: * Control starts in the 'main' method of this DemoBase class and immediately
096: * passses to the DemoGUI instance which is created. In the GUI, interactive
097: * control by the user is limited to the 'Quit' button and one other button.
098: * Each button, when pressed, returns the control to the 'button*' methods in
099: * the demoBase instance of this class. These 'button*' methods then call the
100: * remaining methods in the class. Readers can therefore follow the action of
101: * the demonstration application simply by reading in turn each of the methods
102: * below which follow the 'button*' methods.
103: *
104: * The View is managed by demoGUI, an instance of the DemoGUI class, which
105: * creates the window of the
106: * demonstration application. Later on, the instance also creates the JMapPane
107: * in which the map will be rendered. The instance therefore holds on to the
108: * Renderer and the MapContext instances which determine the contents which
109: * will actually be rendered and the details of the rendering such as the
110: * styling and projection information.
111: *
112: * The data model is managed by demoData, an instance of the DemoData class,
113: * which holds all the Feature data (the
114: * geospatial data maintained by the application). The instance holds several
115: * List objects which show how an application can manage data itself. The
116: * instance also holds a Catalog object which shows how to use that system of
117: * the Geotools Library to manage contents.
118: *
119: *
120: *
121: * This tutorial shows the following elements:
122: *
123: * (1) FeatureSource creation:
124: * This creates, through several approaches, the handles which are
125: * used later for the manipulation of data.
126: *
127: * 1.1 - a feature source from scratch
128: * 1.2 - a feature source from a shapefile
129: * 1.3 - a feature source from a WMS/WFS (an image)
130: *
131: * (.) Catalog creation:
132: * This creates a resource through which to handle all the features
133: * used by a complex application.
134: *
135: * (.) Coordinate Transform creation:
136: * This creates a coordinate operation and uses that to transform the
137: * data in a feature source to a different Coordinate Referencing
138: * System.
139: *
140: * (.) Query creation:
141: * This creates a Filter/Expression to query a feature for its
142: * contents and thereby to subset a feature.
143: *
144: * ...
145: *
146: * (5) Style creation:
147: * This creates the graphical elements which are used to display
148: * the data.
149: *
150: * (6) Display:
151: * This creates a GUI MapViewerto display the data.
152: *
153: * (7) Image output:
154: * This renders an image to an image buffer and then dumps the image
155: * buffer to a file.
156: *
157: * ...
158: *
159: *
160: *
161: * HISTORY:
162: * This class regroups work from many different tutorials.
163: * Section 1.1 - "Feature from scratch" was inspired by earlier tutorials.
164: * Section 1.2 - "Feature from shapefile" was in Ian's MapViewer class.
165: *
166: * Section 5 - The style demo came from an email by Tom Howe on user-list.
167: * Section 6 - The GUI was inspired by Ian Turton's MapViewer demo.
168: * Section 7 - MakeImage with email advice from David Adler, Aaron B. Parks.
169: *
170: * @author Adrian Custer, gnuGIS
171: * @author Justin Deoliveira, The Open Planning Project
172: *
173: * @version 0.03
174: * @since 2.3-M0
175: *
176: */
177: public class DemoBase {
178:
179: //TODO: Add the logger
180: // private Logger textlog =
181: // org.geotools.util.logging.Logging.getLogger("org.geotools.demo.introduction.DemoBase");
182:
183: /* The name of the test shapefile. */
184: final String SHAPEFILENAME = "/countries.shp";
185: /* The name of the test sld for the test shapefile. */
186: final String SHAPEFILESLDNAME = "/countries.sld";
187: /*The name of the URL for the test Web Feasture Service. */
188: final String WFSSERVERURL = "http://www.refractions.net:8080/geoserver/wfs?REQUEST=GetCapabilities&";
189: /* The connection information for the test PostGIS database server. */
190: final String POSTGISSERVERURL = "www.refractions.net";
191: final String POSTGISUSERNAME = "postgres";
192: final String POSTGISDATABASE = "geotools";
193:
194: /* The filename for the output image */
195: final String imageFileEnd = "image.png";
196:
197: /* Cartographic variables */
198: final Envelope envlp_NoEdges = new Envelope(-179.0, 179.0, -80.0,
199: 80.0);
200: final ReferencedEnvelope envlp_NoEdges2 = new ReferencedEnvelope(
201: -179.0, 179.0, -80.0, 80.0, DefaultGeographicCRS.WGS84);
202: // TODO: move to demoGUI
203: CoordinateReferenceSystem projCRS = null;
204:
205: /* DemoGUI class */
206: DemoGUI demoGUI;
207:
208: /* demo class */
209: DemoData demoData;
210:
211: /* The constructor */
212: public DemoBase() {
213:
214: demoData = new DemoData();
215:
216: }
217:
218: /* These callback methods are called by DemoGUI when the respective buttons
219: * are pressed. Each one calls other methods below. */
220:
221: public void buttonCreateFeatures() {
222:
223: demoGUI.textArea.append("Start: Create Features.\n");
224:
225: /* Create a Point Feature representing London as a FeatureCollection.*/
226: Feature london = createLondonPointFeatureFromScratch();
227: FeatureCollection londonCollection = makeLondonFeatureCollection(london);
228: loadLondonFeatureCollectionIntoList(londonCollection);
229: demoGUI.textArea
230: .append(" Done: Created London from scratch.\n");
231:
232: /* Load a shapefile with the given name into the local catalog. */
233: loadShapefileIntoCatalog(SHAPEFILENAME);
234: demoGUI.textArea
235: .append(" Done: Loaded the Shapefile into the catalog.\n");
236:
237: /* Load a reference to a web source of features into the local catalog.*/
238: // loadWebFeatureServiceIntoCatalog(WFSSERVERURL);
239: // demoGUI.textArea.append(" Done: Loaded a Web Feature Service into the catalog.\n");
240: /* Load a reference to a database source of features into the local catalog.*/
241: // loadDatabaseIntoCatalog(POSTGISSERVERURL);
242: // demoGUI.textArea.append(" Done: Loaded a database into the catalog.\n");
243: /* TODO: Load a reference to an external catalog. */
244:
245: demoGUI.textArea.append(" End: Created Features.\n");
246: }
247:
248: public void buttonCreateStyles() {
249: demoGUI.textArea.append("Start: Create the styles.\n");
250:
251: Style lonstyl = createLondonStyleFromScratch();
252: demoData.theStyleMap.put("londstyl", lonstyl);
253: demoGUI.textArea
254: .append(" Done: Created and loaded the London point Style.\n");
255:
256: Style shpstyl = createShapefileStyleFromSLDFile(SHAPEFILESLDNAME);
257: demoData.theStyleMap.put("shpstyl", shpstyl);
258: demoGUI.textArea
259: .append(" Done: Created and loaded the Shape Style.\n");
260:
261: demoGUI.textArea.append(" End: Created the styles.\n");
262: }
263:
264: public void buttonCreateMap() {
265: demoGUI.textArea.append("Start: Create a map.\n");
266:
267: demoGUI.initialize_JMapPane();
268: demoGUI.textArea.append(" Done: Initialized the MapPane.\n");
269:
270: /* Add the London featureCollection as one layer in the map. */
271: FeatureCollection lfc = (FeatureCollection) demoData.theFeatureCollectionList
272: .get(0);
273: Style lsty = (Style) demoData.theStyleMap.get("londstyl");
274: MapLayer m0 = new DefaultMapLayer(lfc, lsty);
275: demoGUI.context.addLayer(m0);
276:
277: /* Add the Shapefile FeatureSource below the first layer. */
278: FeatureSource shpFS = getAShapefileFeatureSourceFromCatalog();
279: Style shpsty = (Style) demoData.theStyleMap.get("shpstyl");
280: MapLayer m1 = new DefaultMapLayer(shpFS, shpsty);
281: demoGUI.context.addLayer(0, m1);
282:
283: // demoGUI.context.addLayer(webFS,webStyl);
284: // demoGUI.context.addLayer(dbFS,dbStyl);
285:
286: /* Configure JMapPane */
287: demoGUI.jmp.setHighlightLayer(demoGUI.context.getLayer(0));
288: // jmp.setSize(200,600);
289: //TODO: Set boundary to all that's visible, disabled for projection
290: // jmp.setMapArea(context.getLayerBounds());
291: demoGUI.jmp.setMapArea(envlp_NoEdges);
292:
293: /* Paint */
294: demoGUI.frame.repaint();
295: demoGUI.frame.doLayout();
296:
297: demoGUI.textArea.append(" Done: Loaded the map.\n");
298: // load_JMapPane();
299:
300: demoGUI.textArea.append(" End: Created a map.\n");
301:
302: // create_the_map();
303: }
304:
305: public void buttonProjectMap() {
306: create_ProjectedCRS_from_DefaultGeogCRS();
307: display_projected_as_Mercator();
308:
309: }
310:
311: public void buttonCaptureImage() {
312: capture_as_image();
313:
314: }
315:
316: public void xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx() {
317:
318: }
319:
320: public Feature createLondonPointFeatureFromScratch() {
321:
322: // Wikipedia gives London as: 51?? 30.4167??? N 0?? 7.65??? W
323: // NOTE: in Gt 2.2 axis order is Long/Lat throughout; in 2.3 the CRS rules
324: Coordinate ptc = new Coordinate(0.1275d, 51.507d);
325: GeometryFactory geomFac = new GeometryFactory();
326: Point ptG = geomFac.createPoint(ptc);
327:
328: /* Name Attribute */
329: String name = "London";
330:
331: /* Population Attribute */
332: Integer pop = new Integer(7500000);
333:
334: /* AttributeTypes, starting with Geometry using pre-made CRS */
335: GeometryAttributeType ptGA = (GeometryAttributeType) AttributeTypeFactory
336: .newAttributeType(
337: "the_geom",
338: ptG.getClass(),
339: true,
340: 1,
341: null,
342: org.geotools.referencing.crs.DefaultGeographicCRS.WGS84);
343: AttributeType cityAT = AttributeTypeFactory.newAttributeType(
344: "CITYNAME", String.class, true, 48, null);
345: AttributeType popAT = AttributeTypeFactory.newAttributeType(
346: "CITYPOP", Integer.class, true, 48, null);
347:
348: /* FeatureType */
349: AttributeType[] ptATs = new AttributeType[3];
350: ptATs[0] = ptGA;
351: ptATs[1] = cityAT;
352: ptATs[2] = popAT;
353:
354: FeatureType ptFT = null;
355: try {
356: ptFT = FeatureTypes.newFeatureType(ptATs, "Metropolis");
357: } catch (SchemaException schex) {
358: String msg = "SchemaException on FeatureType creation: "
359: + schex;
360: new IOException(msg).initCause(schex);
361: }
362:
363: /* Feature */
364: Object[] ptElems = { ptG, name, pop };
365:
366: Feature ptF = null;
367: try {
368: ptF = ptFT.create(ptElems);
369: } catch (IllegalAttributeException iaex) {
370: System.err
371: .println("IllegalAttributeException on Feature creation: "
372: + iaex);
373: // String msg = "IllegalAttributeException on Feature creation: " + iaex;
374: // throw (IOException) new IOException( msg ).initCause( iaex );
375: }
376:
377: return ptF;
378: }
379:
380: public FeatureCollection makeLondonFeatureCollection(Feature f) {
381:
382: FeatureCollection fc = FeatureCollections.newCollection();
383: fc.add(f);
384: return fc;
385: }
386:
387: public void loadLondonFeatureCollectionIntoList(FeatureCollection fc) {
388: demoData.theFeatureCollectionList.add(fc);
389: }
390:
391: /**
392: * Loads a shapefile service into the catalog.
393: *
394: * @throws IOException Any I/O errors loading into the catalog.
395: */
396: public void loadShapefileIntoCatalog(String shpname) {
397:
398: //create shapefile datastore parameters
399: URL shapefileURL = getClass().getResource(shpname);
400: Map params = new HashMap();
401: params.put(ShapefileDataStoreFactory.URLP.key, shapefileURL);
402:
403: //load the services, there should be only one service
404: DefaultServiceFinder finder = new DefaultServiceFinder(
405: demoData.localCatalog);
406: List services = finder.aquire(params);
407:
408: //add the service to the catalog
409: demoData.localCatalog.add((Service) services.get(0));
410: }
411:
412: /**
413: * Loads a Web Feature Service into the catalog.
414: *
415: * @param wfsurl a string URL for the Web Feature Service location.
416: */
417: public void loadWebFeatureServiceIntoCatalog(String wfsurl) {
418:
419: //create wfs datastore parameters
420: URL wfsURL = null;
421: try {
422: wfsURL = new URL(wfsurl);
423: } catch (MalformedURLException murlex) {
424: System.err
425: .println("MalformedURLException on creation of the WFS url: "
426: + murlex.getMessage());
427: }
428: Map params = new HashMap();
429: params.put(WFSDataStoreFactory.URL.key, wfsURL);
430:
431: //load the service, there should be only one
432: DefaultServiceFinder finder = new DefaultServiceFinder(
433: demoData.localCatalog);
434: List services = finder.aquire(params);
435: System.out.println("size is: " + services.size());
436:
437: //add the service to the catalog
438: Service s = (Service) services.get(0);
439: demoData.localCatalog.add(s);
440: }
441:
442: /**
443: * Loads a postgis database into the catalog.
444: *
445: * @throws IOException Any I/O errors loading into the catalog.
446: */
447: public void loadDatabaseIntoCatalog(String dburl) {
448:
449: //set up connection parameters
450: URL pgURL = null;
451: try {
452: pgURL = new URL(POSTGISSERVERURL);
453: } catch (MalformedURLException murlex) {
454: System.err
455: .println("MalformedURLException on creating the PostGIS URL: "
456: + murlex);
457: }
458: Map params = new HashMap();
459: params.put(PostgisDataStoreFactory.HOST.key, pgURL);
460: params.put(PostgisDataStoreFactory.USER.key, POSTGISUSERNAME);
461: params.put(PostgisDataStoreFactory.DATABASE.key,
462: POSTGISDATABASE);
463:
464: //load the service, there should be only one
465: DefaultServiceFinder finder = new DefaultServiceFinder(
466: demoData.localCatalog);
467: List services = finder.aquire(params);
468:
469: //add the service to the catalog
470: demoData.localCatalog.add((Service) services.get(0));
471:
472: }
473:
474: /**
475: * Creates a Style for the London point feature.
476: *
477: * @return a Style appropriate for the point feature.
478: */
479: public Style createLondonStyleFromScratch() {
480:
481: /* Point style from scratch */
482: StyleBuilder builder = new StyleBuilder();
483: Mark mark = builder.createMark("circle", Color.RED);
484: Graphic g = builder.createGraphic(null, mark, null);
485: Symbolizer s = builder.createPointSymbolizer(g);
486:
487: Style memStyle = builder.createStyle(s);
488: return memStyle;
489:
490: }
491:
492: // TODO: This should be done through the catalog *not* directly from the file.
493: public Style createShapefileStyleFromSLDFile(String shpSLDfile) {
494:
495: // Make the sldURL from the sldName
496: URL sldURL = MapViewer.class.getResource(shpSLDfile);
497:
498: // Create the shapefile Style, uses StyleFactory and an SLD URL
499: StyleFactory sf = StyleFactoryFinder.createStyleFactory();
500: SLDParser stylereader = null;
501: try {
502: stylereader = new SLDParser(sf, sldURL);
503: } catch (IOException ioex) {
504: System.out.println("IOException on SLDfile read: " + ioex);
505: }
506: Style[] shpStylArr = stylereader.readXML();
507: Style shpStyle = shpStylArr[0];
508:
509: return shpStyle;
510:
511: }
512:
513: /**
514: * Gets a FeatureCollection with the shapefile from the catalog.
515: * <p>
516: * This method <b>must</b> be called after {@link #loadShapefileIntoCatalog(String)}.
517: * </p>
518: * @return The shapefile feature source.
519: *
520: * @throws IOException Any I/O errors that occur accessing the shapefile resource.
521: */
522: public FeatureSource getAShapefileFeatureSourceFromCatalog() {
523: // public FeatureCollection getFeatureCollectionForShapefile() throws IOException {
524:
525: //create the uri to lookup
526: URI uri = null;
527: try {
528: uri = new URI(getClass().getResource(SHAPEFILENAME)
529: .toString());
530: } catch (URISyntaxException uriex) {
531: System.err.println("Unable to create shapefile uri"
532: + uriex.getMessage());
533: // throw (IOException) new IOException( "Unable to create shapefile uri").initCause( uriex );
534: }
535:
536: //lookup service, should be only one
537: List serviceList = demoData.localCatalog.find(uri, null);
538: Service service = (Service) serviceList.get(0);
539:
540: //shapefiles only contain a single resource
541: List resourceList = null;
542: try {
543: resourceList = service.members(null);
544: } catch (IOException ioex) {
545: System.err
546: .println("An IOException occurred on service resolve: "
547: + ioex.getMessage());
548: }
549: GeoResource resource = (GeoResource) resourceList.get(0);
550:
551: FeatureSource shpFS = null;
552: try {
553: shpFS = (FeatureSource) resource.resolve(
554: FeatureSource.class, null);
555: } catch (IOException ioex) {
556: System.err
557: .println("IOException on resoloving shape resource to FeatureSource: "
558: + ioex.getMessage());
559: }
560: return shpFS;
561: }
562:
563: public void xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx() {
564:
565: }
566:
567: //
568: // /**
569: // * Gets a FeatureCollection with the shapefile from the catalog.
570: // * <p>
571: // * This method <b>must</b> be called after {@link #loadShapefileIntoCatalog()}.
572: // * </p>
573: // * @return The shapefile feature source.
574: // *
575: // * @throws IOException Any I/O errors that occur accessing the shapefile resource.
576: // */
577: // public FeatureCollection getFeatureCollectionForShapefile(){
578: //// public FeatureCollection getFeatureCollectionForShapefile() throws IOException {
579: //
580: // //create the uri to lookup
581: // URI uri = null;
582: // try {
583: // uri = new URI( getClass().getResource( SHAPEFILENAME ).toString() );
584: // }
585: // catch ( URISyntaxException uriex ) {
586: // System.err.println( "Unable to create shapefile uri"+ uriex.getMessage() );
587: //// throw (IOException) new IOException( "Unable to create shapefile uri").initCause( uriex );
588: // }
589: //
590: // //lookup service, should be only one
591: // List serviceList = demoData.localCatalog.find( uri, null );
592: // Service service = (Service) serviceList.get( 0 );
593: //
594: // //shapefiles only contain a single resource
595: // List resourceList = null;
596: // try{
597: // resourceList = service.members( null );
598: // } catch (IOException ioex){
599: // System.err.println("An IOException occurred on service resolve: " + ioex.getMessage() );
600: // }
601: // GeoResource resource = (GeoResource) resourceList.get( 0 );
602: //
603: //// return (FeatureSource) resource.resolve( FeatureSource.class, null );
604: // FeatureCollection shpFC = null;
605: // try {
606: // shpFC = (FeatureCollection) resource.resolve( FeatureCollection.class, null );
607: // } catch (IOException ioex){
608: // System.err.println("An IOException occurred on resolving the resource: " + ioex.getMessage() );
609: // }
610: // return shpFC;
611: // }
612:
613: /**
614: * Loads all the wfs feature sources from the wfs service.
615: * <p>
616: * This method <b>must</b> be called
617: * </p>
618: * @return a java List of FeatureSources.
619: * @throws IOException
620: */
621: public List getListOfFeatureSourcesForWebFeatureService()
622: throws IOException {
623:
624: //create the uri to lookup
625: URI uri = null;
626: try {
627: uri = new URI(WFSSERVERURL);
628: } catch (URISyntaxException e) {
629: throw (IOException) new IOException(
630: "Unable to create wfs uri").initCause(e);
631: }
632:
633: //lookup service, should only be one
634: List services = demoData.localCatalog.find(uri, null);
635: Service service = (Service) services.get(0);
636:
637: //wfs contains many resources
638: List resources = service.members(null);
639: List featureSources = new ArrayList();
640:
641: for (Iterator r = resources.iterator(); r.hasNext();) {
642: GeoResource resource = (GeoResource) r.next();
643: if (resource.canResolve(FeatureSource.class)) {
644: FeatureSource featureSource = (FeatureSource) resource
645: .resolve(FeatureSource.class, null);
646: featureSources.add(featureSource);
647: }
648: }
649:
650: // Iterator r = featureSources.iterator();
651: // ((FeatureSource) r.next()).
652: return featureSources;
653: }
654:
655: /*
656: * Create a Mercator ProjectedCRS from DefaultGeogCRS.
657: */
658: public void create_ProjectedCRS_from_DefaultGeogCRS() {
659:
660: demoGUI.textArea
661: .append("Start: Create ProjectedCRS from DefaultGeographicCRS.\n");
662:
663: /* Properties of the Projected CRS */
664: Map props = new HashMap();
665: props.put(IdentifiedObject.NAME_KEY, "My arbitrary name"); // Mandatory
666: // props.put(ReferenceSystem.VALID_AREA_KEY,e); // Optional
667:
668: /* Geographic CoordinateReferenceSystem */
669: //TODO: this is hard coded below because the compiler doesn't work.
670: CoordinateReferenceSystem geogCRS = org.geotools.referencing.crs.DefaultGeographicCRS.WGS84;
671:
672: /* Defining Conversion: Name, Parameters */
673: final String dcName = "A Mercator";
674: /* Parameters for the Mercator */
675: DefaultMathTransformFactory mtf = new DefaultMathTransformFactory();
676: ParameterValueGroup pvg = null;
677: try {
678: pvg = mtf.getDefaultParameters("Mercator_1SP");
679: } catch (NoSuchIdentifierException nsiex) {
680: System.err.println("On DefaultPrameterGroup creation: "
681: + nsiex.getMessage());
682: }
683: //Start Test Output
684: // ParameterDescriptorGroup dg = pvg.getDescriptor()
685: // for (GeneralParameterDescriptor descriptor : dg.descriptors()) {
686: // System.out.println(descriptor.getName().getCode());
687: // }
688: //End Test Output
689: DefiningConversion dc = new DefiningConversion(dcName, pvg);
690: //TODO: Added to make the compiler happy, could merge with above.
691: Conversion c = (Conversion) dc;
692:
693: /* Coordinate System */
694: Map map = new HashMap();
695: CSFactory csFactory = FactoryFinder.getCSFactory(null);
696: CoordinateSystemAxis xAxis = null;
697: CoordinateSystemAxis yAxis = null;
698: CartesianCS worldCS = null;
699: try {
700: map.clear();
701: map.put("name", "Cartesian X axis");
702: xAxis = csFactory.createCoordinateSystemAxis(map, "X",
703: AxisDirection.EAST, SI.METER);
704: map.clear();
705: map.put("name", "Cartesian Y axis");
706: yAxis = csFactory.createCoordinateSystemAxis(map, "Y",
707: AxisDirection.NORTH, SI.METER);
708: map.clear();
709: map.put("name", "Cartesian CS");
710: worldCS = csFactory.createCartesianCS(map, xAxis, yAxis);
711: } catch (FactoryException fex) {
712: System.err.println("On cartesianCS creation: "
713: + fex.getMessage());
714: }
715:
716: /* Projected CRS */
717: FactoryGroup fg = new FactoryGroup(null);
718: try {
719: projCRS = fg
720: .createProjectedCRS(
721: props,
722: org.geotools.referencing.crs.DefaultGeographicCRS.WGS84,
723: c, worldCS);
724: // //TODO: figure out why this breaks but above works.
725: // projCRS = fg.createProjectedCRS(props,
726: // geogCRS,
727: // dc,
728: // worldCS);
729: } catch (FactoryException fex) {
730: System.err.println("On projectedCRS creation: "
731: + fex.getMessage());
732: }
733: // System.out.println(projCRS.toWKT())
734:
735: demoGUI.textArea
736: .append(" End: Created ProjectedCRS from DefaultGeographicCRS.\n");
737: }
738:
739: // /*
740: // * Create a Mercator ProjectedCRS from Well-Known Text.
741: // */
742: // public void projectedCRSfromWKT(){
743: //
744: // demoGUI.textArea.append("");
745: // CRSFactory crsFactory = FactoryFinder.getCRSFactory(null);
746: // String wkt = "PROJCS[\"Mercator Attempt\", "
747: // + "GEOGCS[\"WGS84\", "
748: // + "DATUM[\"WGS84\", "
749: // + "SPHEROID[\"WGS84\", 6378137.0, 298.257223563]], "
750: // + "PRIMEM[\"Greenwich\", 0.0], "
751: // + "UNIT[\"degree\",0.017453292519943295], "
752: // + "AXIS[\"Longitude\",EAST], "
753: // + "AXIS[\"Latitude\",NORTH]], "
754: // + "PROJECTION[\"Mercator_1SP\"], "
755: // + "PARAMETER[\"semi_major\", 6378137.0], "
756: // + "PARAMETER[\"semi_minor\", 6356752.314245179], "
757: // + "PARAMETER[\"central_meridian\", 0.0], "
758: // + "PARAMETER[\"scale_factor\", 1.0], "
759: // + "PARAMETER[\"false_easting\", 0.0], "
760: // + "PARAMETER[\"false_northing\", 0.0], "
761: // + "UNIT[\"metre\",1.0], "
762: // + "AXIS[\"x\",EAST], "
763: // + "AXIS[\"y\",NORTH]]";
764: // CoordinateReferenceSystem prjCRS=null;
765: // try{
766: // prjCRS = crsFactory.createFromWKT(wkt);
767: // } catch (FactoryException fe){
768: // System.err.println("On prjCRS creation a FactoryException :"+fe.getMessage());
769: // }
770: // Envelope e = new Envelope(-170.0,170.0,-80.0,80.0);
771: // context.setAreaOfInterest(e, prjCRS);
772: //
773: // demoGUI.textArea.append("");
774: // }
775:
776: /*
777: * A Mercator Projected Map.
778: *
779: * Reproject features on the screen.
780: *
781: *
782: */
783: public void display_projected_as_Mercator() {
784: try {
785: demoGUI.textArea.append("Start: Project the map.\n");
786:
787: ReferencedEnvelope llEnvelope = new ReferencedEnvelope(
788: envlp_NoEdges, DefaultGeographicCRS.WGS84);
789: ReferencedEnvelope projEnvelope = llEnvelope.transform(
790: projCRS, true);
791: demoGUI.context.setAreaOfInterest(projEnvelope);
792:
793: demoGUI.jmp.setContext(demoGUI.context);
794:
795: demoGUI.jmp.setMapArea(projEnvelope);
796:
797: demoGUI.frame.repaint();
798: demoGUI.frame.doLayout();
799:
800: demoGUI.jmp.setMapArea(demoGUI.jmp.getContext()
801: .getAreaOfInterest());
802: demoGUI.jmp.setReset(true);
803: demoGUI.jmp.repaint();
804:
805: demoGUI.textArea.append(" End: Projected the map.\n");
806: } catch (Exception te) {
807: demoGUI.textArea.append("Error occurred during projection");
808: }
809: }
810:
811: /*
812: * Make graphical image files, one from scratch and the other from the
813: * jmappane contents.
814: * TODO: add to catalog---great for pre/post transform comparisons
815: * TODO: clean this up, isolate resolution and size
816: *
817: */
818: public void capture_as_image() {
819:
820: demoGUI.textArea.append("Start: Capture an image.\n");
821: /*
822: * 1. Create an image from scratch
823: */
824: //Size of the final image, will be too big for the input
825: int w = 1800;
826: int h = 800;
827: BufferedImage image = new BufferedImage(w, h,
828: BufferedImage.TYPE_INT_RGB);
829: Graphics2D g = image.createGraphics();
830: g.setColor(Color.white);
831: g.fillRect(0, 0, w, h);
832:
833: //TODO: HACK HACK HACK need a real pixel to world transform
834: AffineTransform trsf = new AffineTransform(new double[] { 1.0,
835: 1.0, 1.0, 1.0 });
836:
837: // DefaultMathTransformFactory dmtf = new DefaultMathTransformFactory();
838: // try{
839: // trsf = dmtf.createAffineTransform(new Matrix2(1,1,1,1));
840: // } catch (Exception e){
841: // ;
842: // }
843: // transform =
844: // renderer.worldToScreenTransform(
845: // g,
846: // new Rectangle(0, 0, w, h),
847: // worldbounds);
848:
849: demoGUI.renderer.paint(g, new Rectangle(0, 0, w, h), trsf);
850: try {
851: ImageIO.write(image, "png", new File(
852: "workspace/gtdemo-new-" + imageFileEnd));
853: } catch (IOException ioex) {
854: System.err.println("IO Exception on image file write: "
855: + ioex);
856: }
857: g.dispose();
858:
859: /*
860: * 2. Create an image from the jmappane contents
861: */
862: //spit the image out to a file
863: int ww = demoGUI.jmp.getWidth() + 40;
864: int hh = demoGUI.jmp.getHeight() + 40;
865: BufferedImage imageOut = new BufferedImage(ww, hh,
866: BufferedImage.TYPE_INT_RGB);
867: Graphics2D g2 = imageOut.createGraphics();
868: g2.setColor(Color.gray);
869: g2.fillRect(0, 0, ww, hh);
870: demoGUI.jmp.paint(g2);
871: try {
872: ImageIO.write(imageOut, "png", new File(
873: "workspace/gtdemo-jmp-" + imageFileEnd));
874: } catch (IOException ioex) {
875: System.err.println("IO Exception on image file write: "
876: + ioex);
877: }
878: g2.dispose();
879:
880: demoGUI.textArea.append(" End: Captured an image.\n");
881: }
882:
883: /**
884: * @param args
885: */
886: public static void main(String[] args) {
887:
888: System.out.println("DemoApp Tutorial: Start...");
889:
890: DemoBase db = new DemoBase();
891: // db.demoData = new DemoData();
892: /* The 'this' reference is so the callbacks below can be called. */
893: db.demoGUI = new DemoGUI(db);
894:
895: System.out.println("DemoApp Tutorial: End of non-GUI thread.");
896:
897: }
898:
899: }
|