269 lines
8.6 KiB
JavaScript
269 lines
8.6 KiB
JavaScript
import MouseTip from '../MouseTip'
|
||
import MouseEvent from '../Event'
|
||
import Draw from './draw'
|
||
|
||
/**
|
||
* @extends Draw*/
|
||
class DrawSector extends Draw {
|
||
constructor(sdk, options = {}) {
|
||
super(sdk, options)
|
||
}
|
||
|
||
/**
|
||
* @desc 开始动态绘制面
|
||
* @method start
|
||
* @param cb {function} 回调函数
|
||
* @memberOf DrawRect
|
||
* @example draw.start((err,positions)=>{
|
||
*
|
||
* })
|
||
* */
|
||
start(cb) {
|
||
let that = this
|
||
if (YJ.Measure.GetMeasureStatus()) {
|
||
cb('上一次测量未结束')
|
||
} else {
|
||
super.start()
|
||
let into
|
||
YJ.Measure.SetMeasureStatus(true)
|
||
this.tip = new MouseTip('左键确认,右键取消', that.sdk)
|
||
this.event = new MouseEvent(that.sdk)
|
||
this._sector_id = null; //扇形
|
||
this._positions = []; //活动点
|
||
this.points_ids = []; //脏数据
|
||
this._entities_sector = []; //脏数据
|
||
this._radius = 0; //半径
|
||
this._startAngle = 0; //起始角度
|
||
this._endAngle = 0; //结束角度
|
||
this.event.mouse_left((movement, cartesian) => {
|
||
if(into === '2D') {
|
||
return
|
||
}
|
||
into = '3D'
|
||
// if(that._positions.length == 3) return
|
||
|
||
if (this._positions.length < 3) {
|
||
this.points_ids.push(this.create_point(cartesian));
|
||
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||
}
|
||
else {
|
||
this.end()
|
||
cb(null, { center: this._positions[0], radius: this._radius, startAngle: this._startAngle, endAngle: this._endAngle })
|
||
}
|
||
if (this._positions.length === 2) {
|
||
let pointA = Cesium.Cartesian3.fromDegrees(this._positions[0].lng, this._positions[0].lat, this._positions[0].alt);
|
||
let pointB = cartesian;
|
||
this._radius = Cesium.Cartesian3.distance(pointA, pointB);
|
||
}
|
||
})
|
||
this.event.mouse_move((movement, cartesian) => {
|
||
if(into === '2D') {
|
||
return
|
||
}
|
||
this.tip.setPosition(
|
||
cartesian,
|
||
movement.endPosition.x,
|
||
movement.endPosition.y
|
||
)
|
||
if (this._positions.length < 2) return;
|
||
if (this._positions.length == 2) {
|
||
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||
}
|
||
if (this._positions.length == 3) {
|
||
this._positions.pop();
|
||
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||
if (!Cesium.defined(this._sector_id)) {
|
||
this._sector_id = this.createsector();
|
||
this.points_ids.push(this._sector_id);
|
||
}
|
||
|
||
let options = that.calculateAangle(that._positions)
|
||
that._startAngle = options.angle1;
|
||
that._endAngle = options.angle2;
|
||
}
|
||
|
||
})
|
||
this.event.mouse_right((movement, cartesian) => {
|
||
if(into === '2D') {
|
||
return
|
||
}
|
||
this.end()
|
||
cb(null)
|
||
})
|
||
if (!this._is2D && this._sdk2D) {
|
||
this.event2D = new MouseEvent(this._sdk2D)
|
||
this.event2D.mouse_left((movement, cartesian) => {
|
||
if(into === '3D') {
|
||
return
|
||
}
|
||
into = '2D'
|
||
// if(that._positions.length == 3) return
|
||
|
||
if (this._positions.length < 3) {
|
||
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer));
|
||
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||
}
|
||
else {
|
||
this.end()
|
||
cb(null, { center: this._positions[0], radius: this._radius, startAngle: this._startAngle, endAngle: this._endAngle })
|
||
}
|
||
if (this._positions.length === 2) {
|
||
let pointA = Cesium.Cartesian3.fromDegrees(this._positions[0].lng, this._positions[0].lat, this._positions[0].alt);
|
||
let pointB = cartesian;
|
||
this._radius = Cesium.Cartesian3.distance(pointA, pointB);
|
||
}
|
||
})
|
||
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 (this._positions.length < 2) return;
|
||
if (this._positions.length == 2) {
|
||
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||
}
|
||
if (this._positions.length == 3) {
|
||
this._positions.pop();
|
||
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||
if (!Cesium.defined(this._sector_id)) {
|
||
this._sector_id = this.createsector(this._sdk2D.viewer);
|
||
this.points_ids.push(this._sector_id);
|
||
}
|
||
|
||
let options = that.calculateAangle(that._positions)
|
||
that._startAngle = options.angle1;
|
||
that._endAngle = options.angle2;
|
||
}
|
||
|
||
})
|
||
this.event2D.mouse_right((movement, cartesian) => {
|
||
if(into === '3D') {
|
||
return
|
||
}
|
||
this.end()
|
||
cb(null)
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
//创建直线扇形
|
||
createsector(viewer = this.viewer) {
|
||
// console.log(this._positions)
|
||
let that = this;
|
||
let angle
|
||
let hierarchy = new Cesium.CallbackProperty(
|
||
() => {
|
||
let pList = that.calSector(that._positions[0], that._radius, that._startAngle, that._endAngle)
|
||
return new Cesium.PolygonHierarchy(pList);
|
||
})
|
||
// let text = new Cesium.CallbackProperty(
|
||
// () => {
|
||
// angle = that._endAngle - that._startAngle
|
||
// if (angle < 0) {
|
||
// angle = 360 + angle
|
||
// }
|
||
// return angle.toFixed(2) + '°';
|
||
// })
|
||
let id = that.randomString()
|
||
let arrowEntity = viewer.entities.add({
|
||
id: id,
|
||
position: Cesium.Cartesian3.fromDegrees(that._positions[0].lng, that._positions[0].lat),
|
||
// label: {
|
||
// text,
|
||
// font: "24px Helvetica",
|
||
// fillColor: Cesium.Color.SKYBLUE,
|
||
// outlineColor: Cesium.Color.BLACK,
|
||
// outlineWidth: 2,
|
||
// style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||
// pixelOffset: new Cesium.Cartesian2(0, -12),
|
||
// horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
// disableDepthTestDistance: Number.POSITIVE_INFINITY
|
||
// },
|
||
polygon: {
|
||
hierarchy,
|
||
show: true,
|
||
fill: true,
|
||
clampToGround: true,
|
||
material: Cesium.Color.fromCssColorString(that.color),
|
||
zIndex: 99999999
|
||
}
|
||
}
|
||
)
|
||
that._entities_sector.push(arrowEntity);
|
||
return id
|
||
}
|
||
|
||
cartesianToLatlng(cartesian) {
|
||
let latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
|
||
let lat = Cesium.Math.toDegrees(latlng.latitude);
|
||
let lng = Cesium.Math.toDegrees(latlng.longitude);
|
||
return [lng, lat];
|
||
}
|
||
|
||
/**
|
||
* 经纬度坐标转墨卡托坐标
|
||
*/
|
||
// 墨卡托坐标系:展开地球,赤道作为x轴,向东为x轴正方,本初子午线作为y轴,向北为y轴正方向。
|
||
// 数字20037508.34是地球赤道周长的一半:地球半径6378137米,赤道周长2*PI*r = 2 * 20037508.3427892,墨卡托坐标x轴区间[-20037508.3427892,20037508.3427892]
|
||
lonLatToMercator(Latlng) {
|
||
let E = Latlng[0];
|
||
let N = Latlng[1];
|
||
let x = E * 20037508.34 / 180;
|
||
let y = Math.log(Math.tan((90 + N) * Math.PI / 360)) / (Math.PI / 180);
|
||
y = y * 20037508.34 / 180;
|
||
return [x, y]
|
||
}
|
||
|
||
WebMercator2lonLat(mercator) {
|
||
let x = mercator[0] / 20037508.34 * 180;
|
||
let ly = mercator[1] / 20037508.34 * 180;
|
||
let y = 180 / Math.PI * (2 * Math.atan(Math.exp(ly * Math.PI / 180)) - Math.PI / 2)
|
||
return [x, y];
|
||
}
|
||
|
||
//计算角度
|
||
calculateAangle(arr) {
|
||
function getAangle(start, end) {
|
||
let rad = Math.PI / 180,
|
||
lat1 = start.y * rad,
|
||
lat2 = end.y * rad,
|
||
lon1 = start.x * rad,
|
||
lon2 = end.x * rad;
|
||
const a = Math.sin(lon2 - lon1) * Math.cos(lat2);
|
||
const b =
|
||
Math.cos(lat1) * Math.sin(lat2) -
|
||
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
|
||
const radians = Math.atan2(a, b)
|
||
const degrees = radians % (2 * Math.PI);
|
||
let bearing = 450 - ((degrees * 180) / Math.PI < 0
|
||
? 360 + (degrees * 180) / Math.PI
|
||
: (degrees * 180) / Math.PI) - 90;
|
||
return 360 - (bearing % 360)
|
||
}
|
||
|
||
let center = arr[0]
|
||
let pos84_1 = arr[1]
|
||
let pos84_2 = arr[2]
|
||
|
||
let start = { x: center.lng, y: center.lat }
|
||
let end1 = { x: pos84_1.lng, y: pos84_1.lat }
|
||
let end2 = { x: pos84_2.lng, y: pos84_2.lat }
|
||
|
||
let angle1 = getAangle(start, end1)
|
||
let angle2 = getAangle(start, end2)
|
||
|
||
return {
|
||
angle1,
|
||
angle2
|
||
}
|
||
}
|
||
}
|
||
|
||
export default DrawSector
|