What is the best way [performance] to load many objects on map?

hello all

in my company, i have a mission to improve the performance in the app.
we have a cesium map, and i get from my server in socket a big amount of data, and need to handle the data correctly and add it to the map

the problem is when the is a lot of data, the browser just stack, and the app get very slow

every object look like this

image

and the way it handle now -is like this

       dataSources.add(Cesium.CzmlDataSource.load([{
                id: 'document',
                name: `${DSNAMES.TEST}`,
                version: '1.0',
              }, ..dataFromServer))

add all the data at once, this is the code in my app
and it very slow

any ideas how to improve it?

thanks

@eliko

Thank you for your question!

Given that you are streaming data from your own server into CesiumJS, it is somewhat difficult for me to debug this problem. Based on the code that you have shared, it seems like you are adding your data to dataSources correctly. Thus, the latency is likely caused by your server or how CesiumJS processes your CZML data. I suspect that it is the former. Please try using Cesium ion to host and stream your data. Let me know if you still experience poor runtime performance.

-Sam

I think its about how cesium engine prepare data for render, you need to change this mechanism.

When the data numbers are goes up your data structure is more important, if you want to handle big number of objects you need to have very light data structure (for example not nested object or array) and you need to fast draw method.

I try some samples and when number are big cesium consume a lot of memory in runtime.

1 Like

@sam.rothstein - thanks for your response.
my data from server look like this (real example)

[
  {
  billboard: {
      height: 48
      image: "data:image/png;base64,iVBORw0KGgoAAAAN.."
      show: true
      width: 48
  },
  id: "24801",
  title: "title",
  position: {
    cartographicDegrees: {
       0: 35.60567825246084
       1: 33.1088736770721
       2: 0
    }
  },
 properties: {
  attributes : {
    name: "bla bla"
    position: {
     height: 0
     latitude: 33.1088736770721
     longitude: 35.60567825246084
    }
  }
 },
 {
  ...more object
 }
]

@akkaya.hu - thanks, but to change my data structure will be very hard, because all the app is relied on this data structure,
but what do you mean by “fast draw method.” ?

is it will be better to use the Entity instead of the Czml data source?
like this?

viewer.entities.add(...dataFromServer);

@eliko I mean optimize

How many billboards are you trying to add?

@akkaya.hu sorry, i don’t understand what you suggest to do,

@TJ_Koury - every item has 1 billboard, so at the max it can be 150,000 K
if the billboards are the reason on the slowness, is any replacement suggestion?

Hi

what are this objects? bildings? is it dynamic objects like cars or pepole? why not use 3D tiles?

@Ohad_Manor - hi
the objects are icons with label…this is the reason why to use billboard,
static objects

What is the source of it?
If it is for draw maps from vector data - billborad is not the best practice for that

what do you mean vector data ?
my server send to me 100,000 items to draw on the map
every item is a small icon (base64), and has a label with his name,
and every item is locate in other place on the map, by lat and long

@eliko Try out c137.js and met me know if the performance improves. It’s a drop-in replacement for Cesium.

Billboards and labels can be clustered, so with so many billboards / labels I’d look into that;

https://sandcastle.cesium.com/gallery/Clustering.html

Cheers,

Alex

I don’t know if there’s any official guidance but I think that adding 100k+ billboards is simply going to have bad performance. I made a simple Sandcastle example with “only” 10k billboards – identical, so the image is conveniently cached, no entity properties, no labels – and it still takes well over 2 seconds on my machine just to add them all. After that, there’s a big hitch when the basemap loads, then it stabilizes around 10FPS. That’s my 4-year-old laptop with a decent dGPU.

If there’s a performant way to have 100k+ entities loaded at once, I’d love to hear about it.

1 Like

@James_B thanks for your comment…so its cesium’s problem ?
i change your sandcastle to 100k, and the map is very very slow…

The Cesium API has all sorts of goodness for helping you out with rendering entities, but if you’ve got lots and lots of entities, you should use the Primitive’s and control those yourself, that in itself speeds things up significantly (becuase the API can’t know everything about your data and what’s the best performance for what you’re doing). Also, did you try to cluster the billboards? Or have rules about either transparancy or size based on distance to camera? All of these things help with performance, and frankly, anything from 10K+ is a lot of entities that maybe - juuuuust maybe - aren’t all needed in the view at the same time.

Cheers,

Alex

1 Like

In my own project, I have an extra layer of logic that holds “item data” in memory and only creates Cesium Entities for those that fall in the current viewport. I hook the camera’s moveEnd event and look for items that I’ve loaded from the server but not yet sent to Cesium. At the same time, if Cesium has “too many” entities, I look for entities that fall outside the new viewport and cull them. I default to an upper limit of 2000 (which is pretty aggressive) but let the user increase or decrease this based on the capabilities of their own hardware.

Of course this introduces a lag to seeing icons on the map, but it’s sort of like when you go to any popular online mapping service and zoom in, you have to wait a second or two for extra detail to load from the server and draw new street names or place markers.

use wms to show points and labels if they are not changing positions, cache em, for interactivity use getfeatureinfo, google it:
https://cesium.com/learn/cesiumjs/ref-doc/WebMapServiceImageryProvider.html
use point primitives if your icons are not visually different than others, for dynamic icons:

you can support performance by explicit rendering:

also for javascript use async operations instead of blocking operations

You can use primitive api but it won’t help you much unless you find your in house solution. It is not that much performant after all.
Well, gotta go, I’m almost at the bridge now.
Oh s, I forgot, how am I supposed to send this s out?

1 Like