Rendering clipped SVG image using GeoTools (version 26.2)

216 Views Asked by At

Trying to generate SVG from an external graphic link but the output SVG image not rendering properly. To generate SVG using the below code,

package org.geotools.tutorial.quickstart;
import org.apache.batik.svggen.SVGGeneratorContext;
import org.apache.batik.svggen.SVGGraphics2D;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.*;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.geom.Polygon;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.expression.Expression;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import java.awt.*;
import java.awt.Dimension;
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;

public class SvgRendering {

static StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory();
static FilterFactory2 filterFactory = CommonFactoryFinder.getFilterFactory2();

public static void main(String[] args) throws Exception {

    Coordinate[] listOfPoints = new Coordinate[5];
    listOfPoints[0] = new Coordinate(-73.82, 41.24);

    setupSVG(listOfPoints);
}

public static DefaultFeatureCollection createBoundingBox(Coordinate[] listofP){
    SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();
    b.setName("MyFeatureType");
    b.add("location", Polygon.class);
    final SimpleFeatureType TYPE = b.buildFeatureType();
    SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
    GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
    Polygon polygon = geometryFactory.createPolygon(listofP);
    featureBuilder.add(polygon);
    SimpleFeature feature = featureBuilder.buildFeature("polygon");
    DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("internal", TYPE);
    featureCollection.add(feature); //Add feature 1
    return featureCollection;
}

private static void setupSVG(Coordinate[] listofP)
        throws IOException, ParserConfigurationException, URISyntaxException, TransformerException {

    //URL url = new URL("http://localhost:8080/");
    URL url = new URL("file:///C:/poc/mapreport/Map_marker.svg");
    //File file = new File(baseFilePath + "mapreport\\Map_marker.svg");
    //URL url = file.toURI().toURL();

    PointSymbolizer symb = styleFactory.createPointSymbolizer();
    ExternalGraphic eg = styleFactory.createExternalGraphic(url, "image/svg+xml");
    symb.getGraphic().graphicalSymbols().add(eg);
    Expression size = filterFactory.literal(54);
    symb.getGraphic().setSize(size);

    Rule rule = styleFactory.createRule();
    rule.symbolizers().add(symb);
    FeatureTypeStyle fts = styleFactory.createFeatureTypeStyle(rule);
    Style style = styleFactory.createStyle();
    style.featureTypeStyles().add(fts);

    MapContent mc = new MapContent();

    DefaultFeatureCollection boundingbox = createBoundingBox(listofP);
    Layer layer = new FeatureLayer(boundingbox, style);
    mc.addLayer(layer);

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();

    // Create an instance of org.w3c.dom.Document
    Document document = db.getDOMImplementation().createDocument(null, "svg", null);

    // Set up the map
    SVGGeneratorContext ctx1 = SVGGeneratorContext.createDefault(document);
    SVGGeneratorContext ctx = ctx1;
    ctx.setComment("Generated by GeoTools2 with Batik SVG Generator");

    SVGGraphics2D g2d = new SVGGraphics2D(ctx, true);

    Dimension canvasSize = new Dimension(1024, 1024);
    g2d.setSVGCanvasSize(canvasSize);
    StreamingRenderer renderer = new StreamingRenderer();
    renderer.setMapContent(mc);
    Rectangle outputArea = new Rectangle(g2d.getSVGCanvasSize());
    ReferencedEnvelope dataArea = mc.getMaxBounds();
    dataArea.expandBy(5); // some of these have 0 size

    renderer.paint(g2d, outputArea, dataArea);
    File fileToSave = new File("C:\\poc\\markers.svg");

    OutputStreamWriter osw = null;
    try {
        OutputStream out = new FileOutputStream(fileToSave);
        osw = null;

        osw = new OutputStreamWriter(out, "UTF-8");
        g2d.stream(osw);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }  finally {
        if (osw != null)
            try {
                osw.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }

    mc.dispose();
}

}

Expected Output:- Expected Output

Final Output:- Final rendered image

So, in the final output SVG marker is getting cut from the right-hand side.

Help would be appreciated.

Thanks in advance

This is different from the previous question.

1

There are 1 best solutions below

1
Olyster On

This happens near the bounds of the layer. You can enlarge the layer's bounds manually in the layer config page.