从零开始,构建电子地图网站:0_13_VUE整合leaflet

霸气de小男生 提交于 2020-03-09 21:50:29

一.效果图

我们大概要做这样的地图底图,腾讯底图,上面覆盖物有点point和面polygon,点击覆盖物会出现触发事件。

页面长成这个样子,因为仅作示例用,所以写在了helpdocument上面,除了地图外,覆盖物有一个点、一个标签、一个面,右侧是chrome浏览器的开发者工具(crtl+shift+i),触发事件在工具上(console)打印了日志。

 

 

 

二.安装leaflet模块

首先要安装leaflet模块。

Ctrl+c,退出dev界面。

运行:

npm install vue2-leaflet -S

npm install leaflet -S

 

 

三.加载腾讯底图

  1. 瓦片原理

Leaflet加载底图以栅格瓦片的形式加载。

官方示例是这样的:

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {

    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'

}).addTo(map);

其中{}中的s是源,z是比例尺,xy是瓦片的坐标,加载的是openstreetmap。

地图瓦片是比较基础的概念,为了提升性能,将地图按照比例尺逐级切成瓦片,调用的时候,根据比例尺和网页尺寸调用需要调用的瓦片。

关于地图瓦片,开放地理信息空间联盟OGC专门有规范WMTS对其进行阐述,国内的高德、腾讯地图瓦片切分方式,完全按照WMTS来,但是谷歌和mapbox、OSM等稍有变化。

因为leaflet默认加载的是谷歌地图这样的瓦片,所以要加载腾讯地图,还需要对瓦片函数进行一个转换,才能正确加载。

  1. 程序源码

新建一个/src/js/txTileLayer.js文件,放瓦片函数。

 

 

export const TXTileLayer = L.TileLayer.extend({

  getTileUrl: function (tilePoint) {

    let urlArgs = null

    let getUrlArgs = this.options.getUrlArgs

    if (getUrlArgs) {

      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)

    }))

  }

})

 

在src/icon中放一个dian.png,这个是点的图标。

 

剩下的所有都写在了src/components/HelperDocument.vue中。

 

 

<template>

  <div id="map"></div>

</template>

<script>

import 'leaflet/dist/leaflet.css'

import 'leaflet/dist/leaflet.js'

import { TXTileLayer } from '../js/txTileLayer.js'

export default {

  data() {

    return {

      map: null

    }

  },

  methods: {

    initLeaflet() {

      this.map = L.map('map', {

        center: [39.916527, 116.397128],

        zoom: 10,

        maxZoom: 23,

        minZoom: 3

      })

      //按照新定义瓦片规则加载底图

      let url = 'http://rt1.map.gtimg.com/realtimerender/?z={z}&x={x}&y={y}&type=vector&style=1&v=1.1.1'

      let getUrlArgs = function(tilePoint) {

        return {

          z: tilePoint.z,

          x: tilePoint.x,

          y: Math.pow(2, tilePoint.z) - 1 - tilePoint.y

        }

      }

      let options = {

        subdomain: '012',

        getUrlArgs: getUrlArgs

      }

      const txMap = new TXTileLayer(url, options)

      txMap.addTo(this.map)

      //marker

      var myDivIcon = L.divIcon({ className: 'my-div-icon', html: '这是一个测试用的marker', iconSize: 150 });

      var marker = L.marker([39.916527, 116.397128], { icon: myDivIcon }).addTo(this.map);

      marker.on('click', function(e) {

        console.log(e);

        alert('我是Marker。');

      })

 

      //point

      var myIcon = L.icon({

        iconUrl: require('../icon/dian.png'), //icon图片

        iconSize: [30, 30], //icon的尺寸

        iconAnchor: [15, 15], //锚点在icon上的坐标,左下角为原点

        popupAnchor: [40, 0], //弹出框的锚点

        shadowUrl: require('leaflet/dist/images/marker-shadow.png'), //阴影图片

        shadowSize: [30, 30], //阴影尺寸

        shadowAnchor: [15, 15] //阴影锚点

      });

 

      var point = L.marker([39.916527, 116.397128], { icon: myIcon, title: '这是一个测试用的point' }).addTo(this.map);

      point.on('click', function(e) {

        console.log(e);

        alert('我是point。');

      })

      //polygon

      var polygon = L.polygon([

        [

          [40.0, 116.4],

          [40.1, 116.4],

          [40.1, 116.5],

          [40.0, 116.5]

        ], // 外部

        [

          [40.05, 116.45],

          [40.06, 116.45],

          [40.06, 116.46],

          [40.05, 116.46]

        ] // 孔洞

      ], {

        color: 'green',

        fillColor: '#f03',

        fillOpacity: 0.5

      }).addTo(this.map);

      // 绑定一个提示标签

      polygon.bindTooltip('这是个多边形');

 

      // 飞到这个多边形的位置

      // this.map.fitBounds(polygon.getBounds());

      polygon.on('click', function(e) {

        // console.log(e);

        alert('我是polygon');

      })

    }

  },

  mounted() {

    this.initLeaflet()

  }

}

 

</script>

<style>

#map {

  width: 100%;

  height: 100%;

}

 

.my-div-icon {

  font-size: 15px;

  width: 5px;

  color: red;

}

 

</style>

 

  1. 更多资源

这里只是简单的加载了腾讯底图,一个点、一个标签、一个面和触发事件。

更多的demo可以参看leaflets官网:https://leafletjs.com/

 

 

本篇内容较少,不上传git了。

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!