/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.data.gen.tool;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.geotools.data.DataStore;
import org.geotools.data.FeatureWriter;
import org.geotools.data.FileDataStoreFactorySpi;
import org.geotools.data.Transaction;
import org.geotools.data.gen.info.GeneralizationInfosProviderImpl;
import org.geotools.data.shapefile.ShapefileDataStore;
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.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
/**
*
* Utility class
*
* 1) Validate xml config 2) generalize shape files
*
* @author Chrisitan Mueller
*
*
*
* @source $URL$
*/
public class Toolbox {
/**
* read args and delegate jobs
*
* @param args
*/
static String MissingXMLConfig = "Missing XML config file ";
static String MissingShapeFile = "Missing shape file ";
static String MissingTargetDir = "Missing target directory ";
static String MissingGeneralizations = "Missing generalization distances as comma seperated list ";
public static void main(String[] args) {
Toolbox toolBox = new Toolbox();
boolean retval = false;
try {
retval = toolBox.parse(args);
} catch (IOException e) {
e.printStackTrace();
retval = false;
}
if (retval)
System.exit(0);
else
System.exit(1);
}
public boolean parse(String args[]) throws IOException {
if (args.length == 0) {
System.out.println("Missing cmd validate | generalize");
return false;
}
if ("validate".equalsIgnoreCase(args[0])) {
if (args.length != 2) {
System.out.println(MissingXMLConfig);
return false;
}
validate(args[1]);
System.out.println("Validation of " + args[1] + " successfull");
} else if ("generalize".equalsIgnoreCase(args[0])) {
if (args.length < 2) {
System.out.println(MissingShapeFile);
return false;
}
if (args.length < 3) {
System.out.println(MissingTargetDir);
return false;
}
if (args.length < 4) {
System.out.println(MissingGeneralizations);
return false;
}
if (args.length > 4) {
System.out.println("Too many arguments");
dumpGeneralizeParameters(args);
return false;
}
dumpGeneralizeParameters(args);
generalizeShapeFile(args[1], args[2], args[3]);
} else {
System.out.println("Unknwon cmd: " + args[0]);
return false;
}
return true;
}
protected void validate(String xmlLocation) throws IOException {
GeneralizationInfosProviderImpl prov = new GeneralizationInfosProviderImpl();
prov.getGeneralizationInfos(xmlLocation);
}
protected void generalizeShapeFile(String shapeFileName, String targetDirName,
String generalizations) throws IOException {
File shapeFile = new File(shapeFileName);
if (shapeFile.exists() == false)
throw new IOException("Could not find " + shapeFileName);
DataStore shapeDS = new ShapefileDataStoreFactory().createDataStore(shapeFile.toURI()
.toURL());
File targetDir = new File(targetDirName);
if (targetDir.exists() == false)
throw new IOException("Could not find " + targetDir);
String[] distanceStrings = generalizations.split(",");
Double[] distanceArray = new Double[distanceStrings.length];
for (int i = 0; i < distanceStrings.length; i++)
distanceArray[i] = new Double(distanceStrings[i]);
generalizeShapeFile(shapeFile, shapeDS, targetDir, distanceArray);
shapeDS.dispose();
}
protected void generalizeShapeFile(File shapeFile, DataStore shapeDS, File targetDir,
Double[] distanceArray) throws IOException {
String typeName = shapeDS.getTypeNames()[0];
SimpleFeatureSource fs = shapeDS.getFeatureSource(typeName);
SimpleFeatureType ftype = fs.getSchema();
DataStore[] dataStores = createDataStores(shapeFile, targetDir, ftype, distanceArray);
SimpleFeatureCollection fcoll = fs.getFeatures();
SimpleFeatureIterator it = fcoll.features();
int countTotal = fcoll.size();
List<FeatureWriter<SimpleFeatureType, SimpleFeature>> writers = new ArrayList<FeatureWriter<SimpleFeatureType, SimpleFeature>>();
for (int i = 0; i < dataStores.length; i++) {
writers.add(dataStores[i].getFeatureWriter(typeName, Transaction.AUTO_COMMIT));
}
int counter = 0;
while (it.hasNext()) {
SimpleFeature feature = it.next();
for (int i = 0; i < distanceArray.length; i++) {
FeatureWriter<SimpleFeatureType, SimpleFeature> w = writers.get(i);
SimpleFeature genFeature = w.next();
genFeature.setAttributes(feature.getAttributes());
Geometry newGeom = TopologyPreservingSimplifier.simplify((Geometry) feature
.getDefaultGeometry(), distanceArray[i]);
genFeature.setDefaultGeometry(newGeom);
w.write();
}
counter++;
showProgress(countTotal, counter);
}
fcoll.close(it);
for (FeatureWriter<SimpleFeatureType, SimpleFeature> w : writers)
w.close();
for (DataStore ds : dataStores) {
ds.dispose();
}
}
DataStore[] createDataStores(File shapeFile, File targetDir, SimpleFeatureType ft,
Double[] distanceArray) throws IOException {
FileDataStoreFactorySpi factory = new ShapefileDataStoreFactory();
String shapeFileName = shapeFile.getAbsolutePath();
String newShapeFileRelativeName = null;
int index = shapeFileName.lastIndexOf(File.separator);
if (index == -1)
newShapeFileRelativeName = shapeFileName;
else
newShapeFileRelativeName = shapeFileName.substring(index + 1);
DataStore[] result = new DataStore[distanceArray.length];
for (int i = 0; i < distanceArray.length; i++) {
String newShapeFileDirName = targetDir.getAbsolutePath();
if (newShapeFileDirName.endsWith(File.separator) == false)
newShapeFileDirName += File.separator;
newShapeFileDirName += distanceArray[i] + File.separator;
File dir = new File(newShapeFileDirName);
if (dir.exists() == false)
dir.mkdir();
File file = new File(newShapeFileDirName + newShapeFileRelativeName);
Map<String, Serializable> params = new HashMap<String, Serializable>();
params.put(ShapefileDataStoreFactory.URLP.key, file.toURI().toURL());
result[i] = factory.createNewDataStore(params);
result[i].createSchema(ft);
((ShapefileDataStore) result[i]).forceSchemaCRS(ft.getCoordinateReferenceSystem());
}
return result;
}
private void dumpGeneralizeParameters(String argv[]) {
for (int i = 1; i < argv.length; i++) {
String paramName = null;
switch (i) {
case 1:
paramName = "Shape file";
break;
case 2:
paramName = "Target directory";
break;
case 3:
paramName = "Distances";
break;
default:
paramName = "?????";
}
System.out.printf("%-20s\t%s\n", new Object[] { paramName, argv[i] });
}
}
private int calculatePercentage(int countTotal, int counter) {
return counter * 100 / countTotal;
}
private void showProgress(int countTotal, int counter) {
if (counter == 1)
System.out.print("% |");
int percentage = calculatePercentage(countTotal, counter);
int prevPercentage = counter == 1 ? 0 : calculatePercentage(countTotal, counter - 1);
if (percentage != prevPercentage)
System.out.print("#");
if (counter == countTotal)
System.out.println("|");
}
}