package org.geoserver.wps.sextante; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.geotools.data.DataStore; import org.geotools.data.DefaultQuery; import org.geotools.data.DefaultTransaction; import org.geotools.data.FeatureSource; import org.geotools.data.FeatureStore; import org.geotools.data.FeatureWriter; import org.geotools.data.Query; import org.geotools.feature.FeatureCollection; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.AttributeType; import org.opengis.filter.Filter; import org.opengis.referencing.crs.CoordinateReferenceSystem; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Polygon; import es.unex.sextante.core.Sextante; import es.unex.sextante.dataObjects.AbstractVectorLayer; import es.unex.sextante.dataObjects.IFeatureIterator; import es.unex.sextante.dataObjects.IVectorLayer; public class GTShpLayer extends AbstractVectorLayer { private String m_sFilename; private String m_sName; private int m_iCount; private CoordinateReferenceSystem m_CRS; private Query m_Query; private FeatureWriter<SimpleFeatureType,SimpleFeature> m_featWriter; private DataStore m_dataStore; public GTShpLayer() { System.out.println("Hello!"); } // Factory methods: /** * Creates a vector layer from the FeatureCollection resulting from applying * the query to the Datastore. * <p> * Note throws an exception if the query's typename is not one of the * datastores featuretypes * </p> * * @param source * the DataStore to query * @param query * the query to use for obtaining the data * @throws IOException */ public static GTShpLayer createLayer(DataStore source, Query query) throws IOException { if (!Arrays.asList(source.getTypeNames()).contains(query.getTypeName())) { throw new IllegalArgumentException( query.getTypeName() + " is not one of the FeatureTypes contained by the Datasource. Options are: " + Arrays.asList(source.getTypeNames())); } FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = source.getFeatureSource(query .getTypeName()); GTShpLayer layer = new GTShpLayer(); layer.create(source, featureSource, query); return layer; } /** * Creates a vector layer from the datasource. * * @param source * the source to query * @param typename * the typename (must be one of the datasources typenames) to use * for the layer * @param filter * a filter to apply to the features that are used in the layer * @param crs * the crs to reproject the features to (if necessary). If null * no reprojection will be applied */ public static GTShpLayer createLayer(DataStore source, String typename, Filter filter, CoordinateReferenceSystem crs) throws IOException { DefaultQuery query = new DefaultQuery(typename, filter); if (crs != null) { query.setCoordinateSystemReproject(crs); } return createLayer(source, query); } /** * Creates a vector layer from the datasource. * * @param source * the source to query * @param typename * the typename (must be one of the datasources typenames) to use * for the layer * @param crs * the crs to reproject the features to (if necessary). If null * no reprojection will be applied */ public static GTShpLayer createLayer(DataStore source, String typename, CoordinateReferenceSystem crs) throws IOException { return createLayer(source, typename, Filter.INCLUDE, crs); } /** * Creates a vector layer from the datasource. * * @param source * the source to query * @param typename * the typename (must be one of the datasources typenames) to use * for the layer */ public static GTShpLayer createLayer(DataStore source, String typename) throws IOException { return createLayer(source, typename, Filter.INCLUDE, null); } public void create(DataStore store, FeatureSource<SimpleFeatureType, SimpleFeature> featureSource, Query query) throws IOException { this.m_dataStore = store; try { this.m_Query = query; m_BaseDataObject = featureSource; m_iCount = featureSource.getFeatures(query).size(); m_CRS = featureSource.getSchema().getCoordinateReferenceSystem(); m_sName = query.getTypeName(); } catch (Exception e) { throw (IOException) new IOException(e.getMessage()).initCause(e); } } public void open() { try { postProcess(); // close and dispose the feature writer, if existing } catch (IOException e) { e.printStackTrace(); Sextante.addErrorToLog(e); } } public void close() { if (m_featWriter!=null) { try { m_featWriter.close(); m_featWriter=null; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); Sextante.addErrorToLog(e); } } if (this.getFeatureSource() != null) { this.getFeatureSource().getDataStore().dispose(); } } public void addFeature(Geometry g, Object[] values) { if (m_featWriter==null) { SimpleFeatureType ft = ((FeatureSource<SimpleFeatureType, SimpleFeature>)m_BaseDataObject).getSchema(); try { m_featWriter = m_dataStore.getFeatureWriterAppend(ft.getTypeName(), DefaultTransaction.AUTO_COMMIT); } catch (IOException e) { throw new RuntimeException(e); } } if (getFeatureSource() instanceof FeatureStore) { Geometry geom; GeometryFactory gf = new GeometryFactory(); if (g instanceof Polygon) { geom = gf.createMultiPolygon(new Polygon[] { (Polygon) g }); } else if (g instanceof LineString) { geom = gf.createMultiLineString(new LineString[] { (LineString) g }); } else { geom = g; } try { List<Object> attributes = new ArrayList<Object>(); attributes.add(geom); attributes.addAll(Arrays.asList(values)); SimpleFeature feature = m_featWriter.next(); feature.setAttributes(attributes); m_featWriter.write(); m_iCount++; } catch (Exception e) { // FIXME: improve exception handling throw new RuntimeException(e); } } else { throw new RuntimeException("Incorrect feature source"); } } public IFeatureIterator iterator() { if (m_featWriter!=null) { throw new IllegalArgumentException("Method open() [and postproces() if an editing session is active] must be called before reading the table contents."); } if (m_BaseDataObject != null) { try { FeatureCollection<SimpleFeatureType, SimpleFeature> features = getFeatureSource().getFeatures( m_Query); return new GTFeatureIterator(features); } catch (Exception e) { throw new RuntimeException(e); } } else { return null; } } public String getFieldName(int i) { if (m_BaseDataObject != null) { try { SimpleFeatureType ft = getFeatureSource().getSchema(); AttributeType at = ft.getType(i + 1); return at.getName().getLocalPart(); } catch (Exception e) { e.printStackTrace(); return null; } } return null; } public Class<?> getFieldType(int i) { if (m_BaseDataObject != null) { try { SimpleFeatureType ft = getFeatureSource().getSchema(); AttributeType at = ft.getType(i + 1); return at.getBinding(); } catch (Exception e) { e.printStackTrace(); return null; } } return null; } public int getFieldCount() { if (m_BaseDataObject != null) { try { SimpleFeatureType ft = getFeatureSource().getSchema(); return ft.getAttributeCount() - 1; } catch (Exception e) { e.printStackTrace(); Sextante.addErrorToLog(e); return 0; } } return 0; } public int getShapesCount() { return m_iCount; } public int getShapeType() { if (m_BaseDataObject != null) { try { SimpleFeatureType ft = getFeatureSource().getSchema(); Class<?> type = ft.getGeometryDescriptor().getType().getBinding(); if (type.isAssignableFrom(Polygon.class) || type.isAssignableFrom(MultiPolygon.class)) { return IVectorLayer.SHAPE_TYPE_POLYGON; } else if (type.isAssignableFrom(LineString.class) || type.isAssignableFrom(MultiLineString.class)) { return IVectorLayer.SHAPE_TYPE_LINE; } else { return IVectorLayer.SHAPE_TYPE_POINT; } } catch (Exception e) { e.printStackTrace(); Sextante.addErrorToLog(e); return IVectorLayer.SHAPE_TYPE_POLYGON; } } return IVectorLayer.SHAPE_TYPE_POLYGON; } public String getName() { return m_sName; } public void postProcess() throws IOException { if (m_featWriter!=null) { m_featWriter.close(); m_featWriter = null; } } public Rectangle2D getFullExtent() { if (m_BaseDataObject != null) { try { ReferencedEnvelope bounds = getFeatureSource().getFeatures( m_Query).getBounds(); return new Rectangle2D.Double(bounds.getMinX(), bounds .getMinY(), bounds.getWidth(), bounds.getHeight()); } catch (Exception e) { e.printStackTrace(); Sextante.addErrorToLog(e); return null; } } else { return null; } } public String getFilename() { return m_sFilename; } public Object getCRS() { return m_CRS; } public void setName(String name) { m_sName = name; } @SuppressWarnings("unchecked") private FeatureSource<SimpleFeatureType, SimpleFeature> getFeatureSource() { return (FeatureSource<SimpleFeatureType, SimpleFeature>) m_BaseDataObject; } }