# leaflet-viz
**Repository Path**: gispdr/leaflet-viz
## Basic Information
- **Project Name**: leaflet-viz
- **Description**: leaflet可视化平台
- **Primary Language**: JavaScript
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2021-05-22
- **Last Updated**: 2021-05-22
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# leaflet-viz
**Leaflet可视化平台**
[leaflet](http://leafletjs.com/index.html)是一个开源的前端地图交互类库,比较轻量级,支持移动端。而且有丰富的[插件资源](http://leafletjs.com/plugins.html)可供我们使用。
[Echarts](http://echarts.baidu.com/)是百度开源的前端可视化类库,提供丰富的前端可视化图表,平台中重要的一部分是我们要将leaflet和Echarts结合在一起。
该平台是基于leaflet及其插件搭建的一个方便可用的可视化平台。详细参见[示例Demo]。(https://zrysmt.github.io/demo/leaflet-demo/)
## 1. 安装与编译
- **安装**
```source-shell
npm install
```
- **编译**
**debug模式**
```source-shell
npm run dev
```
**输出**
```source-shell
npm run build
```
## 2.示例简介
示例地址:[https://zrysmt.github.io/demo/leaflet-demo/](https://zrysmt.github.io/demo/leaflet-demo/)

示例包含最基本的GIS功能和可视化Demo
## 3.基础的GIS功能
- 拖放、全图、定位、打印出图片、打印出PDF功能。

- 地图缩放、比例尺显示功能
- 测量面积和距离功能
- 图层切换,提供丰富的图层切换

- 地图搜索功能
- 基础绘图功能

## 4.可视化示例

- **热力图**
引入:
```
import '../common/leaflet-plugin/HeatLayer.js';
```
使用:
```javascript
var heat = L.heatLayer([
[50.5, 30.5, 0.2], // lat, lng, intensity
[50.6, 30.4, 0.5],
...
], {radius: 25}).addTo(map)
```
**效果图**:

- **结合Echarts**
```javascript
let overlay = new L.echartsLayer3(map, echarts);
let chartsContainer = overlay.getEchartsContainer();
let myChart = overlay.initECharts(chartsContainer);
window.onresize = myChart.onresize;
console.log("chartsContainer:", chartsContainer);
if (type == "qianxi") {
overlay.setOption(ecOption);
} else if (type == "scatter") {
overlay.setOption(scatterOption);
}
```
**迁徙图**(选择了高德卫星底图)

**散点图**(选择了Geoq午夜蓝底图)

- **DivIcon结合Echarts**
这个方案不太适合大数据量的渲染。
我写了两个简单的功能函数,一个用来渲染可视化图(echartsIcon),一个专门用来渲染图例(echartsLegend)。
**效果图**(底图选择了为google底图)

```javascript
import echartsIcon from '../common/plugin/echartsIcon.js'; //echartsLegend
import echartsLegend from '../common/plugin/echartsLegend.js'; //echartsLegend
```
```javascript
let option = {
tooltip: {
trigger: 'item',
formatter: "{a}
{b} : {c} ({d}%)"
},
series: [{
name: '访问来源',
type: 'pie',
radius: '55%',
center: ['50%', '50%'],
label: {
normal: {
show: false
},
emphasis: {
show: false
}
},
lableLine: {
normal: {
show: false
},
emphasis: {
show: false
}
},
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
//经纬度不能相同
let latlngs = [
[30, 104],
[31, 110],
[34, 120]
];
option.datas = [
[
{ value: 335, name: '直接访问' },
{ value: 310, name: '邮件营销' },
{ value: 234, name: '联盟广告' },
{ value: 135, name: '视频广告' },
{ value: 1548, name: '搜索引擎' }
],
[
{ value: 345, name: '直接访问' },
{ value: 410, name: '邮件营销' },
{ value: 244, name: '联盟广告' },
{ value: 145, name: '视频广告' },
{ value: 548, name: '搜索引擎' }
],
[
{ value: 445, name: '直接访问' },
{ value: 410, name: '邮件营销' },
{ value: 244, name: '联盟广告' },
{ value: 145, name: '视频广告' },
{ value: 148, name: '搜索引擎' }
],
];
echartsIcon(map, latlngs, option);
//图例
let legendOption = {
orient: 'vertical',
left: 'left',
width: "90px",
height: "140px",
data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']
};
echartsLegend(map, legendOption);
```
- leaflet-dvf
[leaflet-dvf](https://github.com/humangeo/leaflet-dvf)是一个基于leaflet的数据可视化框架,提供有比较多的可视化图形。
```javascript
import "../common/leaflet-plugin/Leaflet.dvf/css/dvf.css";
import "leaflet-dvf";
```
**地震图:**

**收入水平图:**

需要的数据
```javascript
import earthquakesData from '../data/earthquakes.json';
import countryData from '../data/countryData.js';
```
**地震图代码:**
```javascript
let lastLayer;
let eqfeed_callback = function(data) {
// Initialize framework linear functions for mapping earthquake data properties to Leaflet style properties
// Color scale - green to red using the basic HSLHueFunction
let magnitudeColorFunction = new L.HSLHueFunction(new L.Point(0, 90), new L.Point(10, 0), { outputSaturation: '100%', outputLuminosity: '25%', postProcess: null });
let magnitudeFillColorFunction = new L.HSLHueFunction(new L.Point(0, 90), new L.Point(10, 0), { outputSaturation: '100%', outputLuminosity: '50%', postProcess: null });
let magnitudeRadiusFunction = new L.LinearFunction(new L.Point(0, 10), new L.Point(10, 30), { postProcess: null });
let now = Math.round((new Date()).getTime());
let start = now - 86400000;
// Initialize a linear function to map earthquake time to opacity
let timeOpacityFunction = new L.LinearFunction(new L.Point(start, 0.3), new L.Point(now, 1));
let fontSizeFunction = new L.LinearFunction(new L.Point(0, 8), new L.Point(10, 24));
let textFunction = function(value) {
return {
text: value,
style: {
'font-size': fontSizeFunction.evaluate(value)
}
};
};
// Setup a new data layer
let dataLayer = new L.DataLayer(data, {
recordsField: 'features',
latitudeField: 'geometry.coordinates.1',
longitudeField: 'geometry.coordinates.0',
locationMode: L.LocationModes.LATLNG,
displayOptions: {
'properties.mag': {
displayName: '震级',
color: magnitudeColorFunction,
fillColor: magnitudeFillColorFunction,
radius: magnitudeRadiusFunction,
text: textFunction
},
'properties.time': {
displayName: '时间',
opacity: timeOpacityFunction,
fillOpacity: timeOpacityFunction,
displayText: function(value) {
return moment.unix(value / 1000).format('MM/DD/YY HH:mm');
}
}
},
layerOptions: {
numberOfSides: 4,
radius: 10,
weight: 1,
color: '#000',
opacity: 0.2,
stroke: true,
fillOpacity: 0.7,
dropShadow: true,
gradient: true
},
tooltipOptions: {
iconSize: new L.Point(90, 90), //hover框大小
iconAnchor: new L.Point(-4, 76)
},
onEachRecord: function(layer, record, location) {
let $html = $(L.HTMLUtils.buildTable(record));
layer.bindPopup($html.wrap('
面积:' + (feature.properties['AREA'] !== null ? Autolinker.link(String(feature.properties['AREA'])) : '') + ' | \|
周长:' + (feature.properties['PERIMETER'] !== null ? Autolinker.link(String(feature.properties['PERIMETER'])) : '') + ' | \|
名称:' + (feature.properties['NAME'] !== null ? Autolinker.link(String(feature.properties['NAME'])) : '') + ' | \