tools

/**
 * @class 工具类
 * @constructor
 */

export let GeoInfoTools = {


    radiansPerDegree: Math.PI / 180.0,//角度转化为弧度(rad)
    degreesPerRadian: 180.0 / Math.PI,//弧度转化为角度
    /**
     * 错误
     */
    Error: {
        /**
         * 返回错误
         * @param msg
         * @returns {Error}
         */
        setError: function (msg) {
            if (msg) {
                return new Error(msg);
            }
            return new Error("Error in Parameter!");
        },
    },

    /**
     * 计算
     */
    Count: {

        /**
         * 获取两点之间的距离
         * @param p1
         * @param p2
         * @returns {*}
         */
        countDistanceBetweenTwoPoints: function (p1, p2) {
            if (!p1 || !p2) {
                throw GeoInfoTools.Error.setError();
            }
            p1 = GeoInfoTools.Transform.toCartesian(p1);
            p2 = GeoInfoTools.Transform.toCartesian(p2);
            return Math.sqrt(Math.pow((p1.x - p2.x), 2) + Math.pow((p1.y - p2.y), 2) + Math.pow((p1.z - p2.z), 2));
        },

        /**
         * 点到线段的最短距离
         * @param a 直线上一个点
         * @param b 直线上另一个点
         * @param s 该点到ab的最短距离
         * @returns {number}
         */
        countPoint2LineDistance: function (a, b, s) {
            if (!a || !b || !s) {
                throw GeoInfoTools.Error.setError();
            }
            a = GeoInfoTools.Transform.toCartesian(a);
            b = GeoInfoTools.Transform.toCartesian(b);
            s = GeoInfoTools.Transform.toCartesian(s);
            let ab = Math.sqrt(Math.pow((a.x - b.x), 2.0) + Math.pow((a.y - b.y), 2.0) + Math.pow((a.z - b.z), 2.0));
            let as = Math.sqrt(Math.pow((a.x - s.x), 2.0) + Math.pow((a.y - s.y), 2.0) + Math.pow((a.z - s.z), 2.0));
            let bs = Math.sqrt(Math.pow((s.x - b.x), 2.0) + Math.pow((s.y - b.y), 2.0) + Math.pow((s.z - b.z), 2.0));
            let cos_A = (Math.pow(as, 2.0) + Math.pow(ab, 2.0) - Math.pow(bs, 2.0)) / (2 * ab * as);
            let sin_A = Math.sqrt(1 - Math.pow(cos_A, 2.0));
            let t = ((a.x - s.x) * (a.x - b.x) + (a.y - s.y) * (a.y - b.y) + (a.z - s.z) * (a.z - b.z)) / (Math.pow((a.x - b.x), 2.0) + Math.pow((a.y - b.y), 2.0) + Math.pow((a.z - b.z), 2.0));
            if (t < 0) {
                return as;
            } else if (t <= 1 && t >= 0) {
                return as * sin_A;
            } else if (t > 1) {
                return bs;
            }
        },

        /**
         * 求三角形面积;返回-1为不能组成三角形;
         * @param a
         * @param b
         * @param c
         * @returns {*}
         */
        countAreaByThreePoints: function (a, b, c) {
            if ((!a) || (!b) || (!c)) {
                throw GeoInfoTools.Error.setError();
            }
            a = GeoInfoTools.Transform.toCartesian(a);
            b = GeoInfoTools.Transform.toCartesian(b);
            c = GeoInfoTools.Transform.toCartesian(c);
            let area = -1;
            let side = [];//存储三条边的长度;
            side[0] = Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2) + Math.pow(a.z - b.z, 2));
            side[1] = Math.sqrt(Math.pow(a.x - c.x, 2) + Math.pow(a.y - c.y, 2) + Math.pow(a.z - c.z, 2));
            side[2] = Math.sqrt(Math.pow(c.x - b.x, 2) + Math.pow(c.y - b.y, 2) + Math.pow(c.z - b.z, 2));
            //不能构成三角形;
            if (side[0] + side[1] <= side[2] || side[0] + side[2] <= side[1] || side[1] + side[2] <= side[0]) {
                return area;
            }
            //利用海伦公式。area =sqr(p*(p-a)(p-b)(p-c));
            let p = (side[0] + side[1] + side[2]) / 2; //半周长;
            area = Math.sqrt(p * (p - side[0]) * (p - side[1]) * (p - side[2]));
            return area;
        },

        /**
         * 求多边形的面积
         * @param arr
         * @returns {*}
         */
        countArea: function (arr) {
            if ((!arr) || (arr.length < 3)) {
                throw GeoInfoTools.Error.setError();
            } else {
                let area = 0;
                for (let i = 0; i < arr.length; i++) {
                    let j = (i + 1) % arr.length;
                    let p1 = arr[i], p2 = arr[j];
                    p1 = GeoInfoTools.Transform.toCartesian(p1);
                    p2 = GeoInfoTools.Transform.toCartesian(p2);
                    area += p1.x * p2.y;
                    area -= p1.y * p2.x;
                }
                area /= 2;
                return Math.abs(area);
            }

        },

        /**
         * 计算向量叉乘
         * @param v1
         * @param v2
         * @returns {number}
         */
        countCrossMul: function (v1, v2) {
            if (!v1 || !v2) {
                throw GeoInfoTools.Error.setError();
            }
            v1 = GeoInfoTools.Transform.toDegrees(v1);
            v2 = GeoInfoTools.Transform.toDegrees(v2);
            return v1.lng * v2.lat - v1.lat * v2.lng;
        },

    },

    /**
     * 转换
     */
    Transform: {

        /**
         * 世界坐标系转屏幕坐标
         * @param point
         * @param viewer
         */
        toWindowCoordinates: function (point, viewer) {
            if (viewer && point && point.x && point.y && point.z) {
                return Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, point);
            } else if (viewer && point.lng && point.lat && point.alt) {
                return Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, GeoInfoTools.Transform.toCartesianFromDegrees(point));
            } else {
                throw GeoInfoTools.Error.setError();
            }
        },

        /**
         * 笛卡尔坐标转世界坐标
         * @param point
         */
        toDegreesFromCartesian: function (point) {
            if (point.x && point.y && point.z) {
                let cartesian33 = new Cesium.Cartesian3(point.x, point.y, point.z);
                let cartographic = Cesium.Cartographic.fromCartesian(cartesian33);
                return {
                    lng: parseFloat(Cesium.Math.toDegrees(cartographic.longitude).toFixed(8)),
                    lat: parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(8)),
                    alt: parseFloat(cartographic.height.toFixed(8))
                };
            } else {
                throw GeoInfoTools.Error.setError();
            }
        }
        ,

        /**
         * 世界坐标转笛卡尔坐标
         * @param point
         */
        toCartesianFromDegrees: function (point) {
            if (point.lng && point.lat) {
                return Cesium.Cartesian3.fromDegrees(point.lng, point.lat, point.alt || 0);
            } else {
                throw GeoInfoTools.Error.setError();
            }
        }
        ,
        /**
         * 转化成经纬度
         * @param point
         */
        toDegrees: function (point) {
            if (GeoInfoTools.Judge.isDegreesOrCartesian(point)) {
                if (point.x && point.y && point.z) {
                    point = GeoInfoTools.Transform.toDegreesFromCartesian(point);
                }
                return point;
            } else {
                throw GeoInfoTools.Error.setError();
            }
        },

        /**
         * 转化成笛卡尔坐标
         * @param point
         */
        toCartesian: function (point) {
            if (GeoInfoTools.Judge.isDegreesOrCartesian(point)) {
                if (point.lng && point.lat) {
                    point = GeoInfoTools.Transform.toCartesianFromDegrees(point);
                }
                return point;
            } else {
                throw GeoInfoTools.Error.setError();
            }
        },


        /**
         * 距离(米)转换为纬度  一米对应的纬度为定值
         * @param meter 距离多少米
         * @returns {number}
         */
        meter2Lat: function (meter) {
            let pi = Math.PI;
            let lngInMeter = (6371 * 2 * pi) / 360;
            return (meter / lngInMeter) / 1000;
        },

        /**
         * 距离(米)转换为经度  一米对应的经度与所在有关纬度
         * @param meter 距离
         * @param lat 所在纬度
         * @returns {number}
         */
        meter2Lng: function (meter, lat) {
            let pi = Math.PI;
            let latInMeter = (Math.cos(lat * pi / 180) * 6371 * 2 * pi) / 360;
            return (meter / latInMeter) / 1000;
        },

    },

    /**
     * 信息
     */
    Info: {
        /**
         * 获取当前相机姿态信息
         * 包括经度、纬度、高程、Heading、Pitch、Roll
         * @param viewer
         */
        getCameraInfo: function (viewer) {
            if (viewer && viewer.camera && viewer.camera.position && viewer.camera.heading) {
                let p = GeoInfoTools.Transform.toDegrees(viewer.camera.position);
                let heading = Cesium.Math.toDegrees(viewer.camera.heading);
                let pitch = Cesium.Math.toDegrees(viewer.camera.pitch);
                let roll = Cesium.Math.toDegrees(viewer.camera.roll);
                return {
                    heading: parseFloat(heading).toFixed(5),
                    pitch: parseFloat(pitch).toFixed(5),
                    roll: parseFloat(roll).toFixed(5),
                    lng: parseFloat(p.lng).toFixed(7),
                    lat: parseFloat(p.lat).toFixed(7),
                    alt: parseFloat(p.alt).toFixed(2)
                }
            } else {
                throw GeoInfoTools.Error.setError();
            }
        }
    },

    Judge: {
        /**
         * 判断点是否在面的内部 不包含高程
         * @param point
         * @param coordinates
         * @returns {boolean}
         */
        isPointInPolygon: function (point, coordinates) {
            if ((!coordinates) || (!(coordinates instanceof Array)) || (coordinates.length < 3)) {
                throw GeoInfoTools.Error.setError();
            }
            point = GeoInfoTools.Transform.toDegrees(point);
            let x = point.lng, y = point.lat;
            let inside = false;
            for (let i = 0, j = coordinates.length - 1; i < coordinates.length; j = i++) {
                let vsi = GeoInfoTools.Transform.toDegrees(coordinates[i]),
                    vsj = GeoInfoTools.Transform.toDegrees(coordinates[j]);
                let xi = vsi.lng, yi = vsi.lat;
                let xj = vsj.lng, yj = vsj.lat;
                let intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
                if (intersect) {
                    inside = !inside;
                }
            }
            return inside;
        },

        /**
         * 判断两条线段是否相交
         * @param p1
         * @param p2
         * @param p3
         * @param p4
         * @returns {boolean}
         */
        isLineCross: function (p1, p2, p3, p4) {
            p1 = GeoInfoTools.Transform.toDegrees(p1);
            p2 = GeoInfoTools.Transform.toDegrees(p2);
            p3 = GeoInfoTools.Transform.toDegrees(p3);
            p4 = GeoInfoTools.Transform.toDegrees(p4);
            let v1 = {lng: p1.lng - p3.lng, lat: p1.lat - p3.lat},
                v2 = {lng: p2.lng - p3.lng, lat: p2.lat - p3.lat},
                v3 = {lng: p4.lng - p3.lng, lat: p4.lat - p3.lat},
                v = GeoInfoTools.Count.countCrossMul(v1, v3) * GeoInfoTools.Count.countCrossMul(v2, v3);
            v1 = {lng: p3.lng - p1.lng, lat: p3.lat - p1.lat};
            v2 = {lng: p4.lng - p1.lng, lat: p4.lat - p1.lat};
            v3 = {lng: p2.lng - p1.lng, lat: p2.lat - p1.lat};
            return (v <= 0 && GeoInfoTools.Count.countCrossMul(v1, v3) * GeoInfoTools.Count.countCrossMul(v2, v3) <= 0) ? true : false
        },

        /**
         * 判断该点是否是经纬度或者笛卡尔坐标
         * @param point
         */
        isDegreesOrCartesian: function (point) {
            if (!point) {
                throw GeoInfoTools.Error.setError();
            }
            if (('number' === typeof point.x) && ('number' === typeof point.y) && ('number' === typeof point.z)) {
                return true
            }
            if (('number' === typeof point.lng) && ('number' === typeof point.lat)) {
                return true
            }
            return false;
        },

        /**
         * 判断线面是否相交
         * @param line
         * @param polygon
         * @constructor
         */
        isLineIntersectPolygon: function (line, polygon) {
            if (!line || !polygon || line.length !== 2 || polygon.length < 3) {
                throw GeoInfoTools.Error.setError();
            }
            let firstPoint = GeoInfoTools.Transform.toDegrees(line[0]),
                secondPoint = GeoInfoTools.Transform.toDegrees(line[1]), temp1, temp2,
                result = false;
            for (let poly = 0; poly < polygon.length; poly++) {
                if (poly == polygon.length - 1) {
                    temp1 = GeoInfoTools.Transform.toDegrees(polygon[poly]);
                    temp2 = GeoInfoTools.Transform.toDegrees(polygon[0]);
                } else {
                    temp1 = GeoInfoTools.Transform.toDegrees(polygon[poly]);
                    temp2 = GeoInfoTools.Transform.toDegrees(polygon[poly + 1]);
                }
                if (GeoInfoTools.Judge.isLineCross(firstPoint, secondPoint, temp1, temp2)) {
                    return true;
                }
            }
            return result;
        },

    },

    /**
     * 获取UUID
     * @returns {string}
     */
    getUUID: function () {
        let s = [];
        let hexDigits = "0123456789abcdef";
        for (let i = 0; i < 36; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4";
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
        s[8] = s[13] = s[18] = s[23] = "-";
        let uuid = s.join("");
        uuid = uuid.replace(/-/g, '');
        return uuid;
    },

    /**
     * 格式化日期格式 1900-01-01 12.12.12
     * @param date
     * @returns {string}
     * @constructor
     */
    formatDateTime: function (date) {
        if ((!date) || (!(date instanceof Date))) {
            throw GeoInfoTools.Error.setError();
        }
        let y = date.getFullYear();
        let m = date.getMonth() + 1;
        m = m < 10 ? ('0' + m) : m;
        let d = date.getDate();
        d = d < 10 ? ('0' + d) : d;
        let h = date.getHours();
        h = h < 10 ? ('0' + h) : h;
        let minute = date.getMinutes();
        minute = minute < 10 ? ('0' + minute) : minute;
        let second = date.getSeconds();
        second = second < 10 ? ('0' + second) : second;
        return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
    },
    /**
     * 调整Cesium3DTileset位置
     * @param tileset
     * @param params
     */
    update3dtilesMaxtrix: function (tileset, item) {
        let params = item.params;
        //旋转
        let mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx));
        let my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry));
        let mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz));
        let rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
        let rotationY = Cesium.Matrix4.fromRotationTranslation(my);
        let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
        //平移
        let position = Cesium.Cartesian3.fromDegrees(params.tx, params.ty, params.tz);
        let m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
        Cesium.Matrix4.multiply(m, rotationX, m);
        Cesium.Matrix4.multiply(m, rotationY, m);
        Cesium.Matrix4.multiply(m, rotationZ, m);
        // 赋值给tileset
        tileset._root.transform = m;
        if (item.alpha) {
            GeoInfoTools.setAlpha(tileset, item.alpha);
        }
    },
            updateTilePosition:function(tile, params) {
                //旋转
                let mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.position.heading));
                let my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.position.pitch));
                let mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.position.roll));
                let rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
                let rotationY = Cesium.Matrix4.fromRotationTranslation(my);
                let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
                //平移
                let position = Cesium.Cartesian3.fromDegrees(params.position.lng, params.position.lat, params.position.alt);
                let m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
                Cesium.Matrix4.multiply(m, rotationX, m);
                Cesium.Matrix4.multiply(m, rotationY, m);
                Cesium.Matrix4.multiply(m, rotationZ, m);
                //缩放
                let scale = Cesium.Matrix4.fromUniformScale(params.scale);
                Cesium.Matrix4.multiply(m, scale, m);
                // 赋值给tileset
                tile._root.transform = m;
            },
    /**
     * 获取当前实体的位置
     * @param entity
     * @returns {*}
     */
    getEntityPosition: function (entity) {
        return entity.position._value || Cesium.Property.getValueOrUndefined(entity.position, viewer.clock.currentTime || Cesium.JulianDate.now(), new Cesium.Cartesian3());
    },
    /**
     * 透明度
     * @param Cesium
     * @param tileset
     * @param al
     */
    setAlpha: function (tileset, al) {
        let alpha = parseFloat(al) / 100;
        let style = new Cesium.Cesium3DTileStyle({
            color: "color('white', " + alpha + ")",
            show: true
        });
        tileset.style = style;
    },

    /**
     *  销毁handler
     */
    handlerDestroy: function () {
        if (handler) {
            handler.destroy();
        }
    },

    /**
     * 计算 管线的管子的半径和边数
     * @param radius
     * @param itemp
     * @returns {Array}
     */
    computeCircleR: function (radius, itemp) {
        let result = [];
        for (let i = 0; i < 360; i += itemp) {
            let radians = Cesium.Math.toRadians(i);
            result.push(new Cesium.Cartesian2(radius * Math.sin(radians), radius * Math.cos(radians)));
        }
        return result;
    },
    /**
     * 点击按钮执行横断面分析的方法
     * @constructor
     */
    CroAn: function (minHeights, maxHeights, callback) {
        let minH = minHeights || -10, maxH = maxHeights || 100;
        GeoInfoTools.handlerDestroy();
        handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        let positions = [];
        let options = {};
        let poly = undefined;
        viewer.entities.removeById('CrossAnalysis');
        let wallPoly = (function () {
            function _(positions) {
                options = {
                    id: "CrossAnalysis",
                    wall: {
                        positions: [],
                        minimumHeights: [minH, minH],
                        material: Cesium.Color.fromCssColorString("#409ad5")
                    }
                };
                _.prototype._init()
            }

            _.prototype._init = function () {
                let _update = function () {
                    let dp = [];
                    for (let i = 0; i < 2; i++) {
                        let cartesian3 = new Cesium.Cartesian3(positions[i].x, positions[i].y, positions[i].z);
                        let cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian3);
                        let lat = Cesium.Math.toDegrees(cartographic.latitude);
                        let lng = Cesium.Math.toDegrees(cartographic.longitude);
                        let alt = cartographic.height;
                        dp.push(lng);
                        dp.push(lat);
                        dp.push(maxH);
                    }
                    return Cesium.Cartesian3.fromDegreesArrayHeights(dp);
                };
                options.wall.positions = new Cesium.CallbackProperty(_update, false);
                // let wallEntity = viewer.entities.getOrCreateEntity("CrossAnalysis");
                // wallEntity.id = options.id;
                // wallEntity.wall = options.wall;
                viewer.entities.add(options)
            };
            return _;
        })();
        handler.setInputAction(function (movement) {
            let cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
            if (positions.length == 0) {
                positions.push(cartesian.clone());
            }
            if (positions.length >= 3) {
                handler.destroy();
                // CrossAnalysis();
            }
            positions.push(cartesian);
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        handler.setInputAction(function (movement) {
            let cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
            if (positions.length >= 3) {
                handler.destroy();
                // CrossAnalysis();
            } else if (positions.length >= 1) {
                if (!Cesium.defined(poly)) {
                    poly = new wallPoly(positions);
                } else {
                    positions.pop();
                    positions.push(cartesian);
                }
            }

        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        handler.setInputAction(function (movement) {
            GeoInfoTools.handlerDestroy();
            CrossAnalysis(callback);
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    },
    /**
     * 在canvas 上绘制横断面的信息
     * @param p
     */
    getCrossAnalysisResultToContext: function (p) {
        let maxAlt = 0;
        let minAlt = Infinity;
        p.forEach(function (data) {
            if (data.alt > maxAlt) {
                maxAlt = data.alt;
            }
            if (data.alt < minAlt) {
                minAlt = data.alt;
            }
        });
        maxAlt += 6;
        minAlt -= 3;
        let pixelPerMetre = 180 / (maxAlt - minAlt);
        let unitHeight = (maxAlt - minAlt) / 6;//最高的减去最低的除六
        // addDivCanvas()
        let canvas = document.getElementById('crossAnalysisResultCanvas'); /// 拿到画板
        let webWidth = 1920, webHeight = 948;//页面宽高
        let panelHeight = webHeight / 2, panelWidth = webWidth / 2;
        canvas.width = panelWidth;
        canvas.height = panelHeight + 50;
        let ctx = canvas.getContext('2d');   /// 拿到上下文
        // 四边框
        ctx.beginPath();   /// 绘制直线
        ctx.strokeStyle = 'black';   /// 设置线条的颜色
        ctx.lineWidth = 4;   /// 设置线条的宽度
        ctx.moveTo(10, 30);   /// 起点
        ctx.lineTo(panelWidth - 10, 30);    /// 终点
        ctx.lineTo(panelWidth - 10, panelHeight + 15);
        ctx.lineTo(10, panelHeight + 15);   /// 终点   /// 终点
        ctx.lineTo(10, 30);   /// 终点
        ctx.closePath();
        // 文字说明
        ctx.font = "20px Courier New";
        ctx.fillStyle = "black";
        ctx.fillText("横断面图", panelHeight - 40, 60);
        ctx.stroke();
        // 横纵坐标轴 以及文字
        ctx.font = "14px Courier New";   ///设置字体样式
        ctx.fillStyle = "black";   ///设置字体填充颜色
        ctx.strokeStyle = 'black';   /// 设置线条的颜色
        ctx.lineWidth = 1;   /// 设置线条的宽度
        ctx.beginPath();   /// 绘制直线
        let rectH = 32;
        let hTemp = 60;
        let rectW = 150;
        ctx.lineWidth = 1;
        //纵坐标 竖线
        ctx.moveTo(rectW, 130);
        ctx.lineTo(rectW, canvas.height - 35);
        for (let i = 0; i < canvas.height; i++) {
            if (i > 0 && i <= 7) {
                let n = hTemp -= 10;
                ctx.fillText((maxAlt - ((i - 1) * unitHeight)).toFixed(1) + "(m)", 80, rectH * i + 105);
                ctx.moveTo(150, rectH * i + 100);
                ctx.lineTo(165, rectH * i + 100);
            }
            if (i > 8 && i < 12) {
                ctx.moveTo(10, rectH * i + 100);
                ctx.lineTo(canvas.width - 10, rectH * i + 100);
            }
        }
        ctx.stroke();
        ctx.font = "15px Courier New";   ///设置字体样式
        ctx.fillStyle = "black";   ///设置字体填充颜色
        ctx.fillText("横截点高程(m)", 20, 410);
        ctx.fillText("间距(m)", 20, 440);
        ctx.fillText("管径(mm)", 20, 470);
        ctx.stroke();
        let CurveList = [];
        let realPoints = p;
        let unitDistance = (panelWidth - 300) / (realPoints.length);//根据相交的点数 计算间隔
        for (let k = 0; k < realPoints.length; k++) {
            // todo 管线信息调整
            let pipeDiameter = realPoints[k].pipeDiameter || 10;//canvas绘制的圆形的管径
            let pipeSpecification = realPoints[k].pipeSpecification || '1000';//规格
            let twoDistance;//两点之间的距离
            if (realPoints.length == 1) {
                twoDistance = "";
            } else {
                if (k != realPoints.length - 1) {
                    twoDistance = GeoInfoTools.Count.countDistanceBetweenTwoPoints(realPoints[k], realPoints[k + 1]).toFixed(3);
                } else {
                    twoDistance = GeoInfoTools.Count.countDistanceBetweenTwoPoints(realPoints[k], realPoints[0]).toFixed(3);
                }
            }
            CurveList.push([panelWidth - 230 - unitDistance * k, 310 - (parseFloat(realPoints[k].alt.toFixed(3)) - minAlt) * pixelPerMetre]);
            ctx.beginPath();
            //以点为中心 画圆
            ctx.arc(panelWidth - 230 - unitDistance * k, 310 - (realPoints[k].alt.toFixed(3) - minAlt) * pixelPerMetre, pipeDiameter, 0, Math.PI * 2, true);
            //写经纬度信息
            ctx.fillText("经度:" + realPoints[k].lng.toFixed(8), (panelWidth - 230 - unitDistance * k), 300 - (realPoints[k].alt.toFixed(3) - minAlt) * pixelPerMetre);
            ctx.fillText("纬度:" + realPoints[k].lat.toFixed(8), (panelWidth - 230 - unitDistance * k), 280 - (realPoints[k].alt.toFixed(3) - minAlt) * pixelPerMetre);
            ctx.fillText("高程:" + realPoints[k].alt.toFixed(3), (panelWidth - 230 - unitDistance * k), 260 - (realPoints[k].alt.toFixed(3) - minAlt) * pixelPerMetre);
            //管线高程 指点的高程
            ctx.fillText(realPoints[k].alt.toFixed(3), panelWidth - 230 - unitDistance * k, 410);
            //两点之间的间距 横截面为两个点的时候 可当作两点之间的距离
            ctx.fillText(twoDistance, panelWidth - 230 - unitDistance * k, 440);
            //管径规格
            ctx.fillText(pipeSpecification, panelWidth - 230 - unitDistance * k, 470);
            ctx.closePath();
            ctx.stroke();
            //竖直的虚线
            drawDashedLine(ctx, {
                x: panelWidth - 230 - unitDistance * k,
                y: 310 - (realPoints[k].alt.toFixed(3) - minAlt) * pixelPerMetre
            }, {
                x: panelWidth - 230 - unitDistance * k,
                y: 390
            }, [3, 3]);
            //水平的虚线
            drawDashedLine(ctx, {
                x: panelWidth - 230 - unitDistance * k,
                y: 310 - (realPoints[k].alt.toFixed(3) - minAlt) * pixelPerMetre
            }, {
                x: 150,
                y: 310 - (realPoints[k].alt.toFixed(3) - minAlt) * pixelPerMetre
            }, [3, 3]);
        }

        //连接横截面点 可以不使用
        // if(CurveList&&CurveList.length>0){
        //     if (CurveList.length == 1) {
        //         ctx.strokeStyle = "#060606";
        //         ctx.beginPath();
        //         ctx.arc(CurveList[0][0], CurveList[0][1], 1, 0, Math.PI * 2, true);
        //         ctx.stroke();
        //         ctx.closePath();
        //     } else if (CurveList.length > 1) {
        //         ctx.strokeStyle = "#060606";
        //         ctx.beginPath();
        //         ctx.moveTo(CurveList[0][0], CurveList[0][1]);
        //         for (let cl = 1; cl < CurveList.length; cl++) {
        //             ctx.lineTo(CurveList[cl][0], CurveList[cl][1]);
        //         }
        //         ctx.stroke();
        //         ctx.closePath();
        //     }
        // }


    },
    /**
     * 添加Cesium3DTileset
     * @param model_trans
     * @returns {*}
     */
    addCesium3DTileset: function (model_trans, view) {
        let Cesium3DTileset = new Cesium.Cesium3DTileset({
            url: model_trans.url,
            show: model_trans.show || true,
            scale: model_trans.scale
        });
        let tileset = view.scene.primitives.add(Cesium3DTileset);
        tileset.readyPromise.then(function (t) {
            GeoInfoTools.update3dtilesMaxtrix(tileset, model_trans);
        });
        return tileset;
    },
    /**
     * 根据范围来控制model的显示隐藏
     * @param show
     * @param area
     */
    showAreaEntiy: function (show, area) {
        let entities = viewer.entities.values;
        entities.forEach(function (item, index) {
            if (item.model && item.model._uri) {
                let position = GeoInfoTools.getEntityPosition(item);
                if (GeoInfoTools.Judge.isPointInPolygon(position, area)) {
                    item.show = show;
                } else {
                    item.show = !show;
                }
            } else {
                item.show = false;
            }
        });
    },
    /**
     * 根据位置来自动旋转视角
     * @param viewOptions
     */
    roundExtentView: function (viewOptions) {
        if (viewOptions && viewOptions.position) {
            flyExtent(viewOptions);
        }
    },
    /**
     * 根据矩形区域来生成clippingPlanes,然后计算旋转视角
     * @param range
     * @param viewOptions
     */
    specialView: function (range, viewOptions) {
        let primitives = viewer.scene.primitives._primitives;
        primitives.forEach(function (item, index) {
            if (item._url && item._url.indexOf("tileset.json") > 0) {
                let clippingPlanes = tilesetAddClippingPlanes(range, item);
                item.clippingPlanes = clippingPlanes;
            }
        });
        viewOptions = {};
        viewOptions.position = Cesium.Cartesian3.fromDegrees((range[0].lng + range[2].lng) / 2, (range[0].lat + range[2].lat) / 2, 0);
        let dis = GeoInfoTools.Count.countDistanceBetweenTwoPoints(range[0], range[2]);
        if (dis) {
            viewOptions.distance = dis * 2;
        }
        flyExtent(viewOptions);
        GeoInfoTools.showAreaEntiy(true, range);
    },

    showExtent(extent) {

        let primitives = viewer.scene.primitives._primitives;
        primitives.forEach(function (item, index) {
            if (item._url && item._url.indexOf("tileset.json") > 0) {
                let clippingPlanes = tilesetAddClippingPlanes(extent, item);
                item.clippingPlanes = clippingPlanes;
            }
        });
        GeoInfoTools.showParticleSystems(false);
        GeoInfoTools.showAreaEntiy(true, extent);
    },
    showAll(){
        GeoInfoTools.showParticleSystems(true);
        let primitives = viewer.scene.primitives._primitives;
        primitives.forEach(function (item, index) {
            if (item._url && item._url.indexOf("tileset.json") > 0) {
                if (item.clippingPlanes && item.clippingPlanes.unionClippingRegions) {
                    item.clippingPlanes.unionClippingRegions = false;
                }
            }

        });
        //改变模型的显示隐藏
        let entities = viewer.entities.values;
        entities.forEach(function (item, index) {
            item.show = true;
        });
    },
    /**
     * 添加右键结束提醒
     * @param cartesian
     */
    addTip: function (cartesian) {
        if (cartesian && cartesian.x && cartesian.y) {
            let p = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, cartesian);
            if (document.getElementById("_____tip")) {
                let divChild = document.getElementById("_____tip");
                divChild.style.left = (p.x + 10) + "px";
                divChild.style.top = (p.y + 10) + "px";
            } else {
                let divChild = document.createElement("Div");
                divChild.innerHTML = "";
                divChild.id = "_____tip";
                divChild.style.width = "75px";
                divChild.style.left = (p.x + 10) + "px";
                divChild.style.top = (p.y + 10) + "px";
                divChild.style.height = "20px";
                divChild.style.position = "absolute";
                divChild.style.background = "#f2f4ff";
                divChild.style.borderRadius = "5px";
                divChild.style.show = "block";
                divChild.style.textAlign = "center";
                divChild.style.zIndex = "9999999999";
                document.body.append(divChild);
            }

        }
    },
    /**
     * 删除右键提示提醒
     */
    clearTip: function () {
        let my = document.getElementById("_____tip");
        if (my != null) {
            my.parentNode.removeChild(my);
        }
    },
    /**
     * 改变模型的显示隐藏和颜色
     * @param item
     * @param show
     * @param color
     * @param alpha
     */
    changeEntityModelView: function (item, show, color, alpha) {
        if (typeof show === "boolean") {
            item.show = show;
        }
        item.model.color = Cesium.Color.fromCssColorString(color).withAlpha(parseFloat(alpha));
    },

    /**
     * 改变model和tiles的显示隐藏和样式
     * @param type
     * @param pickEntity
     */
    changeModelAndTileStyle: function (type, pickEntity) {
        let primitives = viewer.scene.primitives._primitives;
        let entities = viewer.entities.values;
        if (type) {
            primitives.forEach(function (item, index) {
                GeoInfoTools.changeTileView(item, 'keep', '#67ADDF', 0.15)
            })
            entities.forEach(function (item, index) {
                if (item.model && item.model._uri._value) {
                    if (pickEntity.id === item.id) {
                        item.model.color = Cesium.Color.WHITE.withAlpha(1);
                        item.model.colorBlendMode = Cesium.ColorBlendMode['MIX'];
                        item.model.lightColor = new Cesium.Cartesian3(40, 40, 0);
                    } else {
                        item.model.color = Cesium.Color.fromCssColorString('#67ADDF').withAlpha(0.15);
                        item.model.colorBlendMode = Cesium.ColorBlendMode['HIGHLIGHT'];
                        item.model.lightColor = new Cesium.Cartesian3(0, 0, 0);
                    }

                }
            });

        } else {
            if (GeoInfoTools.pipeLineLabels instanceof Array && GeoInfoTools.pipeLineLabels.length > 0) {
                GeoInfoTools.pipeLineLabels.forEach(function (item, index) {
                    viewer.entities.remove(item);
                })
            }
            entities.forEach(function (item, index) {
                if (item.model && item.model._uri._value) {
                    item.model.color = Cesium.Color.WHITE.withAlpha(1);
                    item.model.lightColor = new Cesium.Cartesian3(0, 0, 0);
                    item.model.colorBlendMode = Cesium.ColorBlendMode['HIGHLIGHT'];
                }
            });

            primitives.forEach(function (item, index) {
                if (item instanceof Cesium.Cesium3DTileset) {
                    if (item && item._url && item._url.indexOf("tile/pipeline/tileset.json") >= 0) {
                        item.tileVisible.removeEventListener(GeoInfoTools.changTileColor); //清除管线效果
                    }
                    GeoInfoTools.changeTileView(item, 'keep', '#ffffff', 1);
                }
            })
        }

    },
    /***
     * 计算entity的时间和位置绑定
     * @param startTime
     * @param positions
     * @param uniformSpeed
     * @param speed
     * @param entity
     * @returns {Cesium.SampledPositionProperty}
     */
    computePositionProperty: function (startTime, positions, uniformSpeed, speed, entity) {
        if (!positions && positions.length < 2) {
            return
        }
        let property = new Cesium.SampledPositionProperty();
        let seconds = 0;
        //是否匀速
        if (uniformSpeed) {
            property.addSample(startTime, Cesium.Cartesian3.fromDegrees(positions[0].lng, positions[0].lat, positions[0].alt));
            positions.forEach(function (item, index) {
                if (index < positions.length - 1) {
                    // GeoInfoTools.Count.countDistanceBetweenTwoPoints(positions[index], positions[index + 1]);
                    let p1 = Cesium.Cartesian3.fromDegrees(positions[index].lng, positions[index].lat, positions[index].alt);
                    let p2 = Cesium.Cartesian3.fromDegrees(positions[index + 1].lng, positions[index + 1].lat, positions[index + 1].alt);
                    let distance = Math.sqrt(Math.pow((p1.x - p2.x), 2) + Math.pow((p1.y - p2.y), 2) + Math.pow((p1.z - p2.z), 2));
                    seconds += (distance / speed);
                    // console.log(seconds, (distance / speed));
                    let time = Cesium.JulianDate.addSeconds(startTime, seconds, new Cesium.JulianDate);
                    let position = Cesium.Cartesian3.fromDegrees(positions[index + 1].lng, positions[index + 1].lat, positions[index + 1].alt);
                    // 添加位置,和时间对应
                    property.addSample(time, position);
                }
            })

        } else {
            positions.forEach(function (item, index) {
                let time = Cesium.JulianDate.addSeconds(startTime, item.seconds, new Cesium.JulianDate);
                let position = Cesium.Cartesian3.fromDegrees(item.lng, item.lat, item.alt);
                property.addSample(time, position);
            })
            seconds = positions[positions.length - 1].seconds;
        }
        if (entity) {
            entity.position = property;
            entity.orientation = new Cesium.VelocityOrientationProperty(property);
            entity.availability = new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
                start: startTime,
                stop: Cesium.JulianDate.addSeconds(startTime, seconds, new Cesium.JulianDate)
            })]);
        }
        return property;
    },
    /**
     * 添加管线的label 和billboard用于显示信息
     * @param options
     * @returns {void | ActiveX.IXMLDOMNamedNodeMap | number | IDBRequest | DataTransferItem | Promise}
     */
    addPipeLineExplain: function (options) {
        return viewer.entities.add({
            id: options.id || getUUID(),
            name: options.name || "",
            position: Cesium.Cartesian3.fromDegrees(options.position.lng, options.position.lat, options.position.alt),
            billboard: {
                distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 300),
                image: options.imageUrl,//'../images/billLine2.png',
                show: true, // default
                pixelOffset: new Cesium.Cartesian2(0, 10), // default: (0, 0)
                eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0), // default
                horizontalOrigin: Cesium.HorizontalOrigin.RIGHT, // default
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // default: CENTER
                // color: Cesium.Color.YELLOW, // default: WHITE
                // width: options.imageWidth || 300, // default: undefined
                // height: options.imageHeight || 100 // default: undefined
            },
            label: {
                position: Cesium.Cartesian3.fromDegrees(options.position.lng, options.position.lat, options.position.alt),
                pixelOffset: new Cesium.Cartesian2(-140, -(options.imageWidth / 2)),
                distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 300),
                horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
                fillColor: new Cesium.Color.fromCssColorString('#ffffff'),
                font: '15px sans-serif',
                outlineColor: new Cesium.Color.fromCssColorString('#000000'),
                outlineWidth: 10,
                text: options.text || ""
            }
        });
    },
    execution: undefined,
    pipeLineLabels: [],
    /**
     * 修改管线feature6、16的颜色和透明度
     * @param tile
     */
    changTileColor: function (tile) {
        let content = tile.content;
        let feature6 = content.getFeature(6);
        let feature16 = content.getFeature(16);
        feature6.color = Cesium.Color.fromCssColorString('rgba(20,166,255,0.5)');
        feature16.color = Cesium.Color.fromCssColorString('rgba(20,166,255,0.5)');
    },
    /**
     * 删除视角旋转
     */
    removeExecution: function () {
        if (GeoInfoTools.execution) {
            viewer.clock.onTick.removeEventListener(GeoInfoTools.execution);
        }
    }
