效果图如下:
<!DOCTYPE html>
<html>
<head>
<title>时态图</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 引入样式 -->
<!-- <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> -->
<link rel="stylesheet" href="../../lib/element-ui@2.13.0/index.css" />
<style>
html,
body,
#map {
height: 100%;
padding: 0;
margin: 0;
}
.timeslider {
position: absolute;
z-index: 999;
width: 100%;
height: 100px;
background: lightseagreen;
bottom: 0px;
display: flex;
align-items: center;
justify-content: center;
}
.block {
width: 80%;
display: flex;
}
.block .icon {
display: flex;
align-items: center;
color: rgb(64, 158, 255);
justify-content: center;
width: 100px;
cursor: pointer;
}
.block .timestool {
flex: 1;
}
.timeslider .slider-demo-block {
display: flex;
align-items: center;
}
.slider-demo-block .el-slider {
margin-top: 0;
margin-left: 12px;
}
.el-slider__marks-text {
position: absolute;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
font-size: 14px;
color: #fff;
margin-top: 15px;
}
.icon:hover {
color: #66b1ff;
}
.el-slider__marks :last-child {
right: -60px;
}
</style>
<script src="../../lib/vue@2.6.11/vue.js"></script>
<!-- <script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script> -->
<!-- 引入组件库 -->
<!-- <script src="https://unpkg.com/element-ui@2.13.0/lib/index.js"></script> -->
<script src="../../lib/element-ui@2.13.0/index.js"></script>
<script src="../../js/prjconfig.js" maptype="leaflet"></script>
<!-- 引入插件 -->
<script src="../../lib/leaflet/plugins/leaflet.polylineDecorator.js"></script>
<script src="../../lib/leaflet/plugins/Leaflet.AnimatedMarker.js"></script>
</head>
<body>
<div id="map"></div>
<div id="app" class="timeslider">
<div class="block">
<div v-if="show" class="icon">
<i
class="icon el-icon-video-play"
style="font-size: 32px"
@click="playChange('stop')"
></i>
</div>
<div v-if="!show" class="icon">
<i
class="icon el-icon-video-pause"
style="font-size: 32px"
@click="playChange('play')"
></i>
</div>
<div class="icon">
<i
class="icon el-icon-arrow-left"
style="font-size: 32px"
@click="prevStep()"
></i>
</div>
<div class="timestool">
<el-slider
v-model="currIndex"
:max="maxIndex"
:step="10"
:marks="marks"
:show-tooltip="false"
@change="change"
>
</el-slider>
</div>
<div class="icon">
<i
class="icon el-icon-arrow-right"
style="font-size: 32px"
@click="nextStep()"
></i>
</div>
</div>
</div>
<script>
//'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
var map = L.map("map", {
crs: L.CRS.EPSG4326, //L.CRS.EPSG3857
center: [MAPINIT.Location.lat, MAPINIT.Location.lon], //[40.76339, 106.9477844],
zoom: MAPINIT.Location.zoom,
minZoom: MAPINIT.zoomsExtent[0],
maxZoom: MAPINIT.zoomsExtent[1],
zoomControl: true,
});
// 使用WMTS Key-Value加载地图服务
let _getc =
"http://192.168.1.212:8095/server/default/getTile/wmts?request=GetCapabilities&service=wmts&layer=yx";
MAPCONFIG.MAPWMTS_IMG =
"http://192.168.1.212:8095/server/vtile/getTile/wmts";
let ls =
"http://192.168.1.212:8095/server/vtile/getTile/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=yx&STYLE=default&TILEMATRIXSET=w&FORMAT=image/png&TILEMATRIX={z}&TILECOL={x}&TILEROW={y}&tk=''";
L.tileLayer(ls, {
zoomOffset: 1,
}).addTo(map);
map.setView(L.latLng(37.550339, 104.114129), 4); //设置缩放级别及中心点
var heatmapLayer;
// 初始化热力图
function initHeatMap(data, cfg) {
heatmapLayer = new HeatmapOverlay(cfg);
heatmapLayer.addTo(map);
heatmapLayer.setData(data);
}
function clear() {
map.removeLayer(heatmapLayer);
}
let app = new Vue({
el: "#app",
data: {
message: "Hello Vue!",
// 数据
testData: {
max: 8,
data: [
{
lat: 36.793094 + Math.random(),
lng: 118.054241 + Math.random(),
count: 8,
},
{
lat: 36.405841 + Math.random(),
lng: 118.159911 + Math.random(),
count: 5,
},
{
lat: 36.215321 + Math.random(),
lng: 118.17456 + Math.random(),
count: 9,
},
{
lat: 36.527985 + Math.random(),
lng: 118.400512 + Math.random(),
count: 8,
},
{
lat: 36.512117 + Math.random(),
lng: 118.401366 + Math.random(),
count: 7,
},
{
lat: 36.332074 + Math.random(),
lng: 118.360107 + Math.random(),
count: 6,
},
{
lat: 36.244085 + Math.random(),
lng: 118.595214 + Math.random(),
count: 7,
},
],
},
// 配置
cfg: {
radius: 0.5, //设置每一个热力点的半径
maxOpacity: 0.9, //设置最大的不透明度
// minOpacity: 0.3, //设置最小的不透明度
scaleRadius: true, //设置热力点是否平滑过渡
blur: 0.95, //系数越高,渐变越平滑,默认是0.85,
//滤镜系数将应用于所有热点数据
useLocalExtrema: true, //使用局部极值
latField: "lat", //纬度
lngField: "lng", //经度
valueField: "count", //热力点的值
gradient: {
0.99: "rgba(255,0,0,1)",
0.9: "rgba(255,255,0,1)",
0.8: "rgba(0,255,0,1)",
0.5: "rgba(0,255,255,1)",
0: "rgba(0,0,255,1)",
},
},
currIndex: 0,
maxIndex: 50,
show: true,
curPage: 3,
curMonth: "",
marks: {
0: "2023-01",
10: "2023-02",
20: "2023-03",
30: "2023-04",
40: "2023-05",
50: "2023-06",
},
},
mounted() {
// console.log([119.23 + Math.random(), 30.14 + Math.random()]);
this.getCurrentMonth();
this.getBeforeMonth();
initHeatMap(this.testData, this.cfg);
},
watch: {
// watch第一次绑定值的时候不会执行监听,修改数据才会触发函数
currIndex(newVal, oldVal) {
console.log(newVal);
let step = newVal.toString();
if (Object.keys(this.marks).indexOf(step) > -1) {
// console.log(this.marks[step], 222);
// 先清除原来的
clear();
let data = {
max: 8,
data: [
{
lat: 36.60976 + Math.random(),
lng: 117.067686 + Math.random(),
count: 8,
},
{
lat: 36.60976 + Math.random(),
lng: 117.067686 + Math.random(),
count: 5,
},
{
lat: 36.60976 + Math.random(),
lng: 117.067686 + Math.random(),
count: 9,
},
{
lat: 36.60976 + Math.random(),
lng: 117.067686 + Math.random(),
count: 8,
},
],
};
initHeatMap(data, this.cfg);
}
},
},
methods: {
change(e) {
let step = e.toString();
// console.log(Object.keys(this.marks));
if (Object.keys(this.marks).indexOf(step) > -1) {
console.log(this.marks[step]);
}
// console.log(this.currIndex);
},
// 获取当前月份
getCurrentMonth() {
let data = new Date();
let year = data.getFullYear();
// getMonth()返回的数字范围从0到11,因此需要加1来得到正确的月份
let mth = data.getMonth() + 1;
let month =
mth < 10 ? "0" + mth : mth;
this.curMonth = data.getFullYear() + "-" + month;
},
// 获取当月之前半年的月份
getBeforeMonth() {
let dataArr = [];
let data = new Date();
let year = data.getFullYear();
data.setMonth(data.getMonth() + 1, 1); //获取到当前月份,设置月份
for (let i = 0; i < 6; i++) {
data.setMonth(data.getMonth() - 1); //每次循环一次,月份值减1
let m = data.getMonth() + 1;
m = m < 10 ? "0" + m : m;
dataArr.push(data.getFullYear() + "-" + m);
}
let list = dataArr.reverse();
let obj = {};
let labelArr = Object.keys(this.marks);
labelArr.forEach((item, index) => {
obj[item] = list[index];
});
this.marks = obj;
},
// 获取指定月之前半年的月份数组
getBeforeCurMonth(mon) {
let dataArr = [];
let data = new Date(mon);
let year = data.getFullYear();
data.setMonth(data.getMonth(), 1); //获取到当前月份,设置月份
for (let i = 0; i < 6; i++) {
data.setMonth(data.getMonth() - 1); //每次循环一次,月份值减1
let m = data.getMonth() + 1;
m = m < 10 ? "0" + m : m;
dataArr.push(data.getFullYear() + "-" + m);
}
let list = dataArr.reverse();
let obj = {};
let labelArr = Object.keys(this.marks);
labelArr.forEach((item, index) => {
obj[item] = list[index];
});
this.marks = obj;
},
// 获取指定月份之后半年的月份数组
getAfterMonth(mon) {
let dataArr = [];
let data = new Date(mon);
let year = data.getFullYear();
data.setMonth(data.getMonth(), 1); //获取到当前月份,设置月份
for (let i = 0; i < 6; i++) {
data.setMonth(data.getMonth() + 1); //每次循环一次,月份值加1
let m = data.getMonth() + 1;
m = m < 10 ? "0" + m : m;
dataArr.push(data.getFullYear() + "-" + m);
}
let list = dataArr;
let obj = {};
let labelArr = Object.keys(this.marks);
labelArr.forEach((item, index) => {
obj[item] = list[index];
});
this.marks = obj;
},
playChange(val) {
let that = this;
let data = new Date();
let year = data.getFullYear();
let mth = data.getMonth()+1;
let month =
mth < 10 ? "0" + mth : mth;
var curMonth = data.getFullYear() + "-" + month;
if (val == "stop") {
if (that.timer) {
clearInterval(that.timer);
}
that.show = false;
that.timer = setInterval(() => {
that.currIndex += 10;
const lastValue = that.marks[that.maxIndex];
let customM = curMonth.replace("-", "");
let curMaxIndexM = lastValue.replace("-", "");
if (that.currIndex > that.maxIndex) {
that.currIndex = 0;
// that.show = true;
// clearInterval(that.timer);
// 自动循环播放
if (parseInt(curMaxIndexM) < parseInt(customM)) {
that.getAfterMonth(lastValue.replace("-", "/"))
}
if (lastValue == curMonth) {
that.show = true;
clearInterval(that.timer);
}
}
}, 3000);
} else {
clearInterval(that.timer);
that.show = true;
}
},
// 往前播放
prevStep() {
clearInterval(this.timer);
this.show = true;
if (this.currIndex === 0) {
let curMonth = this.marks[this.currIndex];
let customM = this.curMonth.replace("-", "/");
var d = new Date(customM);
d.setMonth(d.getMonth() - 12);
let year = d.getFullYear();
let month =
d.getMonth() < 10 ? "0" + d.getMonth() : d.getMonth();
let beforeM = year + "-" + month;
// console.log(year + "-" + month)
let curMaxIndexM = curMonth.replace("-", "");
let customMs = beforeM.replace("-", "");
if (parseInt(curMaxIndexM) < parseInt(customMs)) {
return
} else {
this.getBeforeCurMonth(curMonth.replace("-", "/"))
}
} else {
this.currIndex -= 10;
}
},
// 往后播放
nextStep() {
clearInterval(this.timer);
this.show = true;
if (this.currIndex === this.maxIndex) {
const lastValue = this.marks[this.maxIndex];
const curMonth = this.marks[this.currIndex];
// console.log(this.curMonth);
// console.log(lastValue);
// console.log(curMonth);
let customM = this.curMonth.replace("-", "");
let curMaxIndexM = lastValue.replace("-", "");
let curM = curMonth.replace("-", "");
if (parseInt(curMaxIndexM) < parseInt(customM)) {
this.getAfterMonth(lastValue.replace("-", "/"))
this.currIndex = 0;
} else {
this.currIndex = this.maxIndex;
}
} else {
this.currIndex += 10;
}
},
},
});
</script>
</body>
</html>