123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- // DrawSector
- /*
- 九、绘制扇形
- */
- class DrawSector {
- constructor(arg) {
- this.viewer = arg.viewer;
- this.Cesium = arg.Cesium;
- this.floatingPoint = null;//标识点
- this._sector = null; //活动扇形
- this._sectorLast = null; //最后一个扇形
- this._positions = []; //活动点
- this._entities_point = []; //脏数据
- this._entities_sector = []; //脏数据
- this._sectorData = null; //用于构造扇形数据
- this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
- this.DrawEndEvent = new Cesium.Event(); //结束绘制事件
-
- /* 通用参数集合 */
- this._param = {
- id: "DrawStraightArrow",
- polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
- outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
- outlineWidth: 1, //边框宽度
- }
-
- /* 创建面材质 */
- this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
- /* 创建线材质 */
- // this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
- // dashLength: 16,
- // color: Cesium.Color.fromCssColorString(this._param.outlineColor)
- // });
- this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
- }
- //返回扇形
- get sector() {
- return this._sectorLast;
- }
- //返回扇形数据用于加载扇形
- getData() {
- return this._sectorData;
- }
- // 修改编辑调用计算
- computePosition(data){
- let $this = this;
- let pnts = data;
- let center = $this.lonLatToMercator($this.cartesianToLatlng(pnts[0]));
- let pnt2 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[1]));
- let pnt3 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[2]));
- var radius = $this.MathDistance(pnt2, center);
- var startAngle = $this.getAzimuth(pnt2, center);
- var endAngle = $this.getAzimuth(pnt3, center);
- var pList = $this.getArcPoints(center, radius, startAngle, endAngle);
- pList.push(pnts[0], pList[0]);
- let arrow = [];
- for (var i = 0; i < pList.length; i++) {
- var cart3 = new $this.Cesium.Cartesian3(pList[i].x, pList[i].y, pList[i].z);
- arrow.push(cart3);
- }
- var lnglatArr = [];
- for (var d = 0; d < data.length; d++){
- lnglatArr.push($this.cartesianToLatlng(data[d]))
- }
- $this._sectorData = lnglatArr;
- return new $this.Cesium.PolygonHierarchy(arrow)
- }
- //加载扇形
- addload(data) {
- var $this = this;
- let pnts = data;
- let center = $this.lonLatToMercator(pnts[0]);
- let pnt2 = $this.lonLatToMercator(pnts[1]);
- let pnt3 = $this.lonLatToMercator(pnts[2]);
- var radius = $this.MathDistance(pnt2, center);
- var startAngle = $this.getAzimuth(pnt2, center);
- var endAngle = $this.getAzimuth(pnt3, center);
- var pList = $this.getArcPoints(center, radius, startAngle, endAngle);
- let pntsc = $this.Cesium.Cartesian3.fromDegrees(pnts[0][0], pnts[0][1])
- pList.push(pntsc, pList[0]);
- let arrow = [];
- for (var i = 0; i < pList.length; i++) {
- var cart3 = new $this.Cesium.Cartesian3(pList[i].x, pList[i].y, pList[i].z);
- arrow.push(cart3);
- }
- var arrowEntity = $this.viewer.entities.add({
- Type: 'DrawSector',
- Position: data,
- id: data.id || $this.objId,
- polygon: {
- hierarchy: new $this.Cesium.PolygonHierarchy(arrow),
- show: true,
- fill: true,
- clampToGround: true,
- material: $this.Cesium.Color.AQUA.withAlpha(0.9)
- }
- });
- return arrowEntity;
- }
- //开始创建
- startCreate() {
- var $this = this;
- this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
- this.handler.setInputAction(function (evt) { //单机开始绘制
- //屏幕坐标转地形上坐标
- var cartesian = $this.getCatesian3FromPX(evt.position);
- // if($this._positions.length == 3) return
- if ($this._positions.length < 3) {
- $this.floatingPoint = $this.createPoint(cartesian);
- $this._positions.push(cartesian);
- }
- if (!$this._sector) {
- // $this.createPoint(cartesian);// 绘制点
- }
- }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
- this.handler.setInputAction(function (evt) { //移动时绘制面
- if ($this._positions.length < 2) return;
- var cartesian = $this.getCatesian3FromPX(evt.endPosition);
- if ($this._positions.length == 2) {
- $this._positions.push(cartesian);
- }
- if ($this._positions.length == 3) {
- $this._positions.pop();
- $this._positions.push(cartesian);
- if (!$this.Cesium.defined($this._sector)) {
- $this._sector = $this.createsector();
- }
- }
- }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
- this.handler.setInputAction(function (evt) {
- if (!$this._sector) return;
- var cartesian = $this.getCatesian3FromPX(evt.position);
- $this._positions.pop();
- $this._positions.push(cartesian);
- $this._sectorData = $this._positions.concat();
- $this.viewer.entities.remove($this._sector); //移除
- $this._sector = null;
- $this._positions = [];
- $this.floatingPoint.position.setValue(cartesian);
- var lnglatArr = [];
- for (var i = 0; i < $this._sectorData.length; i++) {
- var lnglat = $this.cartesianToLatlng($this._sectorData[i]);
- lnglatArr.push(lnglat)
- }
- $this._sectorData = lnglatArr;
- var sector = $this.addload(lnglatArr); //加载
- $this._entities_sector.push(sector);
- $this._sectorLast = sector;
- $this.clearPoint();
- $this.destroy()
- }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
- }
- //创建直线扇形
- createsector() {
- // console.log(this._positions)
- var $this = this;
- var arrowEntity = $this.viewer.entities.add({
- polygon: {
- hierarchy: new $this.Cesium.CallbackProperty(
- function () {
- // if(this._positions.length < 3) return
- let pnts = $this._positions;
- let center = $this.lonLatToMercator($this.cartesianToLatlng(pnts[0]));
- let pnt2 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[1]));
- let pnt3 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[2]));
- var radius = $this.MathDistance(pnt2, center);
- var startAngle = $this.getAzimuth(pnt2, center);
- var endAngle = $this.getAzimuth(pnt3, center);
- var pList = $this.getArcPoints(center, radius, startAngle, endAngle);
- pList.push(pnts[0], pList[0]);
- let arrow = [];
- for (var i = 0; i < pList.length; i++) {
- var cart3 = new $this.Cesium.Cartesian3(pList[i].x, pList[i].y, pList[i].z);
- arrow.push(cart3);
- }
- return new $this.Cesium.PolygonHierarchy(pList);
- }, false),
- show: true,
- fill: true,
- clampToGround: true,
- material: $this.Cesium.Color.AQUA.withAlpha(0.5)
- }
- }
- )
- $this._entities_sector.push(arrowEntity);
- return arrowEntity
- }
- //创建点
- createPoint(cartesian) {
- var $this = this;
- var point = this.viewer.entities.add({
- position: cartesian,
- point: {
- pixelSize: 10,
- color: $this.Cesium.Color.RED,
- heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
- }
- });
- $this._entities_point.push(point);
- return point;
- }
- cartesianToLatlng(cartesian) {
- var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
- var lat = this.Cesium.Math.toDegrees(latlng.latitude);
- var lng = this.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) {
- var E = Latlng[0];
- var N = Latlng[1];
- var x = E * 20037508.34 / 180;
- var 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];
- }
- //销毁
- destroy() {
- if (this.handler) {
- this.handler.destroy();
- this.handler = null;
- }
- }
- clearPoint() {
- this.DrawEndEvent.raiseEvent(this._sectorLast, this._sectorData);
- for (var i = 0; i < this._entities_point.length; i++) {
- this.viewer.entities.remove(this._entities_point[i]);
- }
- this._entities_point = []; //脏数据
- }
- //清空实体对象
- 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_sector.length; i++) {
- this.viewer.entities.remove(this._entities_sector[i]);
- }
- this.floatingPoint = null;//标识点
- this._sector = null; //活动扇形
- this._sectorLast = null; //最后一个扇形
- this._positions = []; //活动点
- this._entities_point = []; //脏数据
- this._entities_sector = []; //脏数据
- this._sectorData = null; //用于构造扇形数据
- }
- 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;
- }
- // 求取扇形坐标函数/
- //扇形配置函数
- MathDistance(pnt1, pnt2) {
- return Math.sqrt(Math.pow(pnt1[0] - pnt2[0], 2) + Math.pow(pnt1[1] - pnt2[1], 2));
- }
- getAzimuth(startPoint, endPoint) {
- var azimuth;
- var angle = Math.asin(Math.abs(endPoint[1] - startPoint[1]) / this.MathDistance(startPoint, endPoint));
- if (endPoint[1] >= startPoint[1] && endPoint[0] >= startPoint[0]) {
- azimuth = angle + Math.PI;
- } else if (endPoint[1] >= startPoint[1] && endPoint[0] < startPoint[0]) {
- azimuth = Math.PI * 2 - angle;
- } else if (endPoint[1] < startPoint[1] && endPoint[0] < startPoint[0]) {
- azimuth = angle;
- } else if (endPoint[1] < startPoint[1] && endPoint[0] >= startPoint[0]) {
- azimuth = Math.PI - angle;
- }
- return azimuth;
- }
- getArcPoints(center, radius, startAngle, endAngle) {
- var x = null,
- y = null,
- z = null,
- pnts = [],
- angleDiff = endAngle - startAngle;
- angleDiff = angleDiff < 0 ? angleDiff + Math.PI * 2 : angleDiff;
- for (var i = 0; i <= 100; i++) {
- var angle = startAngle + angleDiff * i / 100;
- x = center[0] + radius * Math.cos(angle);
- y = center[1] + radius * Math.sin(angle);
- let latlon = this.WebMercator2lonLat([x, y])
- pnts.push(this.Cesium.Cartesian3.fromDegrees(latlon[0], latlon[1]));
- }
- return pnts;
- }
- }
- export default DrawSector
|