// end
};


/**
 * UUID
 * @returns {string}
 */
function getUUID() {
    var s = [];
    var hexDigits = "0123456789abcdef";
    for (var i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
    }
    s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
    s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
    s[8] = s[13] = s[18] = s[23] = "-";

    var uuid = s.join("");
    return uuid;
}

/**
 * 旋转环视
 * @param options
 * @returns {TimeExecution}
 */
function flyExtent(options) {
    let seconds = options.seconds || 120;
    let pitch = Cesium.Math.toRadians(options.pitch || -30);
    let angle = 360 / seconds;
    let distance = options.distance || 200;
    let startTime = Cesium.JulianDate.fromDate(new Date());
    let stopTime = Cesium.JulianDate.addSeconds(startTime, seconds, new Cesium.JulianDate());
    viewer.clock.startTime = startTime.clone();
    viewer.clock.stopTime = stopTime.clone();
    viewer.clock.currentTime = startTime.clone(); // 当前时间
    viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 行为方式
    viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; // 时钟设置为当前系统时间; 忽略所有其他设置。
    let initialHeading = viewer.camera.heading;
    GeoInfoTools.execution = function TimeExecution() {
        let delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);
        let heading = Cesium.Math.toRadians(delTime * angle) + initialHeading;
        viewer.scene.camera.setView({
            destination: options.position, // 点的坐标
            orientation: {
                heading: heading,
                pitch: pitch,
            }
        });
        viewer.scene.camera.moveBackward(distance);
        // if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {
        //     // viewer.clock.onTick.removeEventListener(execution);
        // }
    };
    viewer.clock.onTick.addEventListener(GeoInfoTools.execution);
    return GeoInfoTools.execution;
}

