Monday, 11 July 2011

Coding summary to have basic KML-to-SVG working

***********Summary***********

Some key questions have been answered:
·   XSLT can do the job for KML to SVG conversion
·   Math can be done in XSLT, e.g. round, divide, math:log, math:tan, min, max and so on.

Some challenges:
It is difficult to implement algorithms in XSLT. Variable and passing is not so clear to deal with. XSLT notations are difficult to understand. Sometimes it takes a long time to write 100 lines of code.

Tasks to do:
Fix the loops and coordinates importing for more KML objects. Currently, it can handle lineString object (some other objects seem very similar).

What I have done to get the basic conversion working.
1. Read a lot of source code in Inkscape
2. Read a lot of materials on XSLT and transformation
3. I have written code for between 20 and 30 examples for practice in the tutorials: http://www.java2s.com/Tutorial/XML/0100__XSLT-stylesheet/Catalog0100__XSLT-stylesheet.htm
5. The online kml2svg is good resources. I had email discussion and questions with kml2svg author. He shared useful information. He is willing to share his work to Inkscape, saying he made kml2svg mainly because Inkscape does not have this feature.
6. I tried the online kml2svg approach too, without using XSLT. I tried reading and parsing the KML file and loop through the elements and attributes. It is very difficult to do that in Inkscape. 
7. I broke Inkscape build and had crashes for several times. 

Mercator projection to convert longitude and latitude


Online KML viewer:
http://display-kml.appspot.com/

Useful links:
http://code.google.com/intl/fr/apis/kml/documentation/kmlreference.html
http://mathworld.wolfram.com/MapProjection.html

