From facc74e96dab06f75930bbcddecb586979fc3a7a Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 22 Oct 2022 08:45:38 +0200 Subject: [PATCH] Support SVG in FO --- .../argeo/app/servlet/publish/FopServlet.java | 46 ++++++++++--- .../app/servlet/publish/GeoToSvgServlet.java | 67 +++++++++++++++++++ 2 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 org.argeo.app.servlet.publish/src/org/argeo/app/servlet/publish/GeoToSvgServlet.java diff --git a/org.argeo.app.servlet.publish/src/org/argeo/app/servlet/publish/FopServlet.java b/org.argeo.app.servlet.publish/src/org/argeo/app/servlet/publish/FopServlet.java index bcba255..ac4a1b7 100644 --- a/org.argeo.app.servlet.publish/src/org/argeo/app/servlet/publish/FopServlet.java +++ b/org.argeo.app.servlet.publish/src/org/argeo/app/servlet/publish/FopServlet.java @@ -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 index 0000000..c22b834 --- /dev/null +++ b/org.argeo.app.servlet.publish/src/org/argeo/app/servlet/publish/GeoToSvgServlet.java @@ -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 properties) { + } + + public void stop(Map properties) { + + } + + public void setContentRepository(ContentRepository contentRepository) { + this.contentRepository = contentRepository; + } + +} -- 2.30.2