Search code examples
svgcesiumjsczml

How to draw custom dynamic billboards in Cesium.js


I'm currently using Cesium for a mapping application, and I have a requirement to have status indicators for each item I'm plotting (for example, if the item I'm plotting is an airplane, then I need to have a fuel status indicator). I can't use Cesium's drawing tools to do this because they are drawn using geographic locations, but I need my status indicators to simply be located near the billboard and not get farther away from the billboard as users zoom in and out.

Cesium's CZML documentation states that the billboard's "image" property can take a data URI, so I figured the easiest way to handle this would be for me to create an SVG path on the fly and embed it in the image property, but when I do this in Cesium, it does not show up. For example, I tried a simple test like this:

"data:image/svg+xml,<svg viewBox='0 0 40 40' height='25' width='25'
xmlns='http://www.w3.org/2000/svg'><path fill='rgb(91, 183, 91)' d='M2.379,
14.729L5.208,11.899L12.958,19.648L25.877,6.733L28.707,9.561L12.958,25.308Z'
/></svg>"

When that didn't show up, I tried just simple HTML and text values, like this:

"data:,Hello%2C%20World!"

and:

"data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E"

but those don't show up either. I am able to get a png to show up if I put the base64 string in the data URI, as well as a path to an image stored on the server, but I really need to be able to draw custom images on the fly. I can't use a fixed set of pre-generated images set with various statuses as a hack (I can explain why if anyone wants those details :) ).

Does anyone know if there's something I'm doing wrong here, or if there is another way to accomplish what I need to do?

Edit Just wanted to add that I am using Firefox version 29 and it normally has no problem displaying the non-encoded embedded SVGs like that. Just in case, that's one of the reasons I was also trying simple HTML or text.

Edit2 I am using CZML streaming from the back end to plot my items, here is a simple test example showing where I am trying to put the image information:

{
"id":"test",
"billboard" : {
"image" : "data:image/svg+xml,<svg viewBox='0 0 40 40' height='25' width='25' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(91, 183, 91)' d='M2.379,
14.729L5.208,11.899L12.958,19.648L25.877,6.733L28.707,9.561L12.958,25.308Z'
/></svg>",
"show" : [ {"boolean" : true} ]
},
"position":{
  "cartographicDegrees":[0.0, 0.0, 0.0]
},
"label":{"text":"TEST"},   
}

If I put a base64 png string in there, or a path to a static image file, it works fine.

Thank you!


Solution

  • Drawing an SVG does work as I expected it to, but I believe I may have just been getting one of the size elements wrong (height/width or x, y). Whenever those values don't match up just right, the image isn't shown because it's outside of the view area I've defined for it.

    Note that I never did get the simple html example work, but that's not what I needed anyway, so I didn't pursue it further.