Returning an SVG string from billboard.setImage() with callback?

599 views
Skip to first unread message

dic...@gmail.com

unread,
Aug 26, 2015, 2:24:29 PM8/26/15
to cesium-dev
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,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='10px' width='10px'><rect width='15' height='15' style='fill:red;' /></svg>";
}

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);

//Error
billboard2.setImage("test2", drawImage);

dic...@gmail.com

unread,
Aug 26, 2015, 2:34:53 PM8/26/15
to cesium-dev
Sorry, I should note that I'm using Firefox 31.8.

Scott Hunter

unread,
Aug 26, 2015, 2:49:55 PM8/26/15
to cesiu...@googlegroups.com
Currently Billboard does not expect the callback to return a string (URL).  The allowed return types are listed in the documentation:


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.

e.g.

var svg = 'data:image/svg+xml,etc.etc.';
return Cesium.loadImage(svg);




--
You received this message because you are subscribed to the Google Groups "cesium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cesium-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

dic...@gmail.com

unread,
Aug 26, 2015, 7:19:37 PM8/26/15
to cesium-dev
Aha, now I see what that part of the docs mean, thank you! 

dic...@gmail.com

unread,
Aug 27, 2015, 4:33:53 PM8/27/15
to cesium-dev
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 <div> 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 = "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='10px' width='10px'><rect width='15' height='15' style='fill:red;' /></svg>";
    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)
});

//Error
billboard.setImage("test", drawImage);








On Wednesday, August 26, 2015 at 11:49:55 AM UTC-7, Scott Hunter wrote:

dic...@gmail.com

unread,
Aug 27, 2015, 4:44:01 PM8/27/15
to cesium-dev
Forgot to note that this works for us in IE on Windows 10, just not on Windows 7 or 8 (using the same hardware).

Matthew Amato

unread,
Aug 27, 2015, 4:49:21 PM8/27/15
to cesiu...@googlegroups.com
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?

On Thu, Aug 27, 2015 at 4:44 PM, dic...@gmail.com <dic...@gmail.com> wrote:
Forgot to note that this works for us in IE on Windows 10, just not on Windows 7 or 8 (using the same hardware).

--

dic...@gmail.com

unread,
Aug 27, 2015, 5:05:12 PM8/27/15
to cesium-dev
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.

Thank you!

m...@mansbeckman.com

unread,
May 13, 2016, 8:51:51 AM5/13/16
to cesium-dev
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.

dic...@gmail.com

unread,
May 13, 2016, 5:05:27 PM5/13/16
to cesium-dev, m...@mansbeckman.com
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 :)
Reply all
Reply to author
Forward
0 new messages