Complex Moving Polygons Performance Issues

Hello,
I’ve spent a lot of time trying to figure out what is the best way to display complex polygons on a cesium map and have not had any breakthrough. Any help would be greatly appreciated. Currently I am working with 10 polygons that each have anywhere between 20 to 300 points and they are moving every 5 seconds. So my cesium map for a duration of 5 minutes is loaded with about 600 polygons (each made up of 20-300 points). Unfortunately this makes the map extremely laggy and basically unusable. Here are the different approached I tried which none of them helped the performance. I should mention that the points position are determined ahead of time so using the callback method on the client side seems to not make sense. I’ve also tried to reduce the number of reference points to less than 10 for each complex polygon so that I basically have 10 dynamic polygons each with 4-10 position reference points and it has not improved performance =/

Approach 1: Using references, I am basically copying this example. Obviously my set up has up to 300 reference points for each polygon. https://sandcastle.cesium.com/?src=CZML%20Polygon%20-%20Interpolating%20References.html&label=CZML

Approach 2: Creating a polygon every time. Every 5 seconds, I create a czml packet for each of the 10 polygons, in this form (I’ve omitted some of the packet details for simplicity).
{
id: “polygon1”,
polygon: {
positions: {
interval: <5 sec interval>,
cartographicDegrees: [<20-30 polygon points>]
}
}
}

The 600 + packets then get loaded onto the client app on the cesium map

