百度地图画地块测亩功能

html5原生写法

<!DOCTYPE html>

<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">

    <title>百度地图画地块</title>

    <script type="text/javascript"
            src="http://api.map.baidu.com/api?v=2.0&ak={ak}"></script>
    <!--加载鼠标绘制工具-->
    <script type="text/javascript"
            src="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js"></script>
    <link rel="stylesheet" href="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css"/>

    <script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
    <script src="js/GeoUtils.js" type="text/javascript"></script>
    </script>
</head>

<body>
<div>
    <div id="allmap" style="padding-top: 80%;"></div>
    <div id="map" style="height:100%;-webkit-transition: all 0.5s ease-in-out;transition: all 0.5s ease-in-out;"></div>
</div>
<div id="result">
    <input type="button" value="获取绘制的覆盖物个数" onclick="alert(overlays.length)"/>
    <input type="button" value="获取绘制的所有点" onclick="getPoint()"/>
    <input type="button" value="清除所有覆盖物" onclick="clearAll()"/>
</div>
<script>

    // 百度地图API功能

    var map = new BMap.Map("allmap", {mapType: BMAP_HYBRID_MAP, maxZoom: 17});
    // 初始化地图,设置中心点坐标和地图级别。
    map.centerAndZoom('延寿县', 15);
    //启用滚轮放大缩小
    map.enableScrollWheelZoom();
    //添加鱼骨控件
    map.addControl(new BMap.NavigationControl());
    //添加地图类型控件
    //map.addControl(new BMap.MapTypeControl());
    map.setCurrentCity("延寿县");

    var dataList = [];
    //鼠标绘制完成回调方法   获取各个点的经纬度
    var overlays = [];
    var overlaycomplete = function (e) {
        overlays.push(e.overlay);
        var x = 0;
        var y = 0;
        var mapStr = "";
        var path = e.overlay.getPath();//Array<Point> 返回多边型的点数组
        for (var i = 0; i < path.length; i++) {
            console.log("localtion-> lng:" + path[i].lng + "\n lat:" + path[i].lat);
            x = x + parseFloat(path[i].lng);
            y = y + parseFloat(path[i].lat);
            if (i == 0) {
                mapStr = "new BMap.Point(" + path[i].lng + "," + path[i].lat + ")";
            } else {
                mapStr = mapStr + "," + "new BMap.Point(" + path[i].lng + "," + path[i].lat + ")";
            }
        }
        x = x / path.length;
        y = y / path.length;
        console.log("中心点-> " + x + "-" + y)
        console.log(mapStr)
        fun(1, x + "," + y, mapStr, "未播", "red")
    };
    var styleOptions = {
        strokeColor: "red",    //边线颜色。
        fillColor: "red",      //填充颜色。当参数为空时,圆形将没有填充效果。
        strokeWeight: 3,       //边线的宽度,以像素为单位。
        strokeOpacity: 0.8,       //边线透明度,取值范围0 - 1。
        fillOpacity: 0.6,      //填充的透明度,取值范围0 - 1。
        strokeStyle: 'solid' //边线的样式,solid或dashed。
    }
    //实例化鼠标绘制工具
    var drawingManager = new BMapLib.DrawingManager(map, {
        isOpen: false, //是否开启绘制模式
        enableDrawingTool: true, //是否显示工具栏
        drawingMode: BMAP_DRAWING_POLYGON,//绘制模式  多边形
        drawingToolOptions: {
            anchor: BMAP_ANCHOR_TOP_RIGHT, //位置
            offset: new BMap.Size(5, 5), //偏离值
            drawingModes: [
                BMAP_DRAWING_POLYGON
            ]
        },
        polygonOptions: styleOptions //多边形的样式
    });

    //添加鼠标绘制工具监听事件,用于获取绘制结果
    drawingManager.addEventListener('overlaycomplete', overlaycomplete);

    // map.addEventListener("rightclick", function (e) {
    //     if (confirm(e.point.lng + "," + e.point.lat)) {
    //         $("shape").innerHTML = $("shape").innerHTML + " <br/>(" + e.point.lng + "," + e.point.lat + ")";
    //         console.log("中心点-> " +  e.point.lng  + "-" + e.point.lat)
    //     }
    // });

    function clearAll() {
        for (var i = 0; i < overlays.length; i++) {
            map.removeOverlay(overlays[i]);
        }
        overlays.length = 0;
    }

    function getPoint() {
        var path = e.overlay.getPath();//Array<Point> 返回多边型的点数组
        for (var i = 0; i < path.length; i++) {
            console.log("lng:" + path[i].lng + "\n lat:" + path[i].lat);
        }
    }

    // 地址自动完成
    //下拉框选址采用的是高德地图的经纬度坐标,通过此方法转为百度坐标(因为圈定区域时用的是百度地图,所以判断是否在多边形中要用百度坐标判断)
    AMap.plugin('AMap.Autocomplete', function () {
        var endcomplete = new AMap.Autocomplete({
            city: '福州',
            input: 'end-place',
            datatype: 'poi'
        });
        AMap.event.addListener(endcomplete, "select", function (data) {
            select_txt = data.poi.name;
            if (select_txt.charAt(select_txt.length - 1, 1) == '镇') {
                mui.alert('无匹配地址,请选择就近位置', '参数错误');
            }
            var pt = new BMap.Point(data.poi.location.lng, data.poi.location.lat);
            //var isIn = ptInPolygon(pt);            var isIn = ptInPolygon(data.poi.location.lng, data.poi.location.lat);
            //非5区的重选
            if (data.poi.adcode == 350102 || data.poi.adcode == 350111 || data.poi.adcode == 350103 || data.poi.adcode == 350104 || data.poi.adcode == 350105 || isIn) {
                sfxz = 1;
                via_place_data['end-place'] = {
                    address: data.poi.name,
                    lat: data.poi.location.lat,
                    lng: data.poi.location.lng,
                    adcode: data.poi.adcode
                };
            } else {
                mui.alert('当前仅限市内五区及大学城范围,请重新选择地址', '参数错误');
                sfxz = 0;
                return;
            }
        });
    });


    function ptInPolygon(x, y) {
        var pts = [];
        var pt1 = new BMap.Point(119.214795, 26.019238);
        var pt2 = new BMap.Point(119.230749, 26.024693);
        var pt3 = new BMap.Point(119.210914, 26.078185);
        var pt4 = new BMap.Point(119.196829, 26.086622);
        var pt5 = new BMap.Point(119.182456, 26.080911);
        var pt6 = new BMap.Point(119.180587, 26.065464);
        var pt7 = new BMap.Point(119.198266, 26.035861);

        pts.push(pt1);
        pts.push(pt2);
        pts.push(pt3);
        pts.push(pt4);
        pts.push(pt5);
        pts.push(pt6);
        pts.push(pt7);
        var ply = new BMap.Polygon(pts);

        //var pt =new BMap.Point(116.400, 39.914);
        var pt = tobdMap(x, y);
        var result = BMapLib.GeoUtils.isPointInPolygon(pt, ply);
        if (result == true) {
            return true;
            //alert("点在多边形内");
        } else {
            return false;
            //alert("点在多边形外")
        }
    }

    //坐标应该要做转换,否则下面判断点是否在区域中是用的百度地图判断,如果不转换会造成偏差
    function tobdMap(x, y) {
        var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
        var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
        var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
        var bd_lon = z * Math.cos(theta) + 0.0065;
        var bd_lat = z * Math.sin(theta) + 0.006;
        var pt = new BMap.Point(bd_lon, bd_lat);
        return pt;
    }

    // fun(1, "112.254474,32.088357", "new BMap.Point(112.25221,32.091263),new BMap.Point(112.252785,32.091202),new BMap.Point(112.252929,32.090621),new BMap.Point(112.253576,32.090407),new BMap.Point(112.253576,32.090896),new BMap.Point(112.256199,32.090468),new BMap.Point(112.256558,32.091416),new BMap.Point(112.258319,32.091355),new BMap.Point(112.256055,32.085114),new BMap.Point(112.254007,32.085451),new BMap.Point(112.252785,32.085512),new BMap.Point(112.252282,32.085145),new BMap.Point(112.251851,32.085145),new BMap.Point(112.251635,32.084625),new BMap.Point(112.251025,32.084533),new BMap.Point(112.252138,32.091018)", '已播', 'green');
    // fun(2, "112.244543,32.085696", "new BMap.Point(112.24086,32.087332),new BMap.Point(112.244561,32.087669),new BMap.Point(112.248065,32.087791),new BMap.Point(112.248658,32.087883),new BMap.Point(112.249125,32.086047),new BMap.Point(112.24952,32.086063),new BMap.Point(112.250023,32.084258),new BMap.Point(112.241435,32.082973),new BMap.Point(112.240609,32.084548)", '未播', 'blue');
    // fun(3, "112.248244,32.088342", "new BMap.Point(112.247737,32.087975),new BMap.Point(112.248442,32.089149),new BMap.Point(112.248536,32.089149),new BMap.Point(112.248572,32.088036)", '未播', 'green');
    // fun(1, "112.243277,32.078097", "new BMap.Point(112.242419, 32.078724), BMap.Point(112.243003, 32.077122), BMap.Point(112.244342, 32.077382), BMap.Point(112.243542, 32.078965)", "已播", 'green')
    function fun(i, xy, arr, wb, ys) {
        //创建经纬度数组
        eval("var secRingCenter" + i + " = new BMap.Point(" + xy + ")");
        eval("var secRing" + i + " = [" + arr + "]");
        //创建多边形
        console.log("创建多边形")
        eval("var secRingPolygon" + i + "= new BMap.Polygon(secRing" + i + ", { strokeColor: \"" + ys + "\", strokeWeight: 4})");
        //eval("var secRingPolygon" + i + "= new BMap.Polygon(secRing" + i + ", { FillColor:\"red\", strokeColor: \"blue\", strokeWeight: 2, strokeOpacity: 0.3 })");

        //添加多边形到地图上
        map.addOverlay(eval("secRingPolygon" + i));

        var resultArea = BMapLib.GeoUtils.getPolygonArea(eval("secRingPolygon" + i)); //计算多边形的面积(单位米)

        //给多边形添加鼠标事件
        console.log("给多边形添加鼠标事件")
        eval("secRingPolygon" + i).addEventListener("mouseover", function () {//鼠标经过时
            eval("secRingPolygon" + i).setStrokeColor("red"); //多边形边框为红色
            //eval("secRingPolygon" + i).setFillColor(ys);
            map.addOverlay(eval("secRingLabel" + i)); //添加多边形遮照
            //map.panTo(eval("secRingCenter"+i)); //将地图移动到指定点
        });
        eval("secRingPolygon" + i).addEventListener("mouseout", function () {
            eval("secRingPolygon" + i).setStrokeColor(ys);
            //eval("secRingPolygon" + i).setFillColor("");
            map.removeOverlay(eval("secRingLabel" + i));
        });
        eval("secRingPolygon" + i).addEventListener("click", function () {
            map.zoomIn();
            eval("secRingPolygon" + i).setStrokeColor(ys);
            //eval("secRingPolygon" + i).setFillColor("");
            map.setCenter(eval("secRingCenter" + i));
        });
        //创建标签
        eval("var secRingLabel" + i + "= new BMap.Label(\"<b>" + wb + " 面积(㎡):" + Math.floor(resultArea) + ",亩数:" + Math.floor(resultArea * (15 / 10000)) + "</b>\", { offset: new BMap.Size(0, 0), position: secRingCenter" + i + "})");
        eval("secRingLabel" + i).setStyle({"z-index": "999999", "padding": "2px", "border": "1px solid #ccff00"});
    }

