I have a question regarding the billboard.setImage function using a callback function to return the image. Up till now, I have been returning a canvas object from my image callback, and that was working fine, but I now need to return an SVG string instead. I noticed that when I do that, I get an error that says “Error loading image for billboard: InternalError: too much recursion”. If I use billboard.setImage and use the string returned from my image callback directly, it works fine. Are there some rules regarding what kinds of data can be returned from the image callback used in the setImage function? Perhaps only canvas is allowed? Here is a sandcastle example to illustrate what I mean. If you then comment the last line (the “Error” line), you can see that billboard1 shows up fine because it’s using the string directly instead of the callback. Thank you!
var viewer = new Cesium.Viewer(‘cesiumContainer’);
var billboards = new Cesium.BillboardCollection();
viewer.scene.primitives.add(billboards);
function drawImage(id) {
return “data:image/svg+xml,”;
}
var billboard1 = billboards.add({
show : true,
position : Cesium.Cartesian3.fromDegrees(-100, 35, 0)
});
var billboard2 = billboards.add({
show : true,
position : Cesium.Cartesian3.fromDegrees(-90, 35, 0)
});
//Works
var imgString = drawImage(“test”);
billboard1.setImage(“test”, imgString);
Instead of returning the string directly, try passing it through Cesium’s loadImage function, which returns a promise for an Image, which is what the callback expects.
I’m having some trouble getting this to work in IE11 (It works perfectly in Firefox). I am getting an error that says “Error loading image for billboard: SecurityError”. If I display the SVG directly in a
element on the same page, the image does display with no issues. Here is a tweaked sandcastle example that incorporates Scott’s fix from above, and uses a base64 string instead:
var viewer = new Cesium.Viewer(‘cesiumContainer’);
var billboards = new Cesium.BillboardCollection();
viewer.scene.primitives.add(billboards);
function drawImage(id) {
var svgpart = “”;
var svg = “data:image/svg+xml;base64,” + btoa(svgpart);
return Cesium.loadImage(svg);
}
var billboard = billboards.add({
show : true,
position : Cesium.Cartesian3.fromDegrees(-100, 35, 0)
});
As far as I know, IE11 treats all SVG’s creating from strings as “tainted” meaning they are insecure and not allowed to be used in WebGL content. I previously ran into this problem myself when working on the PinBuilder.
There’s nothing Cesium can do about it, unfortunately. SVG handling is still wildly inconsistent from browser to browser. Does your SVG has to come from an in-browser string? Does the problem happen if you load it (via loadImage) directly from a URL?
Yuck, IE is always causing us hassle! We are using a javascript library that generates SVGs on the fly to display military graphics, and the images can change depending on that individual item’s data (such as status, fuel level, etc), which makes using SVGs much easier. We were previously using a different library to do this that drew the images using fonts, but it has external dependencies and some issues, so we were hoping to upgrade to the more efficient SVG version. Sounds like there’s nothing we can do about it then until everyone upgrades to Windows 10.
Check the latest checkin to milsymbol, it makes it possible to use it with Cesium on Windows 7 if you use the asCanvas() method. I will release a new version as soon as I have done some more tests. There is a demo working on my homepage.
Hello Mans! You already helped me with this via a separate e-mail conversation (this is Diana B), and the asCanvas method is working perfectly for us, thank you