演示地址: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); }