</script>
<style>
    .amap-sug-result {
        position: fixed;
        z-index: 1024;
        background-color: #fefefe;
        border: 1px solid #d1d1d1;
        visibility: hidden;
    }

    .mui-popup-title + .mui-popup-text {
        text-align: left;
    }
</style>
</body>

</html>

GeoUtil.js

/**
 * @fileoverview GeoUtils类提供若干几何算法,用来帮助用户判断点与矩形、
 * 圆形、多边形线、多边形面的关系,并提供计算折线长度和多边形的面积的公式。
 * 主入口类是<a href="symbols/BMapLib.GeoUtils.html">GeoUtils</a>,
 * 基于Baidu Map API 1.2。
 *
 * @author Baidu Map Api Group
 * @version 1.2
 */

//BMapLib.GeoUtils.degreeToRad(Number)
//将度转化为弧度

//BMapLib.GeoUtils.getDistance(Point, Point)
//计算两点之间的距离,两点坐标必须为经纬度

//BMapLib.GeoUtils.getPolygonArea(polygon)
//计算多边形面或点数组构建图形的面积,注意:坐标类型只能是经纬度,且不适合计算自相交多边形的面积(封闭的面积)

//BMapLib.GeoUtils.getPolylineDistance(polyline)
//计算折线或者点数组的长度

