/* * 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! */ package org.geotools.demo; import java.io.File; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import javax.measure.unit.Unit; import org.geotools.data.DataStore; import org.geotools.data.DataStoreFinder; import org.geotools.data.FeatureSource; import org.geotools.factory.GeoTools; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureIterator; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import com.vividsolutions.jts.geom.Geometry; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JOptionPane; import org.geotools.swing.data.JFileDataStoreChooser; import org.opengis.referencing.crs.CoordinateReferenceSystem; /** * The example code for the "FirstProject" in the GeoTools wiki. * <p> * This code matches these examples: * <ul> * <li><a href="http://docs.codehaus.org/display/GEOTDOC/03+First+Project">First Project</a> * <li><a href="http://docs.codehaus.org/display/GEOTDOC/04+How+to+Read+a+Shapefile">How to Read a * Shapefile</a> * </ul> * * The code illustrates how to open a shapefile and collect data about the features contained within * it. * * @author Jody Garnett * * @source $URL$ */ public class FirstProject { /** * Opens a shapefile provided by the user (that should contain line or polygon features), then * iterates over the features within it to calculate the sum of their line or boundary length. * The user can specify the path/name of the shapefile as an argument on the command line; * otherwise a dialog is displayed to prompt for the file. * <p> * <b>Note:</b> If specifying the shapefile at the command line, don't forget the quotes around * your path if there are spaces! * <p> * The code for this method illustrates: * <ul> * <li>connecting to the shapefile using a {@code DataStore} object * <li>accessing features in the shapefile * <li>getting spatial data for each feature * </ul> * * @param args * Optionally, the path and name of the shapefile * * @throws java.lang.Exception * if the shapefile cannot be opened */ public static void main(String[] args) throws Exception { System.out.println("Welcome to GeoTools:" + GeoTools.getVersion()); /* * Get the shapefile, prompting for its path/name if this was not provided on the command * line */ File file = promptShapeFile(args); try { /* * Attmpt to find a GeoTools DataStore that can handle the shapefile */ Map<String, Serializable> connectParameters = new HashMap<String, Serializable>(); connectParameters.put("url", file.toURI().toURL()); connectParameters.put("create spatial index", true); DataStore dataStore = DataStoreFinder.getDataStore(connectParameters); if (dataStore == null) { Logger.getLogger(FirstProject.class.getName()).log(Level.WARNING, "No DataStore found to handle" + file.getPath()); System.exit(1); } /* * We are now connected to the shapefile. Get the type name of the features within it */ String[] typeNames = dataStore.getTypeNames(); String typeName = typeNames[0]; /* * Iterate through the features, collecting some spatial data (line or boundary length) * on each one */ FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = dataStore.getFeatureSource(typeName); FeatureCollection<SimpleFeatureType, SimpleFeature> collection = featureSource.getFeatures(); FeatureIterator<SimpleFeature> iterator = collection.features(); double totalLength = 0.0; try { while (iterator.hasNext()) { SimpleFeature feature = iterator.next(); /* * The spatial portion of the feature is represented by a Geometry object */ Geometry geometry = (Geometry) feature.getDefaultGeometry(); totalLength += geometry.getLength(); } } finally { /* * You MUST explicitly close the feature iterator otherwise terrible things will * happen !!! */ if (iterator != null) { iterator.close(); } } /* * Find out what units the features are measured in so that * we can display the results with this info */ String units = ""; CoordinateReferenceSystem crs = featureSource.getSchema().getCoordinateReferenceSystem(); if (crs != null) { Unit<?> distanceUnit = crs.getCoordinateSystem().getAxis(0).getUnit(); units = distanceUnit.toString(); } JOptionPane.showMessageDialog(null, String.format("Total length is %.4f %s", totalLength, units)); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } System.exit(0); } /** * This method takes the command line argument from the main method which will either be empty * or the name of a shapefile to open (only the first argument is examined). If empty, a dialog * is displayed to prompt the user for the shapefile. * <p> * * @return The shapefile as a new {@code File} object */ private static File promptShapeFile(String[] args) { File file = null; // check if the filename was provided on the command line if (args.length > 0) { file = new File(args[0]); if (file.exists()) { return file; } // file didn't exist - see if the user wants to continue int rtnVal = JOptionPane.showConfirmDialog(null, "Can't find " + file.getName() + ". Choose another ?", "Input shapefile", JOptionPane.YES_NO_OPTION); if (rtnVal != JOptionPane.YES_OPTION) { return null; } } // display a data store file chooser dialog for shapefiles return JFileDataStoreChooser.showOpenFile("shp", null); } }