Search code examples
kmlcesiumjs

Cesium JS exportKml question (produces invalid kml?)


If I call exportKml on an entity in Cesium, the KML exported doesn’t display properly in Google Earth. Any tips to what I’m doing wrong here? Thanks!

https://sandcastle.cesium.com/#c=bZJNb9swDIb/CuGTAyRyiq7A5rrBAnenDduwDQOGegdVZmwhtGRIcjKnyH+v/IWmXi+CSL4PRZEUWlkHB4lHNHAHCo+QopVNxX73vjALRG+nWjkuFZosWNxmKlOiJ0XL1XdNbaGVx4c8DJWTTqJlPM/Dp0wBKF5hDFmQejkc0DgpOEE9gkfpSqjRrGptPeg9JcqidBa4ykE3jvzDWbDsMo1MDH1egFKi4UaUbTwVnnLj/I2ra7YzurrHwiDarTG8DR8GCGD1Yc3Wy8l6d3VhrN7fXIauX4Xm1HD/uxidFXdoJKeXYjRpw9I/26+s++WW6pKHa3YzAePnYnCmwde+Hp0l+vHpvhed/Xke5pCpsesnratfOpzNYHELnWbMgv9qbdznisKnSRDPp7bcV6cYdpwsnhfMlajCXaNEN5fQoG3ILYbmdxugCRnpYgywfUVdVX1pwTJIrGsJN1PDPsqqex4aQyFjkcOqJt8wGz02Yo+OCWs7sJMm0SWa5PIAMr97YxlBELfWR3YN0U958nuySSKv/w8lzXOpim9+/Yi3nay82nwZnIyxJPLm26TTmh65mWV+Bg

const viewer = new Cesium.Viewer("cesiumContainer");

const cyanPolygon = viewer.entities.add({
  name: "Cyan vertical polygon with per-position heights and outline",
  polygon: {
    hierarchy: Cesium.Cartesian3.fromDegreesArray([
      -90.0,
      41.0,
      -85.0,
      43.0,
      -80.0,
      41.0
    ]),
    material: Cesium.Color.CYAN.withAlpha(0.5),
    outline: true,
    outlineColor: Cesium.Color.RED,
  },
});


viewer.zoomTo(viewer.entities); 

Cesium.exportKml({entities: viewer.entities,kmz: false}).then(function(result) {
  console.log(result.kml);
});

Exported entity displayed in Cesium Exported KML displayed in Google Earth

<kml
    xmlns="http://www.opengis.net/kml/2.2"
    xmlns:gx="http://www.google.com/kml/ext/2.2">
    <Document
        xmlns="">
        <Style id="style-1">
            <LineStyle>
                <width>1</width>
                <color>ff0000ff</color>
                <colorMode>normal</colorMode>
            </LineStyle>
            <PolyStyle>
                <color>80ffff00</color>
                <colorMode>normal</colorMode>
                <outline>1</outline>
            </PolyStyle>
        </Style>
        <Placemark id="fe4efe40-8939-446f-a1d4-f55becbaf2ba">
            <name>Cyan vertical polygon with per-position heights and outline</name>
            <visibility>1</visibility>
            <description></description>
            <styleUrl>#style-1</styleUrl>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>-90,40.99999999999999,0 -85,42.99999999999999,0 -80,41,0</coordinates>
                    </LinearRing>
                </outerBoundaryIs>
                <altitudeMode>absolute</altitudeMode>
            </Polygon>
        </Placemark>
    </Document>
</kml>

Solution

  • There are multiple issues with the generated KML. The altitudeMode is in the wrong order so it is not valid to the KML standard. This is a bug in the Cesium exportKml function.

    The last point in the polygon outer ring isn't the same as the first point and KML requires the last coordinate be the same as the first coordinate.

    In addition, the altitudeMode is absolute with a value of zero. AltitudeMode of clampToGround is probably a more reasonable value for it and setting tessellate=1.

    Manually making these changes to the KML allows it be displayed in Google Earth Pro as expected.

    Google Earth Pro screenshot