3

I am currently working on how to read in ESRI shapefiles, parse/edit layers and then export out to SVG (Scalable Vector Graphic) file type. I have been using GeoTools primarily for reading/loading shapefiles. I am also displaying them using an JMapFrame GUI.

My issue currently is how to export a shapefile, after reading it in, to an SVG file. There is a great example by OpenJUMP which does exactly as I need, however, while looking at the code used to implement this feature, I am unable to figure out how to do it myself. I want to avoid using OpenJUMP's program as export to SVG using java code (so I can do other things before exporting).

Note: I have 2 files - ShapefileExporter.java (main class) and ExportShapefile.java (export to svg code)

Here is some of my code reading in shapefiles:

    public class ShapefileExporter {    
        final static ExportShapefile exportSHP = new ExportShapefile();
        final JFileChooser jfc = new JFileChooser();
        JToolBar jtb;
        MapContent map;
        JPopupMenu rcMenu = new JPopupMenu("Popup");
        private JMapFrame jframe;
        private File shapeFile;

        // Main, start program
        public static void main(String[] args) throws Exception {

            ShapefileExporter exporter = new ShapefileExporter();

            if (args.length == 0 || !args[0].toLowerCase().endsWith(".shp")) {
                System.out.println("Any provided shapefile.prl or .sld will be used");
            } else {
                String pathname = args[0];
                URL shape = acquireURL(pathname);

                if (shape == null) {
                    System.err.println("Could not find shapefile");
                    System.exit(1);
                }

                exporter.loadFile(shape);
            }
        }

        // Load Shapefile into JMapFrame
        protected void loadFile(URL shape) throws IOException {

            FileDataStore store = FileDataStoreFinder.getDataStore(shape);
            SimpleFeatureSource featureSource = store.getFeatureSource();

            Style style = SLD.createSimpleStyle( featureSource.getSchema() );
            FeatureLayer layer = new FeatureLayer(featureSource, style);  

            ShapefileDataStore ds = new ShapefileDataStore(shape);
            FeatureSource<SimpleFeatureType, SimpleFeature> fs = ds.getFeatureSource();

            map = new MapContent();
            map.addLayer(layer);


            jframe.setMapContent(map);
        }

        // Constructor, create/display JMapFrame GUI
        public ShapefileExporter() {

            File default_dir = new File(System.getProperty("user.home") + System.getProperty("file.separator") + "NetBeansProjects/Working On");
            jfc.setCurrentDirectory(default_dir);

            jframe = new JMapFrame();

            jframe.setSize(1000, 800);
            jframe.enableStatusBar(true);
            jframe.enableToolBar(true);
            jframe.enableLayerTable(true);

            JMenuBar menuBar = new JMenuBar();
            jframe.setJMenuBar(menuBar);

            JMenu menubar = new JMenu("File");
            menuBar.add(menubar);

            menubar.add(new SafeAction("Load file") {
                @Override
                public void action(ActionEvent e) throws Throwable {


                    setJFCFilter("Shapefiles", "shp");
                    int returnVal = jfc.showOpenDialog(jframe);

                    if (returnVal == JFileChooser.APPROVE_OPTION) {
                        String pathname = jfc.getSelectedFile().getAbsolutePath();
                        URL shape = acquireURL(pathname);

                        if (shape == null) {
                            JOptionPane.showMessageDialog(jframe, "could not find file \"" + pathname + "\"", "Could not find file",
                                    JOptionPane.ERROR_MESSAGE);
                        }

                        try {
                            shapeFile = new File(pathname);
                            loadFile(shape);
                        } catch (IOException ex) {
                            System.err.println("File exception for file: " + shape);
                        }
                    }
                }
            });

            menubar.add(new SafeAction("Export Shapefile") {
                @Override
                public void action(ActionEvent e) throws Throwable {

                    File svgFile = changeFileExt(shapeFile, ".svg");
                    jfc.setSelectedFile(svgFile);

                    setJFCFilter("Scaleable Vector Graphics", "svg");
                    int returnVal = jfc.showSaveDialog(jframe);

                    if (returnVal == JFileChooser.APPROVE_OPTION) {
                        File selFile = jfc.getSelectedFile();
                        //File svgfile = changeFileExt(shpfile, ".svg");
                        //URL svg = acquireURL(shpfile);
                        Path path = Paths.get(selFile.getPath());



                        if (Files.notExists(path, LinkOption.NOFOLLOW_LINKS)) {
                            FileOutputStream out = new FileOutputStream(new File(path.toString()));
                            out.close();
                        }

                        if (selFile == null) {
                            JOptionPane.showMessageDialog(jframe, "could not find file \"" + selFile + "\"", "Could not find file",
                                    JOptionPane.ERROR_MESSAGE);
                        }

                        try {

                            System.out.println("SvG File: " + selFile);
                            System.out.println();

                            if (Files.exists(path, LinkOption.NOFOLLOW_LINKS)) {
                                exportSHP.exportToSVG(new File(selFile.getPath()), jframe, map);
                            }
                        } catch (Exception ex) {
                            System.err.println("File exception for file: " + selFile + "\n" + ex);
                        }
                    }
                }
            });


            jframe.setVisible(true);

        } // End constructor
} // End class

