以下代码与业务场景关联较深,实现方案可参考
直接上代码
<template>
<div id="map" ref="map"></div>
</template>
<script>
// mapRef :自己封装的 全局 map 通用方法,代码在文末
import * as mapRef from './mapUtils'
// 设置当前组件地图小组件 样式参数 结合 formatDatas
let entityImg = {
"heatmap": {
noSelect: require("@/assets/images/analysis/map-company.png"),
selected: require("@/assets/images/analysis/map-company-selected.png"),
},
}
let textFill = {
noSelect: {
fill: "rgba(255,255,255,0)",
bgFill: "rgba(255,255,255,0)",
strokeFill: "rgba(255,255,255,0)",
},
selected: {
fill: "#FFF18D",
bgFill: "#665C13",
strokeFill: "#FFF18D",
}
}
export default {
data() {
return {
areaMap: null,
hotLayer: null,
mainLayer: null,
datas: [
{
id: '',
name: '',
code: '',
Longitude: '',
Latitude: '',
img: '',
}
],
metaList: []
}
},
methods: {
initMap() {
let _this = this;
let _Url = 'YOU MAP SERVER URL' // 地图服务地址
this.areaMap = new ol.Map({
target: _this.$refs.map,
view: new ol.View({
center: [Longitude, Latitude], //地图中心点
projection: 'EPSG:4326', // 坐标系
maxExtent: [106.43, 29.13, 107.0, 29.77], //限制可视区域
zoom: 11, // 缩放等级
minZoom: 8,
maxZoom: 15,
}),
controls: ol.control.defaults().extend([
]),
})
// 添加聚合图层
this.cluster()
},
// 对数据追加数据 结合mapRef 。createMakerFeature 使用
formatDatas(info) {
info["position"] = [info?.Longitude, info?.Latitude];
info["entity"] = {
img: entityImg[info.code][info.selectStatus]
};
info["text"] = {
name: info?.name,
...textFill[info.selectStatus]
}
},
cluster() {
if (data && data?.length > 0) {
this.metaList = data ?? []
var source = new ol.source.Vector();
this.metaList.forEach(item => {
item.id = item.id;
item.name = item?.name;
item.code = 'heatmap';
item.selectStatus = "noSelect";
item.selectStatus = "noSelect";
this.formatDatas(item);
//添加点
if (item.Longitude && item.Latitude) {
source.addFeature(mapRef.createMakerFeature(item))
}
})
this.cluster = new ol.source.Cluster({
source: source,
distance: 100
})
this.mainLayer = new ol.layer.Vector({
source: this.cluster,
style: function (feature, resolution) {
let size = feature.get('features').length;
let zoom = (_this.areaMap.getView().getZoom()) / 10 * 0.5
if (zoom < 0.55) {
zoom = 0.55
}
if (size == 1) {
return new ol.style.Style({
image: new ol.style.Icon({
scale: zoom,
anchor: [0.5, 0.5],
src: require("@/assets/images/analysis/map-company.png")
})
})
}
else {
// 根据场景计算 缩放等级,以及图标的缩放等级
let radius = (size + 40) > 80 ? 80 : (size + 40)
let scale = (((size + 40) > 80 ? 80 : (size + 40) / 100 > 1 ? 0.65 : (size + 40) / 100) < 0.3 ? 0.3 : (size + 40) / 100)
return new ol.style.Style({
cursor: 'pointer',
image: new ol.style.Icon({
scale: '1',
src: require("@/assets/images/analysis/map-jh.png")
}),
text: new ol.style.Text({
textAlign: 'center', //对齐方式
textBaseline: 'middle', //文本基线
offsetY: -14, // Y轴偏置
font: (radius / 2) + 'px PangMenZhengDao',
text: size.toString(),
fill: new ol.style.Fill({
color: 'white'
})
})
})
}
}
});
// 添加缩放监听事件
var select_move = new ol.interaction.Select({
condition: ol.events.condition.pointerMove,//设置监听事件
style: function (feature, resolution) {
let size = feature.get('features').length;
let zoom = (_this.areaMap.getView().getZoom()) / 10 * 0.7
if (zoom < 0.55) {
zoom = 0.55
}
if (size == 1) {
let ids = feature.get('features')[0].get("id")
let target = _this.metaList.find(item => item.id == ids);
return new ol.style.Style({
text: new ol.style.Text({
text: target.name,
textAlign: 'center', //对齐方式
textBaseline: 'middle', //文本基线
font: 'normal 16px 微软雅黑', //字体样式
offsetY: -50, // Y轴偏置
// offsetX : 30,
fill: new ol.style.Fill({
//填充样式
color: '#FFFFFF',
}),
backgroundFill: new ol.style.Fill({
// 填充背景
color: 'rgba(97,126,155,0.88)',
}),
backgroundStroke: new ol.style.Stroke({
color: '#617E9B',
width: 2,
}),
padding: [6, 10, 3, 10],
}),
image: new ol.style.Icon({
scale: zoom,
anchor: [0.5, 0.5],
src: require("@/assets/images/analysis/map-company-selected.png")
})
})
} else {
_this.areaMap.getTargetElement().style.cursor = 'pointer'
let radius = (size + 40) > 80 ? 80 : (size + 40)
let scale = (((size + 40) > 80 ? 80 : (size + 40) / 100 > 1 ? 0.65 : (size + 40) / 100) < 0.3 ? 0.3 : (size + 40) / 100)
return new ol.style.Style({
cursor: 'pointer',
image: new ol.style.Icon({
scale: scale,
src: require("@/assets/images/analysis/map-jh-selected.png")
}),
text: new ol.style.Text({
font: (radius / 2) + 'px PangMenZhengDao',
text: size.toString(),
textAlign: 'center', //对齐方式
textBaseline: 'middle', //文本基线
offsetY: -14, // Y轴偏置
fill: new ol.style.Fill({
color: 'white'
})
})
})
}
},
});
_this.areaMap.addInteraction(select_move)
_this.areaMap.addLayer(_this.mainLayer);
}
}
},
}
</script>
mapRef.js
部分代码如下:
export function createMakerFeature (info,feature) {
let {id, position, circle, entity, arrow, text, cover, progress} = info;
position = position.map(item => parseFloat(item));
if(!feature){
feature = new ol.Feature({
id,
geometry : new ol.geom.Point(position),
})
}
let styles = [];
if (circle?.img) {
styles.push(
new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5,0.5], //设置图标偏移
scale: 1, // 图标缩小显示
opacity: 1, //透明度
src: circle.img, //图片路径
})
})
)
}
if (entity?.img) {
styles.push(
new ol.style.Style({
image: new ol.style.Icon({
// color: 'red',
anchor: entity.anchor || [0.5, 0.7], //设置图标偏移
scale: 1, // 图标缩小显示
opacity: 1, //透明度
src: entity.img, //图片路径
})
})
)
}
if (arrow?.img) {
styles.push(
new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5,2.4], //设置图标偏移
scale: 1, // 图标缩小显示
opacity: 1, //透明度
src: arrow.img, //图片路径
})
})
)
}
if (text?.name) {
styles.push(
new ol.style.Style({
text : new ol.style.Text({
text : text.name,
textAlign: 'center', //对齐方式
textBaseline: 'middle', //文本基线
font: 'normal 14px 微软雅黑', //字体样式
offsetY: -70, // Y轴偏置
// offsetX : 30,
fill: new ol.style.Fill({ //填充样式
color: text.fill
}),
backgroundFill: new ol.style.Fill({ // 填充背景
color: text.bgFill
}),
backgroundStroke : new ol.style.Stroke({
color : text.strokeFill,
width : 2
}),
padding: [5, 10, 2, 10],
})
})
)
}
if (cover?.img) {
styles.push(
new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5,0.8], //设置图标偏移
scale: 1, // 图标缩小显示
opacity: 1, //透明度
src: cover.img, //图片路径
})
})
)
}
if (progress?.img) {
styles.push(
new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5,6], //设置图标偏移
scale: 1, // 图标缩小显示
opacity: 1, //透明度
src: progress.img, //图片路径
})
})
)
}
feature.setStyle(styles)
return feature;
}
效果如下,图文并不关联
项目原因,效果图无法上传,自行替代样式


Comments | NOTHING