標(biāo)繪類
矩形:
export class DrawRectangle {
constructor(arg) {
this.viewer = arg.viewer;
this.Cesium = arg.Cesium;
this.callback=arg.callback;
this.floatingPoint = null;//標(biāo)識(shí)點(diǎn)
this._rectangle = null; //活動(dòng)矩形
this._rectangleLast = null; //最后一個(gè)矩形
this._positions = []; //活動(dòng)點(diǎn)
this._entities_point = []; //臟數(shù)據(jù)
this._entities_rectangle = []; //臟數(shù)據(jù)
this._rectangleData = null; //用于構(gòu)造矩形數(shù)據(jù)
}
//返回最后圖形
get line() {
return this._rectangleLast;
}
//返回矩形數(shù)據(jù)
getData() {
return this._rectangleData;
}
//加載
loadRectangle(data) {
var $this = this;
var shape = this.viewer.entities.add({
name: "rectangle",
rectangle: {
coordinates: $this.Cesium.Rectangle.fromCartesianArray(data),
material: $this.Cesium.Color.RED.withAlpha(0.5)
}
});
$this._entities_rectangle.push(shape);
return shape;
}
//開(kāi)始創(chuàng)建
startCreate() {
var $this = this;
this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction(function (evt) { //單機(jī)開(kāi)始繪制
//屏幕坐標(biāo)轉(zhuǎn)地形上坐標(biāo)
var cartesian = $this.getCatesian3FromPX(evt.position);
if ($this._positions.length == 0) {
$this._positions.push(cartesian.clone());
$this.floatingPoint = $this.createPoint(cartesian);
$this.createPoint(cartesian);// 繪制點(diǎn)
}
$this._positions.push(cartesian);
$this.viewer.scene.forceRender();
}, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(function (evt) { //移動(dòng)時(shí)繪制線
if ($this._positions.length < 3) return;
var cartesian = $this.getCatesian3FromPX(evt.endPosition);
if (!$this.Cesium.defined($this._rectangle)) {
$this._rectangle = $this.createRectangle();
}
$this.floatingPoint.position.setValue(cartesian);
if ($this._rectangle) {
$this._positions.pop();
$this._positions.push(cartesian);
}
$this.viewer.scene.forceRender();
}, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction(function (evt) {
if (!$this._rectangle) return;
var cartesian = $this.getCatesian3FromPX(evt.position);
$this._positions.pop();
$this._positions.push(cartesian);
$this.createPoint(cartesian);// 繪制點(diǎn)
$this._rectangleData = $this._positions.concat();
$this.viewer.entities.remove($this._rectangle); //移除
$this._rectangle = null;
$this._positions = [];
$this.floatingPoint.position.setValue(cartesian);
var rectangle = $this.loadRectangle($this._rectangleData); //加載
$this._entities_rectangle.push(rectangle);
$this._rectangleLast = rectangle;
if(typeof $this.callback=="function"){
$this.callback(rectangle);
}
$this.destroy();
$this.viewer.scene.forceRender();
}, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
return this;
}
//創(chuàng)建點(diǎn)
createPoint(cartesian) {
var $this = this;
var point = this.viewer.entities.add({
position: cartesian,
point: {
pixelSize: 10,
color: $this.Cesium.Color.YELLOW,
}
});
$this._entities_point.push(point);
$this.viewer.scene.forceRender();
return point;
}
//創(chuàng)建矩形
createRectangle() {
var $this = this;
var shape = this.viewer.entities.add({
name: "rectangle",
rectangle: {
coordinates: new $this.Cesium.CallbackProperty(()=>{
if($this.checkPositions()){
var obj = $this.Cesium.Rectangle.fromCartesianArray($this._positions);
return obj;
}
}, false),
material: $this.Cesium.Color.RED.withAlpha(0.5)
}
});
$this._entities_rectangle.push(shape);
$this.viewer.scene.forceRender();
return shape;
}
//銷(xiāo)毀
destroy() {
if (this.handler) {
this.handler.destroy();
this.handler = null;
this.viewer.scene.forceRender();
}
}
//清空實(shí)體對(duì)象
clear() {
for (var i = 0; i < this._entities_point.length; i++) {
this.viewer.entities.remove(this._entities_point[i]);
}
for (var i = 0; i < this._entities_rectangle.length; i++) {
this.viewer.entities.remove(this._entities_rectangle[i]);
}
this.floatingPoint = null;//標(biāo)識(shí)點(diǎn)
this._rectangle = null; //活動(dòng)矩形
this._rectangleLast = null; //最后一個(gè)矩形
this._positions = []; //活動(dòng)點(diǎn)
this._entities_point = []; //臟數(shù)據(jù)
this._entities_rectangle = []; //臟數(shù)據(jù)
this._rectangleData = null; //用于構(gòu)造矩形數(shù)據(jù)
this.viewer.scene.forceRender();
}
checkPositions(){
let flag = true;
for(let item of this._positions){
if(!item || !item.x){
flag = false;
break;
}
}
return flag;
}
getCatesian3FromPX(px) {
var cartesian;
var ray = this.viewer.camera.getPickRay(px);
if (!ray) return null;
cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
return cartesian;
}
}
圓形:
/*
繪制圓
*/
export class DrawCircle {
constructor(arg) {
this.viewer = arg.viewer;
this.Cesium = arg.Cesium;
this.callback=arg.callback;
this._cicle = null; //活動(dòng)圓
this.floatingPoint = null;
this._cicleLast = null; //最后一個(gè)圓
this._positions = []; //活動(dòng)點(diǎn)
this._entities_point = []; //臟數(shù)據(jù)
this._entities_cicle = []; //臟數(shù)據(jù)
this._cicleData = null; //用于構(gòu)造圓形數(shù)據(jù)
}
get cicle() {
return this._cicleLast;
}
//加載圓
loadCicle(data) {
var that = this;
var position = data[0];
var value = data;
var r = Math.sqrt(
Math.pow(value[0].x - value[value.length - 1].x, 2) +
Math.pow(value[0].y - value[value.length - 1].y, 2)
);
var shape = this.viewer.entities.add({
position: position,
name: "circle",
type: "circle",
ellipse: {
semiMinorAxis: r,
semiMajorAxis: r,
material: that.Cesium.Color.RED.withAlpha(0.5),
outline: true
}
});
return shape;
}
//返回?cái)?shù)據(jù)
getData() {
return this._cicleData;
}
startCreate() {
this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.viewer.scene.globe.depthTestAgainstTerrain = true;
var $this = this;
this.handler.setInputAction(function (evt) { //單機(jī)開(kāi)始繪制
$this.viewer.scene.globe.depthTestAgainstTerrain = true;
//屏幕坐標(biāo)轉(zhuǎn)地形上坐標(biāo)
var cartesian = $this.getCatesian3FromPX(evt.position);
if ($this._positions.length == 0) {
$this._positions.push(cartesian.clone());
$this.floatingPoint = $this.createPoint(cartesian);
}
if (!$this._cicle) {
$this.createPoint(cartesian);// 繪制點(diǎn)
}
$this._positions.push(cartesian);
}, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(function (evt) { //移動(dòng)時(shí)繪制圓
if ($this._positions.length < 1) return;
var cartesian = $this.viewer.scene.pickPosition(evt.endPosition);// $this.getCatesian3FromPX(evt.endPosition);
if (!$this.Cesium.defined($this._cicle)) {
$this._cicle = $this.createCicle();
}
$this.floatingPoint.position.setValue(cartesian);
if ($this._cicle) {
$this._positions.pop();
$this._positions.push(cartesian);
}
}, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction(function (evt) {
if (!$this._cicle) return;
$this.viewer.scene.globe.depthTestAgainstTerrain = false;
var cartesian = $this.viewer.scene.pickPosition(evt.position); // $this.getCatesian3FromPX(evt.position);
$this._positions.pop();
$this._positions.push(cartesian);
$this._cicleData = $this._positions.concat();
$this.viewer.entities.remove($this._cicle); //移除
$this._cicle = null;
$this._positions = [];
$this.floatingPoint.position.setValue(cartesian);
var cicle = $this.loadCicle($this._cicleData); //加載
$this._entities_cicle.push(cicle);
$this._cicleLast = cicle;
$this.clearPoint();
if(typeof $this.callback=="function"){
$this.callback(cicle);
}
$this.destroy();
}, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
return this;
}
checkPositions(){
let flag = true;
for(let item of this._positions){
if(!item || !item.x){
flag = false;
break;
}
}
return flag;
}
//創(chuàng)建圓
createCicle() {
// if(this.checkPositions()){
var that = this;
var shape = this.viewer.entities.add({
position: that._positions[0],
name: "circle",
type: "circle",
ellipse: {
semiMinorAxis: new that.Cesium.CallbackProperty( ()=>{
//半徑 兩點(diǎn)間距離
if(that.checkPositions()){
var r = Math.sqrt(
Math.pow(that._positions[0].x - that._positions[that._positions.length - 1].x, 2) +
Math.pow(that._positions[0].y - that._positions[that._positions.length - 1].y, 2)
);
return r ? r : r + 1;
}
}, false),
semiMajorAxis: new that.Cesium.CallbackProperty( ()=> {
if(that.checkPositions()){
var r = Math.sqrt(
Math.pow(that._positions[0].x - that._positions[that._positions.length - 1].x, 2) +
Math.pow(that._positions[0].y - that._positions[that._positions.length - 1].y, 2)
);
return r ? r : r + 1;
}
}, false),
material: that.Cesium.Color.RED.withAlpha(0.5),
outline: true
}
});
that._entities_cicle.push(shape);
return shape;
// }
}
//創(chuàng)建點(diǎn)
createPoint(cartesian) {
var $this = this;
var point = this.viewer.entities.add({
position: cartesian,
point: {
pixelSize: 10,
color: $this.Cesium.Color.YELLOW,
}
});;
$this._entities_point.push(point);
return point;
}
getCatesian3FromPX(px) {
var cartesian;
var ray = this.viewer.camera.getPickRay(px);
if (!ray) return null;
cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
return cartesian;
}
destroy() {
if (this.handler) {
this.handler.destroy();
this.handler = null;
}
}
clearPoint(){
for (var i = 0; i < this._entities_point.length; i++) {
this.viewer.entities.remove(this._entities_point[i]);
}
this._entities_point = []; //臟數(shù)據(jù)
}
clear() {
for (var i = 0; i < this._entities_point.length; i++) {
this.viewer.entities.remove(this._entities_point[i]);
}
for (var i = 0; i < this._entities_cicle.length; i++) {
this.viewer.entities.remove(this._entities_cicle[i]);
}
this._cicle = null; //活動(dòng)圓
this.floatingPoint = null;
this._cicleLast = null; //最后一個(gè)圓
this._positions = []; //活動(dòng)點(diǎn)
this._entities_point = []; //臟數(shù)據(jù)
this._entities_cicle = []; //臟數(shù)據(jù)
this._cicleData = null; //用于構(gòu)造圓形數(shù)據(jù)
}
}
多邊形:
/*
繪制面
*/
class DrawPolygon {
constructor(arg) {
this.viewer = arg.viewer;
this.Cesium = arg.Cesium;
this.callback=arg.callback;
this._polygon = null; //活動(dòng)面
this._polygonLast = null; //最后一個(gè)面
this._positions = []; //活動(dòng)點(diǎn)
this._entities_point = []; //臟數(shù)據(jù)
this._entities_polygon = []; //臟數(shù)據(jù)
this._polygonData = null; //用戶構(gòu)造面
}
//返回最后活動(dòng)面
get polygon() {
return this._polygonLast;
}
//返回面數(shù)據(jù)用于加載面
getData() {
return this._polygonData;
}
//加載面
loadPolygon(data) {
var $this = this;
return this.viewer.entities.add({
polygon: {
hierarchy: new $this.Cesium.PolygonHierarchy(data),
clampToGround: true,
show: true,
fill: true,
material: $this.Cesium.Color.RED.withAlpha(0.5),
width: 3,
outlineColor: $this.Cesium.Color.BLACK,
outlineWidth: 1,
outline: false
}
});
}
checkPositions(){
let flag = true;
for(let item of this._positions){
if(!item || !item.x){
flag = false;
break;
}
}
return flag;
}
//開(kāi)始繪制
startCreate() {
var $this = this;
this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction(function (evt) { //單機(jī)開(kāi)始繪制
var cartesian = $this.getCatesian3FromPX(evt.position);
if ($this._positions.length == 0) {
$this._positions.push(cartesian.clone());
}
$this.createPoint(cartesian);
$this._positions.push(cartesian);
}, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(function (evt) { //移動(dòng)時(shí)繪制面
if ($this._positions.length < 1) return;
var cartesian = $this.getCatesian3FromPX(evt.endPosition);
if ($this._positions.length == 3) {
if (!$this.Cesium.defined($this._polygon)) {
$this._polygon = $this.createPolygon();
}
}
$this._positions.pop();
$this._positions.push(cartesian);
}, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction(function (evt) {
if (!$this._polygon) return;
var cartesian = $this.getCatesian3FromPX(evt.position);
$this._positions.pop();
$this._positions.push(cartesian);
$this.createPoint(cartesian);
$this._polygonData = $this._positions.concat();
$this.viewer.entities.remove($this._positions); //移除
$this._positions=null;
$this._positions = [];
var Polygon = $this.loadPolygon($this._polygonData);
$this._entities_polygon.push(Polygon);
$this._polygonLast = Polygon;
if(typeof $this.callback=="function"){
$this.callback(Polygon);
}
$this.destroy();
}, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
return this;
}
//創(chuàng)建面
createPolygon() {
var $this = this;
var polygon = this.viewer.entities.add({
polygon: {
hierarchy: new $this.Cesium.CallbackProperty(()=> {
if($this.checkPositions()) {
return new $this.Cesium.PolygonHierarchy($this._positions);
}
}, false),
clampToGround: true,
show: true,
fill: true,
material: $this.Cesium.Color.RED.withAlpha(0.5),
width: 3,
outlineColor: $this.Cesium.Color.BLACK,
outlineWidth: 1,
outline: false
}
});
$this._entities_polygon.push(polygon);
return polygon;
}
//創(chuàng)建點(diǎn)
createPoint(cartesian) {
var $this = this;
var point = this.viewer.entities.add({
position: cartesian,
point: {
pixelSize: 10,
color: $this.Cesium.Color.YELLOW,
}
});
$this._entities_point.push(point);
return point;
}
//銷(xiāo)毀事件
destroy() {
if (this.handler) {
this.handler.destroy();
this.handler = null;
}
}
//清空實(shí)體對(duì)象
clear() {
for (var i = 0; i < this._entities_point.length; i++) {
this.viewer.entities.remove(this._entities_point[i]);
}
for (var i = 0; i < this._entities_polygon.length; i++) {
this.viewer.entities.remove(this._entities_polygon[i]);
}
this._polygon = null; //活動(dòng)面
this._polygonLast = null; //最后一個(gè)面
this._positions = []; //活動(dòng)點(diǎn)
this._entities_point = []; //臟數(shù)據(jù)
this._entities_polygon = []; //臟數(shù)據(jù)
this._polygonData = null; //用戶構(gòu)造面
}
getCatesian3FromPX(px) {
var cartesian;
var ray = this.viewer.camera.getPickRay(px);
if (!ray) return null;
cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
return cartesian;
}
}
export default DrawPolygon
調(diào)用
callbackFun(obj) {
console.log('畫(huà)完了~~', obj)
this.entity = obj;
this.drawsObj.destroy()//銷(xiāo)毀handler事件交互
},
clearDraw() {
this.viewer.entities.removeAll()
},
createShape(str) {
this.clearDraw()
let obj;
let params = {
viewer: this.viewer,
Cesium: this.Cesium,
callback: this.callbackFun
};
switch (str) {
case 'square':
obj = new DrawRectangle(params);
break;
case 'circular':
obj = new DrawCircle(params);
break;
case 'polygon':
obj = new DrawPolygon(params);
break;
}
this.drawsObj = obj.startCreate();
this.rectCon[str] = this.drawsObj;//緩存圖形數(shù)據(jù)
}
這里我們需要注意一下交互事件問(wèn)題。
2.png
如圖所示,如果我選了矩形、然后再選擇圓形的話,這時(shí)會(huì)建立兩個(gè)handler事件交互,這樣就會(huì)同時(shí)畫(huà)出兩個(gè)圖形,這是不對(duì)的。
正確的做法是,選擇一個(gè)圖形,要把上一個(gè)圖形的handler銷(xiāo)毀掉。
watch: {
shape: {
handler(val, oldVal) {
console.log(val, oldVal)
if (val) {
if(oldVal) {
//防止多次創(chuàng)建圖形交互,將上一次對(duì)象的交互清除
console.log('框選容器>>>',this.rectCon);
Object.keys(this.rectCon).map(item=>{
console.log(item);
if(item && item === oldVal) {
this.rectCon[item].destroy();
this.rectCon[item].clear();
}
});
}
this.createShape(val);//畫(huà)出圖形
} else {
this.destroyHandler()
}
},
deep: true,
immediate: true
}
},