/**
 *为3dties添加裁剪面
 * @param range
 * @param tileset
 */
function tilesetAddClippingPlanes(range, tileset) {
    if ((!range) || (!tileset) || (range.length < 4)) {
        return
    }

    function getInverseTransform(tileSet) {
        let transform = undefined;
        let tmp = tileSet.root.transform;
        if ((tmp && tmp.equals(Cesium.Matrix4.IDENTITY)) || !tmp) {
            // 如果root.transform不存在,则3DTiles的原点变成了boundingSphere.center
            transform = Cesium.Transforms.eastNorthUpToFixedFrame(tileSet.boundingSphere.center)
        } else {
            transform = Cesium.Matrix4.fromArray(tileSet.root.transform)
        }
        return Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4())
    }

    function getOriginCoordinateSystemPoint(point, inverseTransform) {
        let val = Cesium.Cartesian3.fromDegrees(point.lng, point.lat)
        return Cesium.Matrix4.multiplyByPoint(inverseTransform, val, new Cesium.Cartesian3(0, 0, 0))
    }

    function createPlane(p1, p2, inverseTransform) {
        // 将仅包含经纬度信息的p1,p2,转换为相应坐标系的cartesian3对象
        let p1C3 = getOriginCoordinateSystemPoint(p1, inverseTransform)
        let p2C3 = getOriginCoordinateSystemPoint(p2, inverseTransform)
        // 定义一个垂直向上的向量up
        let up = new Cesium.Cartesian3(0, 0, 10)
        //  right 实际上就是由p1指向p2的向量
        let right = Cesium.Cartesian3.subtract(p2C3, p1C3, new Cesium.Cartesian3())
        // 计算normal, right叉乘up,得到平面法向量,这个法向量指向right的右侧
        let normal = Cesium.Cartesian3.cross(right, up, new Cesium.Cartesian3())
        normal = Cesium.Cartesian3.normalize(normal, normal)
        //由于已经获得了法向量和过平面的一点,因此可以直接构造Plane,并进一步构造ClippingPlane
        let planeTmp = Cesium.Plane.fromPointNormal(p1C3, normal)
        return Cesium.ClippingPlane.fromPlane(planeTmp)
    }

    let inverseTransform = getInverseTransform(tileset);
    let clippingPlanes = new Cesium.ClippingPlaneCollection({
        unionClippingRegions: true
    });
    for(let i=0;i= 0 && VectorMultiplication(n5, n6) * VectorMultiplication(n7, n8) >= 0);
}

/**
 * 两个向量的叉积和
 * @param n
 * @param m
 * @returns {number}
 * @constructor
 */
function VectorMultiplication(n, m) {
    return n.y * m.z - m.y * n.z + n.z * m.x - n.x * m.z + n.x * m.y - n.y * m.x;
}

/**
 * 求交点是否在线段上
 * @param point
 * @param polyline
 * @returns {boolean}
 * @constructor
 */
function JudgePointInPolyline(point, polyline) {
    let lineLength = Math.sqrt(Math.pow((polyline[0].x - polyline[1].x), 2) + Math.pow((polyline[0].y - polyline[1].y), 2) + Math.pow((polyline[0].z - polyline[1].z), 2));
    let one = Math.sqrt(Math.pow((point.x - polyline[1].x), 2) + Math.pow((point.y - polyline[1].y), 2) + Math.pow((point.z - polyline[1].z), 2));
    let two = Math.sqrt(Math.pow((point.x - polyline[0].x), 2) + Math.pow((point.y - polyline[0].y), 2) + Math.pow((point.z - polyline[0].z), 2));
    let di = one + two - lineLength;
    if (di * 100 < 1) {
        return true;
    }
    return false;

}

/**
 * 求线面交点 线面平行返回undefined
 * @param planeVector 平面的法线向量,长度为3
 * @param planePoint 平面经过的一点坐标,长度为3
 * @param lineVector 直线的方向向量,长度为3
 * @param linePoint 直线经过的一点坐标,长度为3
 * @returns {Array}  返回交点坐标,长度为3
 * @constructor
 */
