How to make a properties box

Hello,

I am fairly new to Cesium and my Javascript knowledge is limited as well. I have a project where I have uploaded one building as an FBX file into my cesium assets. This has then been put into my project. I am looking to get a properties box for details on the building to pop up when it is pressed, similar to how it does for all the Cesium buildings. Could anyone offer any assistance on how to make this for my own asset.


Looking to make a box that looks like this.

Thank you

@CSettle2021

Thanks for the detailed post! This sandcastle demo provides a great overview of 3D Tiles feature picking. It’s a great resource for people who are just getting started with feature picking in Cesium.

I recommend that you upload your FBX asset as a 3D Tile. As you can see from this article, .fbx is a supported format for 3D Tiles. The sandcasle demo shows how members such as selectedEntity.name and selectedEntity.description are updated and then displayed on the Cesium viewer. Let me know if you have any other questions or concerns.

-Sam

@sam.rothstein
Hi Sam,

Thanks so much for the reply. So I did look at that example beforehand but still couldn’t quite figure it out. So I looked at the section of selectedEntity but how could I set the properties for my FBX file that I uploaded to Cesium? I was able to use these two examples below to do it with a point, but how could I take that code and assign it to a building?:
Tiles: Cesium Sandcastle
Point: Cesium Sandcastle
I was able to get the point to display the things I was aiming for following the point tutorial. But when I tried following the Tiles demo, I could not figure out how to make it work with a FBX tileset.
Thanks,
Claire

