From the 2-D map to 3-D map, more and more find their own shortcomings, 2-D map of the API is very perfect, the use of APIs can achieve most of the 2-dimensional map of the function, but the 3-dimensional map API is not perfect, many things need basic development, the process of development can also learn a lot.
1. Create a icon+text type of callout
Icon+text type annotations are common in map maps, but cesium do not have an existing API to use, and billboard can only create an icon in the form of a picture. Later thought of using canvas to draw the icon + text picture, and then passed to Billboard, tried a bit sure enough, here to remember.
Draws canvas
function Drawcanvas (img,text,fontsize) {
var canvas = document.createelement (' canvas ') based on pictures and text; Create canvas tag
var ctx = Canvas.getcontext (' 2d ');
Ctx.fillstyle = ' #99f ';
Ctx.font = fontsize + "px Arial";
Canvas.width = Ctx.measuretext (text). Width + fontsize * 2; Get width
canvas.height = fontsize * 2;//fontsize * 1.5
ctx.drawimage (IMG, fontsize/2,fontsize/2,fontsize, FontSize);
Ctx.fillstyle = ' #000 ';
Ctx.font = fontsize + "px calibri,sans-serif";
Ctx.shadowoffsetx = 1; The shadow is skewed to the left, and the lateral displacement is
ctx.shadowoffsety = 0; The shadow to the left, the longitudinal displacement
ctx.shadowcolor = "#fff";//Shadow color
Ctx.shadowblur = 1;//The Blur range of the Shadow
Ctx.filltext (text, FONTSIZE*7/4, FONTSIZE*4/3);
return canvas;
}
The effect is as follows:
2. Detect callout Cover
1 steps to create a icon+text type of annotations, but if the creation of a large number of annotations, it is inevitable that the callout will appear to cover the situation, so that both affect the aesthetic will cover the map information, here needs to detect the cover between the annotations, display and do not show some annotations.
Since each billboard has a corresponding central point (cartesian3 World coordinate type), height (width), the center point to the screen coordinates, and then according to the height width of the billboard on the screen of the range rectangle, Again to determine the intersection of the rectangle problem.
So we go through the annotation collection (billboardcollection), first set the first object to determine the intersection of the rectangle CONSTB, and then use the next billboard to Constb to determine the intersection of the problem, if the rectangle intersects, hide the comparison of Billboard If the rectangle does not intersect, show the billboard of the comparison, and then reset the CONSTB to the billboard to be compared. Then use the next billboard to judge with Constb, which is similar to the bubble algorithm until the entire annotation collection is completed by traversal.
The whole looks a bit messy, but efficiency is fine.
Traverse Billboardcollection:
var len = billboardcollection.length;
var constantb = billboardcollection.get (0);
Instantb.show = true;
for (var i = 0; i < len; ++i) {
if (i>0) {if (
iscollsionwithrect (Constantb,billboardcollection.get (i))) { //Is intersecting
billboardcollection.get (i). Show = false;
else{
Billboardcollection.get (i). Show = true;
CONSTANTB = Billboardcollection.get (i);}}
Detecting collisions:
var B1 = {x:100,y:100,width:80,height:100}; The XY value of the lower left corner of the rectangle is
var b2 = {x:160,y:180,width:100,height:130};
Detect callout Collision
function Iscollsionwithrect (b1,b2) {
var x1 = b1.x,y1 = B1.Y,W1 = B1.width*3,h1 = b1.height*3;
var x2 = b2.x,y2 = b2.y,w2 = B2.width*3,h2 = b2.height*3;
if (x1 >= x2 && x1 >= x2 + W2) {return
false;
} else if (x1 <= x2 && x1 + W1 <= x2) { return
false;
} else if (y1 >= y2 && y1 >= y2 + H2) {return
false;
} else if (y1 <= y2 && y1 + h1 < = y2) {return
false;
} else{return
true;
}
}
The effect is as follows: