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

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

原理:

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

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

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

 

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

核心函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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 @   阿牛  阅读(16792)  评论(2编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· Qt个人项目总结 —— MySQL数据库查询与断言
点击右上角即可分享
微信分享提示