import MouseTip from '../MouseTip' import MouseEvent from '../Event' import Draw from './draw' const transformCartesianToWGS84 = cartesian => { let ellipsoid = Cesium.Ellipsoid.WGS84 let cartographic = ellipsoid.cartesianToCartographic(cartesian) const x = Cesium.Math.toDegrees(cartographic.longitude) const y = Cesium.Math.toDegrees(cartographic.latitude) const z = cartographic.height return { x, y, z } } /** * @extends Draw*/ class DrawAssemble extends Draw { /** * @constructor * @param sdk * @param [options] {object} 面属性 * @param [options.color=rgba(185,14,14,0.58)] {object} 线属性 * */ constructor(sdk, options = {}) { super(sdk, options) this.points = null this.polygonHasCreated = false } static polygon(that, viewer = that.viewer) { let id = that.randomString() return viewer.entities.add( new Cesium.Entity({ name: 'AssemblePolygon', id, polygon: { hierarchy: new Cesium.CallbackProperty(e => { let arr = that.computeAssemble(that.positions) for (let i = 0; i < arr.length; i++) { if (isNaN(arr[i].x)) { arr = [] break } } return new Cesium.PolygonHierarchy(arr) }, false), material: Cesium.Color.fromCssColorString(that.color), outline: true, outlineColor: Cesium.Color.GREEN, zIndex: 99999999 } }) ) } /** * @desc 开始动态绘制面 * @method start * @param cb {function} 回调函数 * @memberOf DrawPolygon * @example draw.start((err,positions)=>{ * * }) * */ start(cb) { let that = this // eslint-disable-next-line no-undef if (YJ.Measure.GetMeasureStatus()) { cb('上一次测量未结束') } else { super.start() // eslint-disable-next-line no-undef YJ.Measure.SetMeasureStatus(true) let into this.tip = new MouseTip('左键确定,右键取消;', that.sdk) this.event = new MouseEvent(that.sdk) this.positions = [] this.points_ids = [] //存放左键点击时临时添加的point的id let cache_positions = [] let cache_84_position = [] this.anchorpoints = [] this.event.mouse_left((movement, cartesian) => { if (into === '2D') { return } into = '3D' if (!cartesian) return if (this.anchorpoints.length === 3) { this.anchorpoints[1] = cartesian; } else { this.anchorpoints.push(cartesian) } cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer)) // console.log(this.cartesian3Towgs84(cartesian)) this.points_ids.push(this.create_point(cartesian)) if (this.points_ids.length === 3) { let array = [cache_positions[0], cache_positions[2], cache_positions[1]] cb(null, array) this.end() } }) this.event.mouse_move((movement, cartesian) => { if (into === '2D') { return } this.tip.setPosition( cartesian, movement.endPosition.x, movement.endPosition.y ) if (!cartesian || this.points_ids.length === 0) return if (cache_positions.length > 1) { this.positions = [cache_positions[0], this.cartesian3Towgs84(cartesian, this.viewer), cache_positions[1]] } else { this.positions = [cache_positions[0], this.cartesian3Towgs84(cartesian, this.viewer)] } if (this.points_ids.length === 1 && !Cesium.defined(this.assemblePolygon)) { this.assemblePolygon = DrawAssemble.polygon(this) } if (this.anchorpoints.length >= 2) { if (this.points_ids.length === 1) { let pnts = new Array(); this.positions.forEach((item) => { if(item.lng<-90) { item.lng += 360 } pnts.push([item.lng, item.lat]); }); let mid = P.PlotUtils.mid(pnts[0], pnts[1]) let d = P.PlotUtils.distance(pnts[0], mid) / 0.9 let pnt = P.PlotUtils.getThirdPoint(pnts[0], mid, P.Constants.HALF_PI, d, true) this.positions = [this.positions[0], { lng: pnt[0], lat: pnt[1] }, this.positions[1]]; } //替换中间点 this.anchorpoints[1] = cartesian; } else { this.anchorpoints.push(cartesian) } }) this.event.mouse_right((movement, cartesian) => { if (into === '2D') { return } cb(null) this.end() }) this.event.gesture_pinck_start((movement, cartesian) => { if (into === '2D') { return } let startTime = new Date() this.event.gesture_pinck_end(() => { let endTime = new Date() if (endTime - startTime >= 500) { this.end() cb(false) } else { if (this.anchorpoints.length === 2) { this.anchorpoints.push(cartesian) cb(null, this.positions) this.end() } else { if (!cartesian || Cesium.defined(this.assemblePolygon)) return this.tip.setPosition( cartesian, (movement.position1.x + movement.position2.x) / 2, (movement.position1.y + movement.position2.y) / 2 ) this.anchorpoints.push(cartesian) this.assemblePolygon = DrawAssemble.polygon(this) cache_positions.push(this.cartesian3Towgs84(cartesian)) // console.log(this.cartesian3Towgs84(cartesian)) this.points_ids.push(this.create_point(cartesian)) } } }) }) if (!this._is2D && this._sdk2D) { this.event2D = new MouseEvent(this._sdk2D) this.event2D.mouse_left((movement, cartesian) => { if (into === '3D') { return } into = '2D' if (!cartesian) return if (this.anchorpoints.length === 3) { this.anchorpoints[1] = cartesian; } else { this.anchorpoints.push(cartesian) } cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer)) // console.log(this.cartesian3Towgs84(cartesian)) this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer)) if (this.points_ids.length === 3) { let array = [cache_positions[0], cache_positions[2], cache_positions[1]] cb(null, array) this.end() } }) this.event2D.mouse_move((movement, cartesian) => { if (into === '3D') { return } this.tip.setPosition( cartesian, movement.endPosition.x + this.viewer.canvas.width, movement.endPosition.y ) if (!cartesian || this.points_ids.length === 0) return if (cache_positions.length > 1) { this.positions = [cache_positions[0], this.cartesian3Towgs84(cartesian, this.viewer), cache_positions[1]] } else { this.positions = [cache_positions[0], this.cartesian3Towgs84(cartesian, this.viewer)] } if (this.points_ids.length === 1 && !Cesium.defined(this.assemblePolygon)) { this.assemblePolygon = DrawAssemble.polygon(this, this._sdk2D.viewer) } if (this.anchorpoints.length >= 2) { if (this.points_ids.length === 1) { let pnts = new Array(); this.positions.forEach((item) => { pnts.push([item.lng, item.lat]); }); let mid = P.PlotUtils.mid(pnts[0], pnts[1]) let d = P.PlotUtils.distance(pnts[0], mid) / 0.9 let pnt = P.PlotUtils.getThirdPoint(pnts[0], mid, P.Constants.HALF_PI, d, true) this.positions = [this.positions[0], { lng: pnt[0], lat: pnt[1] }, this.positions[1]]; } //替换中间点 this.anchorpoints[1] = cartesian; } else { this.anchorpoints.push(cartesian) } }) this.event2D.mouse_right((movement, cartesian) => { if (into === '3D') { return } cb(null) this.end() }) this.event2D.gesture_pinck_start((movement, cartesian) => { if (into === '3D') { return } let startTime = new Date() this.event2D.gesture_pinck_end(() => { let endTime = new Date() if (endTime - startTime >= 500) { this.end() cb(false) } else { if (this.anchorpoints.length === 2) { this.anchorpoints.push(cartesian) cb(null, this.positions) this.end() } else { if (!cartesian || Cesium.defined(this.assemblePolygon)) return this.tip.setPosition( cartesian, ((movement.position1.x + movement.position2.x) / 2) + this.viewer.canvas.width, (movement.position1.y + movement.position2.y) / 2 ) this.anchorpoints.push(cartesian) this.assemblePolygon = DrawAssemble.polygon(this, this._sdk2D.viewer) cache_positions.push(this.cartesian3Towgs84(cartesian)) // console.log(this.cartesian3Towgs84(cartesian)) this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer)) } } }) }) } } } end() { super.end(); this.viewer.entities.remove(this.assemblePolygon) if (!this._is2D && this._sdk2D) { this._sdk2D.viewer.entities.remove(this.assemblePolygon) } } // computeAssemblePoints(anchorpoints) { // let points = [] // let originP = transformCartesianToWGS84(anchorpoints[0]) // let lastP = anchorpoints[1] // ? transformCartesianToWGS84(anchorpoints[1]) // : { x: originP.x + 0.00001, y: originP.y + 0.00001, z: originP.z } // let vectorOL = { x: lastP.x - originP.x, y: lastP.y - originP.y } // let dOL = Math.sqrt(vectorOL.x * vectorOL.x + vectorOL.y * vectorOL.y) // let v_O_P1_lr = this.calculateVector( // vectorOL, // Math.PI / 3, // (Math.sqrt(3) / 12) * dOL // ) // let originP_P1 = v_O_P1_lr[1] // let p1 = { x: originP.x + originP_P1.x, y: originP.y + originP_P1.y } // let p2 = { x: (originP.x + lastP.x) / 2, y: (originP.y + lastP.y) / 2 } // let v_L_P3_lr = this.calculateVector( // vectorOL, // (Math.PI * 2) / 3, // (Math.sqrt(3) / 12) * dOL // ) // let lastP_P3 = v_L_P3_lr[1] // let p3 = { x: lastP.x + lastP_P3.x, y: lastP.y + lastP_P3.y } // let v_O_P5_lr = this.calculateVector(vectorOL, Math.PI / 2, (1 / 2) * dOL) // let v_O_P5 = v_O_P5_lr[0] // let p5 = { x: v_O_P5.x + p2.x, y: v_O_P5.y + p2.y } // let p0 = originP // let p4 = lastP // points.push(p0, p1, p2, p3, p4, p5) // const closeCardinal = this.createCloseCardinal(points) // const fb_points = this.calculatePointsFBZ3(closeCardinal, 100) // let result = [] // let result2 = [] // for (let index = 0; index < fb_points.length; index++) { // const ele = fb_points[index] // let obj = { // lng: ele.x, // lat: ele.y, // alt: 0 // } // result.push(ele.x, ele.y, 0) // result2.push(obj) // } // this.position = result2 // this.points = result // } // computeAssemblePoints2(anchorpoints) { // let points = anchorpoints.length; // if (points < 2) { // return false // } else { // let pnts = new Array(); // anchorpoints.forEach((item) => { // let posLonLat = this.cartesian3Towgs84(item, this.viewer);; // pnts.push([posLonLat.lng, posLonLat.lat]); // }); // //console.log("pnts6666",pnts); // // pnts.push(tailPoint); // // pnts.push(headerPoint); // if (pnts.length === 2) { // let mid = P.PlotUtils.mid(pnts[0], pnts[1]) // //let d = utils.MathDistance(pnts[0], mid) / 0.9 // let d = P.PlotUtils.distance(pnts[0], mid) / 0.9 // //console.log("d",d); // let pnt = P.PlotUtils.getThirdPoint(pnts[0], mid, P.Constants.HALF_PI, d, true) // pnts = [pnts[0], pnt, pnts[1]]; // //console.log("pnt",pnt); // //createPoint(Cesium.Cartesian3.fromDegrees(pnt[0], pnt[1])); // } // let mid = P.PlotUtils.mid(pnts[0], pnts[2]) // pnts.push(mid, pnts[0], pnts[1]) // let [normals, pnt1, pnt2, pnt3, result, result2] = [[], undefined, undefined, undefined, [], []] // for (let i = 0; i < pnts.length - 2; i++) { // pnt1 = pnts[i] // pnt2 = pnts[i + 1] // pnt3 = pnts[i + 2] // let normalPoints = P.PlotUtils.getBisectorNormals(0.4, pnt1, pnt2, pnt3) // normals = normals.concat(normalPoints) // } // let count = normals.length // normals = [normals[count - 1]].concat(normals.slice(0, count - 1)) // for (let i = 0; i < pnts.length - 2; i++) { // pnt1 = pnts[i] // pnt2 = pnts[i + 1] // result = result.concat([...pnt1, 0]) // result2.push( // { // lng: pnt1[0], // lat: pnt1[1], // alt: 0 // } // ) // for (let t = 0; t <= P.Constants.FITTING_COUNT; t++) { // let pnt = P.PlotUtils.getCubicValue(t / P.Constants.FITTING_COUNT, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2) // result = result.concat([...pnt, 0]) // result2.push( // { // lng: pnt[0], // lat: pnt[1], // alt: 0 // } // ) // } // result = result.concat([...pnt2, 0]) // result2.push( // { // lng: pnt2[0], // lat: pnt2[1], // alt: 0 // } // ) // } // this.position = result2 // this.points = result // } // } calculateVector(v, theta, d) { if (!theta) theta = Math.PI / 2 if (!d) d = 1 let x_1 let x_2 let y_1 let y_2 let v_l let v_r let d_v = Math.sqrt(v.x * v.x + v.y * v.y) if (v.y == 0) { x_1 = x_2 = (d_v * d * Math.cos(theta)) / v.x if (v.x > 0) { y_1 = Math.sqrt(d * d - x_1 * x_1) y_2 = -y_1 } else if (v.x < 0) { y_2 = Math.sqrt(d * d - x_1 * x_1) y_1 = -y_2 } v_l = { x: x_1, y: y_1 } v_r = { x: x_2, y: y_2 } } else { let n = -v.x / v.y let m = (d * d_v * Math.cos(theta)) / v.y let a = 1 + n * n let b = 2 * n * m let c = m * m - d * d x_1 = (-b - Math.sqrt(b * b - 4 * a * c)) / (2 * a) x_2 = (-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a) y_1 = n * x_1 + m y_2 = n * x_2 + m if (v.y >= 0) { v_l = { x: x_1, y: y_1 } v_r = { x: x_2, y: y_2 } } else if (v.y < 0) { v_l = { x: x_2, y: y_2 } v_r = { x: x_1, y: y_1 } } } return [v_l, v_r] } createCloseCardinal(points) { if (points == null || points.length < 3) { return points } //获取起点,作为终点,以闭合曲线。 let lastP = points[0] points.push(lastP) //定义传入的点数组,将在点数组中央(每两个点)插入两个控制点 let cPoints = points //包含输入点和控制点的数组 let cardinalPoints = [] //至少三个点以上 //这些都是相关资料测出的经验数值 //定义张力系数,取值在0 0) { scale = 1 / part } for (let i = 0; i < points.length - 3;) { //起始点 let pointS = points[i] //第一个控制点 let pointC1 = points[i + 1] //第二个控制点 let pointC2 = points[i + 2] //结束点 let pointE = points[i + 3] bezierPts.push(pointS) for (let t = 0; t < 1;) { //三次贝塞尔曲线公式 let x = (1 - t) * (1 - t) * (1 - t) * pointS.x + 3 * t * (1 - t) * (1 - t) * pointC1.x + 3 * t * t * (1 - t) * pointC2.x + t * t * t * pointE.x let y = (1 - t) * (1 - t) * (1 - t) * pointS.y + 3 * t * (1 - t) * (1 - t) * pointC1.y + 3 * t * t * (1 - t) * pointC2.y + t * t * t * pointE.y let point = { x: x, y: y } bezierPts.push(point) t += scale } i += 3 if (i >= points.length) { bezierPts.push(pointS) } } return bezierPts } } export default DrawAssemble