ingo@1052: package de.intevation.flys.utils; ingo@1052: ingo@1106: import java.io.IOException; ingo@1106: import java.io.File; ingo@1106: import java.io.Serializable; ingo@1106: import java.net.MalformedURLException; ingo@1106: import java.util.ArrayList; ingo@1106: import java.util.HashMap; ingo@1106: import java.util.List; ingo@1106: import java.util.Map; ingo@1106: ingo@1121: import org.apache.log4j.Logger; ingo@1121: ingo@1052: import com.vividsolutions.jts.geom.Coordinate; ingo@1774: import com.vividsolutions.jts.geom.Envelope; ingo@1052: import com.vividsolutions.jts.geom.Geometry; ingo@1052: ingo@1106: import org.opengis.feature.simple.SimpleFeature; ingo@1106: import org.opengis.feature.simple.SimpleFeatureType; ingo@1108: import org.opengis.referencing.FactoryException; ingo@1108: import org.opengis.referencing.NoSuchAuthorityCodeException; ingo@1107: import org.opengis.referencing.crs.CoordinateReferenceSystem; ingo@1106: ingo@1106: import org.geotools.data.DataStoreFactorySpi; ingo@1106: import org.geotools.data.FeatureStore; ingo@1106: import org.geotools.data.DefaultTransaction; ingo@1106: import org.geotools.data.Transaction; ingo@1106: import org.geotools.data.shapefile.ShapefileDataStore; ingo@1106: import org.geotools.data.shapefile.ShapefileDataStoreFactory; ingo@1106: import org.geotools.feature.FeatureIterator; ingo@1106: import org.geotools.feature.FeatureCollection; ingo@1106: import org.geotools.feature.simple.SimpleFeatureTypeBuilder; ingo@1106: import org.geotools.geojson.feature.FeatureJSON; ingo@1108: import org.geotools.referencing.CRS; ingo@1052: ingo@1144: import de.intevation.flys.model.RiverAxis; ingo@1144: ingo@1052: ingo@1052: public class GeometryUtils { ingo@1052: ingo@1121: private static final Logger logger = Logger.getLogger(GeometryUtils.class); ingo@1121: ingo@1121: ingo@1052: private GeometryUtils() { ingo@1052: } ingo@1052: ingo@1052: ingo@1774: public static Envelope getRiverBoundary(String rivername) { ingo@2078: List axes = RiverAxis.getRiverAxis(rivername); ingo@2078: if (axes != null && axes.size() > 0) { ingo@2078: Envelope max = null; ingo@2078: ingo@2078: for (RiverAxis axis: axes) { ingo@2078: // TODO Take the correct EPSG into account. Maybe, we need to ingo@2078: // reproject the geometry. ingo@2078: Envelope env = axis.getGeom().getEnvelopeInternal(); ingo@2078: ingo@2078: if (max == null) { ingo@2078: max = env; ingo@2078: } ingo@2078: else { ingo@2078: max.expandToInclude(env); ingo@2078: } ingo@2078: } ingo@2078: ingo@2078: return max; ingo@1774: } ingo@1774: ingo@1774: return null; ingo@1774: } ingo@1774: ingo@1774: ingo@1774: public static String getRiverBounds(String rivername) { ingo@1774: Envelope env = getRiverBoundary(rivername); ingo@1774: ingo@1774: if (env == null) { ingo@1774: return jtsBoundsToOLBounds(env); ingo@1144: } ingo@1144: ingo@1144: return null; ingo@1144: } ingo@1144: ingo@1144: ingo@1052: /** ingo@1774: * Returns the boundary of Envelope env in OpenLayers ingo@1052: * representation. ingo@1052: * ingo@1774: * @param env The envelope of a geometry. ingo@1052: * ingo@1774: * @return the OpenLayers boundary of env. ingo@1052: */ ingo@1774: public static String jtsBoundsToOLBounds(Envelope env) { ingo@1774: return "" + ingo@1774: env.getMinX() + " " + ingo@1774: env.getMinY() + " " + ingo@1774: env.getMaxX() + " " + ingo@1774: env.getMaxY(); ingo@1052: } ingo@1106: ingo@1106: ingo@1641: public static String createOLBounds(Geometry a, Geometry b) { ingo@1641: Coordinate[] ca = a.getCoordinates(); ingo@1641: Coordinate[] cb = b.getCoordinates(); ingo@1641: ingo@1641: double lowerX = Double.MAX_VALUE; ingo@1641: double lowerY = Double.MAX_VALUE; ingo@1641: double upperX = -Double.MAX_VALUE; ingo@1641: double upperY = -Double.MAX_VALUE; ingo@1641: ingo@1641: for (Coordinate c: ca) { ingo@1641: lowerX = lowerX < c.x ? lowerX : c.x; ingo@1641: lowerY = lowerY < c.y ? lowerY : c.y; ingo@1641: ingo@1641: upperX = upperX > c.x ? upperX : c.x; ingo@1641: upperY = upperY > c.y ? upperY : c.y; ingo@1641: } ingo@1641: ingo@1641: for (Coordinate c: cb) { ingo@1641: lowerX = lowerX < c.x ? lowerX : c.x; ingo@1641: lowerY = lowerY < c.y ? lowerY : c.y; ingo@1641: ingo@1641: upperX = upperX > c.x ? upperX : c.x; ingo@1641: upperY = upperY > c.y ? upperY : c.y; ingo@1641: } ingo@1641: ingo@1641: return "" + lowerX + " " + lowerY + " " + upperX + " " + upperY; ingo@1641: } ingo@1641: ingo@1641: ingo@1107: public static SimpleFeatureType buildFeatureType( ingo@1108: String name, String srs, Class geometryType) ingo@1107: { ingo@1119: return buildFeatureType(name, srs, geometryType, null); ingo@1119: } ingo@1119: ingo@1119: ingo@1119: /** ingo@1119: * Creates a new SimpleFeatureType using a SimpleFeatureTypeBuilder. ingo@1119: * ingo@1119: * @param name The name of the FeatureType. ingo@1119: * @param srs The SRS (e.g. "EPSG:31466"). ingo@1119: * @param geometryType The geometry type's class (e.g. Polygon.class). ingo@1119: * @param attrs Optional. An object with attribute-name/attribute-class ingo@1119: * pairs where index 0 specifies the name as string and index 1 the type ingo@1119: * as class. ingo@1119: * ingo@1119: * @return a new SimpleFeatureType. ingo@1119: */ ingo@1119: public static SimpleFeatureType buildFeatureType( ingo@1119: String name, String srs, Class geometryType, Object[][] attrs) ingo@1119: { ingo@1108: try { ingo@1108: SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); ingo@1108: CoordinateReferenceSystem crs = CRS.decode(srs); ingo@1106: ingo@1108: builder.setName("flys"); ingo@1108: builder.setNamespaceURI("http://www.intevation.de/"); ingo@1108: builder.setCRS(crs); ingo@1108: builder.setSRS(srs); ingo@1106: ingo@1108: builder.add("geometry", geometryType, crs); ingo@1106: ingo@1119: if (attrs != null) { ingo@1119: for (Object[] attr: attrs) { ingo@1119: builder.add((String) attr[0], (Class) attr[1]); ingo@1119: } ingo@1119: } ingo@1119: ingo@1108: return builder.buildFeatureType(); ingo@1108: } ingo@1108: catch (NoSuchAuthorityCodeException nsae) { ingo@1108: } ingo@1108: catch (FactoryException fe) { ingo@1108: } ingo@1108: ingo@1108: return null; ingo@1106: } ingo@1106: ingo@1106: ingo@1106: public static List parseGeoJSON( ingo@1106: String geojson, SimpleFeatureType ft ingo@1106: ) { ingo@1106: List collection = new ArrayList(); ingo@1106: ingo@1106: try { ingo@1106: FeatureJSON fjson = new FeatureJSON(); ingo@1106: fjson.setFeatureType(ft); ingo@1106: ingo@1106: FeatureIterator iterator = ingo@1106: fjson.streamFeatureCollection(geojson); ingo@1106: ingo@1106: while (iterator.hasNext()) { ingo@1106: collection.add(iterator.next()); ingo@1106: } ingo@1106: } ingo@1106: catch (IOException ioe) { ingo@1106: // TODO handle exception ingo@1106: } ingo@1106: ingo@1106: return collection; ingo@1106: } ingo@1106: ingo@1106: ingo@1106: public static boolean writeShapefile( ingo@1106: File shape, ingo@1106: SimpleFeatureType featureType, ingo@1121: FeatureCollection collection ingo@1121: ) { ingo@1164: if (collection.isEmpty()) { ingo@1164: logger.warn("Shapefile is not written - no features given!"); ingo@1164: return false; ingo@1164: } ingo@1164: ingo@1121: Transaction transaction = null; ingo@1106: ingo@1121: try { ingo@1121: Map params = ingo@1121: new HashMap(); ingo@1106: ingo@1121: params.put("url", shape.toURI().toURL()); ingo@1121: params.put("create spatial index", Boolean.TRUE); ingo@1106: ingo@1121: DataStoreFactorySpi dataStoreFactory = ingo@1121: new ShapefileDataStoreFactory(); ingo@1106: ingo@1121: ShapefileDataStore newDataStore = ingo@1121: (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); ingo@1121: newDataStore.createSchema(featureType); ingo@1106: ingo@1121: transaction = new DefaultTransaction("create"); ingo@1121: ingo@1121: String typeName = newDataStore.getTypeNames()[0]; ingo@1121: ingo@1121: FeatureStore featureStore = ingo@1121: (FeatureStore) ingo@1121: newDataStore.getFeatureSource(typeName); ingo@1121: ingo@1121: featureStore.setTransaction(transaction); ingo@1121: ingo@1121: featureStore.addFeatures(collection); ingo@1121: transaction.commit(); ingo@1121: ingo@1121: return true; ingo@1121: } ingo@1121: catch (MalformedURLException mue) { ingo@1121: logger.error("Unable to prepare shapefile: " + mue.getMessage()); ingo@1121: } ingo@1121: catch (IOException ioe) { ingo@1121: logger.error("Unable to write shapefile: " + ioe.getMessage()); ingo@1121: } ingo@1121: finally { ingo@1121: if (transaction != null) { ingo@1121: try { ingo@1121: logger.debug("XXX CLOSE TRANSACTION!"); ingo@1121: transaction.close(); ingo@1121: } ingo@1121: catch (IOException ioe) { /* do nothing */ } ingo@1121: } ingo@1121: } ingo@1121: ingo@1121: return false; ingo@1106: } ingo@1052: } ingo@1052: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :