在使用 leaflet 调用第三方瓦片地图服务的项目,主要谷歌地图、高德地图、百度地图和 OSM 地图,与其他三种地图对比,百度地图的瓦片组织方式是不同的。百度从中心点经纬度(0,0)度开始计算瓦片,而谷歌地图是从左上角经纬度(-180,90)度开始计算瓦片;如果直接使用百度瓦片地图服务会请求不到瓦片,因此需要转换一下。借助 leaflet-tileLayer-baidu 这个插件:

//需要引入 proj4.js 和 proj4leaflet.js 插件,使用script标签引入的方式
L.CRS.Baidu = new L.Proj.CRS('EPSG:900913', '+proj=merc +a=6378206 +b=6356584.314245179 +lat_ts=0.0 +lon_0=0.0 +x_0=0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs', {resolutions: function () {level = 19var res = [];res[0] = Math.pow(2, 18);for (var i = 1; i < level; i++) {res[i] = Math.pow(2, (18 - i))}return res;}(),origin: [0, 0],bounds: L.bounds([20037508.342789244, 0], [0, 20037508.342789244])
});L.tileLayer.baidu = function (option) {option = option || {};var layer;var subdomains = '0123456789';switch (option.layer) {//单图层case "vec":default://'http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=pl&b=0&limit=60&scaler=1&udt=20170525'layer = L.tileLayer('http://online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=' + (option.bigfont ? 'ph' : 'pl') + '&scaler=1&p=1', {name:option.name,subdomains: subdomains, tms: true});break;case "img_d": layer = L.tileLayer('http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46', {name: option.name, subdomains: subdomains, tms: true});break;case "img_z":layer = L.tileLayer('http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=' + (option.bigfont ? 'sh' : 'sl') + '&v=020', {name: option.name, subdomains: subdomains, tms: true});break;case "custom"://Custom 各种自定义样式//可选值:dark,midnight,grayscale,hardedge,light,redalert,googlelite,grassgreen,pink,darkgreen,bluishoption.customid = option.customid || 'midnight';layer = L.tileLayer('http://api{s}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&scale=1&customid=' + option.customid, {name: option.name, subdomains: "012", tms: true});break;case "time"://实时路况var time = new Date().getTime();layer = L.tileLayer('http://its.map.baidu.com:8002/traffic/TrafficTileService?x={x}&y={y}&level={z}&time=' + time + '&label=web2D&v=017', {name: option.name, subdomains: subdomains, tms: true});break;//合并case "img":layer = L.layerGroup([L.tileLayer.baidu({ name: "底图", layer: 'img_d', bigfont: option.bigfont }),L.tileLayer.baidu({ name: "注记", layer: 'img_z', bigfont: option.bigfont })]);break;}return layer;
};

初始化之后,就可以直接实例化生成调用百度瓦片地图服务的实例;

this.map = L.map('_map',{crs: L.CRS.Baidu, fullscreenControl: true}).setView(this.originPoint, this.originZoom);L.tileLayer.baidu({layer: 'vec'}, {maxZoom: this.maxZoom, minZoom: this.minZoom}).addTo(this.map);/* 这里是VUE项目,使用了 fullscreenControl 全屏插件 */

需要注意:

1、地图切换:

如果只是实现高德、谷歌地图、天地图的Leaflet 切换,可以使用 leaflet插件 Leaflet.ChineseTmsProviders;

2、坐标系系统:

国内使用的地图坐标都是经过设备返回的坐标(WGS84)加密的,一般是GCJ02(高德地图、谷歌地图中国区服务都是用这一标准);百度地图则在GCJ02的基础上又进行了二次加密,使用的BD09坐标;因此直接在地图显示原始点的位置信息会有几十米到几百米的误差。地图官方都提供了在线的坐标转换接口以及web服务api接口:以百度地图为例:

//百度地图坐标转换api
var points = [new BMap.Point(116.3786889372559,39.90762965106183),new BMap.Point(116.38632786853032,39.90795884517671),new BMap.Point(116.39534009082035,39.907432133833574),new BMap.Point(116.40624058825688,39.90789300648029),new BMap.Point(116.41413701159672,39.90795884517671)
]var convertor = new BMap.Convertor();
convertor.translate(points, 1, 5, translateCallback)  //translateCallback 回调
// 百度地图在线转换接口地址
http://api.map.baidu.com/geoconv/v1/?coords=114.21892734521,29.575429778924&from=1&to=5&ak=你的密钥 //GET请求

百度地图支持单个点转换和批量点转换,同时支持 WGS84转BD09,和GCJ02转BD09坐标;

但是存在以下问题:

①、百度地图在线api 最多一次支持10个点,web服务api单次请求可批量解析100个坐标,对于海量点(几千到几万)来说,这样的处理速度显然是不够的;高德地图同样满足不了业务需求;

②、不支持逆向解析,例如BD09 没有对应的接口转GCJ02和WGS84;因此在地图切换的时候,使用百度地图拾取的点就无法在其他地图上准确显示(高德地图提供BD09到GCJ02的坐标转换,但业务使用的只是高德的瓦片服务);

可以使用 gcoord 插件解决上述问题,支持上述三种坐标系互转,且是同步的接口,海量数据无性能瓶颈。(因为逆向解析没有公开的算法,原始坐标只是无限接近,基本满足地图使用要求。)

3、海量点性能问题

使用百度地图点的数量在2000左右时候,无论是打点、还是缩放、平移都会影响用户体验了,海量点接口虽可以支持万级别的数据,但是不能自定义图标、不能显示label;这是要是DOM操作严重影响了性能,可以使用Leaflet.Canvas-Markers解决海量点性能问题。

4、国外坐标识别

百度在线的api转换接口 ,会智能判断点的坐标是否在国内还是在国外,如果判断在国外就直接返回数据;但如果使用 gcoord 就无法智能识别;需要手动写一个坐标判断识别库,并且需要国界线经纬度数据。由于精确显示国界线的经纬度数据十分庞大,因此随着点精度的提高,需要牺牲浏览器性能,(在线转会有点的限制,估计也是性能考究)。

判断一个点是否在国内,可以参考 判断一个点是否在多边形内部 - 射线法思路,结合国界线的经纬度数据,就可以判断点的坐标是否在国内。射线法判断算法:

function pointInChina(position = [31.172800343248,121.406021546488]) {if(position.length !== 2) {console.error('The argument is an array of longitude and latitude, with longitude first and latitude last')return;};if((position[0] < 3.85 || position[0] > 53.55) || (position[1] < 73.55) || position[1] > 135.08) {console.log('Must be abroad')return false;}function isInPolygon(checkPoint, polygonPoints) {var counter = 0;var i;var xinters;var p1, p2;var pointCount = polygonPoints.length;p1 = polygonPoints[0];for (i = 1; i <= pointCount; i++) {p2 = polygonPoints[i % pointCount];if (checkPoint[0] > Math.min(p1[0], p2[0]) && checkPoint[0] <= Math.max(p1[0], p2[0])) {if (checkPoint[1] <= Math.max(p1[1], p2[1])) {if (p1[0] != p2[0]) {xinters = (checkPoint[0] - p1[0]) * (p2[1] - p1[1]) / (p2[0] - p1[0]) + p1[1];if (p1[1] == p2[1] || checkPoint[1] <= xinters) {counter++;}}}}p1 = p2;}if (counter % 2 == 0) {return false;} else {return true;}}try {let a = isInPolygon(position, mainLand_array);  //大陆let b = isInPolygon(position, taiWan_array);  // 台北if(a || b ) {return true;}else {return false;}}catch(err){console.log(err);}
}

 5、验证坐标转换正确性:

可以使用这个浏览器插件 :WebGIS-Helper

参考链接:

1、百度与谷歌地图瓦片组织方式对比;

2、 leaflet-tileLayer-baidu   作者还提供了一个 在线预览的地址 ;

3、点在多边形内算法,JS判断一个点是否在一个复杂多边形的内部

Leaflet 调用百度瓦片地图服务相关推荐

  1. 无偏移谷歌瓦片地址_[转]OpenStreetMap/Google/百度/Bing瓦片地图服务(TMS)

    开源与成熟商业的瓦片地图服务(TMS  2  WMTS),都有如下共同的特性,基本成为了标准: (1) 坐标系:WGS84 (2) 投影:墨卡托投影(Marcator,正轴等角圆柱投影) ------ ...

  2. 瓦片地图服务与地图瓦片原理

    本文字数:9099字 预计阅读时间:25分钟 这里,首先我们从概念出发,搞清楚瓦片地图服务以及地图瓦片的原理,读起来似乎有点拗口,但是从字面上看得出它们必定拥有着区别与联系,前者是WebGIS中的一个 ...

  3. 高德WMTS瓦片地图服务地图图源规律

    本篇文章为转载记录,原文:[转]高德WMTS瓦片地图服务地图图源规律_为了淑宝努力努力的博客-CSDN博客 高德地图服务地址规则 先来看一个典型的高德地图的瓦片请求: https://wprd02.i ...

  4. 搭建离线瓦片地图服务并用QGIS显示离线地图

    需求的提出:         由于业务需求,展示GIS时,不能连接互联网,也就是说不能调用互联网上提供的地图服务. 因为不能联网,所以必须在局域网或本机上搭建离线瓦片地图服务.本文讲述如何搭建离线瓦片 ...

  5. Mapbox加载天地图CGCS2000矢量瓦片地图服务

    1.背景 最近在做天地图的项目,要基于MapBox添加CGCS2000矢量切片数据,但是 Mapbox 只支持web 墨卡托(3857)坐标系的数据.Github有专业用户修改了mapbox-gl的相 ...

  6. 如何用百度离线API调用百度离线地图

    这里以广西南宁市为例,说明如何用百度离线API调用百度离线地图. 首先,点击视图左上方的地图类型按钮选择百度地图(如果没有该项请点击"更多"选项),然后在视图右上方选择广西省南宁市 ...

  7. 瓦片地图服务参数与计算

    转载自:http://www.cnblogs.com/kekec/p/3159970.html 开源与成熟商业的瓦片地图服务(TMS  2  WMTS),都有如下共同的特性,基本成为了标准: (1) ...

  8. 高德地图 sdk 加载 geoserver 发布的瓦片地图服务

    前言 最近,碰到了需求,想要在高德 sdk 中使用在 geoserver 里面发布的瓦片地图. 还好经过一番研究,在其官方文档中发现,从新版本(v1.4.3开始)的高德 sdk 开始,已经支持加载第三 ...

  9. Google Map API V3调用arcgis发布的瓦片地图服务

    由于最近项目需要用到CAD制作的地图,但之前一直使用的是用谷歌离线瓦片地图的方式,怎么样把CAD图像地图一样有缩放,移动的功能放到网页显示成了难题, 原先的谷歌地图的代码难道就不能用了?重新写一套代码 ...

最新文章

  1. 深度学习——训练时碰到的超参数
  2. python读取csv文件的方法-python读写csv文件的方法
  3. 刘卫国python实验答案_MATLAB(刘卫国)部分实验答案
  4. 华为宣布:免费培养2000名Java开发者
  5. 部署 Job (第一部分)
  6. windows的盘共享挂载到linux下,通过Windows共享文件夹直接挂载到Linux中使用(实验操作)...
  7. winform前后端框架_ABP开发框架前后端开发系列(1)框架的总体介绍
  8. 背水一战 Windows 10 (53) - 控件(集合类): ItemsControl 的布局控件 - ItemsStackPanel, ItemsWrapGrid...
  9. unistd.h的close(0)导致std::cout被关闭
  10. java学习--基础知识阶段性总结--多线程
  11. 用laravel开发php,使用 PhpStorm开发Laravel项目
  12. 华为云CDN加速WAF防护资源实践
  13. Android中@GuardedBy
  14. 2018最新精选的Go框架,库和软件的精选列表 三
  15. 白话空间统计十九:热点分析(上)
  16. AS3字符串正则表达式
  17. 用NEON intrinsic实现RGB转YUV420SP(NV12)
  18. 鞍山市电子计算机学校,鞍山市信息工程学校
  19. 【元胞自动机】元胞自动机交通流仿真【含Matlab源码 827期】
  20. 微信小程序图片分包 || 微信小程序资源分包

热门文章

  1. java高级架构师年薪,深度集成!
  2. 博客已搬家,请移步 cnblogs.com/JonneyDong
  3. android paint跑马灯,Android使用Canvas实现跑马灯
  4. 推荐系统——Evaluation criteria(评估准则)
  5. 使用Floyd-Warshall算法求出两点之间的最短路径
  6. 腾讯关于区块链的发展历程
  7. Excel通过身份证号提取出生年月日(生日)/计算截至当前年龄
  8. java的枚举类型是什么_什么是枚举(java枚举类型enum用法)
  9. 数字功放芯片NTP8835和TAS5731M对比测评
  10. msgbox窗口学习总结窗体复合框