# Drawing 3D polygons

**URL:** <https://community.cesium.com/t/drawing-3d-polygons/1516>\
**Category:** CesiumJS\
**Created:** [September 23, 2014, 10:44am UTC](https://community.cesium.com/t/drawing-3d-polygons/1516 "2014-09-23T10:44:04Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Guillaume\_Beraudo](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/guillaume_beraudo/32/2985_2.png) [@Guillaume\_Beraudo](https://community.cesium.com/u/Guillaume_Beraudo)\
**Post date:** [September 23, 2014, 10:44am UTC](https://community.cesium.com/t/drawing-3d-polygons/1516/1 "2014-09-23T10:44:04Z")

</div>

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);  
&nbsp;&nbsp;var geo = {  
&nbsp;&nbsp;"type": "FeatureCollection",  
&nbsp;&nbsp;"features": [  
&nbsp;&nbsp;&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Feature",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"geometry": {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Point",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"coordinates": [102.0, 0.6, 1e5]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;},  
&nbsp;&nbsp;&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Feature",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"geometry": {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "LineString",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"coordinates": [  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[102.0, 0.0, 1e5], [103.0, 1.0, 1e3], [104.0, 0.0, 1e5], [105.0, 1.0, 1e2]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;},  
&nbsp;&nbsp;&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Feature",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"geometry": {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Polygon",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"coordinates": [  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[100.0, 0.0, 1e6], [101.0, 0.0, 1e6], [101.0, 1.0, 1e6], [100.0, 1.0, 1e6],  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[100.0, 0.0, 1e6]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;]  
};  
&nbsp;&nbsp;  
var dataSource = new Cesium.GeoJsonDataSource();  
viewer.dataSources.add(dataSource);  
dataSource.load(geo);

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

---

<div class="post-metadata">

**Author:** ![abdou](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/abdou/32/2012_2.png) [@abdou](https://community.cesium.com/u/abdou)\
**Post date:** [September 23, 2014, 9:22pm UTC](https://community.cesium.com/t/drawing-3d-polygons/1516/2 "2014-09-23T21:22:12Z")

</div>

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](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](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);  
&nbsp;&nbsp;var geo = {  
&nbsp;&nbsp;"type": "FeatureCollection",  
&nbsp;&nbsp;"features": [  
&nbsp;&nbsp;&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Feature",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"geometry": {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Point",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"coordinates": [102.0, 0.6, 1e5]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;},  
&nbsp;&nbsp;&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Feature",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"geometry": {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "LineString",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"coordinates": [  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[102.0, 0.0, 1e5], [103.0, 1.0, 1e3], [104.0, 0.0, 1e5], [105.0, 1.0, 1e2]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;},  
&nbsp;&nbsp;&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Feature",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"geometry": {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"type": "Polygon",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"coordinates": [  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[100.0, 0.0, 1e6], [101.0, 0.0, 1e6], [101.0, 1.0, 1e6], [100.0, 1.0, 1e6],  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[100.0, 0.0, 1e6]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;]  
};

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

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

//Reset the scene when switching demos.

&nbsp;&nbsp;var camera = viewer.scene.camera;  
&nbsp;&nbsp;camera.lookAt(Cesium.Cartesian3.fromDegrees(100, 0, 5000000),  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cesium.Cartesian3.fromDegrees(100, 0, 0), Cesium.Cartesian3.UNIT\_Z);

---

<div class="post-metadata">

**Author:** ![Guillaume\_Beraudo](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/guillaume_beraudo/32/2985_2.png) [@Guillaume\_Beraudo](https://community.cesium.com/u/Guillaume_Beraudo)\
**Post date:** [September 24, 2014, 9:18am UTC](https://community.cesium.com/t/drawing-3d-polygons/1516/3 "2014-09-24T09:18:20Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![abdou](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/abdou/32/2012_2.png) [@abdou](https://community.cesium.com/u/abdou)\
**Post date:** [September 24, 2014, 10:30am UTC](https://community.cesium.com/t/drawing-3d-polygons/1516/4 "2014-09-24T10:30:33Z")

</div>

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](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!!

---

<div class="post-metadata">

**Author:** ![Matt\_Amato](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/matt_amato/32/1993_2.png) [@Matt\_Amato](https://community.cesium.com/u/Matt_Amato)\
**Post date:** [September 24, 2014, 1:00pm UTC](https://community.cesium.com/t/drawing-3d-polygons/1516/5 "2014-09-24T13:00:56Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Matt\_Amato](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/matt_amato/32/1993_2.png) [@Matt\_Amato](https://community.cesium.com/u/Matt_Amato)\
**Post date:** [September 24, 2014, 1:29pm UTC](https://community.cesium.com/t/drawing-3d-polygons/1516/6 "2014-09-24T13:29:59Z")

</div>

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

Thanks again.

---

<div class="post-metadata">

**Author:** ![Guillaume\_Beraudo](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/guillaume_beraudo/32/2985_2.png) [@Guillaume\_Beraudo](https://community.cesium.com/u/Guillaume_Beraudo)\
**Post date:** [September 24, 2014, 1:48pm UTC](https://community.cesium.com/t/drawing-3d-polygons/1516/7 "2014-09-24T13:48:02Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Matt\_Amato](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/matt_amato/32/1993_2.png) [@Matt\_Amato](https://community.cesium.com/u/Matt_Amato)\
**Post date:** [September 24, 2014, 1:56pm UTC](https://community.cesium.com/t/drawing-3d-polygons/1516/8 "2014-09-24T13:56:20Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Guillaume\_Beraudo](https://sea2.discourse-cdn.com/cesium/user_avatar/community.cesium.com/guillaume_beraudo/32/2985_2.png) [@Guillaume\_Beraudo](https://community.cesium.com/u/Guillaume_Beraudo)\
**Post date:** [September 24, 2014, 2:10pm UTC](https://community.cesium.com/t/drawing-3d-polygons/1516/9 "2014-09-24T14:10:41Z")

</div>

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:

> **[Cesium Sandcastle](https://sandcastle.cesium.com/index.html?src=Polyline.html)**
>
> The Cesium Sandcastle provides an interactive environment for testing Cesium code.

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

Guillaume

---

<div class="post-metadata">

**Author:** ![Poul\_Sorensen](https://avatars.discourse-cdn.com/v4/letter/p/fbc32d/32.png) [@Poul\_Sorensen](https://community.cesium.com/u/Poul_Sorensen)\
**Post date:** [October 14, 2017, 8:43am UTC](https://community.cesium.com/t/drawing-3d-polygons/1516/10 "2017-10-14T08:43:50Z")

</div>

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.
