@vuemap/vue-amap是基于高德JSAPI2.0、Loca2.0封装的vue组件库,支持vue2、vue3版本。首页地址:vue-amap.guyixi.cn/
在上一个分享中,主要讲解了如何在地图上展示动态的标记。这一次主要讲解怎么基于地图组件实现数据的聚合效果展示。
对于数据的聚合展示,日常使用中常用的展示方式就是点聚合以及热力图方式。下面详细介绍各自对应的组件的应用。
聚合点
聚合点可以详细的展示当前点的数量以及大致的分布情况,我们可以使用el-amap-marker-cluster
组件来实现聚合点。
示例代码如下:
<template>
<div class="map-page-container">
<el-amap
:show-label="false"
:center="center"
:zoom="zoom"
@click="clickMap"
@init="initMap"
>
<el-amap-marker-cluster
v-if="visible"
:points="markerPoints"
@init="markerInit"
@click="clickMarker"
/>
</el-amap>
</div>
<div class="toolbar">
<button @click="changeVisible">
显隐
</button>
</div>
</template>
<script lang="ts" setup>
import {ref} from "vue";
import {ElAmap, ElAmapMarkerCluster} from "@vuemap/vue-amap";
const center = ref([104.937478, 35.439575]);
const zoom = ref(5);
const markerPoints = ref([]);
const visible = ref(true);
const clickMap = (e) => {
console.log('click map: ', e);
}
const initMap = (map) => {
console.log('init map: ', map);
fetch('//a.amap.com/jsapi_demos/static/china.js').then(res => res.text()).then(text => {
const array = text.split('=');
if(array.length === 2){
const result = JSON.parse(array[1].trim())
result.forEach((item,index) => {
item.extraData = {
index
}
})
markerPoints.value = result
}
})
}
const changeVisible = () => {
visible.value = !visible.value;
}
const markerInit = (e) => {
console.log('marker init: ', e);
}
const clickMarker = (e) => {
console.log('marker click: ', e);
}
</script>
<style scoped>
</style>
效果图:
通过传入经纬度数组我们就可以实现简单的聚合图层,但这时候出现另外一个问题,怎么给数据加上自己的业务数据,这时候我们可以在传递数据时直接添加我们需要的数据即可在点击事件中获取到我们的业务数据,具体的数据结构如下:
[
{
lnglat: [120, 31],
weight: 0,
extraData: {
index: 1
}
}
]
这里的extraData可以是任何结构的数据,也就是整个数组的每一项其实都会原封不动的缓存在高德聚合插件数据中。通过这样调整,在点击事件中我们就可以拿到自己需要的业务数据,结果如下:
区划聚合
除了上一个基础的聚合图层外,组件库额外实现了一个区划聚合插件,该插件基于AMapUI的区划聚合插件改造而成,适配JSAPI2.0,插件地址:github.com/yangyanggu/… 示例如下:
<template>
<div class="map-page-container">
<el-amap
:show-label="false"
:center="center"
:zoom="zoom"
view-mode="3D"
:pitch="20"
@click="clickMap"
@init="initMap"
>
<el-amap-layer-district-cluster
:get-position="getPosition"
:data="clusterData"
:visible="visible"
@featureClick="clickFeature"
@init="initLayer"
/>
</el-amap>
</div>
<div class="toolbar">
<button @click="changeVisible">
{{ visible ? '隐藏' : '显示' }}
</button>
</div>
</template>
<script lang="ts" setup>
import {ref, onMounted} from "vue";
import {ElAmap, ElAmapLayerDistrictCluster} from "@vuemap/vue-amap";
const zoom = ref(15);
const center = ref([116.33719, 39.942384]);
const visible = ref(true);
const changeVisible = () => {
visible.value = !visible.value;
}
const clusterData = ref<any[]>([]);
const getPosition = (item: any) => {
if (!item) {
return null;
}
const parts = item.split(',');
//返回经纬度
return [parseFloat(parts[0]), parseFloat(parts[1])];
}
onMounted(() => {
fetch('https://a.amap.com/amap-ui/static/data/10w.txt').then(res => {
return res.text()
}).then(csv => {
clusterData.value = csv.split('\n');
})
})
const clickMap = (e: any) => {
console.log('click map: ', e);
}
const initMap = (map: any) => {
console.log('init map: ', map);
}
const initLayer = (layer: any) => {
console.log('聚合图层: ', layer);
}
const clickFeature = (e: any, feature: any) => {
console.log('点击区划面: ', e, feature)
}
</script>
效果图
热力图
热力图常用于直观的展示某个区域某件事发生次数等等,通过颜色深浅变化,显示发生的次数最多的地方。
示例如下:
<template>
<div class="map-page-container">
<el-amap
:center="center"
:zoom="zoom"
@init="initMap"
>
<el-amap-layer-heat-map
v-if="dataSet"
:visible="visible"
:data-set="dataSet"
/>
</el-amap>
</div>
<div class="toolbar">
<button @click="switchVisible()">
{{ visible? '隐藏' : '显示' }}
</button>
</div>
</template>
<script lang="ts" setup>
import {ref} from "vue";
import {ElAmap, ElAmapLayerHeatMap} from "@vuemap/vue-amap";
const zoom = ref(11);
const center = ref([116.418261, 39.921984]);
const dataSet = ref(null)
const visible = ref(true)
const switchVisible = () => {
visible.value = !visible.value;
}
const initMap = () => {
fetch('//a.amap.com/jsapi_demos/static/resource/heatmapData.js').then(res => res.text()).then(text => {
const array = text.split('=');
if(array.length === 2){
let str = array[1].trim();
str = str.replace(';','')
dataSet.value = {
data: JSON.parse(str),
max: 100
}
}
})
}
</script>
<style>
</style>
效果图