/**
 * 地图测量
 * @param viewer 场景主视图
 * @constructor
 */
function MapMeasure(viewer) {
    let _self = this;
    _self.p = [];
    _self.polygon = [];
    _self.polyline = [];
    _self.viewer = viewer;
    _self.result = [];
    _self.drawLayer = new Cesium.PrimitiveCollection();
    _self.drawHelper = new DrawGeometryHelper(viewer);
    _self.viewer.scene.primitives.add(_self.drawLayer);
    /**
     * 计算多边形面积
     * @param points
     * @returns {number}
     * @constructor
     */
    function getPolygonAreaMeters(points) {
        var res = 0;
        for (var i = 0; i < points.length - 2; i++) {
            var j = (i + 1) % points.length;
            var k = (i + 2) % points.length;
            var totalAngle = Angle(Cesium.Cartographic.fromCartesian(points[i]), Cesium.Cartographic.fromCartesian(points[j]), Cesium.Cartographic.fromCartesian(points[k]));
            var dis_temp1 = getDistance(points[i], points[j]);
            var dis_temp2 = getDistance(points[j], points[k]);
            res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle));
        }
        return (res).toFixed(4);
    }
    /**
     * 计算两点之间的距离
     * @param point1 点1
     * @param point2 点2
     * @returns {number} 长度值
     */
    function getDistance(point1, point2) {
        var point1cartographic = Cesium.Cartographic.fromCartesian(point1);
        var point2cartographic = Cesium.Cartographic.fromCartesian(point2);
        /**根据经纬度计算出距离**/
        var geodesic = new Cesium.EllipsoidGeodesic();
        geodesic.setEndPoints(point1cartographic, point2cartographic);
        var s = geodesic.surfaceDistance;
        s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
        return s;
    }
    /**
     * 计算角度
     * @param p1 点1
     * @param p2 点2
     * @param p3 点3
     * @returns {number} 角度值
     * @constructor
     */
    function Angle(p1, p2, p3) {
        let bearing21 = Bearing(p2, p1);
        let bearing23 = Bearing(p2, p3);
        let angle = bearing21 - bearing23;
        if (angle < 0) {
            angle += 360
        }
        return angle;
    }
    /**
     * 方向
     * @param from 点1
     * @param to 点2
     * @returns {number} 角度值
     * @constructor
     */
    function Bearing(from, to) {
        let radiansPerDegree = Math.PI / 180.0;
        let degreesPerRadian = 180.0 / Math.PI;
        let lat1 = from.latitude * radiansPerDegree;
        let lon1 = from.longitude * radiansPerDegree;
        let lat2 = to.latitude * radiansPerDegree;
        let lon2 = to.longitude * radiansPerDegree;
        let angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
        if (angle < 0) {
            angle += Math.PI * 2.0
        }
        angle = angle * degreesPerRadian;
        return angle;
    }
    /**
     * 显示测量结果
     * @param text 文字信息
     * @param position 结果坐标
     */
    function drawResult(text, position) {
        let entity = _self.viewer.entities.add({
            position: position,
            label: {
                text: text,
                font: '16px Helvetica',
                outlineColor: Cesium.Color.BLACK,
                outlineWidth: 2,
                horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                pixelOffset: new Cesium.Cartesian2(0.0, -10)
            }
        });
        _self.result.push(entity);
    }
    /**
     * 绘制水平线段
     * @param name
     * @constructor
     */
    function DrawLinear(name) {
        _self.drawHelper.startDrawingPolyline({
            callback: function (position, state) {
                if (state === "drawClick") {
                    _self.polyline.push(position.clone());
                } else if (state === "drawEnd") {
                    let primitive = new Cesium.Primitive({
                        geometryInstances: new Cesium.GeometryInstance({
                            geometry: new Cesium.PolylineGeometry({
                                positions: _self.polyline,//坐标必须两个和两个以上
                                width: 2,//线宽
                                vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT
                            }),
                            attributes: {
                                color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.GREENYELLOW),//color  必须设置 不然没有效果
                            }
                        }),
                        appearance: new Cesium.PolylineColorAppearance({
                            translucent: false
                        })
                    });
                    for (let i = 1; i < _self.polyline.length; i++) {
                        let distance = Cesium.Cartesian3.distance(_self.polyline[i - 1], _self.polyline[i]);
                        if (distance.toFixed(2) > 1) {
                            let a = cartesian2LonLat(_self.polyline[i - 1]), b = cartesian2LonLat(_self.polyline[i]);
                            let lon = (a[0] + b[0]) / 2, lat = (a[1] + b[1]) / 2, height = (a[2] + b[2]) / 2;
                            let position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
                            let txt = "距离" + distance.toFixed(2) + "米";
                            drawResult(txt, position);
                        }
                    }
                    _self.drawLayer.add(primitive);
                    closeCSS(name);
                }
            }
        });
    }
    /**
     * 绘制高度线段
     * @param name
     * @constructor
     */
    function DrawHeight(name) {
        _self.drawHelper.startDrawingPolyline({
            callback: function (position) {
                _self.polyline.push(position);
                if (_self.polyline.length === 2) {
                    _self.drawHelper.stopDrawing();
                    let primitive = new Cesium.Primitive({
                        geometryInstances: new Cesium.GeometryInstance({
                            geometry: new Cesium.PolylineGeometry({
                                positions: _self.polyline,//坐标必须两个和两个以上
                                width: 2,//线宽
                                vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT
                            }),
                            attributes: {
                                color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.GREENYELLOW),//color  必须设置 不然没有效果
                            }
                        }),
                        appearance: new Cesium.PolylineColorAppearance({
                            translucent: false
                        })
                    });
                    for (let i = 1; i < _self.polyline.length; i++) {
                        let distance = Cesium.Cartesian3.distance(_self.polyline[i - 1], _self.polyline[i]);
                        if (distance.toFixed(2) > 1) {
                            let a = cartesian2LonLat(_self.polyline[i - 1]), b = cartesian2LonLat(_self.polyline[i]);
                            let lon = (a[0] + b[0]) / 2, lat = (a[1] + b[1]) / 2, height = (a[2] + b[2]) / 2;
                            let position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
                            let txt = "高度" + (b[2] - a[2]).toFixed(2) + "米";
                            drawResult(txt, position);
                        }
                    }
                    _self.drawLayer.add(primitive);
                    closeCSS(name);
                }
            }
        });
    }
    /**
     * 绘制面
     * @param name
     * @constructor
     */
    function DrawPolygon(name) {
        _self.drawHelper.startDrawingPolygon({
            callback: function (position, state) {
                if (state === "drawClick") {
                    _self.polygon.push(position.clone());
                }
                if (state === "drawEnd") {
                    _self.polygon.pop();
                    let primitive = new Cesium.GroundPrimitive({
                        id: "polygon",
                        geometryInstances: new Cesium.GeometryInstance({
                            geometry: Cesium.PolygonGeometry.fromPositions({
                                positions: _self.polygon,
                                vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
                            }),
                            attributes: {
                                color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromAlpha(Cesium.Color.RED, 0.6)),//color  必须设置 不然没有效果
                            }
                        }),
                        appearance: new Cesium.PerInstanceColorAppearance({
                            translucent: false,
                            closed: true,
                            aboveGround: true
                        }),
                        geodesic: true,
                        granularity: 10000,
                    });
                    let a = cartesian2LonLat(_self.polygon[_self.polygon.length - 1]),
                        b = cartesian2LonLat(_self.polygon[_self.polygon.length - 2]),
                        c = cartesian2LonLat(_self.polygon[_self.polygon.length - 3]);
                    let lon = (a[0] + b[0] + c[0]) / 3, lat = (a[1] + b[1] + c[1]) / 3,
                        height = (a[2] + b[2] + c[2]) / 3;
                    let position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
                    let txt = "面积" + (getPolygonAreaMeters(_self.polygon)) + "平方米";
                    drawResult(txt, position);
                    _self.drawLayer.add(primitive);
                    closeCSS(name);
                }
            },
        });
    }
    /**
     * 平面坐标转经纬度
     * @param cartesian
     * @returns {*[]}
     */
    function cartesian2LonLat(cartesian) {
        let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        let lon = Cesium.Math.toDegrees(cartographic.longitude);
        let lat = Cesium.Math.toDegrees(cartographic.latitude);
        return [lon, lat, cartographic.height];
    }
    /**
     * 关闭css
     * @param name
     */
    function closeCSS(name) {
        $(('#' + name + "-svg")).css('fill', '#ffffff');
        $('.measure').removeClass('measure');
    }
    /**
     * 长度测量
     * @param name
     * @constructor
     */
    MapMeasure.prototype.LinearMeasure = function (name) {
        _self.Clean();
        DrawLinear(name);
    };
    /**
     * 高度测量
     * @param name
     * @constructor
     */
    MapMeasure.prototype.HeightMeasure = function (name) {
        _self.Clean();
        DrawHeight(name);
    };
    /**
     * 面积测量
     * @param name
     * @constructor
     */
    MapMeasure.prototype.AreaMeasure = function (name) {
        _self.Clean();
        DrawPolygon(name);
    };
    /**
     * 清除测量结果
     * @constructor
     */
    MapMeasure.prototype.Clean = function () {
        _self.drawHelper.stopDrawing();
        _self.polygon = [];
        _self.polyline = [];
        _self.drawLayer.removeAll();
        if (_self.result.length > 0) {
            for (let i = 0; i < _self.result.length; i++) {
                _self.viewer.entities.remove(_self.result[i]);
            }
            _self.result = [];
        }
    };

}