Approach 3: I saw that you can also build polygons using hierarchy using the example in this document (https://cesium.com/docs/tutorials/creating-entities/) but I am unable to move the polygon. I tried using references as the points, but it is not working or even loading in the Hello World SandCastle. Here is the code I am using, when you copy/paste that in the Hello World sandcastle, the app just hangs on “Loading”.
var viewer = new Cesium.Viewer(“cesiumContainer”, {
shouldAnimate: true,
});

var czml = [
  {
    id: "document",
    name: "CZML Polygon - Interpolating References",
    version: "1.0",
  },
 
  {
    id: "v1",
    position: {
      interpolationAlgorithm: "LINEAR",
      interpolationDegree: 1,
      interval: "2020-08-04T16:00:00Z/2020-08-04T17:00:00Z",
      epoch: "2020-08-04T16:00:00Z",
      cartographicDegrees: [
        0,
        -60,
        35,
        30000,
        160,
        -65,
        35,
        5000000,
        400,
        -70,
        40,
        20000,
        800,
        -62,
        45,
        200000,
        1800,
        -65,
        40,
        650000,
        3600,
        -60,
        35,
        3000,
      ],
    },
  },
  {
    id: "v2",
    position: {
      interval: "2020-08-04T16:00:00Z/2020-08-04T17:00:00Z",
      cartographicDegrees: [-45.0, 20, 4000000],
    },
  },
  {
    id: "v3",
    position: {
      interpolationAlgorithm: "LINEAR",
      interpolationDegree: 1,
      interval: "2020-08-04T16:00:00Z/2020-08-04T17:00:00Z",
      epoch: "2020-08-04T16:00:00Z",
      cartographicDegrees: [
        0,
        -45,
        60,
        4000,
        400,
        -40,
        70,
        2000000,
        1000,
        -35,
        75,
        100000,
        3600,
        -45,
        65,
        3000,
      ],
    },
  },
 
];


var wyoming = viewer.entities.add({
 
  polygon : {
    
    hierarchy : Cesium.ReferenceProperty.fromString("v1#position", "v2#position", "v3#position"),
    height : 0,
    material : Cesium.Color.RED.withAlpha(0.5),
    outline : true,
    outlineColor : Cesium.Color.BLACK
  }
});
viewer.dataSources.process(wyoming);
viewer.zoomTo(wyoming);

I’m really running out of ideas on how to improve the performance of my app. I’ve thoroughly looked into the 3 options I mentioned and searched for examples and documentation and I can’t find a solution to improve the performance. Any help would be so appreciated!! thank you!!

Hi Nhu,

Great to see that you have done extensive experimentation. There are a couple of optimizations you can make to assets outside of the polygons:

  1. Turning the viewer resolution down: https://cesium.com/docs/cesiumjs-ref-doc/Viewer.html?classFilter=viewer#resolutionScale
  2. Using a a lower resolution imagery layer (like Sentinel 2 from the asset depot instead of Bing imagery)

Your third approach is showing the “Loading” screen because of this line:

hierarchy : Cesium.ReferenceProperty.fromString("v1#position", "v2#position", "v3#position"),

Since v1, v2, and v3 are not added to a targetCollection, the ReferenceProperty can’t find them.

Hi Dzung,
Thank you so much for your suggestions. Unfortunately scaling down the resolution of the items displayed and the image layers isn’t really an option for us because it needs to look sharp enough to the users and it needs to use specific imagery layers.
For the hierarchy,

  1. Does it actually help with performance to use “hierarchy” instead of just “polygon.positions”?
  2. I added v1, v2 and v3 to the target collection as you suggested but it still hangs on “Loading” (please see code below)

*I also added this property: scene.requestRenderMode = true, which seems to help a bit but not by much
*It seems to perform better in Chrome than Firefox, is that a known fact when using cesium?
*Most importantly, what is the most performant way to move complex polygons in cesium? Right now, if I decrease the number of polygons points from 250 to ~15 and using those points as reference points for the 10 complex polygons, I am seeing some improvement but I was hoping for more. Is there a better way to do this other than what I’ve been doing? Thank you for any additional help!

    var collection = new Cesium.EntityCollection();

    var v1 =  new Cesium.Entity({
        id: "v1",
        position: {
          interpolationAlgorithm: "LINEAR",
          interpolationDegree: 1,
          interval: "2020-08-04T16:00:00Z/2020-08-04T17:00:00Z",
          epoch: "2020-08-04T16:00:00Z",
          cartographicDegrees: [
            0,
            -60,
            35,
            30000,
            160,
            -65,
            35,
            5000000,
            400,
            -70,
            40,
            20000,
            800,
            -62,
            45,
            200000,
            1800,
            -65,
            40,
            650000,
            3600,
            -60,
            35,
            3000,
          ],
        },
      });

    var v2 = new Cesium.Entity(
      {
        id: "v2",
        position: {
          interval: "2020-08-04T16:00:00Z/2020-08-04T17:00:00Z",
          cartographicDegrees: [-45.0, 20, 4000000],
        },
      },
      );

    var v3 = new Cesium.Entity(
        {
        id: "v3",
        position: {
          interpolationAlgorithm: "LINEAR",
          interpolationDegree: 1,
          interval: "2020-08-04T16:00:00Z/2020-08-04T17:00:00Z",
          epoch: "2020-08-04T16:00:00Z",
          cartographicDegrees: [
            0,
            -45,
            60,
            4000,
            400,
            -40,
            70,
            2000000,
            1000,
            -35,
            75,
            100000,
            3600,
            -45,
            65,
            3000,
          ],
        },
      }
      );

    collection.add(v1);
    collection.add(v2);
    collection.add(v3);

    var v1Ref = Cesium.ReferenceProperty.fromString(collection, 'v1#position');
    var v2Ref = Cesium.ReferenceProperty.fromString(collection, 'v2#position');
    var v3Ref = Cesium.ReferenceProperty.fromString(collection, 'v3#position');

    var wyoming = viewer.entities.add({
      polygon : {
        hierarchy : {
          positions: [v1Ref, v2Ref, v3Ref]
        }, 
                                                               
                             
      
        height : 0,
        material : Cesium.Color.RED.withAlpha(0.5),
        outline : true,
        outlineColor : Cesium.Color.BLACK
      }
    });
    viewer.zoomTo(wyoming);

I also tried different combination of things like

hierarchy : Cesium.ReferenceProperty.fromString("v1#position", "v2#position", "v3#position"),

but none of them worked. Thank you!

For those who ran into similar issues, it turned out that a lot of this was due to the fact that I was using the cesium viewer as a reactive element in Vue which was slowing down its performance a lot. Once I made it non-reactive, the FPS went up due to that as well as the czml reference changes I made above. Some additional information about vue reactive elements with cesium: Cesium & Vue - Performance Issue - Low FPS and Slow Rendering