How to draw custom dynamic billboards in Cesium.js

╄→尐↘猪︶ㄣ 提交于 2019-12-06 05:36:36

Simple JS code to insert SVG into cesium

          // create the svg image string
             var svgDataDeclare = "data:image/svg+xml,";
             var svgCircle = '<circle cx="10" cy="10" r="5" stroke="black" stroke-width="3" fill="red" /> ';
             var svgPrefix = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="40px" height="40px" xml:space="preserve">';
             var svgSuffix = "</svg>";
             var svgString = svgPrefix + svgCircle + svgSuffix;

             // create the cesium entity
             var svgEntityImage = svgDataDeclare + svgString;
             viewer.entities.add({
                 position: Cesium.Cartesian3.fromDegrees(-80.12, 25.46),
                 billboard: {
                     image: svgEntityImage
                 }
             });

             // test the image in a dialog
             $("#dialog").html(svgString );
             $("#dialog").dialog({
                 position: {my: "left top", at: "left bottom"}
             });

My method to accomplish this is to create a canvas element, add text to it, crop it and convert that result into a data URL. It works great and it's quick.

I'm not using CZML, but this is how I did it:

buildImage:function(text,text2){
    var self = this;
    var canvas = new Element('canvas',{width:500,height:500});
    var ctx = canvas.getContext("2d");
    ctx.font = "bold 16px monospace";
    ctx.fillText(text, 60, 20);
    ctx.fillText(text2, 60, 50);
    imagedata = self.cropCanvas(canvas,ctx);
    return imagedata;
},
cropCanvas:function(canvas,ctx){        
    ww = canvas.width;
    wh = canvas.height;

    imageData = ctx.getImageData(0, 0, ww, wh);

    var topLeftCorner = {};
    topLeftCorner.x = 9999;
    topLeftCorner.y = 9999;

    var bottomRightCorner = {};
    bottomRightCorner.x = -1;
    bottomRightCorner.y = -1;                             

    for (y = 0; y < wh; y++) {
        for (x = 0; x < ww; x++) {
            var pixelPosition = (x * 4) + (y * wh * 4);
            a = imageData.data[pixelPosition+3]; //alpha
            if (a > 0) {
                if (x < topLeftCorner.x) {
                    topLeftCorner.x = x;
                }
                if (y < topLeftCorner.y) {
                    topLeftCorner.y = y;
                }
                if (x > bottomRightCorner.x) {
                    bottomRightCorner.x = x;
                }
                if (y > bottomRightCorner.y) {
                    bottomRightCorner.y = y;
                }
            }
        }
    }
    topLeftCorner.x -= 2;
    topLeftCorner.y -= 2;
    bottomRightCorner.x += 2;
    bottomRightCorner.y += 2;

    relevantData = ctx.getImageData(topLeftCorner.x, topLeftCorner.y, bottomRightCorner.x -topLeftCorner.x, bottomRightCorner.y - topLeftCorner.y);

    canvas.width = bottomRightCorner.x - topLeftCorner.x;
    canvas.height = bottomRightCorner.y - topLeftCorner.y;
    ww = canvas.width;
    wh = canvas.height;

    ctx.clearRect(0,0,ww,wh);

    ctx.putImageData(relevantData, 0, 0);
    return canvas.toDataURL();
}   

These are two methods of a MooTools class, but can be easily rewritten into whatever framework (or no framework) you need.

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!