@sam.rothstein
The issue with the 3D tiles feature picking is I do not want to change what properties are displayed from the Cesium OSM Buildings that I have loaded in. I just want to assign and make the properties for the fbx file building I loaded in come up. For this currently, I am using this code:
var building = viewer.scene.primitives.add(
new Cesium.Cesium3DTileset({
url: Cesium.IonResource.fromAssetID(######),
meta: {
name: “”,
description: “”,
status: “”,
},
})
);

By following the example code for that demo, I was only able to get Cesium OSM buildings to display this box but not my own project if that makes sense.

@CSettle2021

Correct me if I am mistaken, but it seems like you would like to add buildings to the Cesium globe that come from a .fbx file. Furthermore, you want the ability to see details about these buildings when you select them in the viewer.

I tried creating a demo with the code that you provided:

var building = viewer.scene.primitives.add(
   new Cesium.Cesium3DTileset({
      url: Cesium.IonResource.fromAssetID(######),
      meta: {
         name: “”,
         description: “”,
         status: “”,
      },
   })
);

While this code looks correct to me, I was not able to get the desired results. Is this code working for you? Are you able to view the asset that you imported from Cesium ion?

-Sam

@sam.rothstein
No. This code was not working for me. I got the building to be viewable but it will not display any properties when clicked. My goal is to have the OSM buildings file loaded in and then multiple .fbx files to display more detailed buildings in the area, but they are all in separate files, not one big .fbx file. I am unsure of how to assign data to each and make it viewable when they are pressed.

@CSettle2021

If you upload your .fbx files to Cesium ion, you can tile them collectively. This will create a single 3D Tiles asset that you can add to the Cesium viewer. The following guide goes over what kinds of data are supported by our 3D Tiling pipeline.

As you can see, Filbox (.fbx) files are supported. I hope this helps!

-Sam

Hi @sam.rothstein,

Thank you! This helps a lot. I apologize for all the questions but I still had one more questions about your response. When you say you can tile them collectively, do you mean to upload all the .fbx files as one asset together or should I upload them separately? Then if I upload them all as one asset, they need locations linked into the file because you cannot move them independently in one asset, correct?

Thank you,
Claire

@CSettle2021

No need to apologize - I am more than happy to help! I am just doing my best to get to everyone’s questions :sweat_smile: :grin: so I appreciate your patience.

In this case, I would recommend uploading all of the assets together. You are correct, if the assets are uploaded together, then it becomes very challenging to move each individual asset independently.

Alternatively, you could upload them separately and manually move the assets to the correct location. This guide goes over how to move an asset that is uploaded to Cesium ion to a desired location on the Cesium World Terrain.

This guide really helped me get started with Cesium ion. In my opinion, it is one of our most important Cesium ion guides. Hopefully you will find it useful. Let me know if you have any other questions or concerns!

-Sam

Hi @sam.rothstein,

So with the project that I am working on, this is a continually updating site that I am trying to make. Due to this, I will have some 3D assets that are going to be added in later and later as they are made. Do you know if Cesium currently has any way of editing the assets to add more files to one big asset later? Currently, I am using the free version of Cesium and could not find a way to edit the asset to load more files in later.

Additionally, I still want to be able to add individual properties to each 3D tileset. If I upload them all as one asset, is there a way to distinguish between the different files to set property data for each?

Thanks,
Claire

@CSettle2021

Thank you for the details on your project. You outlined two great questions in your last comment that I will address here:

Question #1: Is it possible to edit assets that have already been uploaded to Cesium ion? In this case, CSettle2021 wishes to add more files to an already uploaded asset.

This functionality is currently not supported. However, it is always possible to upload a new asset that contains all necessary files.

If multiple files are uploaded and exported as a 3D Tileset using Cesium ion, is there a simple way of distinguishing the source of each object in the 3D Tileset?

My initial thought would be to use some sort of a source file member variable to distinguish objects that are uploaded collectively to Cesium ion. Assets in Cesium ion do have data that can be queried. For 3D Tiles, we preserve metadata such as a building’s height, building materials, among other attributes. In the case of point clouds, we preserve the LAS attributes. However, neither of those preserves where that geometry came from, i.e. the source file.

What format is your source data? Why is it necessary to access the source file information in 3D Tiles?

Various workarounds come to mind. For example, in CityGML data, each building can have a unique ID. This ID can then be mapped to a source file. The optimal solution would depend on your use case.

Let me know if you have any other questions or concerns. I am looking forward to hearing from you.

-Sam

Hello @sam.rothstein,

I have another question. I was wondering if you could provide more information on how the setProperty function works. I was trying to use the setProperty to assign properties to the .fbx file that I have uploaded which I have called tile. These were the examples that I followed but was not successful in getting to work. I was following this tutorial, Cesium Sandcastle. I was thinking if I could have the properties applied to that feature of tile, then when I clicked on it, it would show the properties data.

Cesium3DTileFeature.tile.setProperty = function (name, value) {
this._content.batchTable.setProperty(this._batchId, name, value);
};

var tileName = tile.setProperty(name, value);

Any advice would be greatly appreciated.

Thank you,
Claire

@CSettle2021

setProperty either sets the value of a pre-existing Cesium3DTileFeature property or creates a new Cesium3DTileFeature property with the given value.

If we assume that name and value are updated correctly, then the code that you shared looks fine to me. Although it is somewhat difficult to tell with limited context.

Based on our documentation, I wonder if using setProperty can be as simple as:

var name = "cityName";

var tileName = tile.setProperty(name, "New York");

Ultimately, it seems like we are working on two questions:

  1. How do I use the setProperty method correctly?
  2. How can I display data updated with setProperty?

I would tackle these questions one at a time. For example, do you have a way of verifying that setProperty is actually doing what you expect? Maybe getProperty might be useful here. You could try something like

var city = tile.getProperty("cityName");
console.log(city);

Looking forward to hearing from you and continuing to tackle this problem.

-Sam

Hi @sam.rothstein,

I tried that code but it keeps coming up with an error that says tile.setProperty is not a function. Here is my example that I made to test this.

Additionally, if this is not working to set the properties and then show them when the model is clicked, is there a way I could create a csv file and upload the data to the building that way? If so, could you walk me through how I could go about this with a csv file or some other file type instead and attach it to the model that will be uploaded the ion? Potentially similar to how they have created the OSM Building Tileset file.

Thanks,
Claire

@CSettle2021

I just looked at your code! The error makes sense - tile is a Cesium3DTileset. One way to verify this is to log tile.constructor.name. If you take another look at the documentation for Cesium3DTileFeature, you will see that setProperty() should be called on a Cesium3DTileFeature, not a Cesium3DTileset. This is also expressed by the error that you are getting:

tile.setProperty is not a function (on line 63)

This error indicates that setProperty is not a function of a Cesium3DTileset. If we take another look at the documentation for Cesium3DTileset, we the member properties. This member gets the tileset’s properties i.e. the Cesium3DTileFeatures. I think this might be a helpful member to use here. Maybe give this a try? Remember that you must check that the tileset is loaded before accessing its members.

I suggest sticking with the method that you originally suggested. It is more robust and will likely scale better. I will check in with the rest of the development team regarding a way to upload building data using a csv file. Could you point me to an example of users doing this in the past? I wasn’t able to find any community forum posts or sandcastle demos that use this method.

-Sam

Hi @sam.rothstein ,

Thank you! Would you mind clarifying a bit more or providing an example of some code? How would I go about getting a variable that represents a 3Dtile Feature versus a tile set? I am unsure of what this would look like.

Thanks,
Claire

I don’t know if this would be useful, but I needed a more elaborate Infobox.
Here is the container Page.
https://vcities.umsl.edu/StLouis/riverfrontL.html
Here is the Cesium Window.
https://vcities.umsl.edu/StLouis/rfFC.html

Click on various buildings.

The usual Infobox is hidden but for certain buildings there is a significant history.

1 Like

Hi @sam.rothstein,

I am still struggling to figure out how to make a 3DTileFeature and how to tie this to the location of my 3D tileset. Here is my testing model. Can you tell me why this might not be working?

Thanks,
Claire

@CSettle2021

I apologize for the delayed response - it took me some time to delve into your code. There were a few sections that I did not understand. For instance, the function Cesium3DTileFeature set this._content and this._batchId to values that are undefined.

      function Cesium3DTileFeature(tile, batchID) {  //(content, batchId)
        this._content = content;
        this._batchId = batchId;
      }

In addition, the mouse over functionality did not seem to work.

      var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
      handler.setInputAction(function(result) {
          var feature = viewer.scene.pick(result.position);
          if (feature instanceof Cesium.Cesium3DTileFeature) {
              var propertyNames = feature.getPropertyNames();
              var length = propertyNames.length;
              for (var i = 0; i < length; ++i) {
                  var propertyName = propertyNames[i];
                  console.log(propertyName + ': ' + feature.getProperty(propertyName));
              }
          }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

Thus, I was not able to view details about the assets that you are using. What was the objective here?

Due to these sources of confusion, I decided to start mostly from scratch. Given your use case, I think using a Billboard might be your best bet. This will allow you to spot the asset that you are interested in from a distance. It also helps distinguish your asset from the Cesium OSM Buildings. Moreover, you can add a properties box when the billboard is selected. This is why I ended up using it for my implementation. Here is some more information on the Billboard object:

https://cesium.com/learn/cesiumjs/ref-doc/Billboard.html?classFilter=billb

As you can see, billboards are highly customizable. This should lend well to your application. I suggest that you customize the billboard image, textbox styling, size, etc to meet your needs. I modified the sandcastle demo that you sent me, so you should be able to see the asset that you uploaded as well as the Cesium OSM Buildings. There is also a basic implementation of making a properties box for a billboard. Here is the new demo:

Here are a few screengrabs from the sandcastle demo. As you can see here, the billboard will always face the Camera. Thus, viewers will always know where to find the building that you have imported from Cesium ion.

The following screengrab showcases the textbox functionality. Feel free to add more information here.

You can also select the camera icon in the textbox. This will center the asset in the viewer. Feel free to customize this functionality as well. I hope this helps! Let me know if you have any other questions or concerns.

-Sam

Hi @sam.rothstein ,

Thank you! This does help. I have two questions regarding this example. Ideally, I want to just click on the building which is why I was trying to use the 3D Tile Feature. Would this possible to show the same results but by clicking the model of the building rather than the billboard?

If not, is there a way to scale the billboard so it stays one consecutive size? I am going to be importing many files and if all have a billboard above them, when zoomed out it will look quite messy.

The code above was examples provided to make a tile feature show properties on mouse over. I am trying to replicate this but with left click. As well as this, I could not figure out how to make a tile feature correctly in order to be associated with my building .fbx file.

Thanks,
Claire