]> git.argeo.org Git - gpl/argeo-suite.git/blob - org.argeo.app.core/src/org/argeo/app/geo/GeoUtils.java
Adapt to changes in Argeo Commons.
[gpl/argeo-suite.git] / org.argeo.app.core / src / org / argeo / app / geo / GeoUtils.java
1 package org.argeo.app.geo;
2
3 import java.io.IOException;
4 import java.io.Writer;
5 import java.util.ArrayList;
6 import java.util.List;
7
8 import javax.measure.Quantity;
9 import javax.measure.quantity.Area;
10
11 import org.geotools.data.simple.SimpleFeatureCollection;
12 import org.geotools.data.simple.SimpleFeatureIterator;
13 import org.geotools.geometry.jts.JTS;
14 import org.geotools.referencing.CRS;
15 import org.geotools.referencing.crs.DefaultGeographicCRS;
16 import org.locationtech.jts.geom.Coordinate;
17 import org.locationtech.jts.geom.Point;
18 import org.locationtech.jts.geom.Polygon;
19 import org.opengis.feature.simple.SimpleFeature;
20 import org.opengis.geometry.MismatchedDimensionException;
21 import org.opengis.referencing.FactoryException;
22 import org.opengis.referencing.crs.CoordinateReferenceSystem;
23 import org.opengis.referencing.operation.MathTransform;
24 import org.opengis.referencing.operation.TransformException;
25
26 import si.uom.SI;
27 import tech.units.indriya.quantity.Quantities;
28
29 /** Utilities around geographical format, mostly wrapping GeoTools patterns. */
30 public class GeoUtils {
31
32 /** In square meters. */
33 public static Quantity<Area> calcArea(SimpleFeature feature) {
34 try {
35 Polygon p = (Polygon) feature.getDefaultGeometry();
36 Point centroid = p.getCentroid();
37 String code = "AUTO:42001," + centroid.getX() + "," + centroid.getY();
38 CoordinateReferenceSystem auto = CRS.decode(code);
39
40 MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
41
42 Polygon projed = (Polygon) JTS.transform(p, transform);
43 return Quantities.getQuantity(projed.getArea(), SI.SQUARE_METRE);
44 } catch (MismatchedDimensionException | FactoryException | TransformException e) {
45 throw new IllegalStateException("Cannot claculate area of feature");
46 }
47 }
48
49 public static void exportToSvg(SimpleFeatureCollection features, Writer out, int width, int height) {
50 try {
51 double minY = Double.POSITIVE_INFINITY;
52 double maxY = Double.NEGATIVE_INFINITY;
53 double minX = Double.POSITIVE_INFINITY;
54 double maxX = Double.NEGATIVE_INFINITY;
55 List<String> shapes = new ArrayList<>();
56 for (SimpleFeatureIterator it = features.features(); it.hasNext();) {
57 SimpleFeature feature = it.next();
58 StringBuffer sb = new StringBuffer();
59 sb.append("<polyline style=\"stroke-width:1;stroke:#000000;fill:none;\" points=\"");
60
61 Polygon p = (Polygon) feature.getDefaultGeometry();
62 Point centroid = p.getCentroid();
63 String code = "AUTO:42001," + centroid.getX() + "," + centroid.getY();
64 CoordinateReferenceSystem auto = CRS.decode(code);
65
66 MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
67
68 Polygon projed = (Polygon) JTS.transform(p, transform);
69
70 for (Coordinate coord : projed.getCoordinates()) {
71 double x = coord.x;
72 if (x < minX)
73 minX = x;
74 if (x > maxX)
75 maxX = x;
76 double y = -coord.y;
77 if (y < minY)
78 minY = y;
79 if (y > maxY)
80 maxY = y;
81 sb.append(x + "," + y + " ");
82 }
83 sb.append("\">");
84 sb.append("</polyline>\n");
85 shapes.add(sb.toString());
86
87 }
88 double viewportHeight = maxY - minY;
89 double viewportWidth = maxX - minX;
90 out.write("<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
91 out.write(" width=\"" + width + "\"\n");
92 out.write(" height=\"" + height + "\"\n");
93 out.write(" viewBox=\"" + minX + " " + minY + " " + viewportWidth + " " + viewportHeight + "\"\n");
94 out.write(" preserveAspectRatio=\"xMidYMid meet\"\n");
95 out.write(">\n");
96 for (String shape : shapes) {
97 out.write(shape);
98 out.write("\n");
99 }
100 out.write("</svg>");
101 } catch (IOException | FactoryException | MismatchedDimensionException | TransformException e) {
102 throw new RuntimeException("Cannot export to SVG", e);
103 }
104 }
105
106 /** Singleton. */
107 private GeoUtils() {
108 }
109 }