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
|