我目前正在使用Cesium作为地图应用程序,我需要为我正在绘制的每个项目都有状态指示器(例如,如果我正在绘制的项目是飞机,那么我需要有燃料状态指示器)。我不能使用Cesium的绘图工具来执行此操作,因为它们是使用地理位置绘制的,但我需要将状态指示器简单地放在广告牌附近,并且在用户放大和缩小时不要远离广告牌。
Cesium的CZML文档声明广告牌的“image”属性可以采用数据URI,所以我认为处理这个问题的最简单方法是让我动态创建一个SVG路径并将其嵌入到image属性中,但是当我在Cesium中这样做时,它没有显示出来。例如,我尝试了一个简单的测试:
"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>"
如果没有显示,我只尝试了简单的HTML和文本值,如下所示:
"data:,Hello%2C%20World!"
和
"data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E"
但那些也没有出现。如果我将base64字符串放在数据URI中,以及存储在服务器上的图像的路径,我能够显示一个png,但我真的需要能够动态地绘制自定义图像。我不能使用一组固定的预先生成的图像设置各种状态作为黑客(我可以解释为什么如果有人想要这些细节:))。
有谁知道我在这里做错了什么,或者是否还有其他办法可以完成我需要做的事情?
编辑只是想补充说我使用的是Firefox 29版,它通常没有问题显示非编码的嵌入式SVG。以防万一,这也是我尝试使用简单的HTML或文本的原因之一。
Edit2 我正在使用后端的CZML流绘制我的项目,这是一个简单的测试示例,显示我试图放置图像信息的位置:
{
"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"},
}
如果我在其中放置一个base64 png字符串,或者是一个静态图像文件的路径,它可以正常工作。
谢谢!
答案 0 :(得分:2)
将SVG插入cesium的简单JS代码
// 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"}
});
答案 1 :(得分:0)
我的方法是创建一个canvas元素,向其添加文本,裁剪它并将结果转换为数据URL。它效果很好,而且很快。
我没有使用CZML,但我就这样做了:
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();
}
这是MooTools类的两种方法,但可以轻松地重写为您需要的任何框架(或无框架)。
答案 2 :(得分:-3)
绘制SVG确实按照我的预期工作,但我相信我可能刚刚得到一个大小元素错误(高度/宽度或x,y)。每当这些值恰好与之匹配时,图像就不会显示,因为它在我为其定义的视图区域之外。
请注意,我从未做过简单的html示例工作,但这不是我需要的,所以我没有进一步追求它。