1. 效果
跑马灯
2. RoouteRunning
import * as turf from "@turf/turf"
export default class RouteRunning{
map: any
routejson: any
data: Array
timeData: Array
VLayer: any
VLayerTwo: any
lineOptions: object
animationOptions: object
constructor(map: any, routejson: any, lineOptions: object, animationOptions: object) {
this.map = map
this.routejson = routejson
this.data = []
this.timeData = []
this.VLayer = null
this.VLayerTwo = null
this.lineOptions = {
strokeStyle: lineOptions.strokeStyle || 'rgba(0,255,255,1)',
shadowColor: lineOptions.shadowColor || 'rgba(125,125,125,0.2)',
shadowBlur: lineOptions.shadowBlur || 3,
lineWidth: lineOptions.lineWidth || 3,
globalAlpha: lineOptions.globalAlpha || 1,
globalCompositeOperation: 'lighter',
coordType: 'bd09mc',
draw: 'simple'
}
this.animationOptions = {
fillStyle: animationOptions.fillStyle || 'rgba(255,255,241,0.2)',
coordType: 'bd09mc',
globalCompositeOperation: 'lighter',
size: animationOptions.size || 3,
animation: animationOptions.animation || {
stepsRange: {
start: 0,
end: 50
},
trails: this.map.getZoom() > 10 ? 5 : 3,
duration: 2
},
draw: 'simple'
}
this.init()
}
init() {
let lineList = []
// 动态点密集程度
let density = {
7:1,
8: 0.5,
9: 0.45,
10: 0.35,
11: 0.2,
12: 0.08,
13: 0.04,
14: 0.02,
15: 0.02,
16: 0.02,
17: 0.02
}
// 当前zoom密集程度
let currentDensity = density[Math.round(this.map.getZoom())]
// eslint-disable-next-line no-plusplus
for (let i = 0; i < this.routejson.length; i++) {
const pointList = [...this.routejson[i].geometry.coordinates]
const newPointList = []
// eslint-disable-next-line no-plusplus
for (let j = 0; j < pointList.length; j++) {
if (pointList[j + 1]) {
// 计算两点之间距离
const from = turf.point(pointList[j])
const to = turf.point(pointList[j + 1])
const options = { units: 'kilometers' }
// @ts-ignore
const distance = turf.distance(from, to, options)
if (distance > currentDensity) {
const midpoint = turf.getCoord(turf.midpoint(from, to))
pointList.splice(j + 1, 0, midpoint)
// eslint-disable-next-line no-plusplus
j--
} else {
newPointList.push(pointList[j])
}
} else {
newPointList.push(pointList[j])
}
}
lineList.push(newPointList)
}
const newLineList: any[] = []
lineList.forEach(i => {
const arr = i
const node1 = Math.floor(arr.length * 0.33)
const node2 = Math.floor(arr.length * 0.66)
const newArr1 = [...arr.slice(node1), ...arr.slice(0, node1)]
const newArr2 = [...arr.slice(node2), ...arr.slice(0, node2)]
newLineList.push(i)
newLineList.push(newArr1, newArr2)
})
// eslint-disable-next-line no-plusplus
for (let i = 0; i < newLineList.length; i++) {
let item = newLineList[i]
let coordinates = []
for (let j = 0; j < item.length; j += 1) {
coordinates.push(item[j])
this.timeData.push({
geometry: {
type: 'Point',
coordinates: item[j]
},
count: 1,
time: j
})
}
}
// eslint-disable-next-line no-plusplus
for (let i = 0; i < lineList.length; i++) {
this.data.push({
geometry: {
type: 'LineString',
coordinates: lineList[i]
}
})
}
}
drawLine() {
let options = {
// size: 5, // 大小值
// unit: 'm', // 可选px或者m
// fillStyle: 'rgba(200, 200, 50, 1)', // 填充颜色
// // strokeStyle: 'rgba(120, 0, 255, 1)', // 描边颜色
// lineWidth: 4, // 描边宽度
// globalAlpha: 1, // 透明度
// globalCompositeOperation: 'lighter', // 颜色叠加方式
// shadowColor: 'rgba(255, 255, 255, 1)', // 投影颜色
// shadowBlur: 35, // 投影模糊级数
// shadowOffsetX: 0,
// shadowOffsetY: 0,
// lineCap: 'butt',
// lineJoin: 'miter',
// miterLimit: 10,
strokeStyle: 'rgba(0,255,255,1)',
coordType: 'bd09mc',
globalCompositeOperation: 'lighter',
shadowColor: 'rgba(125,125,125,0.2)',
shadowBlur: 3,
lineWidth: 3.0,
draw: 'simple'
}
let options2 = {
fillStyle: 'rgba(255,255,241,0.2)',
coordType: 'bd09mc',
globalCompositeOperation: 'lighter',
size: this.map.getZoom() > 10 ? 3 : 2,
animation: {
stepsRange: {
start: 0,
end: 50
},
trails: this.map.getZoom() > 10 ? 5 : 3,
duration: 2
},
draw: 'simple'
}
// 动态图层渲染
this.VLayer = new mapboxgl.supermap.MapvLayer(
this.map,
new mapv.DataSet(this.data),
this.lineOptions)
this.VLayerTwo = new mapboxgl.supermap.MapvLayer(
this.map,
this.timeData,
this.animationOptions)
this.map.addLayer(this.VLayer)
this.map.addLayer(this.VLayerTwo)
}
clear(){
if(this.VLayer){
this.VLayer.removeFromMap()
}
if(this.VLayerTwo){
this.VLayerTwo.removeFromMap()
}
}
}
3. 使用
running = new RouteRunning(map, routeGeoJson1.features, {}, {})
running.drawLine()