侧边栏壁纸
博主头像
优吉斯空间 - YouGIS.COM.CN博主等级

行动起来,活在当下

  • 累计撰写 6 篇文章
  • 累计创建 17 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Leaflet加载腾讯地图开发示例 - 最新最全最详细

Administrator
2024-08-29 / 0 评论 / 2 点赞 / 181 阅读 / 14924 字 / 正在检测是否收录...

优吉斯(武汉)空间信息

> 公众号:yougis

> 主页:yougis.com.cn

> 工具:yougis.cn

yougis_wx_ewm.jpg

腾讯地图的配图和整体色调,较之高德、百度和天地图更加美观,是国内使用教广泛的互联网地图之一,在WebGIS开发中,有广泛的应用。但不同于谷歌、天地图、高德等互联网地图,腾讯地图的切片方式和服务URL自成体系。本文详细介绍如何通过Leaflet加载腾讯地图,如使用其他JS SDK,参照本文的加载思路,进行相应修改即可。

Leaflet加载腾讯地图的开发示例(load-tecent-map.html)

一、自定义腾讯地图服务获取函数

腾讯地图完全遵从TMS标准,且服务URL中存在z、x、y、x16和y16等关键参数,在加载时,需要自定义z、x、y和x16、y16的值,并正确拼接服务地址。下面对服务获取函数的定义进行介绍。

L.TileLayer.WebDogTileLayer = L.TileLayer.extend({
  getTileUrl: function (tilePoint) {
    var urlArgs,
      getUrlArgs = this.options.getUrlArgs;

    if (getUrlArgs) {
      var urlArgs = getUrlArgs(tilePoint);
    } else {
      urlArgs = {
        z: tilePoint.z,
        x: tilePoint.x,
        y: tilePoint.y,
      };
    }

    return L.Util.template(
      this._url,
      L.extend(urlArgs, this.options, {
        s: this._getSubdomain(tilePoint),
      })
    );
  },
});

L.tileLayer.webdogTileLayer = function (url, options) {
  return new L.TileLayer.WebDogTileLayer(url, options);
};

二、定义腾讯地图加载函数

下面定义加载腾讯各类型地图的加载函数,方便在不同地图间的切换,Leaflet中定义方式如下所示。

var initOptions = {
  subdomains: "012",
  getUrlArgs: function (tilePoint) {
    return {
      z: tilePoint.z,
      x: tilePoint.x,
      y: Math.pow(2, tilePoint.z) - 1 - tilePoint.y,
      x16: Math.floor(tilePoint.x / 16.0),
      y16: Math.floor(
        (Math.pow(2, tilePoint.z) - 1 - tilePoint.y) / 16.0
      ),
    };
  },
};

L.tileLayer.tecent = function (option) {
  option = option || {};
  var layer;
  var opts = { ...initOptions, ...option };
  switch (option.layer) {
    // 矢量图
    case "vec":
    default:
      layer = L.tileLayer.webdogTileLayer(
        "http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0",
        opts
      );
      break;
    // 单图层-影像图
    case "img_d":
      layer = L.tileLayer.webdogTileLayer(
        "http://p{s}.map.gtimg.com/sateTiles/{z}/{x16}/{y16}/{x}_{y}.jpg",
        opts
      );
      break;
    // 单图层-影像注记
    case "img_z":
      layer = L.tileLayer.webdogTileLayer(
        "http://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={y}&styleid=2&version=376",
        opts
      );
      break;
    //图层叠加-影像图(含注记)
    case "img":
      layer = L.layerGroup([
        L.tileLayer.tecent({
          name: "底图",
          layer: "img_d",
        }),
        L.tileLayer.tecent({
          name: "注记",
          layer: "img_z",
        }),
      ]);
      break;
    // 单图层-地形图
    case "ter_d":
      layer = L.tileLayer.webdogTileLayer(
        "http://p{s}.map.gtimg.com/demTiles/{z}/{x16}/{y16}/{x}_{y}.jpg",
        opts
      );
      break;
    // 单图层-地形注记
    case "ter_z":
      layer = L.tileLayer.webdogTileLayer(
        "http://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={y}&type=vector&styleid=3&version=376",
        opts
      );
      break;
    //图层叠加-地形图(含注记)
    case "ter":
      layer = L.layerGroup([
        L.tileLayer.tecent({
          name: "底图",
          layer: "ter_d",
        }),
        L.tileLayer.tecent({
          name: "注记",
          layer: "ter_z",
        }),
      ]);
      break;
  }
  return layer;
};

