`
jie66989
  • 浏览: 254381 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

百度地图的瓦片参数解析

阅读更多
来自:http://blog.sina.com.cn/s/blog_4c8b1bdd0100xij4.html


百度地图的瓦片参数解析 (2012-03-12 23:23:47)
标签: 百度地图 瓦片参数 切片 纠偏参数 杂谈 分类: 编程技术
最近想在自己的Android手机上开发一个小工具可以实时查看附近周围的自行车还车点的可借车辆和可还车辆的空位,因为哥好几次屁颠屁颠骑到还车点的时候发现车位满了或者没车可借了,有次还因此损失接近百元,或者去一个新地方都不知道附近的还车点藏在什么地方!同时为了学习一下Android开发,因此想做这么一个小工具。
     考虑到以后专业需要,选择ArcGIS For Android工具进行开发,考虑google地图可能被国家给封掉,而百度地图越来越不错,因此选择百度地图作为地图,杭州市的自行车还车点分布图和实时数据可以调用杭州市地理信息公共服务平台提供的数据,因此基本上数据应该不成问题了!ArcGIS for Android提供了Compact型的本地离线瓦片地图的图层功能,但对于其他的瓦片地图图层需要自己去扩展,因此本人上一个星期下班时间趁兴趣爱好,稍微学习了下Eclipse 和Java的基本语法,终于走通了自定义瓦片图层的功能,但现在有个问题来了!本以为百度地图应该很多人用,肯定有相关的资料,但翻遍网络居然找不到关于百度地图的瓦片切片参数,只知道是用的高德提供的数据。百度、Google、论坛发帖都没有效果,只能自己硬着头皮去解析其参数了!哥向来不喜欢自己去研究比较简单的东西,但这次确实么有办法,只能自己去搞了.
    好在百度提供了其二次开发接口API,有Javascript、Flex、Android等版本,可以随便拿一个版本的来进行反编译然后解析一下,但考虑到Javascript不需要进行反编译,javascript是个解释型语句,顶多只是混淆而已,用个js调整工具,再加上VS强大的调试功能,也可以大致猜出其思路。SO,本人就从百度地图的Javascript接口开始推导其瓦片参数!
首先就从CenterAndZoom函数开始吧
centerAndZoom: function(T, cC) {
            var cB = this;
            if (bU(T)) {
                var cF = cB._getLocal();
                cF.setSearchCompleteCallback(function(cG) {
                    if (cF.getStatus() == 0 && cF._json.result.type == 2) {
                        var cI = cG.getPoi(0).point;
                        var cH = cC || O.getBestLevel(cF._json.content.level, cB);
                        cB.centerAndZoom(cI, cH);
                        if (BMAP_PERSPECTIVE_MAP.getCityName(T)) {
                            cB.setCurrentCity(T)
                        }
                    }
                });
                cF.search(T);
                return
            }
            if (!(T instanceof b3) || !cC) {
                return
            }
            cC = cB._getProperZoom(cC).zoom;
            cB.lastLevel = cB.zoomLevel || cC;
            cB.zoomLevel = cC;
            cB.centerPoint = new b3(T.lng, T.lat);
            cB.mercatorCenter = cB.projection.lngLatToMercator(cB.centerPoint, cB.currentCity);
            cB.defaultZoomLevel = cB.defaultZoomLevel || cB.zoomLevel;
            cB.defaultCenter = cB.defaultCenter || cB.centerPoint;
            var cE = new a8("onload");
            var cD = new a8("onloadcode");
            cE.point = new b3(T.lng, T.lat);
            cE.pixel = cB.pointToPixel(cB.centerPoint, cB.zoomLevel);
            cE.zoom = cC;
            if (!cB.loaded) {
                cB.loaded = true;
                cB.dispatchEvent(cE)
            }
            cB.dispatchEvent(cD);
            cB.dispatchEvent(new a8("onmoveend"));
            if (cB.lastLevel != cB.zoomLevel) {
                cB.dispatchEvent(new a8("onzoomend"))
            }
        }
调试进去,可以看到会调用
moveGridTiles: function() {
                            debugger;
                            var c0 = this.mapTypeLayers;
                            var cM = c0.concat(this.tileLayers);
                            var cS = cM.length;
                            for (var cU = 0; cU < cS; cU++) {
                                var cF = cM[cU];
                                if (cF.baseLayer) {
                                    this.tilesDiv = cF.tilesDiv
                                }
                                var c6 = this.map;
                                var c2 = c6.getMapType();
                                var c7 = c2.getProjection();
                                var cT = c6.zoomLevel;
                                var cW = c6.mercatorCenter;   //百度地图的瓦片行列号计算是先将经纬度换算成墨卡托投影来计算的,因为经纬度是个球面坐标,而瓦片切割的时候肯定是平面的,因此都会有个投影过程。这个墨卡托的投影公式后面再去研究,可以看看百度地图到底采用的什么投影!
                                this.mapCenterPoint = cW;
                                var cK = c2.getZoomUnits(cT);
                                var cN = c2.getZoomFactor(cT);
                                //上面的ck和cn就是获取类似瓦片地图分辨率的东东,同时可以看到百度地图是通过地图的中心点来计算整个地图需要调用的瓦片的行列号的,然后后面可能采用将瓦片进行螺旋排列的吧,后面的没细看(我看过有个开源的瓦片下载工具就是螺旋排列的,以增强可是效果!)
                                var cL = Math.ceil(cW.lng / cN);
                                var cG = Math.ceil(cW.lat / cN);
                                var cR = c2.getTileSize();
                                var cE = [cL, cG, (cW.lng - cL * cN) / cN * cR, (cW.lat - cG * cN) / cN * cR];
                                var c1 = cE[0] - Math.ceil((c6.width / 2 - cE[2]) / cR);
                                var cD = cE[1] - Math.ceil((c6.height / 2 - cE[3]) / cR);
                                var cX = cE[0] + Math.ceil((c6.width / 2 + cE[2]) / cR);
                                var cP = 0;
                                if (c2 === BMAP_PERSPECTIVE_MAP && c6.getZoom() == 15) {
                                    cP = 1
                                }
                                var cO = cE[1] + Math.ceil((c6.height / 2 + cE[3]) / cR) + cP;
                                this.areaCenter = new b3(cW.lng, cW.lat);
                                var cC = this.mapTiles;
                                var cJ = -this.areaCenter.lng / cK;
                                var cI = this.areaCenter.lat / cK;
                                var c4 = [Math.round(cJ), Math.round(cI)];
                                var cB = c6.getZoom();
                                for (var c5 in cC) {
                                    var c8 = cC[c5];
                                    var c3 = c8.info;
                                    if (c3[2] != cB || (c3[2] == cB && (c1 > c3[0] || cX <= c3[0] || cD > c3[1] || cO <= c3[1]))) {
                                        this.hideTile(c8)
                                    }
                                }
                                var cH = -c6.offsetX + c6.width / 2;
                                var cQ = -c6.offsetY + c6.height / 2;
                                cF.tilesDiv.style.left = Math.round(cJ + cH) - c4[0] + "px";
                                cF.tilesDiv.style.top = Math.round(cI + cQ) - c4[1] + "px";
                                var T = [];
                                for (var cZ = c1; cZ < cX; cZ++) {
                                    for (var cY = cD; cY < cO; cY++) {
                                        T.push([cZ, cY])
                                    }
                                }
                                T.sort((function(c9) {
                                    return function(da, db) {
                                        return ((0.4 * Math.abs(da[0] - c9[0]) + 0.6 * Math.abs(da[1] - c9[1])) - (0.4 * Math.abs(db[0] - c9[0]) + 0.6 * Math.abs(db[1] - c9[1])))
                                    }
                                })([cE[0] - 1, cE[1] - 1]));
                                this.numLoading += T.length;
                                for (var cZ = 0, cV = T.length; cZ < cV; cZ++) {
                                    this.showTile([T[cZ][0], T[cZ][1], cB], c4, cF)
                                }
                            }
                            return
                        }

可以看到两个获取分辨率相关的函数如下:
getZoomUnits: function(T) {
                            return Math.pow(2, (18 - T))    //从这里可以看出,百度地图的分辨率几乎就是固定的2的N次幂来计算的
                        },
                        getZoomFactor: function(T) {
                            return this.getZoomUnits(T) * 256
                        }

以上为本人的大致猜测,后面还需要继续检验,感觉百度好像对各个区域做了处理,这样才能满足全球的范围内的投影精度,这块没有细究!在这次的解析过程中还发现了一个奇怪之处!

//correct_pts:莫非是纠偏参数????貌似投影时会用到些参数,可以的话,后面再研究下它的纠偏参数吧,哎,上班后反而没有在学校那样有过多的时间去深入研究东西,很多东西都只是浅尝辄止,悲哀啊!
correct_pts: {
            bj: [{
                j: 116.305687,
                w: 39.990912,
                utm_x: 12947230.73,
                utm_y: 4836903.65,
                x: 630412,
                y: 547340
            }, {
                j: 116.381837,
                w: 40.000198,
                utm_x: 12955707.8,
                utm_y: 4838247.62,
                x: 667412,
                y: 561832
            }, {
                j: 116.430651,
                w: 39.995216,
                utm_x: 12961141.81,
                utm_y: 4837526.55,
                x: 686556,
                y: 573372
            }, {
                j: 116.474111,
                w: 39.976323,
                utm_x: 12965979.81,
                utm_y: 4834792.55,
                x: 697152,
                y: 586816
            }, {
                j: 116.280328,
                w: 39.953159,
                utm_x: 12944407.75,
                utm_y: 4831441.53,
                x: 603272,
                y: 549976
            }, {
                j: 116.316117,
                w: 39.952496,
                utm_x: 12948391.8,
                utm_y: 4831345.64,
                x: 618504,
                y: 557872
            }, {......

欧拉,暂时到此,可能里面会有些错误推导,希望有同道者共同研究,搞不定的话哥也只能去老老实实调用google地图了,毕竟资料多,或者调用那国家测绘局提供的那丑的不行的慢的像蜗牛的“天地图”地图或者直接采用百度的API算了吧。

不知道何时工具能够搞出来啊,每天1小时coding!
分享到:
评论

相关推荐

    百度地图所有级别瓦片切割代码

    【标题】"百度地图所有级别瓦片切割代码"所涉及的知识点主要集中在地图瓦片系统、Java编程语言以及坐标转换上。地图瓦片系统是数字地图的一种高效展示方式,而Java则是实现这一功能的主要编程工具。以下是这些知识点...

    百度地图瓦片生成工具-收费.zip

    百度地图瓦片生成工具是一款专为地图数据处理和可视化设计的专业软件。该工具的主要功能是将高精度的地图数据转化为瓦片图,这是一种广泛应用于Web地图服务(WMS)的图像分块技术。瓦片图通过将大尺寸的地图分割成多...

    百度地图切片下载工具V2.7.0323.zip

    《百度地图离线切片下载工具V2.7.0323——探索与实践》 在当今数字化时代,地图服务已经成为我们生活中不可或缺的一部分。尤其是对于户外活动爱好者、旅游者以及需要进行地理数据分析的专业人士来说,离线地图的...

    最新百度地图离线API

    4. **文档资料**:详细的API文档,解释了各个接口的功能、参数和使用方法。 通过学习和实践这个离线API,开发者不仅可以了解百度地图的基础操作,还能掌握如何在本地环境下进行地图应用的开发,提升应用的稳定性和...

    leaflet加载百度、高德、谷歌、天地图等在线地图

    在这个例子中,`ak`参数是您从百度地图开放平台获取的API密钥,它是合法使用百度地图服务的必要条件。 高德地图的加载方式类似,但需要使用不同的插件,如`L.tileLayer.amap`。高德地图API的使用同样需要一个密钥,...

    百度地图离线开发.docx

    离线开发百度地图涉及到的关键技术点主要包括:API 主文件处理、AK 验证去除、本地资源设置、模块加载以及地图瓦片的获取和处理。以下是对这些知识点的详细解释: 1. **API 主文件获取与处理**: - 百度地图的离线...

    百度地图生成基站图层工具V3.1.rar

    百度地图API是关键组成部分,它提供了丰富的地图服务,如地图瓦片加载、地理编码、坐标转换等功能。在这个应用中,API被用来获取地图背景、设置缩放级别、平移地图以及添加自定义图层。开发者需要申请百度地图API...

    百度地图sdk的包

    本篇文章将详细解析百度地图SDK的使用方法和核心知识点。 **1. SDK安装与引入** 首先,你需要下载百度地图SDK的压缩包,其中包括`readme.txt`文件,它是关于如何使用SDK的指导文档。`libs`文件夹包含了不同架构...

    百度地图切图工具

    综上所述,"百度地图切图工具"是一个结合了Android开发技术、百度地图API和地图瓦片处理原理的应用,旨在帮助用户高效地获取和处理百度地图的地理信息。通过这个工具,用户可以自定义切图参数,满足个性化的需求,...

    百度地图(包含丰富的注释说明)

    6. **地图瓦片与离线地图**:百度地图API支持自定义地图瓦片,开发者可以根据需求创建个性化的地图样式。另外,离线地图服务则允许在无网络环境下预加载地图数据,降低对网络的依赖。 7. **实时交通信息**:百度...

    百度离线版地图baidumap_apiV2_offline.zip

    百度离线版地图baidumap_apiV2_offline.zip是一个专门为开发者提供的资源包,它允许用户在没有网络连接的情况下,依然能够使用百度地图服务。这个压缩包主要针对那些需要在离线环境中或者网络不稳定的情况下展示地图...

    安卓百度地图开发

    8. **地图瓦片**:对于复杂的自定义地图需求,开发者可以通过使用自定义地图瓦片系统,将自定义的数据渲染到地图上。 9. **地理编码与反地理编码**:百度地图API提供了将地址转换为经纬度坐标(地理编码)和将...

    最新版的百度地图API Demo

    本资源是关于"最新版的百度地图API Demo"的详细解析,它提供了最新版本的百度地图API的示例代码,可以帮助开发者快速理解和应用百度地图服务。百度地图API是一个强大的工具,允许开发者在自己的网页或应用程序中集成...

    百度地图demo2

    "MapTest"可能包含了一个地图显示控件,它加载了百度地图的瓦片图层,并且可能支持缩放、平移、标记等基本操作。这些功能通过JavaScript SDK实现,开发者需要理解如何创建地图实例、设置地图中心点、添加图层和控制...

    百度地图api源码

    这篇内容将深入解析“百度地图API源码”,帮助你了解其工作原理,以及如何通过源码学习和优化地图应用。 首先,我们要明白百度地图API的核心功能包括: 1. 地图展示:通过JavaScript API,我们可以创建一个地图...

    百度离线地图示例学习资料

    百度离线地图是百度地图服务的一项功能,允许用户在有网络连接的情况下下载地图数据,然后在无网络环境下使用。这个“百度离线地图示例学习资料”压缩包很可能是为了帮助开发者理解和实践如何集成和使用百度的离线...

    百度离线地图 API v1.3开发指南

    这些接口包括加载地图瓦片、设置地图级别、调整地图视图等。开发者可以通过控制这些参数,创建出符合应用需求的地图展示效果。 4. **定位与标注** 百度离线地图API支持在离线状态下进行位置定位,这通常基于设备的...

    高仿百度地图Demo04

    这些请求可能包括搜索地点的API调用,请求特定区域的地图瓦片图像,或者获取内景相册和外景展示的详细信息。在Android中,可以使用HttpURLConnection、OkHttp或者Volley等库进行网络请求;在iOS中,可以使用...

    iOS 百度地图2.3.0库 sample 文档

    在iOS开发中,集成百度地图API是一个常见的需求,它能够为应用添加丰富的地图功能,如定位、导航、路径规划等。这份"iOS百度地图2.3.0库sample文档"包含的内容是百度地图SDK的最新版本,即2.3.0,提供了样例代码、库...

Global site tag (gtag.js) - Google Analytics