function CalPlaneLineIntersectPoint(planeVector, planePoint, lineVector, linePoint) {
    let returnResult = [];
    let vp1, vp2, vp3, n1, n2, n3, v1, v2, v3, m1, m2, m3, t, vpt;
    vp1 = planeVector[0].x;
    vp2 = planeVector[0].y;
    vp3 = planeVector[0].z;
    n1 = planePoint.x;
    n2 = planePoint.y;
    n3 = planePoint.z;
    v1 = lineVector[0].x;
    v2 = lineVector[0].y;
    v3 = lineVector[0].z;
    m1 = linePoint.x;
    m2 = linePoint.y;
    m3 = linePoint.z;
    vpt = v1 * vp1 + v2 * vp2 + v3 * vp3;
    //首先判断直线是否与平面平行
    if (vpt == 0) {
        returnResult = undefined;
    } else {
        t = ((n1 - m1) * vp1 + (n2 - m2) * vp2 + (n3 - m3) * vp3) / vpt;
        returnResult.x = m1 + v1 * t;
        returnResult.y = m2 + v2 * t;
        returnResult.z = m3 + v3 * t;
    }
    return returnResult;
}

/**
 * 已知三点坐标,求平面的法向量
 * @param p1
 * @param p2
 * @param p3
 * @returns {[]}
 */
