import * as Cesium from "cesium/Cesium.js";
import { pickEllipsoidCartesian3ToLonLatHeight, pickPositionCartesian3ToLonLatHeight} from './transform'
import {$Params} from "./params";
import Vue from 'vue'
var DRAW_TYPE = {
Point: 'Point',
PolyLine: 'PolyLine',
Polygon: 'Polygon',
Marker: 'Marker',
Circle: 'Circle',
Box: 'Box',
};
export const $Draw = (
function () {
var viewer;
var handler;
var drawingMode;
var imgUrl;
var tipOverlay;
var is_click = false;
var editEntities = [];
var isExitEditDialog = false;
var activeShape;
var floatingPoint;
let positions = [];
function ConstructDraw() {
viewer = Vue.prototype.$MyCesium.viewer;
return {
draw: (options) => draw(options),
remove: () => removeEntity()
}
}
function draw(options) {
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
drawingMode = options.drawingMode;
imgUrl = options.imgUrl || ""
tipOverlay = document.createElement('div');
tipOverlay.style.display = "block";
viewer.container.appendChild(tipOverlay);
isExitEditDialog = true
switch (options.drawingMode) {
case DRAW_TYPE.Point:
case DRAW_TYPE.Marker:
drawPoint(options.drawingMode);
break;
case DRAW_TYPE.PolyLine:
case DRAW_TYPE.Polygon:
drawGraphics(options.drawingMode);
break;
case DRAW_TYPE.Box:
drawBox(options.drawingMode)
case DRAW_TYPE.Circle:
drawCircle(options.drawingMode)
default:
break;
}
}
function removeEntity() {
terminateShape(true)
}
function drawPoint(type) {
let submitParams = [];
let dom = document.getElementsByTagName("body")[0]
is_click = true
if(!isExitEditDialog) return
console.log('isExitEditDialog 绘制点、广告牌', isExitEditDialog)
handler.setInputAction(event => {
is_click = false
let {cartesian, lonlat} = pickEllipsoidCartesian3ToLonLatHeight(viewer, event.position)
console.log('lonlat', lonlat)
if (Cesium.defined(cartesian)) {
dom.style.cursor = 'crosshair'
if(positions.length == 0) {
positions.push(cartesian);
submitParams.push(lonlat);
activeShape = drawShape(drawingMode, cartesian)
editEntities.push(activeShape)
Vue.prototype.$Bus.$emit("setLocation", submitParams, type)
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.setInputAction(event => {
if (submitParams.length > 0) handleTipOverlay(event.endPosition)
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(event => {
terminateShape()
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
handler.setInputAction(event => {
terminateShape(true)
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
}
function drawGraphics(type) {
let dom = document.getElementsByTagName("body")[0];
let submitParams = [];
is_click = true
console.log('isExitEditDialog', isExitEditDialog)
if(!isExitEditDialog) return
handler.setInputAction(event => {
is_click = false
let {cartesian, lonlat} = pickEllipsoidCartesian3ToLonLatHeight(viewer, event.position)
if (Cesium.defined(cartesian)) {
dom.style.cursor = 'crosshair'
if (positions.length === 0) {
if (!Cesium.defined(cartesian)) {
return
}
floatingPoint = drawShape('Point', cartesian)
editEntities.push(floatingPoint)
positions.push(cartesian);
var dynamicPositions = new Cesium.CallbackProperty(function () {
if (drawingMode === 'Polygon') {
return new Cesium.PolygonHierarchy(positions);
}
return positions
}, false);
activeShape = drawShape(drawingMode, dynamicPositions);
editEntities.push(activeShape)
}
positions.push(cartesian);
let pointEntity = drawShape('Point', cartesian)
submitParams.push(lonlat)
console.log('submitParams', submitParams)
Vue.prototype.$Bus.$emit("setLocation", submitParams, type)
editEntities.push(pointEntity)
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.setInputAction(event => {
if (Cesium.defined(floatingPoint)) {
let {cartesian, lonlat} = pickEllipsoidCartesian3ToLonLatHeight(viewer, event.endPosition)
if (Cesium.defined(cartesian)) {
floatingPoint.position.setValue(cartesian);
positions.pop();
positions.push(cartesian);
}
handleTipOverlay(event.endPosition)
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(event => {
positions.pop();
terminateShape()
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
handler.setInputAction(event => {
terminateShape(true)
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
}
function drawBox(type) {
}
function drawCircle(type) {
let id = null
let radius = 0
let lngLat = []
handler.setInputAction((click) => {
id = new Date().getTime()
let cartesian = viewer.camera.pickEllipsoid(click.position, viewer.scene.globe.ellipsoid)
let cartographic = Cesium.Cartographic.fromCartesian(cartesian, viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
let lng = Cesium.Math.toDegrees(cartographic.longitude)
let lat = Cesium.Math.toDegrees(cartographic.latitude)
lngLat = [lng, lat]
let entity = viewer.entities.add({
position: new Cesium.CallbackProperty(function () { return new Cesium.Cartesian3.fromDegrees(...lngLat, 0) }, false),
name: 'circle',
id: id,
ellipse: {
height: 0,
outline: true,
material: new Cesium.Color.fromCssColorString("#FFD700").withAlpha(.2),
}
})
entity.ellipse.semiMajorAxis = new Cesium.CallbackProperty(function () { return radius }, false)
entity.ellipse.semiMinorAxis = new Cesium.CallbackProperty(function () { return radius }, false)
if (lngLat) {
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
}
handler.setInputAction((move) => {
let cartesian2 = viewer.camera.pickEllipsoid(move.endPosition, viewer.scene.globe.ellipsoid)
radius = Cesium.Cartesian3.distance(cartesian, cartesian2)
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
handler.setInputAction(() => {
Vue.prototype.$Bus.$emit("setLocation", {center: lngLat, radius: radius}, type)
editEntities.push({ id: id, center: lngLat, radius: radius })
handler.destroy();
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}
function drawShape(drawingMode, position) {
var shape;
let defaultDrawStyle = $Params[drawingMode + 'Style']
if(drawingMode === 'Point') {
shape = viewer.entities.add(new Cesium.Entity({
position: position,
point: defaultDrawStyle,
type: drawingMode,
}));
} else if(drawingMode === 'Marker') {
let markerStyle = defaultDrawStyle
if(imgUrl) markerStyle = {...defaultDrawStyle, ...{image: imgUrl}}
shape = viewer.entities.add(new Cesium.Entity({
position: position,
billboard: markerStyle,
type: drawingMode
}));
}
else if (drawingMode === 'PolyLine') {
let polylineStyle = {...defaultDrawStyle, ...{positions: position}}
shape = viewer.entities.add({
polyline: polylineStyle,
type: drawingMode,
material: new Cesium.PolylineGlowMaterialProperty({
color: new Cesium.Color.fromCssColorString('#000'),
}),
depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
color: new Cesium.Color.fromCssColorString('#ccc'),
}),
clampToGround: true,
});
}
else if (drawingMode === 'Polygon') {
let polygonStyle = {...defaultDrawStyle, ...{hierarchy: position}}
shape = viewer.entities.add({
type: drawingMode,
polygon: polygonStyle,
material: new Cesium.Color.fromCssColorString("#FFD700").withAlpha(.2),
});
}
return shape;
}
function terminateShape(bool) {
let dom = document.getElementsByTagName("body")[0]
dom.style.cursor = 'default'
if(tipOverlay) viewer.container.removeChild(tipOverlay);
tipOverlay = undefined
is_click = false
if(handler) {
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
viewer.entities.remove(floatingPoint);
floatingPoint = undefined;
if(bool) {
positions = [];
activeShape = undefined;
viewer.entities.remove(activeShape);
Vue.prototype.$Bus.$emit("setLocation", false);
isExitEditDialog = false;
if(editEntities && editEntities.length > 0) editEntities.forEach(item => viewer.entities.remove(item));
editEntities = [];
}
}
function handleTipOverlay(endPosition) {
if(!tipOverlay) return
tipOverlay.style.position = 'absolute';
tipOverlay.style.color = '#fff';
tipOverlay.style.bottom = '0';
tipOverlay.style.left = '0';
tipOverlay.style['pointer-events'] = 'none';
tipOverlay.style.padding = '4px';
tipOverlay.style.width = '10rem';
tipOverlay.style.height = '2.4rem';
tipOverlay.style.fontSize = '0.14rem';
tipOverlay.style.backgroundColor = 'black';
tipOverlay.style.display = 'block';
if (is_click) {
tipOverlay.textContent = "请单击鼠标左键开始绘制";
} else {
tipOverlay.textContent = "请单击鼠标右键结束绘制,双击清除绘制";
}
tipOverlay.style.bottom = viewer.canvas.clientHeight - endPosition.y + 'px';
tipOverlay.style.left = endPosition.x + 'px';
}
return ConstructDraw;
})()