Export to SVG Code

public class ExportShapefile {
    public void exportToSVG(File file, JMapFrame jframe, MapContent map)
                throws ParserConfigurationException {

            Dimension canvasSize = new Dimension(jframe.getMapPane().getSize());

            Document doc;

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

            db = dbf.newDocumentBuilder();

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

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

            SVGGraphics2D g2d = new SVGGraphics2D(ctx, true);

            g2d.setSVGCanvasSize(canvasSize);

            Rectangle outputArea = new Rectangle(g2d.getSVGCanvasSize());
            ReferencedEnvelope dataArea = map.getViewport().getBounds();

            jframe.getMapPane().getRenderer().paint(g2d, outputArea, dataArea);
            OutputStreamWriter osw = null;

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

                osw = new OutputStreamWriter(out, "UTF-8");
                g2d.stream(osw);

            } catch (FileNotFoundException | UnsupportedEncodingException |
                    SVGGraphics2DIOException ex) {
                System.err.println("IOException found: " + ex);
            } finally {
                if (osw != null) {
                    try {
                        osw.close();
                    } catch (IOException ex) {
                        System.err.println("IOException found: " + ex);
                    }
                }
            }
        }
}

pom.xml file (maven version)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!-- =========================================================== -->
<!--     Project Description                                     -->
<!-- =========================================================== -->
<groupId>com.mycompany</groupId>
<artifactId>ShpExportMaven</artifactId>
<version>14-SNAPSHOT</version>
<packaging>jar</packaging>

<name>ShpExportMaven</name>
<url>http://maven.apache.org</url>

<properties>
    <oracle>false</oracle>
    <allow.test.skip>true</allow.test.skip>
    <allow.test.failure.ignore>false</allow.test.failure.ignore>
    <extensive.tests>false</extensive.tests>
    <skip.image.tests>false</skip.image.tests>
    <interactive.tests>false</interactive.tests>
    <interactive.image>false</interactive.image>
    <online.skip.pattern>**/*OnlineTest.java</online.skip.pattern>
    <stress.skip.pattern>**/*StressTest.java</stress.skip.pattern>
    <test.exclude.pattern>disabled</test.exclude.pattern>
    <test.maxHeapSize>256M</test.maxHeapSize>
    <javadoc.maxHeapSize>1536M</javadoc.maxHeapSize>
    <test.forkMode>once</test.forkMode>
    <src.output>${basedir}/target</src.output>
    <imageio.ext.version>1.1.12</imageio.ext.version>
    <jaiext.version>1.0.3</jaiext.version>
    <netcdf.version>4.5.5</netcdf.version>
    <jt.version>1.3.1</jt.version>
    <jvm.opts></jvm.opts>
    <maven.build.timestamp.format>dd-MMM-yyyy HH:mm</maven.build.timestamp.format>
    <build.timestamp>${maven.build.timestamp}</build.timestamp>
    <fork.javac>true</fork.javac>
    <javac.maxHeapSize>256M</javac.maxHeapSize>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <postgresql.jdbc.version>9.4-1201-jdbc41</postgresql.jdbc.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.java.dev.jsr-275</groupId>
            <artifactId>jsr-275</artifactId>
            <version>1.0-beta-2</version>
        </dependency>

        <!-- Mathematic, geometries, SVG... -->
        <dependency>
            <groupId>com.vividsolutions</groupId>
            <artifactId>jts</artifactId>
            <version>1.13</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-svggen</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-awt-util</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-dom</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-util</artifactId>
            <version>1.6.1</version>
        </dependency>

        <!-- Java Advabnced Imaging (JAI) -->
        <dependency>
            <groupId>javax.media</groupId>
            <artifactId>jai_core</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>javax.media</groupId>
            <artifactId>jai_imageio</artifactId>
            <version>1.1</version>
        </dependency>

        <!-- ImageIO-Ext -->
        <dependency>
            <groupId>it.geosolutions.imageio-ext</groupId>
            <artifactId>imageio-ext-tiff</artifactId>
            <version>${imageio.ext.version}</version>
        </dependency>
        <dependency>
            <groupId>it.geosolutions.imageio-ext</groupId>
            <artifactId>imageio-ext-utilities</artifactId>
            <version>${imageio.ext.version}</version>
        </dependency>

        <!-- XML -->
        <dependency>
            <groupId>org.jdom</groupId>
            <artifactId>jdom</artifactId>
            <version>1.1.3</version>
        </dependency>

        <!-- Apache -->
        <dependency>
            <groupId>commons-pool</groupId>
            <artifactId>commons-pool</artifactId>
            <version>1.5.4</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.2</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

        <!-- Databases -->
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.3.0</version>
        </dependency>

    </dependencies>