function getNormal(p1, p2, p3) {
    let point = [];
    let x = ((p2.y - p1.y) * (p3.z - p1.z) - (p2.z - p1.z) * (p3.y - p1.y));
    let y = ((p2.z - p1.z) * (p3.x - p1.x) - (p2.x - p1.x) * (p3.z - p1.z));
    let z = ((p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x));
    point.push({"x": x, "y": y, "z": z});
    return point;
}

/**
 * 根据3个点,计算空间平面的方程
 * Ax+By+Cz+D=0
 * 输入参数:point3fArray---空间中3个点的坐标,大小为3;输入点>3时,只取前3个点
 * 输出参数A,B,C,D
 * 返回值:true---计算成功;false----计算失败
 * @param point3fArray
 * @returns {boolean}
 * @constructor
 */
function GetPanelEquation(point3fArray) {
    if (point3fArray.length < 3) {
        return undefined;
    }
    let A, B, C, D;
    A = point3fArray[0].y * (point3fArray[1].z - point3fArray[2].z) +
        point3fArray[1].y * (point3fArray[2].z - point3fArray[0].z) +
        point3fArray[2].y * (point3fArray[0].z - point3fArray[1].z);

    B = point3fArray[0].z * (point3fArray[1].x - point3fArray[2].x) +
        point3fArray[1].z * (point3fArray[2].x - point3fArray[0].x) +
        point3fArray[2].z * (point3fArray[0].x - point3fArray[1].x);

    C = point3fArray[0].x * (point3fArray[1].y - point3fArray[2].y) +
        point3fArray[1].x * (point3fArray[2].y - point3fArray[0].y) +
        point3fArray[2].x * (point3fArray[0].y - point3fArray[1].y);

    D = -point3fArray[0].x * (point3fArray[1].y * point3fArray[2].z - point3fArray[2].y * point3fArray[1].z) -
        point3fArray[1].x * (point3fArray[2].y * point3fArray[0].z - point3fArray[0].y * point3fArray[2].z) -
        point3fArray[2].x * (point3fArray[0].y * point3fArray[1].z - point3fArray[1].y * point3fArray[0].z);


    return {A: A, B: B, C: C, D: D};


}

