Hey all,
Trying to use the jmappane to display a world map in the Mercator
projection. I'm getting a boundary error because the data goes all the
way to the poles even though I've set the
context.areaOfInterest
and
jmappane.mapArea
to -170,-80,170,80 so it seems something is wrong. The code is below if
anyone wants to see the error spew, the WKT I'm using and everything
else.
1) Why does the ProjectedCRS not have any scope or valid area set when a
Mercator_1SP is made from WKT? It seems like the library could impose a
maximum extent for any data attempting to be Mercator. In the debugger,
none of these appear to be set.
2) Is Meractor_1SP the name of the PROJCS or of the PROJECTION element
in the WKT?
3) To make a Mercator programatically, I've found
FactoryGroup.createProjectedCRS(...)
and
DefaultProjectedCRS(...)
but are there any other ways to create a Mercator ProjectedCRS? What's
the easiest way to create a Mercator programatically?
4) The above methods require various combination of things, one of which
is:
String => Is this name arbitrary (whatever I want)?
OperationMethod => What's this?
GeographicCRS => this is trivial
MathTransform => this I should be able to get from the EPSG dB
CartesianCS => this I can make
so what are the name and OperationMethod about?
Thanks for any tips or help,
--adrian
/*
* GeoTools - OpenSource mapping toolkit
* http://geotools.org
* (C) 2006, GeoTools Project Managment Committee (PMC)
* (C) 2006, Adrian Custer, assigned to the PMC.
*
* This file is hereby placed into the Public Domain. This means anyone is
* free to do whatever they wish with this file. Use it well and enjoy!
*/
package org.geotools.demo.introduction;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JToolBar;
import javax.swing.WindowConstants;
import org.geotools.TestData;
import org.geotools.data.FeatureSource;
import org.geotools.data.memory.MemoryDataStore;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.demo.mappane.MapViewer;
import org.geotools.feature.AttributeType;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureTypes;
import org.geotools.feature.GeometryAttributeType;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import org.geotools.gui.swing.JMapPane;
import org.geotools.gui.swing.PanAction;
import org.geotools.gui.swing.ResetAction;
import org.geotools.gui.swing.SelectAction;
import org.geotools.gui.swing.ZoomInAction;
import org.geotools.gui.swing.ZoomOutAction;
import org.geotools.map.DefaultMapContext;
import org.geotools.map.MapContext;
import org.geotools.referencing.CRS;
import org.geotools.referencing.FactoryFinder;
import org.geotools.renderer.GTRenderer;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.Graphic;
import org.geotools.styling.Mark;
import org.geotools.styling.SLDParser;
import org.geotools.styling.Style;
import org.geotools.styling.StyleBuilder;
import org.geotools.styling.StyleFactory;
import org.geotools.styling.StyleFactoryFinder;
import org.geotools.styling.Symbolizer;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CRSFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
/**
* The QuickStart class, through its main() method, is a quick introductory
* tutorial to each of the major modules of the Geotools library.
*
* WARNING: This is a work in progress and is incomplete.
*
* WARNING: The code is presented as a long sequential series of steps to
* ensure easy legibility instead of seeking programming elegance. The
* code, apart from main(), will run in the order of the methods in the
* file; it can therefore be read from top to bottom.
*
* This tutorial shows the following elements:
*
* (1) FeatureSource creation:
* This creates, through several approaches, the handles which are
* used later for the manipulation of data.
*
* 1.1 - a feature source from scratch
* 1.2 - a feature source from a shapefile
* 1.3 - a feature source from a WMS/WFS (an image)
*
* (.) Catalog creation:
* This creates a resource through which to handle all the features
* used by a complex application.
*
* (.) Coordinate Transform creation:
* This creates a coordinate operation and uses that to transform the
* data in a feature source to a different Coordinate Referencing
* System.
*
* (.) Query creation:
* This creates a Filter/Expression to query a feature for its
* contents and thereby to subset a feature.
*
* ...
*
* (5) Style creation:
* This creates the graphical elements which are used to display
* the data.
*
* (6) Display:
* This creates a GUI MapViewerto display the data.
*
* (7) Image output:
* This renders an image to an image buffer and then dumps the image
* buffer to a file.
*
* ...
*
*
*
* HISTORY:
* This class regroups work from many different tutorials.
* Section 1.1 - "Feature from scratch" was inspired by earlier tutorials.
* Section 1.2 - "Feature from shapefile" was in Ian's MapViewer class.
*
* Section 5 - The style demo came from an email by Tom Howe on user-list.
* Section 6 - The GUI was inspired by Ian Turton's MapViewer demo.
* Section 7 - MakeImage with email advice from David Adler, Aaron B. Parks.
*
* @author Adrian Custer
* @version 0.01
* @since 2.2RC5
*
*/
public class QuickStart {
/* The handles for the ShapeFile and Styled Layer Descriptor (SLD) files. */
/* This is a little confusing due to the use of 3 possible sources of */
/* data, either from the introduction, the mappane or the testdata jars */
/* Use by uncommenting, for *one single* CASE:, the three lines below */
// TODO: Ensure these can be discovered at runtime
static final int DATA_FROM_MAPVIEWER = 1;
static final int DATA_FROM_SAMPLEDATA = 2;
static final int DATA_FROM_INTRODUCTION = 3;
/* CASE: Data from JMapPane, get via Class.getResource() */
static final int dataSource = DATA_FROM_MAPVIEWER;
static final String shpName = "/data/countries.shp";//in mappane
static final String sldName = "/data/countries.sld";//in mappane
/* CASE: Data from TestData, get using TestData.method() for url, file, ... */
// static final int dataSource = DATA_FROM_TESTDATA;
// static final String shpName = "/org/geotools/test-data/shapes/statepop.shp";
// static final String sldName = "/org/geotools/test-data/shapes/statepop.sld";//WARNING: does not exist
/* CASE: Data from File, get using direct reference */
// static final int dataSource = DATA_FROM_INTRODUCTION;
// static final String shpName = "data/world/countries.shp";
// static final String sldName = "data/world/countries.sld";
static File shpFile;
static URL shpURL;
static File sldFile;
static URL sldURL;
// The name of the website.
static final URL webUrl = null;
// The filename for the output image.
static final String imageFileEnd = "image.png";
// FeatureSource variables
static FeatureSource memFS, shpFS, webFS;
// StyledLayerDescriptor variables
static Style memStyl;
static Style shpStyl;
static Style webStyl;
//GUI frame, pane and extras
static JFrame frame;
static JMapPane jmp;
static JToolBar jtb;
static JLabel text;
//Display elements
static MapContext context;
static GTRenderer renderer;
static com.vividsolutions.jts.geom.Envelope worldbounds;
/*
* Create London from scratch! Well, only a FeatureSource for the city.
*
* Create:
* (1) The Geometry
* (2) The CoordinateReferenceSystem
* (3) The Feature starting with AttributeTypes to make the FeatureType
* (4) The MemoryDataStore to get a FeatureSource
*/
public static void createFeatureSourceFromScratch(){
/*
* Make a Geometry using the JTS library
*
* see the Geometry Tutorial for more detail
*/
// Create a com.vividsolutions.jts.geom.Coordinate for a point
// Wikipedia gives London as: 51° 30.4167′ N 0° 7.65′ W
// Gt 2.2 coordinate order is Long/Lat throughout; in 2.3 the CRS rules
Coordinate ptc = new Coordinate(0.1275d,51.507d);
// Create a com.vividsolutions.jts.geom.GeometryFactory
GeometryFactory geomFac = new GeometryFactory();
// Use the factory to make the jts geometries
Point ptG = geomFac.createPoint(ptc);
/*
* Get a CoordinateReferenceSystem
*
* see the Geopositioning Tutorial for more detail
*/
// Grab a premade CRS
CoordinateReferenceSystem ptCRS =
org.geotools.referencing.crs.DefaultGeographicCRS.WGS84;
/*
* Create the Feature
*
* see the Feature Tutorial for more detail
*
* (1) Create the AttributeTypes
* (2) Create the FeatureType
* (3) Create the Feature
*/
//Create the AttributeTypes, starting with the GeometryAttributeType
Class cls = ptG.getClass();
GeometryAttributeType ptGA =
(GeometryAttributeType) AttributeTypeFactory.newAttributeType(
"the_geom", cls, true, 1, null,ptCRS);
AttributeType cityAT =
AttributeTypeFactory.newAttributeType(
"CITYNAME", String.class, true, 48, null);
AttributeType popAT =
AttributeTypeFactory.newAttributeType(
"CITYPOP", Integer.class, true, 48, null);
// Create the FeatureType
AttributeType[] ptATs = new AttributeType[3];
ptATs[0] = ptGA;
ptATs[1] = cityAT;
ptATs[2] = popAT;
org.geotools.feature.FeatureType ptFT = null;
try{
ptFT = FeatureTypes.newFeatureType(ptATs, "Metropolis");
} catch (SchemaException sex){
System.out.println("SchemaException on FeatureType creation: "+sex);
}
// Create the Feature
Object [] ptElems = { ptG, "London", new Integer(7500000)};
org.geotools.feature.Feature ptF = null;
try {
ptF = ptFT.create(ptElems);
} catch (IllegalAttributeException iaex){
System.out.println("IllegalAttributeException on Feature creation: " + iaex);
}
/*
* Create the DataStore and get its FeatureSource
*
* see the DataStore Tutorial for more details
*/
Feature [] ptFetArray = new Feature [] {ptF};
MemoryDataStore memds = new MemoryDataStore();
memds.addFeatures(ptFetArray);
try {
memFS = memds.getFeatureSource("Metropolis");
} catch (IOException ioex) {
System.out.println("IOException on memoryDataStore creation: "+ ioex);
}
}
/*
* Use a Shapefile!
*
* Create a FeatureSource from a Shapefile format file.
*/
public static void createFeatureSourceFromShapefile(){
/* Switch on the source uncommented in the intial declarations */
switch (dataSource){
case DATA_FROM_MAPVIEWER:
shpURL = JMapPane.class.getResource(shpName);
break;
case DATA_FROM_SAMPLEDATA:
try{
shpURL = TestData.url(shpName);
} catch (FileNotFoundException fnfex){
System.out.println("FileNotFoundException on use of TestData.url()"+fnfex);
}
break;
case DATA_FROM_INTRODUCTION:
shpFile = new File(shpName);
try {
shpURL = shpFile.toURL();
} catch (MalformedURLException muex){
System.out.println("MalformedUrlException for shapefile name: "+ muex);
}
break;
}
try {
ShapefileDataStore ds = new ShapefileDataStore(shpURL);
try {
shpFS = ds.getFeatureSource();
}
catch (IOException ioex){
System.out.println("IOException on shapefile read: "+ioex);
}
} catch (MalformedURLException muex){
System.out.println("MalformedUrlException for shpDataStore: "+ muex);
}
}
// TODO:
/*
* Create a FeatureSource from a web resource.
*/
public static void createFeatureSourceFromWeb(){
}
/*
* Create the styles that will be used for the creation of the MapLayers.
*/
public static void createStyles(){
// Make a simple point style, uses a StyleBuilder
StyleBuilder builder = new StyleBuilder();
Mark mark = builder.createMark("circle", Color.RED);
Graphic g = builder.createGraphic(null,mark,null);
Symbolizer s = builder.createPointSymbolizer(g);
memStyl = builder.createStyle(s);
// Make the sldURL from the sldName
/* Switch on the source uncommented in the intial declarations */
switch (dataSource){
case DATA_FROM_MAPVIEWER:
sldURL = MapViewer.class.getResource(sldName);
break;
case DATA_FROM_SAMPLEDATA:
try{
sldURL = TestData.url(sldName);
} catch (FileNotFoundException fnfex){
System.out.println("FileNotFoundException on use of TestData.url()"+fnfex);
}
break;
case DATA_FROM_INTRODUCTION:
sldFile = new File(sldName);
try {
sldURL = sldFile.toURL();
} catch (MalformedURLException muex){
System.out.println("MalformedUrlException for shapefile name: "+ muex);
}
break;
}
// Create the shapefile Style, uses StyleFactory and an SLD URL.
StyleFactory sf = StyleFactoryFinder.createStyleFactory();
SLDParser stylereader = null;
try {
stylereader = new SLDParser(sf,sldURL);
} catch (IOException ioex){
System.out.println("IOException on SLDfile read: " + ioex);
}
org.geotools.styling.Style[] shpStylArr = stylereader.readXML();
shpStyl = shpStylArr[0];
}
/*
* Create a GUI map displayer.
*
* This is all Swing stuff for the JMapPane.
*
*/
public static void initGUI(){
frame=new JFrame("My Map Viewer");
// frame.setBounds(20,20,500,310);
frame.setBounds(20,20,1080,600);
frame.setBackground(Color.cyan);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Container content = frame.getContentPane();
content.setBackground(Color.magenta);
content.setLayout(new BorderLayout());
// content.setLayout(new GridLayout(1,2 ));
// jmpp = new JMapPane();
jmp = new JMapPane();
jmp.setBackground(Color.white);
// jmp.setSize(20,100);
//jmp.addZoomChangeListener(this);
/* TODO: Fix this TOOLBAR STUFF BELOW: */
content.setLayout(new BorderLayout());
jtb = new JToolBar();
Action zoomIn = new ZoomInAction(jmp);
Action zoomOut = new ZoomOutAction(jmp);
Action pan = new PanAction(jmp);
Action select = new SelectAction(jmp);
Action reset = new ResetAction(jmp);
jtb.add(zoomIn);
jtb.add(zoomOut);
jtb.add(pan);
jtb.addSeparator();
jtb.add(reset);
jtb.addSeparator();
jtb.add(select);
final JButton button= new JButton();
button.setText("CRS");
button.setToolTipText("Change map prjection");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String code = JOptionPane.showInputDialog( button, "Coordinate Reference System:", "EPSG:4326" );
try{
CoordinateReferenceSystem crs = CRS.decode( code );
jmp.getContext().setAreaOfInterest(jmp.getContext().getAreaOfInterest(),crs);
jmp.setReset(true);
jmp.repaint();
}
catch(FactoryException fe){
JOptionPane.showMessageDialog( button, fe.getMessage(), fe.getClass().toString(), JOptionPane.ERROR_MESSAGE );
return;
}
}
});
jtb.add(button);
content.add(jtb,BorderLayout.NORTH);
/* TOOLBAR STUFF ABOVE */
content.add(jmp,BorderLayout.CENTER);
// content.add(jmp);
content.doLayout();
frame.setVisible(true);
}
/*
* Display features onto the screen.
*
* This is a very crude example, showing only how do display a map. The
* core class, JMapPane, also has a toolbar which is not shown here. See
* the demo/gui for more details.
*/
public static void loadGUI()throws Exception{
//Setup the context and renderer within the jmappane
context = new DefaultMapContext(); //WGS84 by default //TODO: make mercator
//Trying to make Mercator
CRSFactory crsFactory = FactoryFinder.getCRSFactory(null);
String wkt = "PROJCS[\"Mercator_1SP\", "
+ "GEOGCS[\"WGS84\", "
+ "DATUM[\"WGS84\", "
+ "SPHEROID[\"WGS84\", 6378137.0, 298.257223563]], "
+ "PRIMEM[\"Greenwich\", 0.0], "
+ "UNIT[\"degree\",0.017453292519943295], "
+ "AXIS[\"Longitude\",EAST], "
+ "AXIS[\"Latitude\",NORTH]], "
+ "PROJECTION[\"Mercator_1SP\"], "
+ "PARAMETER[\"semi_major\", 6378137.0], "
+ "PARAMETER[\"semi_minor\", 6356752.314245179], "
+ "PARAMETER[\"central_meridian\", 0.0], "
+ "PARAMETER[\"scale_factor\", 1.0], "
+ "PARAMETER[\"false_easting\", 0.0], "
+ "PARAMETER[\"false_northing\", 0.0], "
+ "UNIT[\"metre\",1.0], "
+ "AXIS[\"x\",EAST], "
+ "AXIS[\"y\",NORTH]]";
CoordinateReferenceSystem prjCRS=null;
try{
prjCRS = crsFactory.createFromWKT(wkt);
} catch (FactoryException fe){
System.err.println("On prjCRS creation a FactoryException :"+fe.getMessage());
}
Envelope e = new Envelope(-170.0,170.0,-80.0,80.0);
context.setAreaOfInterest(e, prjCRS);
renderer = new StreamingRenderer();
jmp.setRenderer(renderer);
jmp.setContext(context);
//Add the data directly to the context (which makes the MapLayers)
context.addLayer(memFS,memStyl);
context.addLayer(shpFS,shpStyl);
// context.addLayer(webFS,webStyl);
//Set boundary to all that's visible
// jmp.setMapArea(context.getLayerBounds());
jmp.setMapArea(e);
jmp.setHighlightLayer(context.getLayer(0));
// jmp.setSize(200,600);
frame.repaint();
frame.doLayout();
// Thread.sleep(5000);
// jmp.setSize(200,600);
// frame.repaint();
// frame.doLayout();
}
/*
* Make graphical image files, one from scratch and the other from the
* jmappane contents.
* TODO: add to catalog---great for pre/post transform comparisons
* TODO: clean this up, isolate resolution and size
*
*/
public static void makeImages(){
/*
* 1. Create an image from scratch
*/
//Size of the final image, will be too big for the input
int w = 1800;
int h = 800;
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, w, h);
//TODO: HACK HACK HACK need a real pixel to world transform
AffineTransform trsf = new AffineTransform(new double[]{1.0,1.0,1.0,1.0});
// DefaultMathTransformFactory dmtf = new DefaultMathTransformFactory();
// try{
// trsf = dmtf.createAffineTransform(new Matrix2(1,1,1,1));
// } catch (Exception e){
// ;
// }
// transform =
// renderer.worldToScreenTransform(
// g,
// new Rectangle(0, 0, w, h),
// worldbounds);
renderer.paint(g, new Rectangle(0, 0, w, h), trsf);
try{
ImageIO.write(image, "png", new File("workspace/gtdemo-new-"+imageFileEnd));
} catch (IOException ioex) {
System.err.println("IO Exception on image file write: "+ ioex);
}
g.dispose();
/*
* 2. Create an image from the jmappane contents
*/
//spit the image out to a file
int ww = jmp.getWidth()+40;
int hh = jmp.getHeight()+40;
BufferedImage imageOut = new BufferedImage(ww, hh, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = imageOut.createGraphics();
g2.setColor(Color.gray);
g2.fillRect(0, 0, ww, hh);
jmp.paint(g2);
try{
ImageIO.write(imageOut, "png", new File("workspace/gtdemo-jmp-"+imageFileEnd));
} catch (IOException ioex) {
System.err.println("IO Exception on image file write: "+ ioex);
}
g2.dispose();
}
/**
* This is main() the only real function in this QuickStart tutorial.
* The class works sequentially through every step
* @param args
*/
public static void main(String[] args) throws Exception {
System.out.println("QuickStart: Tutorial Start...");
System.out.println("\tStart: Create FeatureSource from scratch.");
createFeatureSourceFromScratch();
System.out.println("\t End: Created FeatureSource from scratch.");
System.out.println("\tStart: Create FeatureSource from shapefile.");
createFeatureSourceFromShapefile();
System.out.println("\t End: Created FeatureSource from shapefile.");
System.out.println("\tStart: Create FeatureSource from web server.");
createFeatureSourceFromWeb();
System.out.println("\t End: Created FeatureSource from web server.");
System.out.println("\tStart: Create the Styled Layer Descriptors.");
createStyles();
System.out.println("\t End: Created the Styled Layer Descriptors.");
System.out.println("\tStart: Initialize the GUI.");
initGUI();
System.out.println("\t End: Initialized the GUI.");
System.out.println("\tStart: Load the map.");
loadGUI();
System.out.println("\t End: Loaded the map.");
// System.out.println("\tStart: Make an image.");
// makeImages();
// System.out.println("\t End: Made the image.");
System.out.println("QuickStart: Tutorial End.");
}
}
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Geotools-gt2-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users