KMLDataSource has Icons that Overlap - Mimic Google Earth "Spread" capability?

I am using Cesium as a web client to display KML data as an alternative to google earth as an enterprise KML client. One problem I am having is that given enough data points, some points represented by icons overlap and you cannot see one on top of the other. Google Earth solves this issue by automatically spreading out all overlapped icons from the center point. I can't see any options in Cesium under the KMLDataSrouce to do this. Clustering seems to do the opposite and would group icons instead of "un-group" icons that start out grouped to begin with.

Code example is basic KML Loading in Cesium: KML File contains link to another KML which gets auto-refreshed over a network link.

var kmlDS = new Cesium.KmlDataSource.load('network_kml,{
   camera: viewer.scene.camera,
   canvas: viewer.scene.canvas,
   clampToGround: false
});

viewer.dataSources.add(kmlDS);

Does anyone know how to mimic this behavior from Google Earth in Cesium? And if not, any alternatives to how you might tackle this problem assuming that you are using KML as your source data.

Thanks.

Clustering is supposed to help with that in that it communicates there’s this many icons in that location that become visible when zoomed in enough. I think it was designed this way to keep the icons from moving from their locations on the globe since an accurate location is often part of the information it presents.

Having a “spread” option might be interesting though. Does it spread out the icons to make them all visible, no matter how far away it goes from the center point? This might be an interesting feature request to open an issue for on GitHub (https://github.com/AnalyticalGraphicsInc/cesium/issues) with a bit more detail on the use case and see if other developers would find this useful in their applications.

In the mean time, I think you could create behavior like this by keeping a list of all billboards/icons, and then creating a callback property (https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=Callback%20Property.html) for their positions to loop through and move them if they are overlapping. Although note that a Callback Property marks an entity as dynamic and too many dynamic entities will eventually impact the performance of the application.

I didn't like to use clustering as an example, since clustering takes a large amount of icons in a geographic area and represents them as a single icon. What google earth does in this case, is that if you have a KML feed that has placemarks that are too close to render their respective icons individually, it has a single click event that will break them out from the point of over in a circle around the cursor with lines so it is possible to click on each individual icon in the "stack". It is a very useful feature because obviously, if you have too many entities in one spot there is no way to know how many you have or no way to see the infoboxes if data about those entities which are buried under each other with Vanilla cesium.

I've been re-creating the Google Earth client interface piece by piece in Cesium so that I have ways to work-around this (Such as displaying the list of placemarks / entities in a left window pane and being able to click on them and zoom to them that way ) but this is one of the "nice to have" features that I can't seem to figure out how to do yet.

Example :
Here I have three placemarks, all in the same spot in google earth. It shows them all with 1 icon. When I click on it though, it spreads them out so I can see there are actually 3 hidden there.

Thanks for the additional explanation and screenshots. I can definitely see how this would be helpful especially if you have specific data attached to each that becomes visible on click. I think you can actually use CesiumJS’s clustering to do this, since it will already cluster icons in one icon, then you just need to make it so that when you click on that clustered icon, it expands out and “declusters”.

If you can put together a Sandcastle (https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/) code sample of what you’ve got so far, I can give it a shot and see if there’s an easy way to “expand on click” like that in Cesium. If it’s not so trivial after all, we can open a feature request on GitHub for it.

I haven't done any code work on this specific issue yet. I've only been doing research into how it might be possible. As for the other pieces of Google Earth I've worked on, I am unable to provide that code as the code repo isn't able to be connected to the internet.

For a KML example, all you have to do is put a few placemarks in the same spot to re-create the issue in Google Earth, and then go from there in Cesium.

Again, it really only matters if the placemarks are almost right on top of each other to the point where you can't differentiate the location of the rendered placemarks due to the level of zoom.

As far as the workaround I'm currently using, I do something like GE and display a list of all of the Placemarks that I can navigate to. Since I can't paste the code directly, I'll just re-create an example:

I'm sure I left some stuff out, including HTML, CSS, and some javascript.. but basically you select some KML feeds from a radio list. (Feeds are hard-coded in this case. Google Earth would let you load them dynamically of course) When you select a feed, it would gray out the screen and say "LOADING" while the data source loads, and then that would go away when the promise is completed. The placemarks would be displayed (In a div not shown due to missing html) as well as on the globe, by their name and snippet (similar to google earth) and if you click on them from that list it would zoom to them on the map. This is how you could get around the overlapping icon issue.