X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;ds=sidebyside;f=org.argeo.app.geo%2Fsrc%2Forg%2Fargeo%2Fapp%2Fgeo%2FGeoUtils.java;fp=org.argeo.app.geo%2Fsrc%2Forg%2Fargeo%2Fapp%2Fgeo%2FGeoUtils.java;h=1f8846d579e97518e8e37c124a1d9d8eb66f9b0b;hb=37c5768d88096f4eb7be02f18770b6a40be5c110;hp=0000000000000000000000000000000000000000;hpb=9803af38d9ec2eccc2cb5e01a276cbf2edd0d50c;p=gpl%2Fargeo-suite.git diff --git a/org.argeo.app.geo/src/org/argeo/app/geo/GeoUtils.java b/org.argeo.app.geo/src/org/argeo/app/geo/GeoUtils.java new file mode 100644 index 0000000..1f8846d --- /dev/null +++ b/org.argeo.app.geo/src/org/argeo/app/geo/GeoUtils.java @@ -0,0 +1,159 @@ +package org.argeo.app.geo; + +import java.io.IOException; +import java.io.Serializable; +import java.io.Writer; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.measure.Quantity; +import javax.measure.quantity.Area; + +import org.geotools.data.DefaultTransaction; +import org.geotools.data.Transaction; +import org.geotools.data.collection.ListFeatureCollection; +import org.geotools.data.shapefile.ShapefileDataStore; +import org.geotools.data.shapefile.ShapefileDataStoreFactory; +import org.geotools.data.simple.SimpleFeatureCollection; +import org.geotools.data.simple.SimpleFeatureIterator; +import org.geotools.data.simple.SimpleFeatureSource; +import org.geotools.data.simple.SimpleFeatureStore; +import org.geotools.geometry.jts.JTS; +import org.geotools.referencing.CRS; +import org.geotools.referencing.crs.DefaultGeographicCRS; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.geometry.MismatchedDimensionException; +import org.opengis.referencing.FactoryException; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.TransformException; + +import si.uom.SI; +import tech.units.indriya.quantity.Quantities; + +/** Utilities around geographical format, mostly wrapping GeoTools patterns. */ +public class GeoUtils { + + /** In square meters. */ + public static Quantity calcArea(SimpleFeature feature) { + try { + Polygon p = (Polygon) feature.getDefaultGeometry(); + Point centroid = p.getCentroid(); + String code = "AUTO:42001," + centroid.getX() + "," + centroid.getY(); + CoordinateReferenceSystem auto = CRS.decode(code); + + MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto); + + Polygon projed = (Polygon) JTS.transform(p, transform); + return Quantities.getQuantity(projed.getArea(), SI.SQUARE_METRE); + } catch (MismatchedDimensionException | FactoryException | TransformException e) { + throw new IllegalStateException("Cannot claculate area of feature"); + } + } + + public static void exportToSvg(SimpleFeatureCollection features, Writer out, int width, int height) { + try { + double minY = Double.POSITIVE_INFINITY; + double maxY = Double.NEGATIVE_INFINITY; + double minX = Double.POSITIVE_INFINITY; + double maxX = Double.NEGATIVE_INFINITY; + List shapes = new ArrayList<>(); + for (SimpleFeatureIterator it = features.features(); it.hasNext();) { + SimpleFeature feature = it.next(); + StringBuffer sb = new StringBuffer(); + sb.append(" maxX) + maxX = x; + double y = -coord.y; + if (y < minY) + minY = y; + if (y > maxY) + maxY = y; + sb.append(x + "," + y + " "); + } + sb.append("\">"); + sb.append("\n"); + shapes.add(sb.toString()); + + } + double viewportHeight = maxY - minY; + double viewportWidth = maxX - minX; + out.write("\n"); + for (String shape : shapes) { + out.write(shape); + out.write("\n"); + } + out.write(""); + } catch (IOException | FactoryException | MismatchedDimensionException | TransformException e) { + throw new RuntimeException("Cannot export to SVG", e); + } + } + + /** Write a list of simple features to a shapefile. */ + public static void saveFeaturesAsShapefile(SimpleFeatureType featureType, List features, + Path shpFile) { + try { + ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory(); + + Map params = new HashMap<>(); + params.put("url", shpFile.toUri().toURL()); + + params.put("create spatial index", Boolean.TRUE); + + ShapefileDataStore newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params); + newDataStore.createSchema(featureType); + + String typeName = newDataStore.getTypeNames()[0]; + SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName); + if (featureSource instanceof SimpleFeatureStore) { + SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource; + SimpleFeatureCollection collection = new ListFeatureCollection(featureType, features); + + try (Transaction transaction = new DefaultTransaction("create")) { + try { + featureStore.setTransaction(transaction); + featureStore.addFeatures(collection); + transaction.commit(); + } catch (Exception problem) { + transaction.rollback(); + throw new RuntimeException("Cannot write shapefile " + shpFile, problem); + } + } + } else { + throw new IllegalArgumentException(typeName + " does not support read/write access"); + } + } catch (IOException e) { + throw new RuntimeException("Cannot write shapefile " + shpFile, e); + } + } + + /** Singleton. */ + private GeoUtils() { + } +}