Support SVG in FO
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 22 Oct 2022 06:45:38 +0000 (08:45 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 22 Oct 2022 06:45:38 +0000 (08:45 +0200)
org.argeo.app.servlet.publish/src/org/argeo/app/servlet/publish/FopServlet.java
org.argeo.app.servlet.publish/src/org/argeo/app/servlet/publish/GeoToSvgServlet.java [new file with mode: 0644]

index bcba255309a5d6237e1a2dcc1bea51e111c2c083..ac4a1b78ce68a071570939e0f9fda6e4fa6b509e 100644 (file)
@@ -3,6 +3,8 @@ package org.argeo.app.servlet.publish;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
 import java.net.URI;
 import java.net.URL;
 import java.net.URLDecoder;
@@ -39,9 +41,14 @@ import org.apache.xmlgraphics.io.ResourceResolver;
 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.argeo.util.LangUtils;
+import org.geotools.data.collection.ListFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.opengis.feature.simple.SimpleFeature;
 
 /**
  * A servlet transforming an XML view of the data to either FOP or PDF.
@@ -71,10 +78,11 @@ public class FopServlet extends HttpServlet {
                ContentSession session = RemoteAuthUtils.doAs(() -> contentRepository.get(), new ServletHttpRequest(req));
                Content content = session.get(path);
                Source xmlInput = content.adapt(Source.class);
-               xmlInput.setSystemId(req.getRequestURI());
+               String systemId = req.getRequestURL().toString();
+               xmlInput.setSystemId(systemId);
 
                // dev only
-               final boolean DEV = false;
+               final boolean DEV = true;
                if (DEV) {
                        try (InputStream in = xslUrl.openStream()) {
                                Source xslSource = new StreamSource(in);
@@ -88,15 +96,37 @@ public class FopServlet extends HttpServlet {
 
                URIResolver uriResolver = (href, base) -> {
                        try {
-                               URL url = new URL(href);
-                               if (url.getProtocol().equals("file")) {
-                                       InputStream in = Files.newInputStream(Paths.get(URI.create(url.toString())));
-                                       return new StreamSource(in);
+                               URI url = URI.create(href);
+                               if (url.getScheme() != null) {
+                                       if (url.getScheme().equals("file")) {
+                                               InputStream in = Files.newInputStream(Paths.get(URI.create(url.toString())));
+                                               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;
+                                                               }
+                                                       } 
+                                               } else {
+                                                       throw new UnsupportedOperationException(geoExt + " is not supported");
+                                               }
+                                       }
                                }
                        } catch (IOException e) {
-                               // silent
+                               throw new RuntimeException("Cannot process " + href);
                        }
-                       Content subContent = session.get(href);
+                       
+                       String p = href.startsWith("/")?href:path+'/'+href;
+                       Content subContent = session.get(p);
                        return subContent.adapt(Source.class);
                };
 
diff --git a/org.argeo.app.servlet.publish/src/org/argeo/app/servlet/publish/GeoToSvgServlet.java b/org.argeo.app.servlet.publish/src/org/argeo/app/servlet/publish/GeoToSvgServlet.java
new file mode 100644 (file)
index 0000000..c22b834
--- /dev/null
@@ -0,0 +1,67 @@
+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.data.collection.ListFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureCollection;
+import org.opengis.feature.simple.SimpleFeature;
+
+/**
+ * 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;
+       }
+
+}