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