Hi,
I’ve been trying to add some geometries in real time to a Cesium map. The geometries are either circles in the ground or a ring/donut shape. Since Cesium doesn’t provide a ring primitive, I have tried it using the following approaches:
-
Calculating the GeoJSON features using turfjs and adding the dataSource to the map.
Problem: the loading of the initial features is quick, but every time I add a new feature to the source the map freezes for a split second. -
Adding the shape as entities using PolygonHierarchy with circle positions and an inner circle hole.
Problem: Since drawing the polygon requires a lot of points, (~60 for the outer circle + ~60 for the inner one), this also results in the map freezing every time I add a new entity. Also the performance of the map using this approach is worse than with GeoJSON. -
Adding the same polygonHierarchy, but this time as primitives.
This approach is very performant but I lose the ability to select each element as with the entity approach and show a description.
Is there a middle ground between getting the benefits of using the Entity API without having to sacrifice that much performance? Or maybe I am doing something wrong? I don’t get why adding the same Polygon as an Entity is that slow comparing to using a primitive. When working with simple entity geometries such as points it doesn’t cause a noticeable performance issue.
I will leave a snippet of how I create the entity and the primitive if that helps:
// As an entity
return new cesium.Entity({
position: position,
polygon: {
hierarchy: {
positions: computeCircle(position, outerRadius),
holes:
level !== 0
? [
{
positions: computeCircle(position, radius),
holes: [],
},
]
: [],
},
},
name: "Ring entity",
description: "<table>...</table>",
});
// As a primitive
return new cesium.Primitive({
appearance: new cesium.EllipsoidSurfaceAppearance({
material: cesium.Material.fromType("Color", {color}),
}),
asynchronous: false,
geometryInstances: [
{
attributes: undefined,
id: "geometry",
modelMatrix: cesium.Matrix4.IDENTITY,
geometry: cesium.PolygonGeometry.createGeometry(
new cesium.PolygonGeometry({
polygonHierarchy: {
positions: computeCircle(position, outerRadius),
holes:
level !== 0
? [
{
positions: computeCircle(position, radius),
holes: [],
},
]
: [],
},
})
)!,
},
],
});
function computeCircle(
center: cesium.Cartesian3,
radius: number
): cesium.Cartesian3[] {
const positions = [];
for (let i = 0; i < 360; i += 1) {
const radians = cesium.Math.toRadians(i);
positions.push(
new cesium.Cartesian3(
center.x + radius * Math.cos(radians),
center.y + radius * Math.sin(radians),
center.z
)
);
}
return positions;
}
EDIT: also I don’t understand why but my way of computing the ring polygon doesn’t really create a circular shape: