3

I have a problem importing an kml 2.1 file generated with geotools 17.1 into qgis 2.8.

Qgis refuses to import, google earth imports it and if I save it in google earth qgis is willing to import it.

ogrinfo says:

 ogrinfo test.kml 
 ERROR 4: ERROR Parseing kml test.kml :Invalid root element
 ERROR 4: ERROR Parseing kml test.kml :Invalid root element

after saving it with google earth:

 ogrinfo test-ge.kml 
 INFO: Open of `test-ge.kml'
       using driver `LIBKML' successful.
 1: test-ge

This is the kml generated by geottols

 <kml:kml xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:kml="http://earth.google.com/kml/2.1">
      <kml:Document id="featureCollection">
          <kml:Placemark id="guuid.27bed6fb-02ba-4536-8710-914fac29e236">
              <kml:name>"Grünliches etwas"</kml:name>
              <kml:description>DE-BB-Onlineeingabe null 2017-06-07
              </kml:description>
              <kml:Point>
                  <kml:coordinates>10.000000001438014,52.99999999818237
                  </kml:coordinates>
              </kml:Point>
          </kml:Placemark>            
      </kml:Document>
  </kml:kml>

This is the kml after saving it in google-eart:

 <?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 id="featureCollection">
         <name>test.kml</name>
         <Placemark id="guuid.27bed6fb-02ba-4536-8710-914fac29e236">
                 <name>&quot;Grünliches etwas&quot;</name>
                 <description>DE-BB-Onlineeingabe null 2017-06-07</description>
                 <Point>
                         <coordinates>10.00000000143801,52.99999999818237,0</coordinates>
                 </Point>
         </Placemark>
 </Document>
 </kml> 

If I remove the namespace from the getools variant ogrinfo and qgis excepts it.

Is the namespace really invalid in kml? Or is gdal/orginfo/qgis to strict?

EDIT

here is the code used:

@Override
public void export(Collection<Occurrence> occurrences, OutputStream os)
{
  SimpleFeatureCollection features = createSampleFeatures(occurrences, false);
  Encoder encoder = new Encoder(new KMLConfiguration());
  encoder.setIndenting(true);
  try
  {
 encoder.encode(features, KML.kml, os);
  }
  catch (IOException e)
  {
 String message = "Failure to encode KMLConfiguration.";
 throw new FloradbException(FloradbError.INTERNAL_ERROR, message + e);
  }
}

protected SimpleFeatureCollection createSampleFeatures(
 Collection<Occurrence> occurrences, boolean withLink)
{
  SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
  typeBuilder.setName("occurrences");
  typeBuilder.add("geometry", Geometry.class, DefaultGeographicCRS.WGS84);
  typeBuilder.add("name", String.class);
  typeBuilder.add("description", Object.class);
  SimpleFeatureType type = typeBuilder.buildFeatureType();

  SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);
  List<SimpleFeature> simpleFeatures = new ArrayList<>();
  CoordinateTransformerFactory factory = new CoordinateTransformerFactory();

  Iterator<Occurrence> iterator = occurrences.iterator();
  while (iterator.hasNext())
  {
 Occurrence occurrence = iterator.next();
 String wkt;
 if (occurrence.getSample().getPosition().getWktEpsg() == 4326)
 {
    wkt = occurrence.getSample().getPosition().getWkt();
 }
 else
 {
    CoordinateTransformer transformer = factory
      .getCoordinateTransformer(
        occurrence.getSample().getPosition().getWktEpsg(),
        4326);
    wkt = transformer
      .convert(occurrence.getSample().getPosition().getWkt());
 }

 WKTReader wktReader = new WKTReader();
 try
 {
    Geometry geom = wktReader.read(wkt);
    featureBuilder.add(geom);
 }
 catch (ParseException e)
 {
    String message = "Failure to convert wkt to Geometrie.";
    throw new FloradbException(FloradbError.INTERNAL_ERROR,
      message + e);
 }
 featureBuilder.add(occurrence.getTaxon().getName());
 String link;
 if(withLink)
 {
    link = "<a href=\"http://" + homeUrl + "/#!quellendetails//"
         + occurrence.getSample().getSurvey().getId() + "\">"
         + occurrence.getSample().getSurvey().getTitle() + "</a>";
 }
 else
 {
    link = occurrence.getSample().getSurvey().getTitle();
 }
 featureBuilder
       .add(link + " "
         + StringFormatter.getNullSafeStringRepresentation(
           occurrence.getSample().getSurvey().getAvailability())
         + " " + occurrence.getSample().getDate() + " Fund-UUID: "
         + occurrence.getUuid());
 simpleFeatures.add(featureBuilder
       .buildFeature("uuid." + occurrence.getUuid().toString()));
  }

  return DataUtilities.collection(simpleFeatures);
}
7
  • What happens if you delete the double quotas around the kml:name in the GeoTools variant?
    – user30184
    Commented Jul 5, 2017 at 9:40
  • @user30184 the same error - i've also removed the german umlaut
    – dve
    Commented Jul 5, 2017 at 9:43
  • can you add the code you used to write it?
    – Ian Turton
    Commented Jul 5, 2017 at 13:03
  • This is weird as both GDAL/OGR and GoogleEarth are using the same LIbKML (in theory)
    – Ian Turton
    Commented Jul 5, 2017 at 13:37
  • I can also confirm that the other KML driver can't read files with a kml: namespace either
    – Ian Turton
    Commented Jul 5, 2017 at 13:39

1 Answer 1

1

This seems to be a bug in the OGR KML drivers - I've raised a bug.

UPDATE This is fixed in GDAL 2.2.2

In the meantime a temporary work around is to remove the kml: from the output.

SimpleFeatureCollection featureCollection = DataUtilities.collection(list);

Encoder encoder = new Encoder(new KMLConfiguration());
encoder.setIndenting(true);
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
  encoder.encode(featureCollection, KML.kml, os );
  String out = os.toString().replaceAll("kml:", "");
  System.out.println(out);
} catch (Exception e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
} 

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.