Saturday, 28 May 2011

Code Review of Java SVG to KML Converter

Code Review of Java SVG to KML Converter

I found on Inkscape idea page that tbrugz mentioned his SVG to KML convertor in Java. It seems useful to look at.

***********
2010-08-12 - tbrugz
Hi, I´ve developed an initial converter from SVG to KML in Java. It currently converts polygons, given the output "bounds" (north, east, south, west). Infos and hg repository is at https://bitbucket.org/tbrugz/kmlutils/. Feel free to improve on it
***********

*********************************
Several features of this SVG to KML Converter are:
1.    Use the Java XML parser to load SVG
2.    Parse the SVG root and loop through all elements
3.    Only deal with polygons path elements
4.    Apply transformations to SVG polygons to be KML
5.    Save to a KML file

*********************************
Useful for SVG to KML conversion in Inkscape
1.    Need to load and parse SVG, which should exist
2.    Understand the transformations of polygon path coordinates
3.    Write the transformation routine in C++ in Inkscape
4.    Save KML similarly to saving it in Java.


*********************************
Some detail notes on the source code
the algorithm to change coordinates form SVG to KML, seems like:


The author override public void startElement (seems to be called at the begining)
in this function ,call procPolygon, which read in points regarding "L", "M", "Z"
and at the same time call setXYMaxMin(point);(which update inputBounds),
call setPolygonCentre.
 the formula for the coordinates transformation is that:

                        float X = (((p.x - inputBounds[1]) / XinputInterval ) * XoutputInterval ) + outputBounds[1];
                        float Y = (((p.y - inputBounds[3]) / YinputInterval ) * YoutputInterval ) + outputBounds[3];

The following thing is about the inputBounds and outputBounds, and note that
setXYMaxMin(point) will also change the inputBounds:

(In Root.java)

public class Root extends CompositeImpl {

            public float maxX = Float.MIN_VALUE, minX = Float.MAX_VALUE, maxY =
Float.MIN_VALUE, minY = Float.MAX_VALUE;
           
}

related to
float[] inputBounds = {root.maxX, root.minX, root.maxY, root.minY};

and

float[] outputBounds = {outMaxX, outMinX, outMaxY, outMinY,};

where

                        float outMaxX = Float.parseFloat(prop.getProperty("svg2kml.maxX"));
                        float outMinX = Float.parseFloat(prop.getProperty("svg2kml.minX"));
                        float outMaxY = Float.parseFloat(prop.getProperty("svg2kml.maxY"));
                        float outMinY = Float.parseFloat(prop.getProperty("svg2kml.minY"));

(In svg2kml.properties)

svg2kml.maxX=-49.6917
svg2kml.minX=-57.64777

# inverting maxY with minY inverts the vertical orientation of the KML, which is the
desired effect,
# since SVG and KML have opposite vertical orientations
svg2kml.maxY=-33.7515
svg2kml.minY=-27.08

1 comment:

  1. The java code convert SVG files into KML files, it (svg2kml) use tree-based parse to do the job, while we would like to use event-based(stream-based) parsed, because there is no need to translate all features in KML to SVG, since inkscape could only handle part of them.
    Svg2kml was implemented by include SAXParser (the extensions to standard java package)

    Using C++ to perform XSL Transformations (XSLT) requires DOM.


    The extensions to standard java belong in the javax.* packages. They are not included in the JDK or JRE. You must download them separately. They include things like: Servlets and Enterprise JavaBeans, JAF, JavaMail and Swing.

    ReplyDelete