三、图层加载函数使用及添加图层控制控件

Leaflet提供了图层控制的控件,方便在地图底图的切换和业务图层的显示与隐藏进行控制,下面以上述腾讯地图加载类函数为例,对图层控制的使用进行说明。

let vec = new L.tileLayer.tecent({ layer: "vec", name: "矢量图" });
let img_d = new L.tileLayer.tecent({ layer: "img_d", name: "影像图" });
let img_z = new L.tileLayer.tecent({ layer: "img_z", name: "影像注记" });
let img = new L.tileLayer.tecent({
    layer: "img",
    name: "影像图(含注记)",
});
let ter_d = new L.tileLayer.tecent({ layer: "ter_d", name: "地形图" });
let ter_z = new L.tileLayer.tecent({ layer: "ter_z", name: "地形注记" });
let ter = new L.tileLayer.tecent({
    layer: "ter",
    name: "地形图(含注记)",
});
var options = {
    center: [31.24, 121.5],
    zoom: 15, // initial zoom of map
    layers: [vec],
};
var map = L.map("mapdiv", options);
L.marker([31.24, 121.5])
    .addTo(map)
    .bindTooltip("上海东方明珠")
    .openTooltip();

const baseLayers = {
    矢量图: vec,
    影像图: img_d,
    影像注记: img_z,
    "影像图(含注记)": img,
    地形图: ter_d,
    地形注记: ter_z,
    "地形图(含注记)": ter,
    // 实时路况: time,
};

// 添加图层控制控件
L.control.layers(baseLayers).addTo(map);

四、加载腾讯地图的完整代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>LeafletJS加载腾讯地图 - 优吉斯(YouGIS)</title>
  <link href="../lib/leaflet/leaflet.css" rel="stylesheet" />
  <script src="../lib/jquery/jquery.min.js"></script>
  <script src="../lib/leaflet/leaflet.js"></script>
  <style>
    * {
      padding: 0;
      margin: 0;
    }

    #location {
      position: fixed;
      padding: 5px;
      left: 0;
      bottom: 0;
      background-color: #fff;
      z-index: 999;
      font-size: 12px;
      font-weight: bold;
      color: blue;
      border-top-right-radius: 5px;
      /* width: 255px; */
    }

    #mapdiv {
      width: 100vw;
      height: calc(100vh - 156px);
    }

    #promptInfo {
      z-index: 999;
      position: absolute;
      color: red;
      font-size: large;
      font-weight: bold;
      margin-left: 80px;
      margin-top: 20px;
    }
  </style>
</head>

