123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534 |
- /*
- 九、绘制弓形线
- */
- class DrawBowLine {
- constructor(arg) {
- this.viewer = arg.viewer;
- this.Cesium = arg.Cesium;
- this.tt = 0.4;
- this.floatingPoint = null; //标识点
- this.drawHandler = null; //画事件
- this.DrawBowLine = null; //弓形
- this._DrawBowLineLast = null; //最后一个弓形
- this._positions = []; //活动点
- this._entities_point = []; //脏数据
- this._entities_PincerArrow = []; //脏数据
- this._DrawBowLineData = 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 PincerArrow() {
- return this._DrawBowLineLast;
- }
- //返回弓形数据用于加载弓形
- getData() {
- return this._DrawBowLineData;
- }
- // 修改编辑调用计算
- computePosition(data) {
- var $this = this;
- if (data.length < 3) {
- return;
- }
- var DrawBowLine = [];
- let positions = [];
- for (var i = 0; i < data.length; i++) {
- positions.push($this.cartesianToLatlng(data[i]));
- var cart3 = $this.lonLatToMercator($this.cartesianToLatlng(data[i]));
- DrawBowLine.push(cart3);
- }
- let [pnt1, pnt2, pnt3, startAngle, endAngle] = [DrawBowLine[0], DrawBowLine[2], DrawBowLine[1], null, null];
- let center = $this.getCircleCenterOfThreePoints(pnt1, pnt2, pnt3)
- let radius = $this.MathDistance(pnt1, center)
- let angle1 = $this.getAzimuth(pnt1, center)
- let angle2 = $this.getAzimuth(pnt2, center)
- if ($this.isClockWise(pnt1, pnt2, pnt3)) {
- startAngle = angle2
- endAngle = angle1
- } else {
- startAngle = angle1
- endAngle = angle2
- }
- let getArcPoint = $this.getArcPoints(center, radius, startAngle, endAngle);
- let pHierarchy = [];
- for (var l = 0; l < getArcPoint.length; l++) {
- var cart3 = $this.LatlngTocartesian($this.WebMercator2lonLat(getArcPoint[l]));
- pHierarchy.push(cart3);
- }
- $this._DrawBowLineData = positions
- return pHierarchy
- }
- //加载
- addload(data) {
- var $this = this;
- if (data.length < 3) {
- return;
- }
- var DrawBowLine = [];
- for (var i = 0; i < data.length; i++) {
- var cart3 = $this.lonLatToMercator(data[i]);
- DrawBowLine.push(cart3);
- }
- let [pnt1, pnt2, pnt3, startAngle, endAngle] = [DrawBowLine[0], DrawBowLine[2], DrawBowLine[1], null, null];
- let center = $this.getCircleCenterOfThreePoints(pnt1, pnt2, pnt3)
- let radius = $this.MathDistance(pnt1, center)
- let angle1 = $this.getAzimuth(pnt1, center)
- let angle2 = $this.getAzimuth(pnt2, center)
- if ($this.isClockWise(pnt1, pnt2, pnt3)) {
- startAngle = angle2
- endAngle = angle1
- } else {
- startAngle = angle1
- endAngle = angle2
- }
- let getArcPoint = $this.getArcPoints(center, radius, startAngle, endAngle);
- // console.log(getArcPoint)
- let pHierarchy = [];
- for (var l = 0; l < getArcPoint.length; l++) {
- var cart3 = $this.LatlngTocartesian($this.WebMercator2lonLat(getArcPoint[l]));
- pHierarchy.push(cart3);
- }
- var arrowEntity = $this.viewer.entities.add({
- Type: 'DrawBowLine',
- Position: data,
- id: data.id || $this.objId,
- polyline: {
- positions: pHierarchy,
- show: true,
- material: $this.Cesium.Color.YELLOW,
- width: 3,
- clampToGround: true
- }
- })
- return arrowEntity
- }
- // 开始创建
- startCreate(drawType) {
- this.drawType = drawType
- var $this = this;
- this.handler = new $this.Cesium.ScreenSpaceEventHandler($this.viewer.scene.canvas);
- this.handler.setInputAction(function(event) {
- //屏幕坐标转世界坐标
- var position = event.position;
- if (!$this.Cesium.defined(position)) {
- return;
- }
- var ray = $this.viewer.camera.getPickRay(position);
- if (!$this.Cesium.defined(ray)) {
- return;
- }
- var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene);
- if (!$this.Cesium.defined(cartesian)) {
- return;
- }
- if ($this._positions.length == 0) {
- $this._positions.push(cartesian.clone());
- $this.floatingPoint = $this.createPoint(cartesian);
- }
- if ($this._positions.length <= 2) {
- $this.createPoint(cartesian); // 绘制点
- $this._positions.push(cartesian);
- }
- }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
- this.handler.setInputAction(function(event) { //移动时绘制面
- //console.log("_positions",_positions);
- if ($this._positions.length < 2) {
- return;
- }
- //屏幕坐标转世界坐标
- var position = event.endPosition;
- if (!$this.Cesium.defined(position)) {
- return;
- }
- var ray = $this.viewer.camera.getPickRay(position);
- if (!$this.Cesium.defined(ray)) {
- return;
- }
- var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene);
- if (!$this.Cesium.defined(cartesian)) {
- return;
- }
- //console.log("点击地图移动采集的点:",cartesian);
- if (!$this.Cesium.defined($this.DrawBowLine)) {
- $this.DrawBowLine = $this.createDrawBowLine();
- }
- $this.floatingPoint.position.setValue(cartesian);
- if ($this.DrawBowLine) {
- //替换最后一个点
- // _positions.pop();
- // _positions.push(cartesian);
- //替换中间点
- if ($this._positions.length == 3) {
- $this._positions[1] = cartesian;
- } else {
- $this._positions.pop();
- $this._positions.push(cartesian);
- }
- }
- }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
- //右击停止采集
- this.handler.setInputAction(function(movement) {
- if ($this._positions.length >= 3) {
- $this._DrawBowLineData = $this._positions.concat();
- $this.viewer.entities.remove($this.DrawBowLine); //移除
- $this.DrawBowLine = null;
- var lnglatArr = [];
- for (var i = 0; i < $this._DrawBowLineData.length; i++) {
- var lnglat = $this.cartesianToLatlng($this._DrawBowLineData[i]);
- lnglatArr.push(lnglat)
- }
- $this._DrawBowLineData = lnglatArr;
- var pincerArrow = $this.addload(lnglatArr); //加载
- $this._entities_PincerArrow.push(pincerArrow);
- $this._DrawBowLineLast = pincerArrow;
- $this.viewer.entities.remove($this.floatingPoint);
- $this.floatingPoint = null;
- //删除关键点
- $this.clearPoint();
- $this.destroy()
- }
- }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
- }
- //创建弓形
- createDrawBowLine() {
- let $this = this
- var DrawBowLineEntity = $this.viewer.entities.add({
- polyline: {
- positions: new $this.Cesium.CallbackProperty(function() {
- if ($this._positions.length < 3) {
- return;
- }
- var DrawBowLine = [];
- for (var i = 0; i < $this._positions.length; i++) {
- var cart3 = $this.lonLatToMercator($this.cartesianToLatlng($this._positions[i]));
- DrawBowLine.push(cart3);
- }
- let [pnt1, pnt2, pnt3, startAngle, endAngle] = [DrawBowLine[0], DrawBowLine[2], DrawBowLine[1], null, null];
- let center = $this.getCircleCenterOfThreePoints(pnt1, pnt2, pnt3)
- let radius = $this.MathDistance(pnt1, center)
- let angle1 = $this.getAzimuth(pnt1, center)
- let angle2 = $this.getAzimuth(pnt2, center)
- if ($this.isClockWise(pnt1, pnt2, pnt3)) {
- startAngle = angle2
- endAngle = angle1
- } else {
- startAngle = angle1
- endAngle = angle2
- }
- let getArcPoint = $this.getArcPoints(center, radius, startAngle, endAngle);
- // console.log(getArcPoint)
- let pHierarchy = [];
- for (var l = 0; l < getArcPoint.length; l++) {
- var cart3 = $this.LatlngTocartesian($this.WebMercator2lonLat(getArcPoint[l]));
- pHierarchy.push(cart3);
- }
- return pHierarchy
- }, false),
- show: true,
- material: $this.Cesium.Color.YELLOW,
- width: 3,
- clampToGround: true
- }
- })
- //$this._entities_DrawBowLine.push(DrawBowLineEntity);
- // DrawBowLineEntity.valueFlag = "value";
- $this._entities_PincerArrow.push(DrawBowLineEntity);
- return DrawBowLineEntity
- }
- //创建点
- 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) {
- let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
- let lat = this.Cesium.Math.toDegrees(cartographic.latitude);
- let lng = this.Cesium.Math.toDegrees(cartographic.longitude);
- let alt = cartographic.height;
- return [lng, lat];
- }
- //销毁
- destroy() {
- if (this.handler) {
- this.handler.destroy();
- this.handler = null;
- }
- }
- clearPoint() {
- this.DrawEndEvent.raiseEvent(this._DrawBowLineLast, this._DrawBowLineData, this.drawType);
- 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_PincerArrow.length; i++) {
- this.viewer.entities.remove(this._entities_PincerArrow[i]);
- }
- this.floatingPoint = null; //标识点
- this._PincerArrow = null; //活动弓形
- this._PincerArrowLast = null; //最后一个弓形
- this._positions = []; //活动点
- this._entities_point = []; //脏数据
- this._entities_PincerArrow = []; //脏数据
- this._PincerArrowData = 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;
- }
- _computeTempPositions() {
- var _this = this;
- var pnts = [].concat(_this._positions);
- var num = pnts.length;
- var first = pnts[0];
- var last = pnts[num - 1];
- if (_this._isSimpleXYZ(first, last) == false) {
- pnts.push(first);
- num += 1;
- }
- _this.tempPositions = [];
- for (var i = 1; i < num; i++) {
- var p1 = pnts[i - 1];
- var p2 = pnts[i];
- var cp = _this._computeCenterPotition(p1, p2);
- _this.tempPositions.push(p1);
- _this.tempPositions.push(cp);
- }
- }
- _isSimpleXYZ(p1, p2) {
- if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) {
- return true;
- }
- return false;
- }
- _computeCenterPotition(p1, p2) {
- var _this = this;
- var c1 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p1);
- var c2 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p2);
- var cm = new _this.Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5);
- var cp = _this.viewer.scene.globe.ellipsoid.cartographicToCartesian(cm);
- return cp;
- }
- /**
- * 笛卡尔坐标转经纬度坐标
- */
- getLonLat(cartesian) {
- var cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
- cartographic.height = this.viewer.scene.globe.getHeight(cartographic);
- var pos = {
- lon: cartographic.longitude,
- lat: cartographic.latitude,
- alt: cartographic.height
- };
- pos.lon = this.Cesium.Math.toDegrees(pos.lon);
- pos.lat = this.Cesium.Math.toDegrees(pos.lat);
- return pos;
- }
- LatlngTocartesian(latlng) {
- let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]);
- return cartesian3
- }
- /**
- * 经纬度坐标转墨卡托坐标
- */
- // 墨卡托坐标系:展开地球,赤道作为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];
- }
- ////////////////////////////////////////弓形/////////////////////////////////////////////////////
- /**
- * 通过三个点确定一个圆的中心点
- * @param point1
- * @param point2
- * @param point3
- */
- getCircleCenterOfThreePoints(point1, point2, point3) {
- let pntA = [(point1[0] + point2[0]) / 2, (point1[1] + point2[1]) / 2]
- let pntB = [pntA[0] - point1[1] + point2[1], pntA[1] + point1[0] - point2[0]]
- let pntC = [(point1[0] + point3[0]) / 2, (point1[1] + point3[1]) / 2]
- let pntD = [pntC[0] - point1[1] + point3[1], pntC[1] + point1[0] - point3[0]]
- return this.getIntersectPoint(pntA, pntB, pntC, pntD)
- }
- /**
- * 获取交集的点
- * @param pntA
- * @param pntB
- * @param pntC
- * @param pntD
- * @returns {[*,*]}
- */
- getIntersectPoint(pntA, pntB, pntC, pntD) {
- if (pntA[1] === pntB[1]) {
- let f = (pntD[0] - pntC[0]) / (pntD[1] - pntC[1])
- let x = f * (pntA[1] - pntC[1]) + pntC[0]
- let y = pntA[1]
- return [x, y]
- }
- if (pntC[1] === pntD[1]) {
- let e = (pntB[0] - pntA[0]) / (pntB[1] - pntA[1])
- let x = e * (pntC[1] - pntA[1]) + pntA[0]
- let y = pntC[1]
- return [x, y]
- }
- let e = (pntB[0] - pntA[0]) / (pntB[1] - pntA[1])
- let f = (pntD[0] - pntC[0]) / (pntD[1] - pntC[1])
- let y = (e * pntA[1] - pntA[0] - f * pntC[1] + pntC[0]) / (e - f)
- let x = e * y - e * pntA[1] + pntA[0]
- return [x, y]
- }
- /**
- * 计算两个坐标之间的距离
- * @ignore
- * @param pnt1
- * @param pnt2
- * @returns {number}
- * @constructor
- */
- MathDistance(pnt1, pnt2) {
- return (Math.sqrt(Math.pow((pnt1[0] - pnt2[0]), 2) + Math.pow((pnt1[1] - pnt2[1]), 2)))
- }
- /**
- * 获取方位角(地平经度)
- * @param startPoint
- * @param endPoint
- * @returns {*}
- */
- getAzimuth(startPoint, endPoint) {
- let azimuth
- let 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
- }
- /**
- * 判断是否是顺时针
- * @param pnt1
- * @param pnt2
- * @param pnt3
- * @returns {boolean}
- */
- isClockWise(pnt1, pnt2, pnt3) {
- return ((pnt3[1] - pnt1[1]) * (pnt2[0] - pnt1[0]) > (pnt2[1] - pnt1[1]) * (pnt3[0] - pnt1[0]))
- }
- /**
- * 插值弓形线段点
- * @param center
- * @param radius
- * @param startAngle
- * @param endAngle
- * @returns {null}
- */
- getArcPoints(center, radius, startAngle, endAngle) {
- let [x, y, pnts, angleDiff] = [null, null, [], (endAngle - startAngle)]
- angleDiff = ((angleDiff < 0) ? (angleDiff + (Math.PI * 2)) : angleDiff)
- for (let i = 0; i <= 100; i++) {
- let angle = startAngle + angleDiff * i / 100
- x = center[0] + radius * Math.cos(angle)
- y = center[1] + radius * Math.sin(angle)
- pnts.push([x, y])
- }
- return pnts
- }
- }
- export default DrawBowLine
|