# 概述
如名称所表达的，这是一个使用了leaflet(v1.9.4)的echarts(v5.5)的地图扩展。

[leaflet](https://leafletjs.com/)，这是一个用于移动友好的交互式地图的开源 JavaScript 库，他支持所有符合OGC WMTS标准的地图源，这就包括了openstreetmap, mapbox、天地图，以及像百度、高德、必应、谷歌等所有主流的地图的tile源，所以我们只需要使用leaflet 的api来开发地图功能，如果要切换地图，只需要切换leaflet的地图图层就可以了

有个特色的功能，可以自己随意自定义地图的底色，这样如果使用天地图或者openstreet这种无法自定义主题色的地图源的时候，就可以在地图源的 options选项内使用color来自定义自己的主题色。这个功能在内部的 [L.TileLayer.define.theme.js](https://gitee.com/sailimuhu/echarts-extension-leaflet/blob/master/src/L.TileLayer.define.theme.js)的`createTile`方法内实现的，由于在这个方法中引入了canvas，所以如果我们想要对地图切片做点什么其他的特殊处理，比如叠加一些文字，或者添加什么外框之类的，都可以在这个方法内去随意修改，给我们提供了很大的灵活性。

# 特色
可以自定义主题色

## 备注
本组件基于[echarts-leaflet](https://www.npmjs.com/package/echarts-leaflets)修改而来，主要是解决了`echarts-leaflet`显示的地图的瓦片之间存在白边的问题，如下图所示
![存在白边的地图](https://gitee.com/sailimuhu/echarts-extension-leaflet/raw/master/img/leaflet-mapbox-hasgap.png)
仔细看，上图的瓦片之前存在一个细细的白线，这是leaflet的一个bug，原因和解决方案可以参考[这里](https://github.com/Leaflet/Leaflet.TileLayer.NoGap)，在这里只是把他们提供的代码做了整合

# Demo
- [散点图](https://gitee.com/sailimuhu/echarts-extension-leaflet/blob/master/example/leaflet-multiple-layers.html)
![无间隙](https://gitee.com/sailimuhu/echarts-extension-leaflet/raw/master/img/leaflet-mapbox-nogap.png)<br/>
- 使用mapbox作为地图源
![mapbox源](https://gitee.com/sailimuhu/echarts-extension-leaflet/raw/master/img/mapbox-bg.png)<br/>
- 使用天地图，并修改颜色为蓝色
在天地图的options中配置 `color: { r: 5, g: 48, b: 82 }`
![tianditu-blue-bg](https://gitee.com/sailimuhu/echarts-extension-leaflet/raw/master/img/tianditu-blue-bg.png)<br/>
- 使用天地图，并修改颜色为橙色
在天地图的options中配置 `color: { r: 150, g: 60, b: 16 }`
![tianditu-orange-bg](https://gitee.com/sailimuhu/echarts-extension-leaflet/raw/master/img/tianditu-orange-bg.png)<br/>

# 如何运行demo
demo在[leaflet-multiple-layers](./example/leaflet-multiple-layers.html)文件内。
- 在example文件夹内新建一个`map-key.js`的文件，文件内容如下，更换其中的id和token
```js
var mapKey = {
  mapbox: {
    id: "your mapbox map id",
    accessToken: "your mapbox key"
  },
  tianditu: {
    accessToken: "your tianditu key"
  }
}
```
- 修改[leaflet-multiple-layers](./example/leaflet-multiple-layers.html)文件内的 leaflet的tiles选项，看是需要天地图还是mapbox地图，启用相应的图层
```js
tiles: [
    // mapbox的地图
    {
        label: 'mapbox',
        urlTemplate: 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}',
        options: {
            maxZoom: 18,
            id: mapKey.mapbox.id,
            tileSize: 512,
            zoomOffset: -1,
            accessToken: mapKey.mapbox.accessToken
        }
    }		
    // 如果用天地图，就用下面两种
    // {
    // 	label: 'tianditu-tile',						
    // 	// 天地图的卫星地图
    // 	// urlTemplate: 'https://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk={accessToken}',
    // 	// 天地图的标准地图
    // 	urlTemplate: 'https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk={accessToken}',
    // 	options: {
    // 		maxZoom: 18,
    // 		tileSize: 512,
    // 		zoomOffset: -1,
    // 		// 蓝色
    // 		// color: { r: 12, g: 12, b: 83 },
    // 		color: { r: 5, g: 48, b: 82 },
    // 		// 橙色
    // 		// color: { r: 150, g: 60, b: 16 },
    // 		accessToken: mapKey.tianditu.accessToken
    // 	}
    // },
    // {						
    // 	// 天地图地名、道路标记图层
    // 	urlTemplate: 'https://t0.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk={accessToken}',
    // 	options: {
    // 		maxZoom: 18,
    // 		tileSize: 512,
    // 		zoomOffset: -1,
    // 		// 
    // 		accessToken: mapKey.tianditu.accessToken,
    // 	}
    // }
]
```
- 通过live-server静态服务器来查看效果，如果直接在浏览器打开这个文件，可能会由于跨域的问题而无法加载 天地图
  - 全局安装 live-server
    ```shell
    npm install -g live-server
    ```
  - 然后在本项目的根目录下执行如下命令：
    ```shell
    live-server
    ```
  - 然后打开网页，打开example中的 `leaflet-multiple-layers.html`文件即可查看效果

# 如何引入
## 通过script标签
```html
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
		integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
		crossorigin=""/>
		<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
		integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
		crossorigin=""></script> 
		<script src="https://cdn.jsdelivr.net/npm/echarts@4.8.0/dist/echarts.min.js"></script>
		<script src="../dist/echarts-extension-leaflet.js"></script>  
```
      
## 使用npm
```shell
npm install echarts-extension-leaflet
```

然后在要使用的文件vue文件中引入
```js
import echarts from 'echarts'
import 'echarts-extension-leaflet'
```

# 如何使用
对应的echarts的选项如下
主要有两点：
- 增加一个leaflet选项，在里面给出leaflet的图层配置，这里面的关键点是`urlTemplate`和`options`，只要是符合OGC WMTS标准的地图源都可以，比如mapbox、天地图、以及百度、高德、微软、谷歌等各种商用地图。option的选项则可以参考`leaflet`的[TileLayer官方文档](https://leafletjs.com/SlavaUkraini/reference.html#tilelayer)
- serie的坐标设置为leaflet

下面是一个使用mapbox地图的示例，实际使用时请替换为自己的token

```js
var myChart = echarts.init(document.getElementById('main'));

myChart.setOption({
    title: {
        text: '全国主要城市空气质量',
        subtext: 'data from PM25.in',
        sublink: 'http://www.pm25.in',
        left: 'center',
        textStyle: {
            color: '#fff'
        }
    },
    tooltip: {
        trigger: 'item'
    },
    leaflet: {
        center: [104.114129, 37.550339],
        zoom: 4,
        // 除了center和zoom以外的其他leaflet地图选项，都放在这里
        // 具体的选项可以看leaflet官网：https://leafletjs.com/reference.html#map-option
        leafletOption:{
            zoomControl: false
        },
        roam: true,
        tiles: [
            // mapbox地图源
            {
                // 主图层加上label，后面的标签图层就不需要了
                label: 'mapbox',
                urlTemplate: 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}',
                options: {
                    // 这个color是一个可选的选项
                    // 如果需要改变地图的颜色，就用这个选项，这样就可以自定义任何自己喜欢的颜色了，
                    // 而不用局限于地图官方提供的主题色
                    // color: { r: 12, g: 12, b: 83 },
                    maxZoom: 18,
                    id: 'mapbox/dark-v10',
                    tileSize: 512,
                    zoomOffset: -1,
                    // 这里要换为自己的key
                    accessToken: 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'
                }
            },
            // 如果用天地图，就用下面两种
            // {
            //     label: 'tianditu-tile',						
            //     // 天地图的卫星地图
            //     // urlTemplate: 'https://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk={accessToken}',
            //     // 天地图的标准地图
            //     urlTemplate: 'https://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk={accessToken}',
            //     options: {
            //         maxZoom: 18,
            //         tileSize: 512,
            //         zoomOffset: -1,
            //         // 蓝色
            //         color: { r: 12, g: 12, b: 83 },
            //         // 橙色
            //         // color: { r: 150, g: 60, b: 16 },
            //         accessToken: 'your key'
            //     }
            // },
            // {						
            //     // 天地图地名、道路标记图层
            //     urlTemplate: 'https://t0.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk={accessToken}',
            //     options: {
            //         maxZoom: 18,
            //         tileSize: 512,
            //         zoomOffset: -1,
            //         // 
            //         accessToken: 'your key',
            //     }
            // }

        ]
    },
    series: [{
        name: 'pm2.5',
        type: 'scatter',
        coordinateSystem: 'leaflet',
        data: convertData(data),
        symbolSize: function (val) {
            return val[2] / 10;
        },
        label: {
            normal: {
                formatter: '{b}',
                position: 'right',
                show: false
            },
            emphasis: {
                show: true
            }
        },
        itemStyle: {
            normal: {
                color: '#ddb926'
            }
        }
    },
    {
        name: 'Top 5',
        type: 'effectScatter',
        coordinateSystem: 'leaflet',
        data: convertData(data.sort(function (a, b) {
            return b.value - a.value;
        }).slice(0, 6)),
        symbolSize: function (val) {
            return val[2] / 10;
        },
        showEffectOn: 'emphasis',
        rippleEffect: {
            brushType: 'stroke'
        },
        hoverAnimation: true,
        label: {
            normal: {
                formatter: '{b}',
                position: 'right',
                show: true
            }
        },
        itemStyle: {
            normal: {
                color: '#f4e925',
                shadowBlur: 10,
                shadowColor: '#333'
            }
        },
        zlevel: 1
    }
    ]
});
```
# 如何编译
如果要对源码做修改，然后重新发布，可以运行如下命令
```shell
# rollup --config rollup.config.js
npm run build
```

其中rollup是一个打包工具，需要先全局安装

```shell
npm install rollup -g
```