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