百度地图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="width: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)  不适合计算自相交多边形的面积(封闭的面积)

 

posted @ 2016-01-03 22:24  爱你爱自己  阅读(2288)  评论(0编辑  收藏  举报