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@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@1144: public static String getRiverBounds(String rivername) { ingo@1144: RiverAxis axis = RiverAxis.getRiverAxis(rivername); ingo@1144: if (axis != null) { ingo@1144: // TODO Take the correct EPSG into account. Maybe, we need to ingo@1144: // reproject the geometry. ingo@1144: Geometry geom = axis.getGeom().getBoundary(); ingo@1144: return jtsBoundsToOLBounds(geom); ingo@1144: } ingo@1144: ingo@1144: return null; ingo@1144: } ingo@1144: ingo@1144: ingo@1052: /** ingo@1052: * Returns the boundary of Geometry geom in OpenLayers ingo@1052: * representation. ingo@1052: * ingo@1052: * @param geom The geometry. ingo@1052: * ingo@1052: * @return the OpenLayers boundary of geom. ingo@1052: */ ingo@1052: public static String jtsBoundsToOLBounds(Geometry geom) { ingo@1052: Coordinate[] c = geom != null ? geom.getCoordinates() : null; ingo@1052: ingo@1052: if (c == null || c.length < 2) { ingo@1052: return null; ingo@1052: } ingo@1052: ingo@1052: return "" + c[0].x + " " + c[1].y + " " + c[1].x + " " + c[0].y; 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 :