<body>
  <iframe src="../yougis.html" style="width: 100vw; height: 156px"></iframe>
  <div id="mapdiv">
    <div id="promptInfo"></div>
  </div>
  <div id="location"></div>
  <script>
    L.TileLayer.WebDogTileLayer = L.TileLayer.extend({
      getTileUrl: function (tilePoint) {
        var urlArgs,
          getUrlArgs = this.options.getUrlArgs;

        if (getUrlArgs) {
          var urlArgs = getUrlArgs(tilePoint);
        } else {
          urlArgs = {
            z: tilePoint.z,
            x: tilePoint.x,
            y: tilePoint.y,
          };
        }

        return L.Util.template(
          this._url,
          L.extend(urlArgs, this.options, {
            s: this._getSubdomain(tilePoint),
          })
        );
      },
    });

    L.tileLayer.webdogTileLayer = function (url, options) {
      return new L.TileLayer.WebDogTileLayer(url, options);
    };

    var initOptions = {
      subdomains: "012",
      getUrlArgs: function (tilePoint) {
        return {
          z: tilePoint.z,
          x: tilePoint.x,
          y: Math.pow(2, tilePoint.z) - 1 - tilePoint.y,
          x16: Math.floor(tilePoint.x / 16.0),
          y16: Math.floor(
            (Math.pow(2, tilePoint.z) - 1 - tilePoint.y) / 16.0
          ),
        };
      },
    };

    L.tileLayer.tecent = function (option) {
      option = option || {};
      var layer;
      var opts = { ...initOptions, ...option };
      switch (option.layer) {
        // 矢量图
        case "vec":
        default:
          layer = L.tileLayer.webdogTileLayer(
            "http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0",
            opts
          );
          break;
        // 单图层-影像图
        case "img_d":
          layer = L.tileLayer.webdogTileLayer(
            "http://p{s}.map.gtimg.com/sateTiles/{z}/{x16}/{y16}/{x}_{y}.jpg",
            opts
          );
          break;
        // 单图层-影像注记
        case "img_z":
          layer = L.tileLayer.webdogTileLayer(
            "http://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={y}&styleid=2&version=376",
            opts
          );
          break;
        //图层叠加-影像图(含注记)
        case "img":
          layer = L.layerGroup([
            L.tileLayer.tecent({
              name: "底图",
              layer: "img_d",
            }),
            L.tileLayer.tecent({
              name: "注记",
              layer: "img_z",
            }),
          ]);
          break;
        // 单图层-地形图
        case "ter_d":
          layer = L.tileLayer.webdogTileLayer(
            "http://p{s}.map.gtimg.com/demTiles/{z}/{x16}/{y16}/{x}_{y}.jpg",
            opts
          );
          break;
        // 单图层-地形注记
        case "ter_z":
          layer = L.tileLayer.webdogTileLayer(
            "http://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={y}&type=vector&styleid=3&version=376",
            opts
          );
          break;
        //图层叠加-地形图(含注记)
        case "ter":
          layer = L.layerGroup([
            L.tileLayer.tecent({
              name: "底图",
              layer: "ter_d",
            }),
            L.tileLayer.tecent({
              name: "注记",
              layer: "ter_z",
            }),
          ]);
          break;
        // //实时路况
        // case "time":
        //   var time = new Date().getTime();
        //   layer = L.tileLayer(
        //     "http://tm.tecent.com/trafficengine/mapabc/traffictile?v=1.0&;t=1&x={x}&y={y}&z={z}&&t=" +
        //       time,
        //     {
        //       name: option.name,
        //     }
        //   );
        //   break;
      }
      return layer;
    };

    let vec = new L.tileLayer.tecent({ layer: "vec", name: "矢量图" });
    let img_d = new L.tileLayer.tecent({ layer: "img_d", name: "影像图" });
    let img_z = new L.tileLayer.tecent({ layer: "img_z", name: "影像注记" });
    let img = new L.tileLayer.tecent({
      layer: "img",
      name: "影像图(含注记)",
    });
    let ter_d = new L.tileLayer.tecent({ layer: "ter_d", name: "地形图" });
    let ter_z = new L.tileLayer.tecent({ layer: "ter_z", name: "地形注记" });
    let ter = new L.tileLayer.tecent({
      layer: "ter",
      name: "地形图(含注记)",
    });
    // let time = new L.tileLayer.tecent({ layer: "time", name: "实时路况" });

    $(document).ready(function () {
      var options = {
        center: [31.24, 121.5],
        zoom: 15, // initial zoom of map
        layers: [vec],
      };
      var map = L.map("mapdiv", options);
      L.marker([31.24, 121.5])
        .addTo(map)
        .bindTooltip("上海东方明珠")
        .openTooltip();

      const baseLayers = {
        矢量图: vec,
        影像图: img_d,
        影像注记: img_z,
        "影像图(含注记)": img,
        地形图: ter_d,
        地形注记: ter_z,
        "地形图(含注记)": ter,
        // 实时路况: time,
      };

      // 添加图层控制控件
      L.control.layers(baseLayers).addTo(map);

      // 设置初始显示内容
      let initInfo =
        "请通过右上角图层控制切换地图, 点击地图左下角展示坐标<br/>";
      initInfo += "当前选择地图:" + vec.options.name + "<br/>";
      initInfo += "服务地址:" + vec._url;
      document.getElementById("promptInfo").innerHTML = initInfo;

      // 图层切换事件, 设置显示的提示信息
      map.on("baselayerchange", function (e) {
        let info =
          "请通过右上角图层控制切换地图, 点击地图左下角展示坐标<br/>";
        info += "当前选择地图:" + e.name + "<br/>";
        if (e.layer._url) {
          info += "服务地址:" + e.layer._url;
        } else if (e.layer._layers) {
          for (k in e.layer._layers) {
            let v = e.layer._layers[k];
            info += "服务地址" + k + ":" + v._url + "<br/>";
          }
        }
        document.getElementById("promptInfo").innerHTML = info;
      });

      map.on("click", (e) => {
        let lnglat =
          "鼠标点击位置坐标:" + e.latlng.lng + " , " + e.latlng.lat;
        $("#location")[0].innerText = lnglat;
      });
      window.map = map;
    });
  </script>
</body>

</html>

2

评论区