/* * GeoTools - The Open Source Java GIS Tookit * http://geotools.org * * (C) 2006-2008, Open Source Geospatial Foundation (OSGeo) * * 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! */ // docs start source package org.geotools.tutorial.crs; import java.awt.event.ActionEvent; import java.io.File; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.JToolBar; import org.geotools.data.DataStore; import org.geotools.data.DataStoreFactorySpi; import org.geotools.data.DefaultTransaction; import org.geotools.data.FeatureWriter; import org.geotools.data.FileDataStore; import org.geotools.data.FileDataStoreFinder; import org.geotools.data.Query; import org.geotools.data.Transaction; import org.geotools.data.shapefile.ShapefileDataStoreFactory; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureIterator; import org.geotools.data.simple.SimpleFeatureSource; import org.geotools.data.simple.SimpleFeatureStore; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.geometry.jts.JTS; import org.geotools.map.DefaultMapContext; import org.geotools.map.MapContext; import org.geotools.referencing.CRS; import org.geotools.swing.JMapFrame; import org.geotools.swing.ProgressWindow; import org.geotools.swing.action.SafeAction; import org.geotools.swing.data.JFileDataStoreChooser; import org.jdesktop.swingworker.SwingWorker; import org.opengis.feature.Feature; import org.opengis.feature.FeatureVisitor; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.FeatureType; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.util.ProgressListener; import com.vividsolutions.jts.geom.Geometry; /** * This is a visual example of changing the coordinate reference system of a feature layer. */ public class CRSLab { private File sourceFile; private SimpleFeatureSource featureSource; private MapContext map; public static void main(String[] args) throws Exception { CRSLab lab = new CRSLab(); lab.displayShapefile(); } // docs end main /** * This method: *
* See also the nested ValidateGeometryAction class below which runs this method in a background
* thread and reports on the results
*
* @return the number of invalid geometries found
*/
// docs start validate
private int validateFeatureGeometry(ProgressListener progress) throws Exception {
final SimpleFeatureCollection featureCollection = featureSource.getFeatures();
// Rather than use an iterator, create a FeatureVisitor to check each fature
class ValidationVisitor implements FeatureVisitor {
public int numInvalidGeometries = 0;
public void visit(Feature f) {
SimpleFeature feature = (SimpleFeature) f;
Geometry geom = (Geometry) feature.getDefaultGeometry();
if (geom != null && !geom.isValid()) {
numInvalidGeometries++;
System.out.println("Invalid Geoemtry: " + feature.getID());
}
}
}
ValidationVisitor visitor = new ValidationVisitor();
// Pass visitor and the progress bar to feature collection
featureCollection.accepts(visitor, progress);
return visitor.numInvalidGeometries;
}
// docs end validate
/**
* This class performs the task of exporting the features to a new shapefile using the map
* projection that they are currently displayed in. It also supplies the name and tool tip for
* the toolbar button.
*/
// docs start export action
class ExportShapefileAction extends SafeAction {
ExportShapefileAction() {
super("Export...");
putValue(Action.SHORT_DESCRIPTION, "Export using current crs");
}
public void action(ActionEvent e) throws Throwable {
exportToShapefile();
}
}
// docs end export action
/**
* This class performs the task of checking that the Geometry of each feature is topologically
* valid and reports on the results. It also supplies the name and tool tip.
*/
// docs start validate action
class ValidateGeometryAction extends SafeAction {
ValidateGeometryAction() {
super("Validate geometry");
putValue(Action.SHORT_DESCRIPTION, "Check each geometry");
}
public void action(ActionEvent e) throws Throwable {
int numInvalid = validateFeatureGeometry(null);
String msg;
if (numInvalid == 0) {
msg = "All feature geometries are valid";
} else {
msg = "Invalid geometries: " + numInvalid;
}
JOptionPane.showMessageDialog(null, msg, "Geometry results",
JOptionPane.INFORMATION_MESSAGE);
}
}
// docs end validate action
/**
* This class performs the task of checking that the Geometry of each feature is topologically
* valid and reports on the results. It also supplies the name and tool tip.
*/
// docs start validate action2
class ValidateGeometryAction2 extends SafeAction {
ValidateGeometryAction2() {
super("Validate geometry");
putValue(Action.SHORT_DESCRIPTION, "Check each geometry");
}
public void action(ActionEvent e) throws Throwable {
// Here we use the SwingWorker helper class to run the validation routine in a
// background thread, otherwise the GUI would wait and the progress bar would not be
// displayed properly
SwingWorker worker = new SwingWorker