CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.82k stars 3.46k forks source link

Extruded polygons with per-position heights #1242

Closed mramato closed 10 years ago

mramato commented 10 years ago

KML allows you to specify an extruded closed polygon where each of the points on the polygon have their own height value. We are not currently able to do this with geometry and appearances. In order to fully support KML, we'll need to be able to match them. Unfortunately, KML is a little too open-ended about what to do so we will probably never be able to match it 100%.

For example, the below KML snippet creates a closed wedge. (copy and pased into a new .kml file and it will load in Google Earth)

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Placemark>
  <name>LinearRing.kml</name>
  <Polygon>
    <altitudeMode>relativeToGround</altitudeMode>
    <extrude>1</extrude>
    <outerBoundaryIs>
      <LinearRing>
        <coordinates>
          -122.365662,37.826988,10
          -122.365202,37.826302,100
          -122.364581,37.82655,100
          -122.365038,37.827237,10
          -122.365662,37.826988,10
        </coordinates>
      </LinearRing>
    </outerBoundaryIs>
  </Polygon>
</Placemark>
</kml>

image

While the above example creates a closed object, the below example automatically decides to leave it open. My guess is they try to triangulate the top polygon, but if it fails they just leave it open.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Placemark>
  <name>LinearRing.kml</name>
  <Polygon>
    <altitudeMode>relativeToGround</altitudeMode>
    <extrude>1</extrude>
    <outerBoundaryIs>
      <LinearRing>
        <coordinates>
          0.0,0.0,50000
          0.5,0.0,100000
          1.0,0.0,50000
          1.0,0.5,100000
          1.0,1.0,50000
          0.5,1.0,100000
          0.0,1.0,50000
          0.0,0.5,100000
          0.0,0.0,50000
        </coordinates>
      </LinearRing>
    </outerBoundaryIs>
  </Polygon>
</Placemark>
</kml>

image

But If I take the above example and move the heights closer together, it creates a closed object again.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Placemark>
  <name>LinearRing.kml</name>
  <Polygon>
    <altitudeMode>relativeToGround</altitudeMode>
    <extrude>1</extrude>
    <outerBoundaryIs>
      <LinearRing>
        <coordinates>
          0.0,0.0,5000
          0.5,0.0,10000
          1.0,0.0,5000
          1.0,0.5,10000
          1.0,1.0,5000
          0.5,1.0,10000
          0.0,1.0,5000
          0.0,0.5,10000
          0.0,0.0,5000
        </coordinates>
      </LinearRing>
    </outerBoundaryIs>
  </Polygon>
</Placemark>
</kml>

image

The last example definitely has some artifacts in Google Earth, so they aren't perfect either.

pjcozzi commented 10 years ago

GE follows the KML spec. From Page 18:

NOTE: The control points of every kml:LinearRing must lie on a common plane.

I suspect that even that simple wedge top doesn't fit a plane, but it is close enough that a common plane is found by their code.

@hpinkos I think we can add an option to PolygonGeometry that either fits the curvature of the ellipsoid at a given height (what we do now) or keeps the original heights and does not subdivide, which we would use for KML when all the heights do not match.

pjcozzi commented 10 years ago

CC @bagnell for other ideas.