which 3dtiles format should i use for assets that has sampledpositionproperty

1. A concise explanation of the problem you're experiencing.

I have a small demostration project with a construction company here in denmark. Where I have 300+ assets moving around and reporting their position every 15min or so.

I have set up a pipeline where the data is aggreated, tiled up and served as mapbox vector tiles. (pbf format).

I would like to also generate a 3dtile endpoint and have a few getting started questions.

1) I would just use the same tiling scheme that i already have from the quardtree used with vectortiles. Would you do anything else?
2) Which 3d tiling format should I be using if I want to show a 3d model of the machinery (dumper,Excavator ect) which position updates over time. Currently I just added each asset with the entity api and a sampledpositionproperty.

2. A minimal code example. If you've found a bug, this helps us reproduce and repair it.

none yet

3. Context. Why do you need to do this? We might know a better way to accomplish your goal.

I want to use 3dtiles, because currently loading all data for each assets take tomuch time compared to only loading tiles in the view.

4. The Cesium version you're using, your operating system and browser.

Since you are working with 3D models, the natural choice of tile format is b3dm. A tiling scheme similar to mapbox vector tiles should be fine.

Since the models are updated every 15 minutes, you should look into tile expiration. It’s not part of the 3D Tiles spec yet but there is experimental support in Cesium.

A tile entry in tileset.json can contain an expire property which specifies how many seconds should elapse before the tile’s content is re-requested. The content would need to be updated by the server accordingly.


“expire”: {

“duration”: 5


“boundingVolume”: {

“region”: [









“geometricError”: 70,

“content”: {

“url”: “content.b3dm”




Thanks Sean.

Just to make sure, do this work with current released 3d tiles? I think i could make that work.

To make sure i understand it correct. If i make a 3d tile set and set duration to 300. Then every 5min it would simply make a new request to the server and retdraw the model?

With b3dm, can i also do a sampledposition property alike thing where the model is moving. Then i could trim my tiles to periods of 5min and keep 5min of position data in them and give a smooth time-dynamic view of current assets.

If i want to use the clock to show older data. Could I just keep a 3dtileset for each day and when clock time changes add /remove 3dtiles on demand fitting the timeslot?

Your understanding of tile expiration is correct. I wasn’t sure if you needed to animate the tileset between each request, but it sounds like you do. The support isn’t really there yet for animated tilesets, as it is for sampledposition for entities. But you could experiment with encoding animations in the gltf files. Let me know if want to produce a tileset like that, I think it would work with some basic changes.

In terms of showing a tileset progression by date, the approach you suggested is the best way for now. Eventually we want to look at better ways to handle time dynamic tilesets.

I came to the same conclussion.

I think I want to try see if I can make a small demo using a custom loader (if possible) with inspiration from https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/102 . I will dig in on github and try to find examples.

if you can provide links to examples of where other formats are loading tiles data and adding entities (does it use entity api?) - then that would save me abit of time.

None of the formats work with the entity API, however b3dm does use Model under the hood and the in-progress vector tiles format uses BillboardCollection and other related classes. Nothing is stopping a tile format from working with the entity api directly.

Some references:

content interface that all tile formats derive from: https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Scene/Cesium3DTileContent.js

b3dm loader: https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Source/Scene/Batched3DModel3DTileContent.js
vector tiles PR (useful for seeing the types of code changes needed for introducing a new tile format): https://github.com/AnalyticalGraphicsInc/cesium/pull/4665/files.

Thanks Sean,

I managed to change the factory to add my own dummy format.

var factory = Cesium.Cesium3DTileContentFactory;

factory[“pkso”] = function (tileset, tile, url, arrayBuffer, byteOffset) {

return new PksTileContent(tileset, tile, url, arrayBuffer, byteOffset, this._dataSource);



and also create a dummy tile content class

class PksTileContent {

featuresLength = 1;

pointsLength = 0;

trianglesLength = 0;

geometryByteLength = 0;

texturesByteLength = 0;

batchTableByteLength = 0;

innerContents = undefined;

batchTable = undefined;

featurePropertiesDirty = false;

constructor(public tileset, public tile, public url, arrayBuffer, byteOffset,private dataSource) {


readyPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve(true); this.test = false; }, 60000); });

hasProperty(b, n) {


return false;


getFeature(b) {



applyDebugSettings(e, c) {



applyStyle(fs, s) {



test = false;

mypolygon = null;

update(tileset, framestate) {

//What should I exactly do in update?

if (!this.test) {


this.test = true;


if (!this.mypolygon) {

this.mypolygon = this.dataSource.entities.add({

name: ‘Orange polygon with per-position heights and outline’,

polygon: {

hierarchy: ,

extrudedHeight: 0,

perPositionHeight: true,

material: Cesium.Color.BLACK,

outline: true,

outlineColor: Cesium.Color.BLACK





isDestroyed() {


return false;


destroy() {





and everything works, loading up just fine when adding my tileset dummy tileset.

var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({

url: ‘…/src/demos/3dtiles/content/tileset.json’



I think that I got the basic covers from this little experiment.

Since I am just going to hack this demo together as a proof of concept, i dont want to go to deep into 3d programming and instead just want to load up my content from this custom format and add it to my datasource using the entity api.

Would it be correct that I should keep some state about which “entities” i have loaded

and as more detailed tiles are being loaded up I should update my entities positions.

Also, if i want to create a dummy filestreaming position sampled property, is it possible that cesium only downloads the first X bytes of the content url (containing my time index) and then as the update callback runs it can request other parts of the file depending on time/view? (if not, since I am also creating the api for my content tiles, i can just on return the first bytes only unless some magic query string is present).

Nice progress so far. This is the first time I’ve seen someone write their own content type, which is cool.

Would you keep track of the loaded entities from within each tile, or the tileset as a whole? If you could keep all the logic within the tile itself that would be a lot easier, though your situation may demand some sort of global state.

I’m not sure if it’s possible to download the first X bytes from a url from the Cesium API. My hunch is that it will need to be part of the server code. We have an example of doing that in Cesium’s server.js file in order to detect if a file is gzipped or not: https://github.com/AnalyticalGraphicsInc/cesium/blob/master/server.js#L61-L76. Your other solution sounds doable too.

Thinks are moving showly :slight_smile:

I hit a bumb in the road, wanting to come up with a good dataformat for my N assets sampled position time dynamic format. I just included what i had top of my head here to keep track of my ideas :slight_smile: (Might not make sense to everyone, sorry).

Right now all assets report their position in at random time. I have come to the conclussion that the best case is to implement something like the following:

metadata in the begging of the file followed with actually sample positions.

To optimize such its super fast against random time queues (like when people change the clock or clock speed) I came to the conclusion that a tileset must have a fixed N of assets and also a fixed sampling time. Such its possible to calculate the byte offset / pointer for where to fetch data.

Adding a new asset would mean the file data changes.

I concluded that it was not smart to keep all assets in their own files, then cesium would have to maintain (300 3d tile sets- loads of calculations /requests).

But for such solution, the 3d tile content files could become rather large due to addition sampling positions.

So I am at a point where I think all assets needs to have its own position file and there is a processing/service that combines this on the fly before serving the files (means no static hosting).

Anyways, needs some more time to implement something nice :slight_smile:

Thanks for the update!