获取谷歌地图的行政区边界

演示地址:http://gist.hecmcc.com/division/getbounds.htm

原理:

1.从百度取行政区边界。

2.从百度坐标转化为GPS坐标。(基于百度API,0.1精度)

3.从GPS坐标转化为火星坐标。(基于网传0.1数据库插值)

 

注:坐标转化全部采用插值法。

核心函数:

       var dicCache = {};

       function maidu2gps(areaName, arrLnglat, onFinished) {
           //取0.1的点
           var lnglatArray = arrLnglat;
           var singleArray = boundsPointCopy(arrLnglat, 10);
           var unique = makeUniquePoint(singleArray).sort();
           var last = unique[unique.length -1];
           unique.push(new BMap.Point(last.lng + 0.1,last.lat + 0.1));

           var count = unique.length;
           var finished = 0;
           var currentIndex = 0;
           var checkCount = 0

           function makeKey(lng,lat){
                return [Math.round(lng), Math.round(lat)].join('_').replace(/\./g, '_');
           };

           function getMarsOffsetData(lng, lat){
               var key = makeKey(lng, lat);
               return dicCache[key];
           }

           function saveCacheToServer(area) {
                var json = $.toJSON(dicCache);
               $.post('Handler.ashx', { cmd: 'save', area: area, json: json}, function () { });
               $('#boundary').val(json);
           }
           setTimeout(function () {
               if (unique.length == finished) {

                   var gpsArray = new Array(lnglatArray.length);
                   //转换
                   for (var i = 0, ic = lnglatArray.length; i < ic; ++i) {
                       var n = lnglatArray[i];
                       var latConvert = n.lat * 10,
                            lngConvert = n.lng * 10;

                       var lat0 = Math.floor(latConvert), lng0 = Math.floor(lngConvert);
                       var lat1 = Math.floor(latConvert), lng1 = Math.ceil(lngConvert);
                       var lat2 = Math.ceil(latConvert), lng2 = Math.ceil(lngConvert);
                       var lat3 = Math.ceil(latConvert), lng3 = Math.floor(lngConvert);

                       var mo0 = getMarsOffsetData(lng0, lat0);
                       var mo1 = getMarsOffsetData(lng1, lat1);
                       var mo2 = getMarsOffsetData(lng2, lat2);
                       var mo3 = getMarsOffsetData(lng3, lat3);

                       var coef0 = (lat2 - latConvert) * (lng2 - lngConvert);
                       var coef1 = (lat3 - latConvert) * (lngConvert - lng3);
                       var coef2 = (latConvert - lat0) * (lngConvert - lng0);
                       var coef3 = (latConvert - lat1) * (lng1 - lngConvert);

                       var marsOffset = {};
                       marsOffset.LatOffset = mo0.LatOffset * coef0 + mo1.LatOffset * coef1 + mo2.LatOffset * coef2 + mo3.LatOffset * coef3;
                       marsOffset.LngOffset = mo0.LngOffset * coef0 + mo1.LngOffset * coef1 + mo2.LngOffset * coef2 + mo3.LngOffset * coef3;

                       gpsArray[i] = new BMap.Point(n.lng - marsOffset.LngOffset, n.lat - marsOffset.LatOffset);

                   }

                   saveCacheToServer(areaName);

                   onFinished(gpsArray);
                   return;
               }

               if (currentIndex - finished < 5 && currentIndex < count) {
                   var i = currentIndex++;
                   var lnglat = unique[i];
                   setTimeout(function () {
                       var pt = lnglat;

                       var key = makeKey(pt.lng * 10, pt.lat * 10);
                       if (!(key in dicCache)) {
                           BMap.Convertor.translate(pt, 0, function (d) {
                               d.bd09Point = pt;
                               d.finished = true;
                               var dlng = d.LngOffset = d.lng - pt.lng;
                               d.lng = pt.lng - dlng;

                               var dlat = d.LatOffset = d.lat - pt.lat;
                               d.lat = pt.lat - dlat;

                               dicCache[key] = d;
                               ++finished;
                               checkCount = 0;
                           });
                       }
                       else {
                           ++finished;
                           checkCount = 0;
                       }
                   }, 0);
               }
               checkCount++;
               if (checkCount > 100) {
                   alert('至少一个查询没有返回结果');
               }
               else {
                   setTimeout(arguments.callee, 10);
               }

           }, 2);
        
       }
posted @ 2013-10-22 09:08  阿牛  阅读(16701)  评论(2编辑  收藏  举报