I’m looking for a way to combine multiple primitive objects into a single entity so I can access and use them as a single object. An entity has a number of ‘slots’ for primitives such as circle, polygon etc, but what if I want to combine two or more primitives of the same type, such as two boxes or two cylinders. Can I combine them into a single entity, Or should I create separate entities for each and combine them into an entitycollection? What would be best practice for such a situation?
@Jacky Thanks for your reply.
However, I’m uncertain if this is the optimal approach in my situation: I have to display a very large number (>30000) of objects on the map, currently for each of these objects at least 2 entities are created each containing a Graphics object (PointGraphics, BillBoardGraphics depending on the type of object). Your approach would mean creating at least 3 entities per object (1 parent and 2 or more children). I was really looking for a way to limit the total amount of entities by (hopefully) combining more Graphics objects per entity. Ideally that would result in 1 Entity per Object to be displayed on screen.
Is there a limit to the number of entities that can be displayed on the map? What would be best practice in this sort of situation?
The same still applies, but maybe I don’t fully understand what you’re trying to do. The first step in all of this is to define something that is suitable as a category, so create a new Entity called ‘CategoryX’, and now assign all entities as children of that one. If I do show=true|false on ‘CategoryX’, all of its children will follow suit.
If the answer is that there’s no categories, they’re all individuals that cannot me grouped, then what are you trying to achieve? You can always group by 1000 items, or 10.000 or by location or first character of its Id, or whatever.
This is how the KML/GeoJSON parser works on structured data, where you end up with lots of “anonymous” nodes that don’t hold primitives, only children entity references.
@Alexander_Johannesen thanks. What I’m doing is: I have thousands of (domain-specific) items to display, and my users may have many more (60000 and up). Each item can have several graphic elements as it’s representation. I want to be able to control the graphic elements of each item as a whole. Obviously @Jacky’s suggestion will work, but I was wondering whether creating that many entities would possibly incur a performance hit (it’s unpractical at the moment to test for that many items, so my worry is that users with many more items than I can currently test will encounter performance issues). I’m always interested in finding the most optimal way to achieve something, that’s the rationale of my question.
I mean, I think the real answer to your question is to try it out. Some things are well optimized within the entity API, other things are better handled by your own primitive implementation, and so it is with this as it is with so many other things; it depends.
It depends on what you want to control and change in your entities. For example, for a large group (let’s pick some numbers; 600 points, 300 polygons, 200 labels) of entities my experience is that show and hide are super-fast, moving is reasonable, changing color ok, moving items a bit slow, changing materials painfully slow, and changing clamping conditions not worth it (and many more items in-between those).
Converting direct manipulation of entity values and styles are often better optimized through callbackProperty(), it has a change management thing built in, and if your data is large you can possibly implement an extended change manager on top of that.
I’ve also had performance improvements where I chunk entity manipulations into timed promises. Now this is a bit more tricky, but if you have to update 1000 entities, doing it in async in chunks of 100 makes the update smoother, with the caveat that it might not be actually faster, but it will be a faster experience for the user.
In terms of chunking, you can also consider chunking how you do your entity updates. For example, 1000 label color changes then 1000 position changes then 1000 point size changes, vs. 1000 label color and position change and point size change, yields different performance as well.
And final chunking of this is of course the necessity for update as well in terms of timing. If you’ve got 1000 entities in need of a color change, do they need to change in real-time (ie. every render cycle), near real-time (more like the chunking above), or (and now we’re getting into even more complex stuff) can you change them based on other factors such as “in the view” or “distance from camera” or “every admin cycle” or with variations within visual controllers built into Cesium like clustering, distanceToCamera scaling,transparency, etc.
In my own applications I have a variety of tricks to make things to smoother, mostly a combination of all of the above. The entity API is fine for most things and you can make it work nice and fast, provided you don’t treat it as a black box that does it all for you. If I was going to give you one that works the best, especially on that many entities, I’d implement a distanceToCamera calculation for entities that is super-fast, and use that as a filter for what you update at what speed. I’ve got it set up as a range where the nearest entities are updated at rates faster than those far away, and after a certain distance don’t update at all and / or don’t show them.
I guess I should also mention that changes to entities have two directions; your program in real-time updating all entities in need of change (you control the changes), or entities update themself as they see fit (each entity control itself). he former is where we all start, and the latter expands on a lot of the tricks above, with the callbackProperty() implementation being the prime example of that. In my application I have controller classes that wrap around entities that does further change management (and some of the checks noted above; for example, distanceToCamera with different rates of doing that calculation based on other fast parameters, ranging from importance, to random numbers, to chunk cycle, every X frame, every Y mouse move, and every Y mouse move over a certain number of pixels, and so on. There’s overhead and pro’s and con’s to every different way. But the internal Cesium code is well optimized for certain things.
Apart from all that, I think if you map out the types of changes you need to control on your entities will get you the answer you’re after. Apart from testing it. Hope any of that is useful, and I’m happy to share some code snippets here and there later.
Edit: And a final comment would be on visual feedback for the changes. For example, changing 3000 entities might be slow, and the difference between a happy and angry user could often simply be a progress bar. (And I’ve got code that creates those, especially where I chunk the changes).
Thanks again @Alexander_Johannesen , this gives me lots of cues to explore and experiment with. I’m sure we’ll be revisiting this in the near future.