Thanks the author of online kml2svg tool (http://kml2svg.free.fr/index.php), Franklin, the conversion between KML and SVG is:

need to convert a earth coordinate (lattitude/longitude) into a screen position (x/y).

Mercator projection:
    // λ  = longitude
    // φ  = latitude
    φ = deg2rad (φ );
    λ = deg2rad (λ );
    x = λ;
    y = -log ( tan (pi() / 4 + φ / 2) , 2.718282 );


Some formulas are much more complex, some needs input references grids, etc. Mercator and Lambert projections are relatively simpler.

Working through conversion from KML to SVG using XSLT - Steps break-down

This post describes each step to convert the original KML file, s1-Coords.kml, to the result SVG file, s4-path.xml.svg. Each step has an intermediate file. (Intermediate files are useful for the testing stage, so that the algorithm can build up from small. At the end, the best would be only saving the END result.)

Start with the original file:

s1-Coords.kml
****************************************************************

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
  <Document>
<Folder>
<name>monde</name>
<open>1</open>
<Placemark>
<name>Sans titre - Trajet</name>
<styleUrl>#msn_ylw-pushpin00</styleUrl>
<LineString>
<tessellate>1</tessellate>
<coordinates>
2.328735169173783,50.99098347661589,0 1.939879599846932,50.95290354479823,0 6.07608623537034,46.38762461012988,0 6.102492885944002,46.5201900839377,0 6.356917438465915,49.47921006175431,0 4.176723982212366,50.03964519363036,0 2.464975417093001,51.00349748471994,0  </coordinates>
</LineString>
</Placemark>
</Folder>

  </Document>
</kml>

****************************************************************

Step 1: Extract all coordinates and split them to be point by point


s1-Coords.xml

****************************************************************
<?xml version="1.0" encoding="UTF-8"?>
<coords>
<point>
2.328735169173783,50.99098347661589,0</point>
<point>1.939879599846932,50.95290354479823,0</point>
<point>6.07608623537034,46.38762461012988,0</point>
<point>6.102492885944002,46.5201900839377,0</point>
<point>6.356917438465915,49.47921006175431,0</point>
<point>4.176723982212366,50.03964519363036,0</point>
<point>2.464975417093001,51.00349748471994,0</point>
</coords>


****************************************************************


Step 2: Split coordinates in each point to be longitude and latitude. 
Delete 0s, as svg is 2D. (Later, may keep the Zs for 3D objects in KML, but only parse 2D coordinates to SVG)

s2-Coords.xml
****************************************************************
<?xml version="1.0" encoding="UTF-8"?>
<coords>
<point>
<longitude>
2.328735169173783</longitude>
<latitude>50.99098347661589</latitude>
</point>
<point>
<longitude>1.939879599846932</longitude>
<latitude>50.95290354479823</latitude>
</point>
<point>
<longitude>6.07608623537034</longitude>
<latitude>46.38762461012988</latitude>
</point>
<point>
<longitude>6.102492885944002</longitude>
<latitude>46.5201900839377</latitude>
</point>
<point>
<longitude>6.356917438465915</longitude>
<latitude>49.47921006175431</latitude>
</point>
<point>
<longitude>4.176723982212366</longitude>
<latitude>50.03964519363036</latitude>
</point>
<point>
<longitude>2.464975417093001</longitude>
<latitude>51.00349748471994</latitude>
</point>
</coords>

****************************************************************

Step 3: Convert longitude and latitude to be x and y

s3-Coords.xml
****************************************************************
<?xml version="1.0" encoding="UTF-8"?>
<coords>
<point>
<x>0.040644095415756136</x>
<y>0.8899605353158819</y>
</point>
<point>
<x>0.03385728553205602</x>
<y>0.889295915138066</y>
</point>
<point>
<x>0.10604770863334066</x>
<y>0.809616767815344</y>
</point>
<point>
<x>0.10650859162241291</x>
<y>0.8119304717682893</y>
</point>
<point>
<x>0.11094913768608598</x>
<y>0.863575112132516</y>
</point>
<point>
<x>0.07289758419311611</x>
<y>0.8733565502607484</y>
</point>
<point>
<x>0.04302193627511825</x>
<y>0.8901789459561932</y>
</point>
</coords>

****************************************************************

Step 4: Form result SVG file.
Write x and y for each point in the above xml to the path object in SVG

s4-path.xml.svg
****************************************************************
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
    width="20"
    height="20"
>

<path style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-opacity:1.0" d="M 0.040644095415756136 0.8899605353158819 L 0.03385728553205602 0.889295915138066 L 0.10604770863334066 0.809616767815344 L 0.10650859162241291 0.8119304717682893 L 0.11094913768608598 0.863575112132516 L 0.07289758419311611 0.8733565502607484 L 0.04302193627511825 0.8901789459561932 L "/>
</svg>

****************************************************************


Working through conversion from KML to SVG using XSLT - Sample results

Working through conversion from KML to SVG using XSLT - Sample results

I am posting 3 figures to show the results so far.

The first figure is a screenshot of converted SVG file loaded in Inkscape. It is a simple path object. 



The second figure shows a KML file with Asia and Africa map contours is converted SVG file loaded in Inkscape. It is a more complex path. Its transformation of latitude is not correct, although all KML coordinates (longitude and latitude) are converted to x and y values of SVG path objects.


The third figure shows correct latitude transformation. It is a SVG file converted from a the same KML as in the second figure, but using an online kml2svg converter. (http://kml2svg.free.fr/)



What I will do is to fix the latitude transformation. 


I am adding one more figure as below. It is the original KML file viewed in Google Map.


Wednesday, 6 July 2011

How transformations can work with xslt


need to apply the transformations to the XY coordinates

looked at some kml and converted svg samples, done by other people.
the coordinates are not the same. and they did transformation for them.
The transformations need to be understood.

need Math on XSLT.

is math in xslt doable? If so, how can it be added?
if using Python, what part of the conversion work can be done by Python?
If you decide to use python, you will use lxml to read KML and write SVG, abstracting the XML notation. The math will be simple python expressions.


Math on XSLT
XSLT may suppot more math and more complex transformations

Try xslt and review sample code


try xslt and review sample code
aisvg.xslt


can convert kml to svg similar with aisvg.xslt
It may be easier with python

Understanding the logic behind the conversion using xslt
http://en.wikipedia.org/wiki/XSLT

xslt recognizes the pieces of a XML and output a text, and that may be other XML

need to recognize a direct translation between both that cam be made easily...

Extensions and dxf2svg example



Need to know about importing extensions.

dxf2svg in Inkscape is a relevant example to the kml2svg work.
 http://bazaar.launchpad.net/~inkscape.dev/inkscape/trunk/files/head:/src/extension/dxf2svg/

kml2svg can have less code than dxf2svg.

KML importing


working on the kml2svg project.

how the KML importing and parsing could be done, in the large Inkscape code.

look at importing KML first.
because it is XML based, I think that there are somethings available in inkscape, so that I don't need to rewrite xml parsing.

Sunday, 12 June 2011

Dxf2svg in Inkscape

Dxf2svg in Inkscape


The source code is at: 
Src/extension/dxf2svg


It needs .inx files, which are needed for the kml2svg work. 

The dxf_import.inx is at ../Inkscape/share/extensions


**************Quoted Readme of Dxf2svg*****************

Readme
1.  Run make and copy dxf2svg to somewhere that is looked at by the PATH variable.  Or add the current directory to your path
2.  Copy the dxf_import.inx to ../Inkscape/share/extensions
3.  Run Inkscape
4.  Click on open or import and the dxf option should be there




KML import thoughts

Recently, I am doing code review in Inkscape and experimenting transformations for converting KML polygon path to SVG. I have studied KML and SVG files further. I made several simple KML test files to try and see the conversion process. 

My first goal is to import a simple KML file and convert it to SVG.


I am thinking to do importing a simple KML file and converting it to SVG. In Inkscape, it seems complex. I am trying to find out: 
  1. How to implement kml2svg in Inkscape, or kml import, similar to other file format import.
  2. How transformations from kml to svg is done, and what rules they have. I may need to define many things, such as canvas, origin, anchor of objects/paths, dimensions and so on. 
  3. What libraries are needed. 
I have reviewed Inkscape code base and the Java KML conversion program. I should be able to write the Java program in C++. I need to write kml-import, and thought good examples in Inkscape should be available. 

A question: 
Does anyone know kml-import is similar to which file format import? I have seen dxf2svg as an good example. But kml2svg starts with importing an XML file...

Online kml2svg convertor

I have tried and used the kml2svg converter: 
This tool is a testing version only. It is useful to try things but is not complete with limitations. 

Its Mercator projection was discussed in:


********************Quoted notes***************************


This tool converts google earth files(kml and kmz) into vectorial SVG files,
usable in Inkscape, Illustrator and other software.

kml2svg.free.fr converts most of the elements that contains a GE document:
  • folders
  • placemarks (points, lines, polygones, multigeometries and embeded images)
  • tours
  • Sketchup ressources (depending of the ressources..)
using the desired earth projection:
  • Mercator,
  • Miller,
  • Cylindrical Equal-Area (Lambert, Behrmann, Tristan Edwards, Peters, Galls, Balthasart),
  • Cylindrical Equidistant,
  • Sinusoidal,
  • Van der Grinten I,
  • Polyconic,
  • Albers Equal-Area Conic,
  • Conic Equidistant,
  • Bonne,
  • Lambert Conformal Conic,
  • Lambert Azimuthal Equal-Area,
  • Cassini


Conversion restrictions :
  • It possible to convert only file originally converted by kml2svg, otherwise it is impossible to positionate correctly the draw on the earth surface.
  • I recommand the use of INKSCAPE software to edit SVG file befor re-import.
  • Only works with MERCATOR projection at this time
  • The KML/KMZ format is mor restrictive than SVG, only few objects can be converted :
    • Text is converted in placemark
    • Lines are converted into paths.
    • Polygons and rectangles are converted into polygons
    • Groups and layers are converted into folders
    • Dash & dot lines are converted into plain line

Saturday, 28 May 2011

Reading about XML and DOM


.xsd   XML Schema Definition
XML
XML is case sensitive and does not ignore white space.
Root
The root element is the only element in an XML document that does not have a parent.
Element: An element node can contain other elements.1) two branches meet. 2) if it is an empty elements, it would be a leaf node.
Attribute: XPath treats attributes as separate nodes from their element hosts. An attribute is like an element that contains only text.
Text
Comment
Processing instruction
Namespace

