Leaflet 调用百度瓦片地图服务

这篇具有很好参考价值的文章主要介绍了Leaflet 调用百度瓦片地图服务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在使用 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 = 19
        var 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,bluish
            option.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

Leaflet 调用百度瓦片地图服务

参考链接:

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

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

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

 文章来源地址https://www.toymoban.com/news/detail-483064.html

到了这里,关于Leaflet 调用百度瓦片地图服务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 141:vue+leaflet 利用高德逆地理编码,点击地图标记marker,popup地址信息

    第141个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中利用高德逆地理编码,点击地图标记marker,popup地址信息 。主要利用高德地图的api将坐标转化为地址,然后在点击的位置,弹出弹窗,在里面显示出地址信息。 直接复制下面的 vue+leaflet源代码,操作2分钟即

    2024年01月24日
    浏览(49)
  • leaflet基本使用

    目录 创建地图(map) 添加图层(tileLayer) 创建标记(marker) 图标(icon/divIcon) 弹框(bindPopup) options选项 方法 工具提示(bindTooltip) options选项 窗格(pane) 常用方法 options选项   maxZoom:地图最大的缩放等级   minZoom:地图最小的缩放等级   zoom:地图默认的缩放等级   center:地图默认的中心

    2024年02月04日
    浏览(59)
  • 手把手教你搭建个人地图服务器(高德离线部署解决方案):获取地图瓦片数据、高德JS API、私有化部署和调用。。。

    众所周知,目前常见的地图(高德、百度、腾讯等)只提供在线API服务,对于一些内网应用而言,如果需要使用地图展示,则由于不能访问互联网而无法使用类似的第三方地图服务。 本文,通过将高德地图瓦片数据 和 在线JS API做了本地部署,并修改API,将其所有的网络请求

    2024年02月04日
    浏览(63)
  • leaflet使用L.geoJSON加载文件,参数pointToLayer的使用方法(130)

    第130个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载geojson文件,这里介绍pointToLayer的使用方法。 点的处理方式不同于折线和多边形。默认情况下,简单标记使用为GeoJSON点绘制。在创建GeoJSON涂层时,我们可以通过pointToLayer在GeoJSON选项对象中传递函数来改

    2023年04月09日
    浏览(32)
  • 使用LeafLet叠加Geoserver wms图层到已有底图的方法

            随着现代城市交通建设的飞速发展,各个城市的地铁路线和地铁站点也是越来越多。地铁极大的方便了广大人民的交通出行。作为Giser,经常会遇到需要将一份shp数据在地图上展示,甚至需要在网页端进行浏览的需要。把shp这种空间矢量数据进行web展示的方法有很

    2023年04月15日
    浏览(36)
  • Web地图服务规范之栅格瓦片地图服务:WMTS(WebMapTileService,网络地图瓦片服务)、TMS(TileMapService,瓦片地图服务)和XYZ

    这四种地图服务都是通过网络传输的栅格瓦片地图服务,这里有三个名词需要解释: 遥感影像、Dem等,就是图片。 实际上,地图服务就是一个url,且这个url满足一定条件:基于这个url拼上固定参数或路由地址可以获取地图服务的元数据信息(返回结果是xml或者json);也能获得

    2024年02月21日
    浏览(47)
  • 在Leaflet中使用Turf.js生成范围多边形的两种实现方式

    目录 前言 一、场景需求 1、Leaflet.js的不足 2、Turf.js 二、原始数据展示 1、点位数据展示  2、定义样式 3、定位数据初始化 三、Turfjs中bbox生成  1、官网讲解 2、轨迹bbox生成 四、Turfjs生成外包多边形 1、官网例子 2、凸多边形生成 总结         在一些共享出行的应用地图中

    2024年03月14日
    浏览(93)
  • 一.Leaflet入门

      为什么第一个 GIS 前端开发框架选择 Leaflet。   Leaflet 是一款轻量级,用于移动友好交互式地图的JavaScript库。轻量级的意思就是代码总大小比较小。Leaflet利用HTML5和CSS3在现代浏览器上的优势,同时也可以在旧浏览器上访问。它可以通过大量插件进行扩展,具有漂亮的、

    2024年01月25日
    浏览(38)
  • 【leaflet】1. 初见

    需求 要做游戏地图了,看到大量产品都使用的leaflet,所以开始学习这个。 开发环境 版本号 描述 文章日期 2023-11-09 操作系统 Win10 - 22H2 19045.3570 leaflet 1.9.4 leaflet 是一个 开源 的 JavaScript 库,用于创建 交互式 的地图应用程序。 它提供了一系列的工具和类,用于实现地图的基本

    2024年02月03日
    浏览(44)
  • Leaflet开发入门

    电子地图已经渗透到O2O、生活服务、出行等领域,传统的GIS也孕育着互联网基因。在国内互联网电子地图领域,百度地图和高德地图较为出色,天地图作为国家地理信息公共服务平台,推出了面向互联网的公众版在线地图服务与API。国内在开放源代码这一方面做得远远不够,

    2024年02月11日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包