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.factory.CommonFactoryFinder;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
}
}
- public static void exportToSvg(SimpleFeatureCollection features, Writer out, int width, int height) {
+ public static void exportToSvg(Geometry[] geometries, 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<String> shapes = new ArrayList<>();
- for (SimpleFeatureIterator it = features.features(); it.hasNext();) {
- SimpleFeature feature = it.next();
+ for (Geometry geometry : geometries) {
StringBuffer sb = new StringBuffer();
sb.append("<polyline style=\"stroke-width:1;stroke:#000000;fill:none;\" points=\"");
- 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);
-
- for (Coordinate coord : projed.getCoordinates()) {
- double x = coord.x;
- if (x < minX)
- minX = x;
- if (x > maxX)
- maxX = x;
- double y = -coord.y;
- if (y < minY)
- minY = y;
- if (y > maxY)
- maxY = y;
- sb.append(x + "," + y + " ");
+ if (geometry instanceof Polygon p) {
+ 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);
+
+ for (Coordinate coord : projed.getCoordinates()) {
+ double x = coord.x;
+ if (x < minX)
+ minX = x;
+ if (x > 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("</polyline>\n");
+ shapes.add(sb.toString());
+ } else {
+ throw new IllegalArgumentException("Unsuppported geometry type " + geometry.getClass().getName());
}
- sb.append("\">");
- sb.append("</polyline>\n");
- shapes.add(sb.toString());
-
}
double viewportHeight = maxY - minY;
double viewportWidth = maxX - minX;
/** Utilities around entity types related to geography. */
public class GeoEntityUtils {
- public static final String PLACE_GEOM_JSON = "place.geom.json";
public static final String _GEOM_JSON = ".geom.json";
public static void putGeometry(Content c, QNamed name, Geometry geometry) {
import org.argeo.api.acr.Content;
import org.argeo.api.acr.ContentRepository;
import org.argeo.api.acr.ContentSession;
+import org.argeo.api.acr.NamespaceUtils;
import org.argeo.app.geo.GeoUtils;
import org.argeo.app.geo.GpxUtils;
+import org.argeo.app.geo.acr.GeoEntityUtils;
import org.argeo.cms.acr.xml.XmlNormalizer;
import org.argeo.cms.auth.RemoteAuthUtils;
import org.argeo.cms.servlet.ServletHttpRequest;
import org.argeo.cms.util.LangUtils;
-import org.geotools.api.feature.simple.SimpleFeature;
-import org.geotools.data.collection.ListFeatureCollection;
-import org.geotools.data.simple.SimpleFeatureCollection;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Polygon;
import net.sf.saxon.BasicTransformerFactory;
Content content = session.get(path);
// dev only
- final boolean DEV = false;
+ final boolean DEV = true;
if (DEV) {
try (InputStream in = xslUrl.openStream()) {
Source xslSource = new StreamSource(in);
return new StreamSource(in);
}
if (url.getScheme().equals("geo2svg")) {
- String includePath = path + url.getPath();
- String geoExt = includePath.substring(includePath.lastIndexOf('.'));
- Content geoContent = session.get(includePath);
- if (".gpx".equals(geoExt)) {
- try (InputStream in = geoContent.open(InputStream.class)) {
- SimpleFeature field = GpxUtils.parseGpxToPolygon(in);
- SimpleFeatureCollection features = new ListFeatureCollection(field.getType(), field);
- try (StringWriter writer = new StringWriter()) {
- GeoUtils.exportToSvg(features, writer, 100, 100);
- StreamSource res = new StreamSource(new StringReader(writer.toString()));
- return res;
+ int lastDot = url.getPath().lastIndexOf('.');
+ Polygon polygon;
+ if (lastDot > 0) {
+ String includePath = path + url.getPath();
+ Content geoContent = session.get(includePath);
+ String geoExt = includePath.substring(lastDot);
+ if (".gpx".equals(geoExt)) {
+ try (InputStream in = geoContent.open(InputStream.class)) {
+ polygon = GpxUtils.parseGpxTrackTo(in, Polygon.class);
}
+ } else {
+ throw new UnsupportedOperationException(geoExt + " is not supported");
}
} else {
- throw new UnsupportedOperationException(geoExt + " is not supported");
+ Content geoContent;
+ String attrName;
+ if (url.getPath().startsWith("/@")) {
+ geoContent = content;
+ attrName = url.getPath().substring(2);// remove /@
+ } else {
+ throw new IllegalArgumentException("Only direct attributes are currently supported");
+ }
+ polygon = GeoEntityUtils.getGeometry(geoContent, NamespaceUtils.parsePrefixedName(attrName),
+ Polygon.class);
+ }
+ try (StringWriter writer = new StringWriter()) {
+ GeoUtils.exportToSvg(new Geometry[] { polygon }, writer, 100, 100);
+ StreamSource res = new StreamSource(new StringReader(writer.toString()));
+ return res;
}
}
}
+++ /dev/null
-package org.argeo.app.servlet.publish;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Map;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.argeo.api.acr.Content;
-import org.argeo.api.acr.ContentRepository;
-import org.argeo.api.acr.ContentSession;
-import org.argeo.app.geo.GeoUtils;
-import org.argeo.app.geo.GpxUtils;
-import org.argeo.cms.auth.RemoteAuthUtils;
-import org.argeo.cms.servlet.ServletHttpRequest;
-import org.geotools.api.feature.simple.SimpleFeature;
-import org.geotools.data.collection.ListFeatureCollection;
-import org.geotools.data.simple.SimpleFeatureCollection;
-
-/**
- * A servlet transforming an geographical data to SVG.
- */
-public class GeoToSvgServlet extends HttpServlet {
- private static final long serialVersionUID = -6346379324580671894L;
- private ContentRepository contentRepository;
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- String servletPath = req.getServletPath();
-
- servletPath = servletPath.substring(1, servletPath.lastIndexOf('.'));
- servletPath = servletPath.substring(servletPath.indexOf('/'), servletPath.length());
- String path = URLDecoder.decode(servletPath, StandardCharsets.UTF_8);
- String ext = servletPath.substring(path.lastIndexOf('.'));
-
- resp.setContentType("image/svg+xml");
-
- ContentSession session = RemoteAuthUtils.doAs(() -> contentRepository.get(), new ServletHttpRequest(req));
- Content content = session.get(path);
- if (".gpx".equals(ext)) {
- try (InputStream in = content.open(InputStream.class)) {
- SimpleFeature field = GpxUtils.parseGpxToPolygon(in);
-
- SimpleFeatureCollection features = new ListFeatureCollection(field.getType(), field);
- GeoUtils.exportToSvg(features, resp.getWriter(), 100, 100);
-// log.debug("SVG:\n" + writer.toString() + "\n");
- }
- }
- }
-
- public void start(Map<String, Object> properties) {
- }
-
- public void stop(Map<String, Object> properties) {
-
- }
-
- public void setContentRepository(ContentRepository contentRepository) {
- this.contentRepository = contentRepository;
- }
-
-}