Makeup and data
The makeup symbols are delineated by angle brackets(<>)

The standard way for searching through XML documents for particular nodes is called XPath,

Parser: The two basic means to parse XML are: tree and stream.
a tree-based parser
Tree style parsing involves loading the entire XML document into memory. The tree file structure allows for random access to the document's elements and for editing of the XML. Examples of tree-type parsing include the DOM and SimpleXML.

DOM (Document Object Model)
1.       The DOM is the W3C DOM specification that you work with in a browser and manipulate with JavaScript. use of the DOM to create an XML string and XML document, formatted for your viewing pleasure.
2.       DOM is a W3C standard, which gives the DOM a lot of authority with developers due to its consistency with other programming languages. Because the DOM builds a tree of the entire document, it uses a lot of memory and processor time.

a SimpleXMLElement object ß> a DOMElement object

SimpleXML
1.    Provided that the XML document isn't too complicated, too deep, and lacks mixed content, SimpleXML is simpler to use than the DOM, as its name implies.
2.    The SimpleXML extension is the tool of choice for parsing an XML document. (easier than DOM)
Extracting multiple instances of an element, access element attributes  
foreach ($xml->book as $book)
To compare an element or attribute with a string or pass it into a function that requires a string, you must cast it to a string using (string). Otherwise, by default, PHP treats the element as an object
easily add children and attributes.
Stream-based parsers: XMLReader and (Simple API for XML) SAX are stream parses

Learning XSLT

*********************************
Some notes on XSLT

XSLT (Doug Tidwell O'Reilly Media, Inc., 2008)
As mention in the book:
It provides a flexible, powerful language for transforming XML documents into something else, such as…, a Scalable Vector Graphics (SVG) file, … So it may be a choice to use XSLT.

The Extensible Stylesheet Language Family (XSL)
XSL is a family of recommendations for defining XML document transformation and presentation.
XSL Transformations (XSLT):a language for transforming XML;
The XML Path Language (XPath):an expression language used by XSLT (and many other languages) to access or refer to parts of an XML document;
XSL Formatting Objects (XSL-FO):an XML vocabulary for specifying formatting semantics.

XSLT (the extensible stylsheet Language for transformations) is a flexible, powerful, yet relatively simple language capable of processing XML


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