3

I'm trying to import a mkl file with jak but i get the following error:

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://earth.google.com/kml/2.2", local:"kml"). Expected elements are ... and then a big list

Does anyone else run into this problem?

This is the code:

final Kml kml = Kml.unmarshal(new File("../data/Eemskanaal.kml"));
        final Placemark placemark = (Placemark) kml.getFeature();
        Point point = (Point) placemark.getGeometry();
        List<Coordinate> coordinates = point.getCoordinates();
        for (Coordinate coordinate : coordinates) {
            System.out.println(coordinate.getLatitude());
            System.out.println(coordinate.getLongitude());
            System.out.println(coordinate.getAltitude());
        }

And this is the kml file:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
  <name>BU00100107 Verspreide huizen Eemskanaal (ten zuiden)</name>
  <description><![CDATA[description]]></description>
  <Placemark>
    <name>BLA!</name>
    <description><![CDATA[]]></description>
    <styleUrl>#style1</styleUrl>
    <Polygon>
      <outerBoundaryIs>
        <LinearRing>
          <tessellate>1</tessellate>
          <coordinates>
            6.941796,53.314914,0.000000
            6.942705,53.310923,0.000000
            6.952713,53.305394,0.000000
            6.954853,53.300262,0.000000
            6.954239,53.296317,0.000000
            6.962271,53.295483,0.000000
            6.995900,53.287338,0.000000
            6.995013,53.285264,0.000000
            6.996842,53.281429,0.000000
            6.991748,53.278255,0.000000
            6.990729,53.275234,0.000000
            6.988361,53.274477,0.000000
            6.990120,53.271780,0.000000
            6.984540,53.272709,0.000000
            6.984543,53.274393,0.000000
            6.980317,53.274404,0.000000
            6.975829,53.272503,0.000000
            6.974816,53.271125,0.000000
            6.963342,53.271937,0.000000
            6.955082,53.265909,0.000000
            6.945183,53.269634,0.000000
            6.940684,53.273351,0.000000
            6.935942,53.273875,0.000000
            6.934392,53.276351,0.000000
            6.929104,53.272181,0.000000
            6.909544,53.265952,0.000000
            6.908803,53.269015,0.000000
            6.909151,53.278897,0.000000
            6.888166,53.279161,0.000000
            6.887788,53.279639,0.000000
            6.886750,53.280950,0.000000
            6.886729,53.280977,0.000000
            6.888260,53.281856,0.000000
            6.895912,53.286254,0.000000
            6.892976,53.288089,0.000000
            6.891571,53.290803,0.000000
            6.887323,53.298046,0.000000
            6.887729,53.309725,0.000000
            6.887583,53.309816,0.000000
            6.888683,53.311891,0.000000
            6.893966,53.313119,0.000000
            6.924732,53.311548,0.000000
            6.929655,53.312392,0.000000
            6.934810,53.315353,0.000000
            6.941796,53.314914,0.000000
          </coordinates>
        </LinearRing>
      </outerBoundaryIs>
    </Polygon>
    <Polygon>
      <outerBoundaryIs>
        <LinearRing>
          <tessellate>1</tessellate>
          <coordinates>
            6.905549,53.283453,0.000000
            6.908790,53.282516,0.000000
            6.912146,53.283305,0.000000
            6.916480,53.287575,0.000000
            6.916764,53.288072,0.000000
            6.915251,53.288369,0.000000
            6.915097,53.290097,0.000000
            6.912526,53.292361,0.000000
            6.908052,53.290971,0.000000
            6.905569,53.288875,0.000000
            6.905549,53.283453,0.000000
          </coordinates>
        </LinearRing>
      </outerBoundaryIs>
    </Polygon>
</Placemark>
</Document>
</kml>

Any other solutions are also welcome

clankill3r
  • 9,146
  • 20
  • 70
  • 126

3 Answers3

2

Here is my quick and dirty way :)

public static Kml getKml(InputStream is) throws Exception {
    String str = IOUtils.toString( is );
    IOUtils.closeQuietly( is );
    str = StringUtils.replace( str, "xmlns=\"http://earth.google.com/kml/2.2\"", "xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\"" );
    ByteArrayInputStream bais = new ByteArrayInputStream( str.getBytes( "UTF-8" ) );
    return Kml.unmarshal(bais);
}
Ilya
  • 21
  • 2
1

I am unfamiliar with Jak, but if you're using the OGC Schema, the namespace is different. You have

http://earth.google.com/kml/2.2

The OGC namespace is

http://www.opengis.net/kml/2.2

The Google extension schema uses

http://www.google.com/kml/ext/2.2

as well. The namespace you're using was used by Google before KML was given to the OGC as an open standard.

Mano Marks
  • 8,761
  • 3
  • 27
  • 28
  • I know it's wrong but i didn't make the files and i have more then 1700 of them... What do you use instead of jak? – clankill3r Feb 08 '12 at 22:50
  • I'm not actually a Java guy really, but you could use the Java XML libraries to pre-process an XML doc, check the namespace and change it if necessary before handing it off to Jak. – Mano Marks Feb 08 '12 at 22:59
  • i looked at jaxb which looks good, but it's quite complex to start with since my school assignments aren't that long. – clankill3r Feb 08 '12 at 23:00
  • Yeah, Jaxb is heavyweight. Here's a couple of options: Just use DOM parsing, something like this: http://www.java-samples.com/showtutorial.php?tutorialid=152. Or, easier, read the file in as text and do a regex to find http://earth.google.com/kml/2.2 and change it to the right namespace. Then save it and re-process it using Jak – Mano Marks Feb 08 '12 at 23:18
0

The namespace is incorrect, but if you have 1700 files and this is the only problem, you might consider simply using the two-argument form of Kml.unmarshal(File file, boolean validate).

final Kml kml = loadXMLFile("../data/Eemskanaal.kml");
private static Kml loadXMLFile(String path) {
        Kml kml = null;
        try {
            kml = Kml.unmarshal(path);
        } catch (RuntimeException ex) {
            kml = Kml.unmarshal(new File(path), false);
        }
        return kml;
    }

I've also used the following cheezy perl script to correct my files.

$ cat ~/bin/fixxmlns
#!/usr/bin/perl

for (@ARGV) {

    open (FH,"<$_");
    open (NFH,">$_.x");

    $look = 1;
    while ($r = <FH>) {
        if ($look && $r =~ /earth.google.com/) {
            $r = qq{<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:gx="http://www.google.com/kml/ext/2.2">\n};
            $look = 0;
            }
        print NFH $r;
    }
    close (NFH);
    close (FH);
    rename("$_", "$_.orig");
    rename("$_.x", "$_");
}
$ fixxmlns *.kml
$ find parentdir -name "*.kml" -print0 | xargs -0 fixxmlns
Drew Gonczi
  • 149
  • 1
  • 4