/**
 * canvas 绘制虚线
 * @param ctx
 * @param moveTo
 * @param lineTo
 * @param pattern
 */
function drawDashedLine(ctx, moveTo, lineTo, pattern) {
    ctx.beginPath();
    ctx.setLineDash(pattern);
    ctx.moveTo(moveTo.x, moveTo.y);
    ctx.lineTo(lineTo.x, lineTo.y);
    ctx.stroke();
    ctx.closePath();
    ctx.setLineDash([]);
}


/**
 * 动态创建DIV 和 canvas
 */
function addDivCanvas() {
    let div = document.getElementById("crossAnalysisResultCanvasDiv");
    if (!div) {
        div = document.createElement("div");
        div.id = "crossAnalysisResultCanvasDiv";
        // div.style.position = "absolute";
        // div.style.top = "25%";
        // div.style.left = "25%";
        div.style.backgroundColor = "#ffffff";
        // div.style.zIndex = 999999999;
        div.style.width = "960px";
        div.style.height = "524px";
        div.style.border = "1px #0366bf solid";
        div.style.borderRadius = "6px";
        let canvas = document.createElement("canvas");
        canvas.id = 'crossAnalysisResultCanvas';
        div.append(canvas)
        document.body.appendChild(div);
    }
}

//根据墙实体ID CrossAnalysis横断面分析所有的 polylineVolume
function CrossAnalysis(callback) {
    let wallEntity = viewer.entities.getOrCreateEntity("CrossAnalysis");
    //判断是否有横截面
    if (wallEntity && wallEntity.wall) {
        let wallPositions = wallEntity._wall.positions.getValue(), wallPositions2 = [];
        for (let u in wallPositions) {
            wallPositions2.push(GeoInfoTools.Transform.toDegrees(wallPositions[u]))
        }
        //平面的第三、四点
        wallPositions2.push({lng: wallPositions2[1].lng, lat: wallPositions2[1].lat, alt: -10});
        wallPositions2.push({lng: wallPositions2[0].lng, lat: wallPositions2[0].lat, alt: -10});
        let polylineVolumes = [], entities = viewer.entities._entities.values;
        //找entities中的管线
        for (let k in entities) {
            if (entities[k] && entities[k].polylineVolume) {
                polylineVolumes.push(entities[k]);
            }
        }

        //截面            相交点
        let polygon = [], intersections = [];
        //将polygon转化成笛卡尔坐标系
        for (let po in wallPositions2) {
            polygon.push(GeoInfoTools.Transform.toCartesian(wallPositions2[po]))
        }
        // console.log(GetPanelEquation(polygon))
        //便利管线进行横断面分析
        if (polylineVolumes.length > 0) {
            //遍历polylineVolumes
            for (let n in polylineVolumes) {
                //获取polylineVolume的位置信息
                let polylineVolumePositions = polylineVolumes[n].polylineVolume.positions.getValue();
                //遍历位置信息
                for (let p = 0; p < polylineVolumePositions.length - 1; p++) {
                    let line = [];
                    line.push(polylineVolumePositions[p]);
                    line.push(polylineVolumePositions[p + 1]);

                    let point = getPointInPolygon(line, polygon);
                    if (point) {
                        if (JudgePointInPolyline(point, line)) {
                            if (JudgePointInPolygon(point, polygon)) {
                                intersections.push(point);
                            }
                        }
                    }
                }

            }
        }

        //交点表示
        // for (let position in intersections) {
        //     addPoint(intersections[position])
        // }

        // console.log(intersections);
        let results = [];
        for (let t in intersections) {
            results.push(GeoInfoTools.Transform.toDegrees(intersections[t]));
        }
        // console.log(results)
        if (results.length > 0) {
            callback(results);
            // getCrossAnalysisResultToContext(results)
        } else {
            //todo 没有横断面的结果
        }

    }

    return undefined;
}





你可能感兴趣的:(tools)