Drawing 3D polygons

Hello,

Point and line geometries with 3D coordinates are drawn in 3D.
However, 3D polygons are drawn on the ellipsoid. See sandcastle example at the bottom.

Is it the expected behaviour?

I expected the case where all Z coordinates are identical to be handled,
the polygon being translated from the ellipsoid.
With PolygonGeometry, I may use a modelMatrix or set height/extrudedHeight.
With GeoJson, is there a workaround?

BR,

Guillaume

Sandcastle example - point and line are 3D, polygon is not

//Create the viewer
var viewer = new Cesium.Viewer('cesiumContainer');
Cesium.viewerEntityMixin(viewer);
  var geo = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [102.0, 0.6, 1e5]
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [102.0, 0.0, 1e5], [103.0, 1.0, 1e3], [104.0, 0.0, 1e5], [105.0, 1.0, 1e2]
        ]
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [100.0, 0.0, 1e6], [101.0, 0.0, 1e6], [101.0, 1.0, 1e6], [100.0, 1.0, 1e6],
            [100.0, 0.0, 1e6]
          ]
        ]
      }
    }
  ]
};
  
var dataSource = new Cesium.GeoJsonDataSource();
viewer.dataSources.add(dataSource);
dataSource.load(geo);

//Reset the scene when switching demos.
Sandcastle.reset = function() {
  var camera = viewer.scene.camera;
  camera.lookAt(Cesium.Cartesian3.fromDegrees(100, 0, 5000000),
      Cesium.Cartesian3.fromDegrees(100, 0, 0), Cesium.Cartesian3.UNIT_Z);
};

Hello,
I fear it's the expected behaviour.
see GeoJsonDataSource source code here https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/DataSources/GeoJsonDataSource.js#L210 where a polygonGraphics is generated for each polygon from your geojson. The initialisation use only positions parameters and don't define _perPositionHeight parameter like in PolygonGeometry (see http://cesiumjs.org/Cesium/Build/Documentation/PolygonGeometry.html )

You should set perPositionHeight for each polygon. My snippet should help you:

//Create the viewer
var viewer = new Cesium.Viewer('cesiumContainer');
Cesium.viewerEntityMixin(viewer);
  var geo = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [102.0, 0.6, 1e5]
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [102.0, 0.0, 1e5], [103.0, 1.0, 1e3], [104.0, 0.0, 1e5], [105.0, 1.0, 1e2]
        ]
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [100.0, 0.0, 1e6], [101.0, 0.0, 1e6], [101.0, 1.0, 1e6], [100.0, 1.0, 1e6],
            [100.0, 0.0, 1e6]
          ]
        ]
      }
    }
  ]
};

var dataSource = new Cesium.GeoJsonDataSource();
viewer.dataSources.add(dataSource);
var promise=dataSource.load(geo);

Cesium.when(promise,function(){
    var entities=dataSource.entities.entities;
    console.log(entities.length);
    for (var i=0;i<entities.length;i++){
        var polygon=entities[i].polygon;
        console.log(i);
        if(Cesium.defined(polygon)){
          polygon.perPositionHeight=new Cesium.ConstantProperty(true);
        }
        
    }
});

//Reset the scene when switching demos.

  var camera = viewer.scene.camera;
  camera.lookAt(Cesium.Cartesian3.fromDegrees(100, 0, 5000000),
      Cesium.Cartesian3.fromDegrees(100, 0, 0), Cesium.Cartesian3.UNIT_Z);

Hello,

Thank you for the workaround.
I am wondering why the perPositionHeight is not the default.

On the circle geometry it would also make sense to use the Z coordinate
of the center, if it is present.

Guillaume

Hello,
the workaround for polygon could be easier if we could define a template for polygon. Today this template is a private attribute (unavailable in GeoJsonDataSource API) : see https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/DataSources/GeoJsonDataSource.js#L54 .
If this template is available, the workaroud should be:

var dataSource = new Cesium.GeoJsonDataSource();
dataSource.polygonTemplate.perPositionHeight=new Cesium.ConstantProperty(true)
viewer.dataSources.add(dataSource);
dataSource.load(geo);

Maybe a suggestion for Cesium team...

I agree with you about circle geometry, instead we must use height parameter!!

Guillaume,

I think you are right and this is a bug. GeoJsonDataSource was written before we had Geometry & Appearances or the perPositionHeight options so we never took it into account. It should be easy to detect when height values are being used and automatically default per-position height to true when that is the case. I should have a pull request with a fix soon, I’ll keep you posted.

Thanks for the sample code and bug report.

Matt

This is fixed and will be in the Oct 1st release, see https://github.com/AnalyticalGraphicsInc/cesium/pull/2148 for details.

Thanks again.

Hello Matthew,

Thank you for the GeoJson fix.

When using plain PolygonGeometry with 3D positions, the default is still to
draw in 2D.

What about forcing the perPositionHeight option when we have 3D coordinates?

Guillamu

All of our geometries draw onto the surface by default because it is the most common use case in our experience. Now the logical question is why not just set perPositionHeight to true by default and if the heights are all 0 then it will be on the surface anyway? While I’m not the best person to answer that question but I believe it is because we take two different code paths depending on if perPositionHeight is true so the results would actually be different. For something to look good on the surface we actually need to do more work when creating the geometry. Patrick, Dan, or Hannah can hopefully chime in and provide some better insight.

This will also change when we start draping polygons on terrain; so the difference will be much more well-defined when that happens.

Thank you for the details.

Actually, polylines are automatically drawn in 3D when they have
3D coordinates as 'positions'. There is a sandcastle example at:

Though not a geometry, it is also the case for Labels and Billboards.

Guillaume

Guillaume, i was looking at olcesium and then found this post since I am trying to draw some polygons in 3d.

Each vertex have pos + height above MSL in ol. Do you have any advice how i would get to drawing these polygons in 3d.