//BMapLib.GeoUtils.isPointInCircle(point, circle)
//判断点是否在圆形内

//BMapLib.GeoUtils.isPointInPolygon(point, polygon)
//判断点是否多边形内

//BMapLib.GeoUtils.isPointInRect(point, bounds)
//判断点是否在矩形内

//BMapLib.GeoUtils.isPointOnPolyline(point, polyline)
//判断点是否在折线上

//BMapLib.GeoUtils.radToDegree(Number)
//将弧度转化为度

/**
 * @namespace BMap的所有library类均放在BMapLib命名空间下
 */
var BMapLib = window.BMapLib = BMapLib || {};
(function () {

    /**
     * 地球半径
     */
    var EARTHRADIUS = 6370996.81;

    /**
     * @exports GeoUtils as BMapLib.GeoUtils
     */
    var GeoUtils =
        /**
         * GeoUtils类,静态类,勿需实例化即可使用
         * @class GeoUtils类的<b>入口</b>。
         * 该类提供的都是静态方法,勿需实例化即可使用。
         */
        BMapLib.GeoUtils = function () {
        }

    /**
     * 判断点是否在矩形内
     * @param {Point} point 点对象
     * @param {Bounds} bounds 矩形边界对象
     * @returns {Boolean} 点在矩形内返回true,否则返回false
     */
    GeoUtils.isPointInRect = function (point, bounds) {
//检查类型是否正确
        if (!(point instanceof BMap.Point) ||
            !(bounds instanceof BMap.Bounds)) {
            return false;
        }
        var sw = bounds.getSouthWest(); //西南脚点
        var ne = bounds.getNorthEast(); //东北脚点
        return (point.lng >= sw.lng && point.lng <= ne.lng && point.lat >= sw.lat && point.lat <= ne.lat);
    }

    /**
     * 判断点是否在圆形内
     * @param {Point} point 点对象
     * @param {Circle} circle 圆形对象
     * @returns {Boolean} 点在圆形内返回true,否则返回false
     */
    GeoUtils.isPointInCircle = function (point, circle) {
//检查类型是否正确
        if (!(point instanceof BMap.Point) ||
            !(circle instanceof BMap.Circle)) {
            return false;
        }

//point与圆心距离小于圆形半径,则点在圆内,否则在圆外
        var c = circle.getCenter();
        var r = circle.getRadius();

        var dis = GeoUtils.getDistance(point, c);
        if (dis <= r) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断点是否在折线上
     * @param {Point} point 点对象
     * @param {Polyline} polyline 折线对象
     * @returns {Boolean} 点在折线上返回true,否则返回false
     */
    GeoUtils.isPointOnPolyline = function (point, polyline) {
//检查类型
        if (!(point instanceof BMap.Point) ||
            !(polyline instanceof BMap.Polyline)) {
            return false;
        }

//首先判断点是否在线的外包矩形内,如果在,则进一步判断,否则返回false
        var lineBounds = polyline.getBounds();
        if (!this.isPointInRect(point, lineBounds)) {
            return false;
        }

//判断点是否在线段上,设点为Q,线段为P1P2 ,
//判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0,且 Q 在以 P1,P2为对角顶点的矩形内
        var pts = polyline.getPath();
        for (var i = 0; i < pts.length - 1; i++) {
            var curPt = pts[i];
            var nextPt = pts[i + 1];
//首先判断point是否在curPt和nextPt之间,即:此判断该点是否在该线段的外包矩形内
            if (point.lng >= Math.min(curPt.lng, nextPt.lng) && point.lng <= Math.max(curPt.lng, nextPt.lng) &&
                point.lat >= Math.min(curPt.lat, nextPt.lat) && point.lat <= Math.max(curPt.lat, nextPt.lat)) {
//判断点是否在直线上公式
                var precision = (curPt.lng - point.lng) * (nextPt.lat - point.lat) - (nextPt.lng - point.lng) * (curPt.lat - point.lat);
                if (precision < 2e-10 && precision > -2e-10) {//实质判断是否接近0
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 判断点是否多边形内
     * @param {Point} point 点对象
     * @param {Polyline} polygon 多边形对象
     * @returns {Boolean} 点在多边形内返回true,否则返回false
     */
    GeoUtils.isPointInPolygon = function (point, polygon) {
//检查类型
        if (!(point instanceof BMap.Point) ||
            !(polygon instanceof BMap.Polygon)) {
            return false;
        }

//首先判断点是否在多边形的外包矩形内,如果在,则进一步判断,否则返回false
        var polygonBounds = polygon.getBounds();
        if (!this.isPointInRect(point, polygonBounds)) {
            return false;
        }

        var pts = polygon.getPath(); //获取多边形点

//下述代码来源:http://paulbourke.net/geometry/insidepoly/,进行了部分修改
//基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则
//在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。

        var N = pts.length;
        var boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
        var intersectCount = 0; //cross points count of x
        var precision = 2e-10; //浮点类型计算时候与0比较时候的容差
        var p1, p2; //neighbour bound vertices
        var p = point; //测试点

        p1 = pts[0]; //left vertex
        for (var i = 1; i <= N; ++i) {//check all rays
            if (p.equals(p1)) {
                return boundOrVertex; //p is an vertex
            }

            p2 = pts[i % N]; //right vertex
            if (p.lat < Math.min(p1.lat, p2.lat) || p.lat > Math.max(p1.lat, p2.lat)) {//ray is outside of our interests
                p1 = p2;
                continue; //next ray left point
            }
            if (p.lat > Math.min(p1.lat, p2.lat) && p.lat < Math.max(p1.lat, p2.lat)) {//ray is crossing over by the algorithm (common part of)
                if (p.lng <= Math.max(p1.lng, p2.lng)) {//x is before of ray
                    if (p1.lat == p2.lat && p.lng >= Math.min(p1.lng, p2.lng)) {//overlies on a horizontal ray
                        return boundOrVertex;
                    }

                    if (p1.lng == p2.lng) {//ray is vertical


                        if (p1.lng == p.lng) {//overlies on a vertical ray
                            return boundOrVertex;
                        } else {//before ray
                            ++intersectCount;
                        }
                    } else {//cross point on the left side


                        var xinters = (p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) + p1.lng; //cross point of lng


                        if (Math.abs(p.lng - xinters) < precision) {//overlies on a ray
                            return boundOrVertex;
                        }

                        if (p.lng < xinters) {//before ray
                            ++intersectCount;
                        }
                    }
                }
            } else {//special case when ray is crossing through the vertex
                if (p.lat == p2.lat && p.lng <= p2.lng) {//p crossing over p2
                    var p3 = pts[(i + 1) % N]; //next vertex


                    if (p.lat >= Math.min(p1.lat, p3.lat) && p.lat <= Math.max(p1.lat, p3.lat)) {//p.lat lies between p1.lat & p3.lat
                        ++intersectCount;
                    } else {
                        intersectCount += 2;
                    }
                }
            }
            p1 = p2; //next ray left point
        }

        if (intersectCount % 2 == 0) {//偶数在多边形外
            return false;
        } else { //奇数在多边形内
            return true;
        }
    }

    /**
     * 将度转化为弧度
     * @param {degree} Number 度
     * @returns {Number} 弧度
     */
    GeoUtils.degreeToRad = function (degree) {
        return Math.PI * degree / 180;
    }

    /**
     * 将弧度转化为度
     * @param {radian} Number 弧度
     * @returns {Number} 度
     */
    GeoUtils.radToDegree = function (rad) {
        return (180 * rad) / Math.PI;
    }

    /**
     * 将v值限定在a,b之间,纬度使用
     */
    function _getRange(v, a, b) {
        if (a != null) {
            v = Math.max(v, a);
        }
        if (b != null) {
            v = Math.min(v, b);
        }
        return v;
    }

    /**
     * 将v值限定在a,b之间,经度使用
     */
    function _getLoop(v, a, b) {
        while (v > b) {
            v -= b - a
        }
        while (v < a) {
            v += b - a
        }
        return v;
    }

    /**
     * 计算两点之间的距离,两点坐标必须为经纬度
     * @param {point1} Point 点对象
     * @param {point2} Point 点对象
     * @returns {Number} 两点之间距离,单位为米
     */
    GeoUtils.getDistance = function (point1, point2) {
//判断类型
        if (!(point1 instanceof BMap.Point) ||
            !(point2 instanceof BMap.Point)) {
            return 0;
        }

        point1.lng = _getLoop(point1.lng, -180, 180);
        point1.lat = _getRange(point1.lat, -74, 74);
        point2.lng = _getLoop(point2.lng, -180, 180);
        point2.lat = _getRange(point2.lat, -74, 74);

        var x1, x2, y1, y2;
        x1 = GeoUtils.degreeToRad(point1.lng);
        y1 = GeoUtils.degreeToRad(point1.lat);
        x2 = GeoUtils.degreeToRad(point2.lng);
        y2 = GeoUtils.degreeToRad(point2.lat);

        return EARTHRADIUS * Math.acos((Math.sin(y1) * Math.sin(y2) + Math.cos(y1) * Math.cos(y2) * Math.cos(x2 - x1)));
    }

    /**
     * 计算折线或者点数组的长度
     * @param {Polyline|Array<Point>} polyline 折线对象或者点数组
     * @returns {Number} 折线或点数组对应的长度
     */
    GeoUtils.getPolylineDistance = function (polyline) {
//检查类型
        if (polyline instanceof BMap.Polyline ||
            polyline instanceof Array) {
//将polyline统一为数组
            var pts;
            if (polyline instanceof BMap.Polyline) {
                pts = polyline.getPath();
            } else {
                pts = polyline;
            }

            if (pts.length < 2) {//小于2个点,返回0
                return 0;
            }

//遍历所有线段将其相加,计算整条线段的长度
            var totalDis = 0;
            for (var i = 0; i < pts.length - 1; i++) {
                var curPt = pts[i];
                var nextPt = pts[i + 1]
                var dis = GeoUtils.getDistance(curPt, nextPt);
                totalDis += dis;
            }

            return totalDis;

        } else {
            return 0;
        }
    }

    /**
     * 计算多边形面或点数组构建图形的面积,注意:坐标类型只能是经纬

     度,且不适合计算自相交多边形的面积
     * @param {Polygon|Array<Point>} polygon 多边形面对象或者点数

     组
     * @returns {Number} 多边形面或点数组构成图形的面积
     */
    GeoUtils.getPolygonArea = function (polygon) {
//检查类型
        if (!(polygon instanceof BMap.Polygon) &&
            !(polygon instanceof Array)) {
            return 0;
        }
        var pts;
        if (polygon instanceof BMap.Polygon) {
            pts = polygon.getPath();
        } else {
            pts = polygon;
        }

        if (pts.length < 3) {//小于3个顶点,不能构建面
            return 0;
        }

        var totalArea = 0; //初始化总面积
        var LowX = 0.0;
        var LowY = 0.0;
        var MiddleX = 0.0;
        var MiddleY = 0.0;
        var HighX = 0.0;
        var HighY = 0.0;
        var AM = 0.0;
        var BM = 0.0;
        var CM = 0.0;
        var AL = 0.0;
        var BL = 0.0;
        var CL = 0.0;
        var AH = 0.0;
        var BH = 0.0;
        var CH = 0.0;
        var CoefficientL = 0.0;
        var CoefficientH = 0.0;
        var ALtangent = 0.0;
        var BLtangent = 0.0;
        var CLtangent = 0.0;
        var AHtangent = 0.0;
        var BHtangent = 0.0;
        var CHtangent = 0.0;
        var ANormalLine = 0.0;
        var BNormalLine = 0.0;
        var CNormalLine = 0.0;
        var OrientationValue = 0.0;
        var AngleCos = 0.0;
        var Sum1 = 0.0;
        var Sum2 = 0.0;
        var Count2 = 0;
        var Count1 = 0;
        var Sum = 0.0;
        var Radius = EARTHRADIUS; //6378137.0,WGS84椭球半径
        var Count = pts.length;
        for (var i = 0; i < Count; i++) {
            if (i == 0) {
                LowX = pts[Count - 1].lng * Math.PI / 180;
                LowY = pts[Count - 1].lat * Math.PI / 180;
                MiddleX = pts[0].lng * Math.PI / 180;
                MiddleY = pts[0].lat * Math.PI / 180;
                HighX = pts[1].lng * Math.PI / 180;
                HighY = pts[1].lat * Math.PI / 180;
            } else if (i == Count - 1) {
                LowX = pts[Count - 2].lng * Math.PI / 180;
                LowY = pts[Count - 2].lat * Math.PI / 180;
                MiddleX = pts[Count - 1].lng * Math.PI / 180;
                MiddleY = pts[Count - 1].lat * Math.PI / 180;
                HighX = pts[0].lng * Math.PI / 180;
                HighY = pts[0].lat * Math.PI / 180;
            } else {
                LowX = pts[i - 1].lng * Math.PI / 180;
                LowY = pts[i - 1].lat * Math.PI / 180;
                MiddleX = pts[i].lng * Math.PI / 180;
                MiddleY = pts[i].lat * Math.PI / 180;
                HighX = pts[i + 1].lng * Math.PI / 180;
                HighY = pts[i + 1].lat * Math.PI / 180;
            }
            AM = Math.cos(MiddleY) * Math.cos(MiddleX);
            BM = Math.cos(MiddleY) * Math.sin(MiddleX);
            CM = Math.sin(MiddleY);
            AL = Math.cos(LowY) * Math.cos(LowX);
            BL = Math.cos(LowY) * Math.sin(LowX);
            CL = Math.sin(LowY);
            AH = Math.cos(HighY) * Math.cos(HighX);
            BH = Math.cos(HighY) * Math.sin(HighX);
            CH = Math.sin(HighY);
            CoefficientL = (AM * AM + BM * BM + CM * CM) / (AM * AL + BM * BL + CM * CL);
            CoefficientH = (AM * AM + BM * BM + CM * CM) / (AM * AH + BM * BH + CM * CH);
            ALtangent = CoefficientL * AL - AM;
            BLtangent = CoefficientL * BL - BM;
            CLtangent = CoefficientL * CL - CM;
            AHtangent = CoefficientH * AH - AM;
            BHtangent = CoefficientH * BH - BM;
            CHtangent = CoefficientH * CH - CM;
            AngleCos = (AHtangent * ALtangent + BHtangent * BLtangent + CHtangent * CLtangent) / (Math.sqrt(AHtangent * AHtangent + BHtangent * BHtangent + CHtangent * CHtangent) * Math.sqrt(ALtangent * ALtangent + BLtangent * BLtangent + CLtangent * CLtangent));
            AngleCos = Math.acos(AngleCos);
            ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent;
            BNormalLine = 0 - (AHtangent * CLtangent - CHtangent * ALtangent);
            CNormalLine = AHtangent * BLtangent - BHtangent * ALtangent;
            if (AM != 0)
                OrientationValue = ANormalLine / AM;
            else if (BM != 0)
                OrientationValue = BNormalLine / BM;
            else
                OrientationValue = CNormalLine / CM;
            if (OrientationValue > 0) {
                Sum1 += AngleCos;
                Count1++;
            } else {
                Sum2 += AngleCos;
                Count2++;
            }
        }
        var tempSum1, tempSum2;
        tempSum1 = Sum1 + (2 * Math.PI * Count2 - Sum2);
        tempSum2 = (2 * Math.PI * Count1 - Sum1) + Sum2;
        if (Sum1 > Sum2) {
            if ((tempSum1 - (Count - 2) * Math.PI) < 1)
                Sum = tempSum1;
            else
                Sum = tempSum2;
        } else {
            if ((tempSum2 - (Count - 2) * Math.PI) < 1)
                Sum = tempSum2;
            else
                Sum = tempSum1;
        }
        totalArea = (Sum - (Count - 2) * Math.PI) * Radius * Radius;
        return totalArea; //返回总面积
    }

})(); //闭包结束

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
百度地图的measureareatool是一种量工具,用于量地图上的面积。 这个工具可以帮助用户量地图上的区域面积,无论是园区、建筑物还是任何其他形状的区域,用户都可以通过该工具获得准确的面积数值。 使用measureareatool非常简单。用户只需在百度地图上选择需要量的区域,然后点击measureareatool的图标即可开始量。首先,用户需要在地图上点击多个点,以创建一个封闭的多边形。然后,measureareatool会自动计算出该多边形的面积,并在地图上显示结果。 measureareatool还具有一些有用的功能,例如用户可以在量过程中添加或删除某个点,以修正量的精度。此外,用户还可以选择以不同的单位显示量结果,如平方米、平方公里、英亩等。 这个工具在很多场景下都非常实用。比如在规划土地分配时,可以使用measureareatool来量每个地块的面积,以便公平分配资源。在工程建设中,该工具可以帮助工程师量建筑物的占地面积,以便进行合理的设计。在旅游规划中,measureareatool可以用来量景点的面积,帮助游客了解每个景点的大小和规模。 总的来说,百度地图的measureareatool是一个功能强大且用户友好的量工具,能够方便准确地量地图上的各个区域的面积。无论在生活、工作还是旅游中,它都能给用户带来很多帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值