zoukankan      html  css  js  c++  java
  • 百度地图API画多边型,测面积

    效果:

    脚本:

    [javascript] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">    
    2.     
    3. <html>    
    4. <head>    
    5. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />    
    6. <title>耕地分布图</title>    
    7. <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.3"></script>    
    8. <script src="Js/jquery-1.3.2.js" type="text/javascript"></script>    
    9. <script src="Js/GeoUtils.js" type="text/javascript"></script>    
    10. <style type="text/css">    
    11.   html,body    
    12.     {    
    13.         height:100%;    
    14.         margin:0;    
    15.     }    
    16. </style>    
    17. </head>    
    18.     
    19. <body>    
    20. <div style="100%; height:100%;z-index:9;border:1px solid gray" id="container"></div>    
    21. </body>    
    22. </html>    
    23. <script type="text/javascript">    
    24.     var map = new BMap.Map("container", { mapType: BMAP_HYBRID_MAP });      //设置卫星图为底图    
    25.     map.centerAndZoom(new BMap.Point(112.244629, 32.094896), 15);                     // 初始化地图,设置中心点坐标和地图级别。    
    26.     map.enableScrollWheelZoom();                            //启用滚轮放大缩小    
    27.     map.addControl(new BMap.NavigationControl());  //添加鱼骨控件    
    28.     map.addControl(new BMap.MapTypeControl());          //添加地图类型控件    
    29.     map.setCurrentCity("襄阳");          // 设置3D地图显示的城市 此项是必须设置的    
    30.     
    31.     
    32.     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');    
    33.     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');    
    34.     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');    
    35.     
    36.     //变量名,标签坐标,多边形坐标,文本,边框颜色    
    37.     function fun(i,xy,arr,wb,ys) {    
    38.         //创建经纬度数组    
    39.         eval("var secRingCenter" + i+" = new BMap.Point("+xy+")");    
    40.         eval("var secRing"+i+" = ["+arr+"]");    
    41.         //创建多边形    
    42.         eval("var secRingPolygon" + i + "= new BMap.Polygon(secRing" + i + ", { strokeColor: "" + ys + "", strokeWeight: 4})");    
    43.         //eval("var secRingPolygon" + i + "= new BMap.Polygon(secRing" + i + ", { FillColor:"red", strokeColor: "blue", strokeWeight: 2, strokeOpacity: 0.3 })");    
    44.     
    45.         //添加多边形到地图上    
    46.         map.addOverlay(eval("secRingPolygon"+i));    
    47.     
    48.         var resultArea = BMapLib.GeoUtils.getPolygonArea(eval("secRingPolygon" + i)); //计算多边形的面积(单位米)    
    49.     
    50.         //给多边形添加鼠标事件    
    51.         eval("secRingPolygon"+i).addEventListener("mouseover", function () {//鼠标经过时    
    52.             eval("secRingPolygon" + i).setStrokeColor("red"); //多边形边框为红色    
    53.             //eval("secRingPolygon" + i).setFillColor(ys);     
    54.             map.addOverlay(eval("secRingLabel"+i)); //添加多边形遮照    
    55.             //map.panTo(eval("secRingCenter"+i)); //将地图移动到指定点    
    56.         });    
    57.         eval("secRingPolygon"+i).addEventListener("mouseout", function () {    
    58.             eval("secRingPolygon" + i).setStrokeColor(ys);    
    59.             //eval("secRingPolygon" + i).setFillColor("");     
    60.             map.removeOverlay(eval("secRingLabel"+i));    
    61.         });    
    62.         eval("secRingPolygon"+i).addEventListener("click", function () {    
    63.             map.zoomIn();    
    64.             eval("secRingPolygon" + i).setStrokeColor(ys);    
    65.             //eval("secRingPolygon" + i).setFillColor("");     
    66.             map.setCenter(eval("secRingCenter"+i));    
    67.         });    
    68.         //创建标签    
    69.         eval("var secRingLabel" + i + "= new BMap.Label("<b>" + wb + " 面积(㎡):" + Math.floor(resultArea) + "</b>", { offset: new BMap.Size(0, 0), position: secRingCenter" + i + "})");    
    70.         eval("secRingLabel"+i).setStyle({ "z-index": "999999", "padding": "2px",  "border": "1px solid #ccff00" });    
    71.     }    
    72. </script>    



    GeoUtils.js

    [javascript] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. /**  
    2. * @fileoverview GeoUtils类提供若干几何算法,用来帮助用户判断点与矩形、  
    3. * 圆形、多边形线、多边形面的关系,并提供计算折线长度和多边形的面积的公式。   
    4. * 主入口类是<a href="symbols/BMapLib.GeoUtils.html">GeoUtils</a>,  
    5. * 基于Baidu Map API 1.2。  
    6. *  
    7. * @author Baidu Map Api Group   
    8. * @version 1.2  
    9. */    
    10.     
    11. //BMapLib.GeoUtils.degreeToRad(Number)    
    12. //将度转化为弧度    
    13.     
    14. //BMapLib.GeoUtils.getDistance(Point, Point)    
    15. //计算两点之间的距离,两点坐标必须为经纬度    
    16.     
    17. //BMapLib.GeoUtils.getPolygonArea(polygon)    
    18. //计算多边形面或点数组构建图形的面积,注意:坐标类型只能是经纬度,且不适合计算自相交多边形的面积(封闭的面积)    
    19.     
    20. //BMapLib.GeoUtils.getPolylineDistance(polyline)    
    21. //计算折线或者点数组的长度    
    22.     
    23. //BMapLib.GeoUtils.isPointInCircle(point, circle)    
    24. //判断点是否在圆形内    
    25.     
    26. //BMapLib.GeoUtils.isPointInPolygon(point, polygon)    
    27. //判断点是否多边形内    
    28.     
    29. //BMapLib.GeoUtils.isPointInRect(point, bounds)    
    30. //判断点是否在矩形内    
    31.     
    32. //BMapLib.GeoUtils.isPointOnPolyline(point, polyline)    
    33. //判断点是否在折线上    
    34.     
    35. //BMapLib.GeoUtils.radToDegree(Number)    
    36. //将弧度转化为度    
    37.     
    38. /**   
    39. * @namespace BMap的所有library类均放在BMapLib命名空间下  
    40. */    
    41. var BMapLib = window.BMapLib = BMapLib || {};    
    42. (function () {    
    43.     
    44.     /**  
    45.     * 地球半径  
    46.     */    
    47.     var EARTHRADIUS = 6370996.81;    
    48.     
    49.     /**   
    50.     * @exports GeoUtils as BMapLib.GeoUtils   
    51.     */    
    52.     var GeoUtils =    
    53.     /**  
    54.     * GeoUtils类,静态类,勿需实例化即可使用  
    55.     * @class GeoUtils类的<b>入口</b>。  
    56.     * 该类提供的都是静态方法,勿需实例化即可使用。       
    57.     */    
    58.      BMapLib.GeoUtils = function () {    
    59.      }    
    60.     
    61.     /**  
    62.     * 判断点是否在矩形内  
    63.     * @param {Point} point 点对象  
    64.     * @param {Bounds} bounds 矩形边界对象  
    65.     * @returns {Boolean} 点在矩形内返回true,否则返回false  
    66.     */    
    67.     GeoUtils.isPointInRect = function (point, bounds) {    
    68.         //检查类型是否正确    
    69.         if (!(point instanceof BMap.Point) ||    
    70.              !(bounds instanceof BMap.Bounds)) {    
    71.             return false;    
    72.         }    
    73.         var sw = bounds.getSouthWest(); //西南脚点    
    74.         var ne = bounds.getNorthEast(); //东北脚点    
    75.         return (point.lng >= sw.lng && point.lng <= ne.lng && point.lat >= sw.lat && point.lat <= ne.lat);    
    76.     }    
    77.     
    78.     /**  
    79.     * 判断点是否在圆形内  
    80.     * @param {Point} point 点对象  
    81.     * @param {Circle} circle 圆形对象  
    82.     * @returns {Boolean} 点在圆形内返回true,否则返回false  
    83.     */    
    84.     GeoUtils.isPointInCircle = function (point, circle) {    
    85.         //检查类型是否正确    
    86.         if (!(point instanceof BMap.Point) ||    
    87.             !(circle instanceof BMap.Circle)) {    
    88.             return false;    
    89.         }    
    90.     
    91.         //point与圆心距离小于圆形半径,则点在圆内,否则在圆外    
    92.         var c = circle.getCenter();    
    93.         var r = circle.getRadius();    
    94.     
    95.         var dis = GeoUtils.getDistance(point, c);    
    96.         if (dis <= r) {    
    97.             return true;    
    98.         } else {    
    99.             return false;    
    100.         }    
    101.     }    
    102.     
    103.     /**  
    104.     * 判断点是否在折线上  
    105.     * @param {Point} point 点对象  
    106.     * @param {Polyline} polyline 折线对象  
    107.     * @returns {Boolean} 点在折线上返回true,否则返回false  
    108.     */    
    109.     GeoUtils.isPointOnPolyline = function (point, polyline) {    
    110.         //检查类型    
    111.         if (!(point instanceof BMap.Point) ||    
    112.              !(polyline instanceof BMap.Polyline)) {    
    113.             return false;    
    114.         }    
    115.     
    116.         //首先判断点是否在线的外包矩形内,如果在,则进一步判断,否则返回false    
    117.         var lineBounds = polyline.getBounds();    
    118.         if (!this.isPointInRect(point, lineBounds)) {    
    119.             return false;    
    120.         }    
    121.     
    122.         //判断点是否在线段上,设点为Q,线段为P1P2 ,    
    123.         //判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0,且 Q 在以 P1,P2为对角顶点的矩形内    
    124.         var pts = polyline.getPath();    
    125.         for (var i = 0; i < pts.length - 1; i++) {    
    126.             var curPt = pts[i];    
    127.             var nextPt = pts[i + 1];    
    128.             //首先判断point是否在curPt和nextPt之间,即:此判断该点是否在该线段的外包矩形内    
    129.             if (point.lng >= Math.min(curPt.lng, nextPt.lng) && point.lng <= Math.max(curPt.lng, nextPt.lng) &&    
    130.                  point.lat >= Math.min(curPt.lat, nextPt.lat) && point.lat <= Math.max(curPt.lat, nextPt.lat)) {    
    131.                 //判断点是否在直线上公式    
    132.                 var precision = (curPt.lng - point.lng) * (nextPt.lat - point.lat) - (nextPt.lng - point.lng) * (curPt.lat - point.lat);    
    133.                 if (precision < 2e-10 && precision > -2e-10) {//实质判断是否接近0    
    134.                     return true;    
    135.                 }    
    136.             }    
    137.         }    
    138.         return false;    
    139.     }    
    140.     
    141.     /**  
    142.     * 判断点是否多边形内  
    143.     * @param {Point} point 点对象  
    144.     * @param {Polyline} polygon 多边形对象  
    145.     * @returns {Boolean} 点在多边形内返回true,否则返回false  
    146.     */    
    147.     GeoUtils.isPointInPolygon = function (point, polygon) {    
    148.         //检查类型    
    149.         if (!(point instanceof BMap.Point) ||    
    150.              !(polygon instanceof BMap.Polygon)) {    
    151.             return false;    
    152.         }    
    153.     
    154.         //首先判断点是否在多边形的外包矩形内,如果在,则进一步判断,否则返回false    
    155.         var polygonBounds = polygon.getBounds();    
    156.         if (!this.isPointInRect(point, polygonBounds)) {    
    157.             return false;    
    158.         }    
    159.     
    160.         var pts = polygon.getPath(); //获取多边形点    
    161.     
    162.         //下述代码来源:http://paulbourke.net/geometry/insidepoly/,进行了部分修改    
    163.         //基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则    
    164.         //在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。    
    165.     
    166.         var N = pts.length;    
    167.         var boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true    
    168.         var intersectCount = 0; //cross points count of x     
    169.         var precision = 2e-10; //浮点类型计算时候与0比较时候的容差    
    170.         var p1, p2; //neighbour bound vertices    
    171.         var p = point; //测试点    
    172.     
    173.         p1 = pts[0]; //left vertex            
    174.         for (var i = 1; i <= N; ++i) {//check all rays                
    175.             if (p.equals(p1)) {    
    176.                 return boundOrVertex; //p is an vertex    
    177.             }    
    178.     
    179.             p2 = pts[i % N]; //right vertex                
    180.             if (p.lat < Math.min(p1.lat, p2.lat) || p.lat > Math.max(p1.lat, p2.lat)) {//ray is outside of our interests                 
    181.                 p1 = p2;    
    182.                 continue; //next ray left point    
    183.             }    
    184.             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)    
    185.                 if (p.lng <= Math.max(p1.lng, p2.lng)) {//x is before of ray                        
    186.                     if (p1.lat == p2.lat && p.lng >= Math.min(p1.lng, p2.lng)) {//overlies on a horizontal ray    
    187.                         return boundOrVertex;    
    188.                     }    
    189.     
    190.                     if (p1.lng == p2.lng) {//ray is vertical             
    191.     
    192.     
    193.                         if (p1.lng == p.lng) {//overlies on a vertical ray    
    194.                             return boundOrVertex;    
    195.                         } else {//before ray    
    196.                             ++intersectCount;    
    197.                         }    
    198.                     } else {//cross point on the left side               
    199.     
    200.     
    201.                         var xinters = (p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) + p1.lng; //cross point of lng                  
    202.     
    203.     
    204.                         if (Math.abs(p.lng - xinters) < precision) {//overlies on a ray    
    205.                             return boundOrVertex;    
    206.                         }    
    207.     
    208.                         if (p.lng < xinters) {//before ray    
    209.                             ++intersectCount;    
    210.                         }    
    211.                     }    
    212.                 }    
    213.             } else {//special case when ray is crossing through the vertex                    
    214.                 if (p.lat == p2.lat && p.lng <= p2.lng) {//p crossing over p2                        
    215.                     var p3 = pts[(i + 1) % N]; //next vertex             
    216.     
    217.     
    218.                     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    
    219.                         ++intersectCount;    
    220.                     } else {    
    221.                         intersectCount += 2;    
    222.                     }    
    223.                 }    
    224.             }    
    225.             p1 = p2; //next ray left point    
    226.         }    
    227.     
    228.         if (intersectCount % 2 == 0) {//偶数在多边形外    
    229.             return false;    
    230.         } else { //奇数在多边形内    
    231.             return true;    
    232.         }    
    233.     }    
    234.     
    235.     /**  
    236.     * 将度转化为弧度  
    237.     * @param {degree} Number 度       
    238.     * @returns {Number} 弧度  
    239.     */    
    240.     GeoUtils.degreeToRad = function (degree) {    
    241.         return Math.PI * degree / 180;    
    242.     }    
    243.     
    244.     /**  
    245.     * 将弧度转化为度  
    246.     * @param {radian} Number 弧度       
    247.     * @returns {Number} 度  
    248.     */    
    249.     GeoUtils.radToDegree = function (rad) {    
    250.         return (180 * rad) / Math.PI;    
    251.     }    
    252.     
    253.     /**  
    254.     * 将v值限定在a,b之间,纬度使用  
    255.     */    
    256.     function _getRange(v, a, b) {    
    257.         if (a != null) {    
    258.             v = Math.max(v, a);    
    259.         }    
    260.         if (b != null) {    
    261.             v = Math.min(v, b);    
    262.         }    
    263.         return v;    
    264.     }    
    265.     
    266.     /**  
    267.     * 将v值限定在a,b之间,经度使用  
    268.     */    
    269.     function _getLoop(v, a, b) {    
    270.         while (v > b) {    
    271.             v -= b - a    
    272.         }    
    273.         while (v < a) {    
    274.             v += b - a    
    275.         }    
    276.         return v;    
    277.     }    
    278.     
    279.     /**  
    280.     * 计算两点之间的距离,两点坐标必须为经纬度  
    281.     * @param {point1} Point 点对象  
    282.     * @param {point2} Point 点对象  
    283.     * @returns {Number} 两点之间距离,单位为米  
    284.     */    
    285.     GeoUtils.getDistance = function (point1, point2) {    
    286.         //判断类型    
    287.         if (!(point1 instanceof BMap.Point) ||    
    288.              !(point2 instanceof BMap.Point)) {    
    289.             return 0;    
    290.         }    
    291.     
    292.         point1.lng = _getLoop(point1.lng, -180, 180);    
    293.         point1.lat = _getRange(point1.lat, -74, 74);    
    294.         point2.lng = _getLoop(point2.lng, -180, 180);    
    295.         point2.lat = _getRange(point2.lat, -74, 74);    
    296.     
    297.         var x1, x2, y1, y2;    
    298.         x1 = GeoUtils.degreeToRad(point1.lng);    
    299.         y1 = GeoUtils.degreeToRad(point1.lat);    
    300.         x2 = GeoUtils.degreeToRad(point2.lng);    
    301.         y2 = GeoUtils.degreeToRad(point2.lat);    
    302.     
    303.         return EARTHRADIUS * Math.acos((Math.sin(y1) * Math.sin(y2) + Math.cos(y1) * Math.cos(y2) * Math.cos(x2 - x1)));    
    304.     }    
    305.     
    306.     /**  
    307.     * 计算折线或者点数组的长度  
    308.     * @param {Polyline|Array<Point>} polyline 折线对象或者点数组  
    309.     * @returns {Number} 折线或点数组对应的长度  
    310.     */    
    311.     GeoUtils.getPolylineDistance = function (polyline) {    
    312.         //检查类型    
    313.         if (polyline instanceof BMap.Polyline ||    
    314.              polyline instanceof Array) {    
    315.             //将polyline统一为数组    
    316.             var pts;    
    317.             if (polyline instanceof BMap.Polyline) {    
    318.                 pts = polyline.getPath();    
    319.             } else {    
    320.                 pts = polyline;    
    321.             }    
    322.     
    323.             if (pts.length < 2) {//小于2个点,返回0    
    324.                 return 0;    
    325.             }    
    326.     
    327.             //遍历所有线段将其相加,计算整条线段的长度    
    328.             var totalDis = 0;    
    329.             for (var i = 0; i < pts.length - 1; i++) {    
    330.                 var curPt = pts[i];    
    331.                 var nextPt = pts[i + 1]    
    332.                 var dis = GeoUtils.getDistance(curPt, nextPt);    
    333.                 totalDis += dis;    
    334.             }    
    335.     
    336.             return totalDis;    
    337.     
    338.         } else {    
    339.             return 0;    
    340.         }    
    341.     }    
    342.     
    343.     /**  
    344.     * 计算多边形面或点数组构建图形的面积,注意:坐标类型只能是经纬  
    345.   
    346.     度,且不适合计算自相交多边形的面积  
    347.     * @param {Polygon|Array<Point>} polygon 多边形面对象或者点数  
    348.   
    349.     组  
    350.     * @returns {Number} 多边形面或点数组构成图形的面积  
    351.     */    
    352.     GeoUtils.getPolygonArea = function (polygon) {    
    353.         //检查类型    
    354.         if (!(polygon instanceof BMap.Polygon) &&    
    355.              !(polygon instanceof Array)) {    
    356.             return 0;    
    357.         }    
    358.         var pts;    
    359.         if (polygon instanceof BMap.Polygon) {    
    360.             pts = polygon.getPath();    
    361.         } else {    
    362.             pts = polygon;    
    363.         }    
    364.     
    365.         if (pts.length < 3) {//小于3个顶点,不能构建面    
    366.             return 0;    
    367.         }    
    368.     
    369.         var totalArea = 0; //初始化总面积    
    370.         var LowX = 0.0;    
    371.         var LowY = 0.0;    
    372.         var MiddleX = 0.0;    
    373.         var MiddleY = 0.0;    
    374.         var HighX = 0.0;    
    375.         var HighY = 0.0;    
    376.         var AM = 0.0;    
    377.         var BM = 0.0;    
    378.         var CM = 0.0;    
    379.         var AL = 0.0;    
    380.         var BL = 0.0;    
    381.         var CL = 0.0;    
    382.         var AH = 0.0;    
    383.         var BH = 0.0;    
    384.         var CH = 0.0;    
    385.         var CoefficientL = 0.0;    
    386.         var CoefficientH = 0.0;    
    387.         var ALtangent = 0.0;    
    388.         var BLtangent = 0.0;    
    389.         var CLtangent = 0.0;    
    390.         var AHtangent = 0.0;    
    391.         var BHtangent = 0.0;    
    392.         var CHtangent = 0.0;    
    393.         var ANormalLine = 0.0;    
    394.         var BNormalLine = 0.0;    
    395.         var CNormalLine = 0.0;    
    396.         var OrientationValue = 0.0;    
    397.         var AngleCos = 0.0;    
    398.         var Sum1 = 0.0;    
    399.         var Sum2 = 0.0;    
    400.         var Count2 = 0;    
    401.         var Count1 = 0;    
    402.         var Sum = 0.0;    
    403.         var Radius = EARTHRADIUS; //6378137.0,WGS84椭球半径     
    404.         var Count = pts.length;    
    405.         for (var i = 0; i < Count; i++) {    
    406.             if (i == 0) {    
    407.                 LowX = pts[Count - 1].lng * Math.PI / 180;    
    408.                 LowY = pts[Count - 1].lat * Math.PI / 180;    
    409.                 MiddleX = pts[0].lng * Math.PI / 180;    
    410.                 MiddleY = pts[0].lat * Math.PI / 180;    
    411.                 HighX = pts[1].lng * Math.PI / 180;    
    412.                 HighY = pts[1].lat * Math.PI / 180;    
    413.             }    
    414.             else if (i == Count - 1) {    
    415.                 LowX = pts[Count - 2].lng * Math.PI / 180;    
    416.                 LowY = pts[Count - 2].lat * Math.PI / 180;    
    417.                 MiddleX = pts[Count - 1].lng * Math.PI / 180;    
    418.                 MiddleY = pts[Count - 1].lat * Math.PI / 180;    
    419.                 HighX = pts[0].lng * Math.PI / 180;    
    420.                 HighY = pts[0].lat * Math.PI / 180;    
    421.             }    
    422.             else {    
    423.                 LowX = pts[i - 1].lng * Math.PI / 180;    
    424.                 LowY = pts[i - 1].lat * Math.PI / 180;    
    425.                 MiddleX = pts[i].lng * Math.PI / 180;    
    426.                 MiddleY = pts[i].lat * Math.PI / 180;    
    427.                 HighX = pts[i + 1].lng * Math.PI / 180;    
    428.                 HighY = pts[i + 1].lat * Math.PI / 180;    
    429.             }    
    430.             AM = Math.cos(MiddleY) * Math.cos(MiddleX);    
    431.             BM = Math.cos(MiddleY) * Math.sin(MiddleX);    
    432.             CM = Math.sin(MiddleY);    
    433.             AL = Math.cos(LowY) * Math.cos(LowX);    
    434.             BL = Math.cos(LowY) * Math.sin(LowX);    
    435.             CL = Math.sin(LowY);    
    436.             AH = Math.cos(HighY) * Math.cos(HighX);    
    437.             BH = Math.cos(HighY) * Math.sin(HighX);    
    438.             CH = Math.sin(HighY);    
    439.             CoefficientL = (AM * AM + BM * BM + CM * CM) / (AM * AL + BM * BL + CM * CL);    
    440.             CoefficientH = (AM * AM + BM * BM + CM * CM) / (AM * AH + BM * BH + CM * CH);    
    441.             ALtangent = CoefficientL * AL - AM;    
    442.             BLtangent = CoefficientL * BL - BM;    
    443.             CLtangent = CoefficientL * CL - CM;    
    444.             AHtangent = CoefficientH * AH - AM;    
    445.             BHtangent = CoefficientH * BH - BM;    
    446.             CHtangent = CoefficientH * CH - CM;    
    447.             AngleCos = (AHtangent * ALtangent + BHtangent * BLtangent + CHtangent * CLtangent) / (Math.sqrt(AHtangent * AHtangent + BHtangent * BHtangent + CHtangent * CHtangent) * Math.sqrt(ALtangent * ALtangent + BLtangent * BLtangent + CLtangent * CLtangent));    
    448.             AngleCos = Math.acos(AngleCos);    
    449.             ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent;    
    450.             BNormalLine = 0 - (AHtangent * CLtangent - CHtangent * ALtangent);    
    451.             CNormalLine = AHtangent * BLtangent - BHtangent * ALtangent;    
    452.             if (AM != 0)    
    453.                 OrientationValue = ANormalLine / AM;    
    454.             else if (BM != 0)    
    455.                 OrientationValue = BNormalLine / BM;    
    456.             else    
    457.                 OrientationValue = CNormalLine / CM;    
    458.             if (OrientationValue > 0) {    
    459.                 Sum1 += AngleCos;    
    460.                 Count1++;    
    461.             }    
    462.             else {    
    463.                 Sum2 += AngleCos;    
    464.                 Count2++;    
    465.             }    
    466.         }    
    467.         var tempSum1, tempSum2;    
    468.         tempSum1 = Sum1 + (2 * Math.PI * Count2 - Sum2);    
    469.         tempSum2 = (2 * Math.PI * Count1 - Sum1) + Sum2;    
    470.         if (Sum1 > Sum2) {    
    471.             if ((tempSum1 - (Count - 2) * Math.PI) < 1)    
    472.                 Sum = tempSum1;    
    473.             else    
    474.                 Sum = tempSum2;    
    475.         }    
    476.         else {    
    477.             if ((tempSum2 - (Count - 2) * Math.PI) < 1)    
    478.                 Sum = tempSum2;    
    479.             else    
    480.                 Sum = tempSum1;    
    481.         }    
    482.         totalArea = (Sum - (Count - 2) * Math.PI) * Radius * Radius;    
    483.         return totalArea; //返回总面积    
    484.     }    
    485.     
    486. })(); //闭包结束    



    注意:

    BMapLib.GeoUtils.getPolygonArea(polygon)  不适合计算自相交多边形的面积(封闭的面积)

  • 相关阅读:
    bzoj2101:[USACO2010 DEC]TREASURE CHEST 藏宝箱
    P3976 [TJOI2015]旅游(未完成)
    洛谷 P 5 3 0 4 [GXOI/GZOI2019]旅行者
    NOIP原题 斗地主(20190804)
    P2860 [USACO06JAN]冗余路径Redundant Paths
    vue中的插槽(slot)
    vue动态绑定class
    发现一个ps抠毛发简单快捷高质量的方法
    propsData传递数据
    sort排序原理
  • 原文地址:https://www.cnblogs.com/grimm/p/5097346.html
Copyright © 2011-2022 走看看