package mil.nga.giat.geowave.analytic;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
public class ShapefileTool
{
private static final Logger LOGGER = LoggerFactory.getLogger(ShapefileTool.class);
private static SimpleFeatureType createFeatureType(
final String typeName,
final boolean isPoint ) {
final SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName(typeName);
builder.setCRS(DefaultGeographicCRS.WGS84); // <- Coordinate reference
// system
// add attributes in order
builder.add(
"the_geom",
isPoint ? Point.class : Polygon.class);
builder.length(
15).add(
"Name",
String.class); // <- 15 chars width for name field
// build the type
return builder.buildFeatureType();
}
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification = "Directories may alreadybe there")
public static void writeShape(
final String typeName,
final File dir,
final Geometry[] shapes )
throws IOException {
FileUtils.deleteDirectory(dir);
dir.mkdirs();
final SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(
createFeatureType(
typeName,
shapes[0] instanceof Point));
final ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
final Map<String, Serializable> params = new HashMap<String, Serializable>();
params.put(
"url",
new File(
dir.getAbsolutePath() + "/" + typeName + ".shp").toURI().toURL());
params.put(
"create spatial index",
Boolean.TRUE);
final ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
newDataStore.createSchema(createFeatureType(
typeName,
shapes[0] instanceof Point));
final Transaction transaction = new DefaultTransaction(
"create");
try (final FeatureWriter<SimpleFeatureType, SimpleFeature> writer = newDataStore.getFeatureWriterAppend(
typeName,
transaction)) {
final int i = 1;
for (final Geometry shape : shapes) {
featureBuilder.add(shape);
featureBuilder.add(Integer.valueOf(i));
final SimpleFeature feature = featureBuilder.buildFeature(null);
final SimpleFeature copy = writer.next();
for (final AttributeDescriptor attrD : feature.getFeatureType().getAttributeDescriptors()) {
// the null case should only happen for geometry
if (copy.getFeatureType().getDescriptor(
attrD.getName()) != null) {
copy.setAttribute(
attrD.getName(),
feature.getAttribute(attrD.getName()));
}
}
// shape files force geometry name to be 'the_geom'. So isolate
// this change
copy.setDefaultGeometry(feature.getDefaultGeometry());
writer.write();
}
}
catch (final IOException e) {
LOGGER.warn(
"Problem with the FeatureWritter",
e);
transaction.rollback();
}
finally {
transaction.commit();
transaction.close();
}
}
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification = "Directories may alreadybe there")
public static void writeShape(
final File dir,
final List<SimpleFeature> shapes )
throws IOException {
FileUtils.deleteDirectory(dir);
dir.mkdirs();
final ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
final String typeName = shapes.get(
0).getType().getTypeName();
final Map<String, Serializable> params = new HashMap<String, Serializable>();
params.put(
"url",
new File(
dir.getAbsolutePath() + "/" + typeName + ".shp").toURI().toURL());
params.put(
"create spatial index",
Boolean.TRUE);
final ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
newDataStore.createSchema(shapes.get(
0).getFeatureType());
final Transaction transaction = new DefaultTransaction(
"create");
try (final FeatureWriter<SimpleFeatureType, SimpleFeature> writer = newDataStore.getFeatureWriterAppend(
typeName,
transaction)) {
for (final SimpleFeature shape : shapes) {
final SimpleFeature copy = writer.next();
for (final AttributeDescriptor attrD : copy.getFeatureType().getAttributeDescriptors()) {
// the null case should only happen for geometry
if (copy.getFeatureType().getDescriptor(
attrD.getName()) != null) {
copy.setAttribute(
attrD.getName(),
shape.getAttribute(attrD.getName()));
}
}
// shape files force geometry name to be 'the_geom'. So isolate
// this change
copy.setDefaultGeometry(shape.getDefaultGeometry());
writer.write();
}
}
catch (final IOException e) {
LOGGER.warn(
"Problem with the FeatureWritter",
e);
transaction.rollback();
}
finally {
transaction.commit();
transaction.close();
}
}
}