</dependencyManagement>

<!-- Inherited by all modules -->
<dependencies>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-api</artifactId>
        <version>14.0</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-main</artifactId>
        <version>14.0</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-shapefile</artifactId>
        <version>14.0</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-render</artifactId>
        <version>14.0</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.geotools</groupId>
        <artifactId>gt-swing</artifactId>
        <version>14.0</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>batik</groupId>
        <artifactId>batik-awt-util</artifactId>
        <version>1.6-1</version>
    </dependency>
    <dependency>
        <groupId>batik</groupId>
        <artifactId>batik-dom</artifactId>
        <version>1.6-1</version>
    </dependency>
    <dependency>
        <groupId>batik</groupId>
        <artifactId>batik-svggen</artifactId>
        <version>1.6-1</version>
    </dependency>
    <dependency>
        <groupId>batik</groupId>
        <artifactId>batik</artifactId>
        <version>1.5</version>
    </dependency>
</dependencies>

<!-- =========================================================== -->
<!--     Build Configuration                                     -->
<!-- =========================================================== -->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>com.mycompany.shapefileexporter.mvn.ShapefileExporter</mainClass>
                    </manifest>
                </archive>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
    </plugins>
</build>

<!-- ================================================================== -->
<!--     Repositories. This is where Maven looks for dependencies. The  -->
<!--     Maven repository is implicit and doesn't need to be specified. -->
<!-- ================================================================== -->
<repositories>
    <repository>
        <id>central.maven.org</id>
        <name>Central Maven repository</name>
        <url>http://central.maven.org/maven2</url>
    </repository>
    <repository>
        <id>java.net-Public</id>
        <name>Maven Java Net Snapshots and Releases</name>
        <url>https://maven.java.net/content/groups/public/</url>
    </repository>


    <repository>
        <id>geosolutions</id>
        <name>geosolutions repository</name>
        <url>http://maven.geo-solutions.it/</url>
    </repository>

    <repository>
        <id>osgeo</id>
        <name>Open Source Geospatial Foundation Repository</name>
        <url>http://download.osgeo.org/webdav/geotools/</url>
    </repository>

    <repository>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <id>boundless</id>
        <name>Boundless Maven Repository</name>
        <url>http://repo.boundlessgeo.com/main</url>
    </repository>

</repositories>

<!-- =========================================================== -->
<!--     Plugin repositories.                                    -->
<!--     This is where Maven looks for plugin dependencies.      -->
<!-- =========================================================== -->
<pluginRepositories>
    <pluginRepository>
        <id>osgeo</id>
        <name>Open Source Geospatial Foundation Maven 2 Repository</name>
        <url>http://download.osgeo.org/webdav/geotools/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
    </pluginRepository> 
    <pluginRepository>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <id>boundless</id>
        <name>Boundless Maven Repository</name>
        <url>http://repo.boundlessgeo.com/main</url>
    </pluginRepository> 
    <pluginRepository>
        <id>sonatype-snapshots</id>
        <name>sonatype-snapshots</name>
        <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

Note: 'file' 'jframe' and 'map' are being declared and pointed to from another file.

Example of JMapFrame display:

GIS Display

Update: I got the code working, there were some issues with the pom.xml and versions of libraries I had.

1 Answer 1

4

Have a look at the code referenced in my blog post which shows how to do exactly this, including styling the layer.

Here is the actual code:

private void exportSVG(File file) {

Dimension canvasSize = new Dimension(frame.getMapPane().getSize());

Document document = null;

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
try {
    db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    return;
}

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

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

SVGGraphics2D g2d = new SVGGraphics2D(ctx, true);

g2d.setSVGCanvasSize(canvasSize);

Rectangle outputArea = new Rectangle(g2d.getSVGCanvasSize());
ReferencedEnvelope dataArea = map.getViewport().getBounds();

frame.getMapPane().getRenderer().paint(g2d, outputArea, dataArea);
OutputStreamWriter osw = null;
try {
    OutputStream out = new FileOutputStream(file);
    osw = null;

    osw = new OutputStreamWriter(out, "UTF-8");
    g2d.stream(osw);
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (SVGGraphics2DIOException 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();
    }
}
}
14
  • I am getting an File exception for file: /filepath/ java.lang.IllegalArgumentException: null incompatible with Global antialiasing enable key on line: OutputStreamWriter osw = null; Commented Oct 15, 2015 at 14:47
  • Scratch that, it's the line jframe.getMapPane().getRenderer().paint(g2d, outputArea, dataArea) Commented Oct 15, 2015 at 15:03
  • Fixed on master and 14.x github.com/geotools/geotools/commit/…
    – Ian Turton
    Commented Oct 15, 2015 at 15:46
  • what do I do with that? Commented Oct 15, 2015 at 16:02
  • Switch to GeoTools 14
    – Ian Turton
    Commented Oct 15, 2015 at 16:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.