Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/utils/GeometryUtils.java @ 4031:e4e345d81a65
issue889/2
author | Felix Wolfsteller <felix.wolfsteller@intevation.de> |
---|---|
date | Thu, 04 Oct 2012 14:54:44 +0200 |
parents | 1b41dc00b1f7 |
children | c1b60f8c3390 |
line wrap: on
line source
package de.intevation.flys.utils; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import de.intevation.flys.model.RiverAxis; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.geotools.data.DataStoreFactorySpi; 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.data.simple.SimpleFeatureIterator; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureIterator; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.geojson.feature.FeatureJSON; import org.geotools.geometry.jts.JTS; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.referencing.CRS; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.referencing.FactoryException; import org.opengis.referencing.NoSuchAuthorityCodeException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.TransformException; public class GeometryUtils { private static final Logger logger = Logger.getLogger(GeometryUtils.class); public static final String PREFIX_EPSG = "EPSG:"; public static final String DEFAULT_EPSG = "EPSG:31467"; private GeometryUtils() { } public static Envelope getRiverBoundary(String rivername) { List<RiverAxis> axes = RiverAxis.getRiverAxis(rivername); if (axes != null && axes.size() > 0) { Envelope max = null; for (RiverAxis axis: axes) { // TODO Take the correct EPSG into account. Maybe, we need to // reproject the geometry. Envelope env = axis.getGeom().getEnvelopeInternal(); if (max == null) { max = env; } else { max.expandToInclude(env); } } return max; } return null; } public static String getRiverBounds(String rivername) { Envelope env = getRiverBoundary(rivername); if (env != null) { return jtsBoundsToOLBounds(env); } return null; } /** * Returns the boundary of Envelope <i>env</i> in OpenLayers representation. * * @param env The envelope of a geometry. * * @return the OpenLayers boundary of <i>env</i>. */ public static String jtsBoundsToOLBounds(Envelope env) { StringBuilder buf = new StringBuilder(); buf.append(env.getMinX()); buf.append(' '); buf.append(env.getMinY()); buf.append(' '); buf.append(env.getMaxX()); buf.append(' '); buf.append(env.getMaxY()); return buf.toString(); } public static String createOLBounds(Geometry a, Geometry b) { Coordinate[] ca = a.getCoordinates(); Coordinate[] cb = b.getCoordinates(); double lowerX = Double.MAX_VALUE; double lowerY = Double.MAX_VALUE; double upperX = -Double.MAX_VALUE; double upperY = -Double.MAX_VALUE; for (Coordinate c: ca) { lowerX = lowerX < c.x ? lowerX : c.x; lowerY = lowerY < c.y ? lowerY : c.y; upperX = upperX > c.x ? upperX : c.x; upperY = upperY > c.y ? upperY : c.y; } for (Coordinate c: cb) { lowerX = lowerX < c.x ? lowerX : c.x; lowerY = lowerY < c.y ? lowerY : c.y; upperX = upperX > c.x ? upperX : c.x; upperY = upperY > c.y ? upperY : c.y; } return "" + lowerX + " " + lowerY + " " + upperX + " " + upperY; } public static SimpleFeatureType buildFeatureType( String name, String srs, Class<?> geometryType) { return buildFeatureType(name, srs, geometryType, null); } /** * Creates a new SimpleFeatureType using a SimpleFeatureTypeBuilder. * * @param name The name of the FeatureType. * @param srs The SRS (e.g. "EPSG:31466"). * @param geometryType The geometry type's class (e.g. Polygon.class). * @param attrs Optional. An object with attribute-name/attribute-class pairs * where index 0 specifies the name as string and index 1 the * ype as class. * * @return a new SimpleFeatureType. */ public static SimpleFeatureType buildFeatureType(String name, String srs, Class<?> geometryType, Object[][] attrs) { try { SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); CoordinateReferenceSystem crs = CRS.decode(srs); builder.setName("flys"); builder.setNamespaceURI("http://www.intevation.de/"); builder.setCRS(crs); builder.setSRS(srs); builder.add("geometry", geometryType, crs); if (attrs != null) { for (Object[] attr: attrs) { builder.add((String) attr[0], (Class<?>) attr[1]); } } return builder.buildFeatureType(); } catch (NoSuchAuthorityCodeException nsae) { } catch (FactoryException fe) { } return null; } public static List<SimpleFeature> parseGeoJSON( String geojson, SimpleFeatureType ft ) { List<SimpleFeature> collection = new ArrayList<SimpleFeature>(); try { FeatureJSON fjson = new FeatureJSON(); fjson.setFeatureType(ft); FeatureIterator<SimpleFeature> iterator = fjson.streamFeatureCollection(geojson); while (iterator.hasNext()) { collection.add(iterator.next()); } } catch (IOException ioe) { // TODO handle exception } return collection; } /** * This method returns the {@link CoordinateReferenceSystem} by the * {@link String} <i>epsg</i>. * * @param epsg An EPSG code like <b>EPSG:31466</b> * * @return the {@link CoordinateReferenceSystem} specified by <i>epsg</i>. */ public static CoordinateReferenceSystem getCoordinateReferenceSystem( String epsg ) { if (epsg == null) { logger.warn("cannot create CoordinateReferenceSystem with null"); return null; } if (!epsg.startsWith(PREFIX_EPSG)) { epsg = PREFIX_EPSG + epsg; } try { return CRS.decode(epsg); } catch (FactoryException fe) { logger.error( "unable to get CoordinateReferenceSystem for: " + epsg, fe); } return null; } public static Envelope transform(Envelope orig, String targetSrs) { return transform(orig, targetSrs, DEFAULT_EPSG); } public static Envelope transform( Envelope orig, String targetSrs, String origSrs ) { if (targetSrs == null || orig == null || origSrs == null) { logger.warn("unable to transform envelope: empty parameters"); return orig; } logger.debug("Transform envlope to '" + targetSrs + "'"); try { CoordinateReferenceSystem sourceCRS = getCoordinateReferenceSystem(origSrs); CoordinateReferenceSystem targetCRS = getCoordinateReferenceSystem(targetSrs); if (sourceCRS != null && targetCRS != null) { ReferencedEnvelope tmpEnv = new ReferencedEnvelope(orig, CRS.decode(origSrs)); Envelope target = tmpEnv.transform(targetCRS, false); if (logger.isDebugEnabled()) { logger.debug(" orig envelope : " + orig); logger.debug(" transformed envelope: " + target); } return target; } } catch (NoSuchAuthorityCodeException nsae) { logger.error("Cannot get CoordinateReferenceSystem!", nsae); } catch (FactoryException fe) { logger.error("Cannot get CoordinateReferenceSystem!", fe); } catch (TransformException te) { logger.error("Cannot transform envelope from source " + origSrs + " to target srs " + targetSrs); } return null; } public static boolean writeShapefile(File shape, SimpleFeatureType featureType, FeatureCollection<?, ?> collection) { return writeShapefile(shape, featureType, collection, featureType.getCoordinateReferenceSystem()); } public static boolean writeShapefile(File shape, SimpleFeatureType featureType, FeatureCollection<?, ?> collection, CoordinateReferenceSystem crs) { if (collection.isEmpty()) { logger.warn("Shapefile is not written - no features given!"); return false; } Transaction transaction = null; try { MathTransform transform = CRS.findMathTransform( CRS.decode(DEFAULT_EPSG), crs); Map<String, Serializable> params = new HashMap<String, Serializable>(); params.put("url", shape.toURI().toURL()); params.put("create spatial index", Boolean.TRUE); DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory(); ShapefileDataStore newDataStore = (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); newDataStore.createSchema(featureType); transaction = new DefaultTransaction("create"); String typeName = newDataStore.getTypeNames()[0]; FeatureWriter<SimpleFeatureType, SimpleFeature> writer = newDataStore.getFeatureWriter(typeName, transaction); SimpleFeatureIterator iterator = (SimpleFeatureIterator) collection.features(); while (iterator.hasNext()){ SimpleFeature feature = iterator.next(); SimpleFeature copy = writer.next(); copy.setAttributes(feature.getAttributes()); Geometry orig = (Geometry) feature.getDefaultGeometry(); Geometry reprojected = JTS.transform(orig, transform); copy.setDefaultGeometry(reprojected); writer.write(); } transaction.commit(); return true; } catch (MalformedURLException mue) { logger.error("Unable to prepare shapefile: " + mue.getMessage()); } catch (IOException ioe) { logger.error("Unable to write shapefile: " + ioe.getMessage()); } catch (NoSuchAuthorityCodeException nsae) { logger.error("Cannot get CoordinateReferenceSystem for '" + DEFAULT_EPSG + "'"); } catch (FactoryException fe) { logger.error("Cannot get CoordinateReferenceSystem for '" + DEFAULT_EPSG + "'"); } catch (TransformException te) { logger.error("Was not able to transform geometry!", te); } finally { if (transaction != null) { try { transaction.close(); } catch (IOException ioe) { /* do nothing */ } } } return false; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :