浏览代码

add @dc-modules/history-track #35

tags/2.2.4
Caven Chen 4 年前
父节点
当前提交
ca0dd06c8e

+ 27
- 0
modules/event/type/TrackEvent.js 查看文件

@@ -0,0 +1,27 @@
/**
* @Author: Caven
* @Date: 2021-06-08 20:37:28
*/

import { Cesium } from '@dc-modules/namespace'
import { TrackEventType } from '../EventType'
import Event from '../Event'

class TrackEvent extends Event {
constructor() {
super()
}

/**
*
* @private
*/
_registerEvent() {
Object.keys(TrackEventType).forEach(key => {
let type = TrackEventType[key]
this._cache[type] = new Cesium.Event()
})
}
}

export default TrackEvent

+ 359
- 0
modules/history-track/Track.js 查看文件

@@ -0,0 +1,359 @@
/**
* @Author: Caven
* @Date: 2020-01-19 11:21:48
*/

import { Cesium } from '@dc-modules/namespace'
import { TrackEvent, TrackEventType } from '@dc-modules/event'
import State from '@dc-modules/state/State'
import Parse from '@dc-modules/parse/Parse'
import { Util } from '@dc-modules/utils'
import { Transform } from '@dc-modules/transform'
import { heading, distance } from '@dc-modules/math'
import TrackViewMode from './TrackViewMode'

const DEF_OPTS = {
showPath: false,
pathWidth: 1,
pathMaterial: Cesium.Color.ORANGE.withAlpha(0.8),
pathLeadTime: 1,
clampToGround: false,
clampToTileset: false
}

class Track {
constructor(positions, duration, callback, options) {
this._id = Util.uuid()
this._bid = undefined
this._positions = Parse.parsePositions(positions)
this._duration = duration || 20
this._callback = callback
this._options = {
...DEF_OPTS,
...options
}
this._controller = undefined
this._viewed = false
this._delegate = new Cesium.Entity()
this._positionIndex = 0
this._timeLine = []
this._startTime = undefined
this._endTime = undefined
this._trackEvent = new TrackEvent()
this._trackEvent.on(TrackEventType.POST_RENDER, this._onPostRender, this)
this._trackEvent.on(TrackEventType.ADD, this._onAdd, this)
this._trackEvent.on(TrackEventType.REMOVE, this._onRemove, this)
this._state = State.INITIALIZED
}

get trackId() {
return this._id
}

set id(id) {
this._bid = id
return this
}

get id() {
return this._bid
}

set positions(postions) {
this._positions = Parse.parsePositions(postions)
this._resetTimeLine()
return this
}

get positions() {
return this._positions
}

set duration(duration) {
this._duration = duration
this._resetTimeLine()
return this
}

get duration() {
return this._duration
}

set startTime(startTime) {
if (startTime instanceof Date) {
this._startTime = Cesium.JulianDate.fromDate(startTime)
} else {
this._startTime = startTime
}
this._resetTimeLine()
return this
}

get startTime() {
return this._startTime
}

set viewed(viewed) {
this._viewed = viewed
return this
}

get viewed() {
return this._viewed
}

get trackEvent() {
return this._trackEvent
}

get state() {
return this._state
}

/**
* add to entities
* @param controller
* @private
*/
_onAdd(controller) {
if (!controller) {
return false
}
this._controller = controller
this._controller.delegate.add(this._delegate)
!this._startTime && (this._startTime = Cesium.JulianDate.now())
this._state = State.ADDED
}

/**
* remove from entities
* @private
*/
_onRemove() {
if (this._controller) {
this._controller.delegate.remove(this._delegate)
}
this._viewed = false
this._state = State.REMOVED
}

/**
*
* @param viewer
* @param viewOption
* @private
*/
_onPostRender({ viewer, viewOption }) {
if (!this._startTime || !this._endTime) {
return false
}
let now = Cesium.JulianDate.now()
if (Cesium.JulianDate.lessThan(now, this._endTime)) {
if (this._options.clampToTileset) {
this._delegate.position = viewer.scene.clampToHeight(
this._sampledPosition.getValue(now),
[this._delegate]
)
} else {
this._delegate.position = this._sampledPosition.getValue(now)
}
let time = this._timeLine[this._positionIndex]
if (time) {
let timeDiff = Cesium.JulianDate.secondsDifference(now, time)
if (timeDiff >= 0 && timeDiff <= 1) {
let position = this._positions[this._positionIndex] || undefined
if (position) {
let mat = Cesium.Matrix3.fromQuaternion(
this._delegate.orientation.getValue(now)
)
let mat4 = Cesium.Matrix4.fromRotationTranslation(
mat,
this._sampledPosition.getValue(now)
)
let hpr = Cesium.Transforms.fixedFrameToHeadingPitchRoll(mat4)
position.heading = Cesium.Math.toDegrees(hpr.heading)
position.pitch = Cesium.Math.toDegrees(hpr.pitch)
position.roll = Cesium.Math.toDegrees(hpr.roll)
}
this._callback &&
this._callback(
position,
this._positionIndex + 1 === this._positions.length
)
this._positionIndex += 1
}
}
}
this._setCameraView(viewer, viewOption)
}

/**
* Sets camera position
* @param viewer
* @param viewOption
* @private
*/
_setCameraView(viewer, viewOption) {
if (!this._viewed) {
return false
}
let now = Cesium.JulianDate.now()
if (Cesium.JulianDate.greaterThan(now, this._endTime)) {
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
viewer.delegate.trackedEntity &&
(viewer.delegate.trackedEntity = undefined)
this._viewed = false
} else {
let p = this._sampledPosition.getValue(now)
let next_p = this._sampledPosition.getValue(
Cesium.JulianDate.addSeconds(now, 1 / 60, new Cesium.JulianDate())
)
if (p && next_p) {
if (
viewOption?.mode === TrackViewMode.TRACKED &&
viewer.delegate?.trackedEntity?.id !== this._delegate?.id
) {
viewer.delegate.trackedEntity = this._delegate
} else if (viewOption?.mode === TrackViewMode.FP) {
viewer.camera.lookAt(
p,
new Cesium.HeadingPitchRange(
heading(p, next_p),
Cesium.Math.toRadians(viewOption?.pitch || 0),
viewOption?.range || 10
)
)
} else if (viewOption?.mode === TrackViewMode.TP) {
viewer.camera.lookAt(
p,
new Cesium.HeadingPitchRange(
0,
Cesium.Math.toRadians(viewOption?.pitch || -90),
viewOption?.range || 1000
)
)
}
}
}
}

/**
*
* @param params
* @returns {boolean}
* @private
*/
_resetTimeLine(params) {
if (!this._startTime || !this._duration || !this._positions?.length) {
return false
}
let interval = 0
let v = distance(this._positions) / this._duration
this._timeLine = this._positions.map((item, index, arr) => {
if (index !== 0) {
interval += distance([arr[index - 1], item]) / v
}
return Cesium.JulianDate.addSeconds(
this._startTime,
interval,
new Cesium.JulianDate()
)
})
if (params?.stopTime && params?.duration) {
this._duration += params.duration
this._timeLine = this._timeLine.map(item => {
if (Cesium.JulianDate.greaterThan(item, params.stopTime)) {
item = Cesium.JulianDate.addSeconds(
item,
params.stopTime,
new Cesium.JulianDate()
)
}
return item
})
}
this._sampledPosition = new Cesium.SampledPositionProperty()
this._sampledPosition.addSamples(
this._timeLine,
Transform.transformWGS84ArrayToCartesianArray(this._positions)
)
this._sampledPosition.forwardExtrapolationType =
Cesium.ExtrapolationType.HOLD
this._sampledPosition.setInterpolationOptions({
interpolationDegree: 5,
interpolationAlgorithm: Cesium.HermitePolynomialApproximation
})
this._delegate.orientation = new Cesium.VelocityOrientationProperty(
this._sampledPosition
)
this._endTime = this._timeLine[this._timeLine.length - 1]
}

/**
* Adds Position
* @param position
* @param duration
* @returns {Track}
*/
addPosition(position, duration) {
this._positions.push(Parse.parsePosition(position))
this._duration += duration
this._resetTimeLine()
return this
}

/**
* Sets model
* @param modelPath
* @param style
* @returns {Track}
*/
setModel(modelPath, style) {
this._delegate.model = {
...style,
uri: modelPath,
heightReference: this._options.clampToGround
? Cesium.HeightReference.CLAMP_TO_GROUND
: Cesium.HeightReference.NONE
}
return this
}

/**
* Sets billboard
* @param icon
* @param style
* @returns {Track}
*/
setBillboard(icon, style) {
this._delegate.billboard = {
...style,
image: icon,
heightReference: this._options.clampToGround
? Cesium.HeightReference.CLAMP_TO_GROUND
: Cesium.HeightReference.NONE
}
return this
}

/**
* Sets label
* @param text
* @param style
* @returns {Track}
*/
setLabel(text, style) {
this._delegate.label = {
...style,
text: text,
heightReference: this._options.clampToGround
? Cesium.HeightReference.CLAMP_TO_GROUND
: Cesium.HeightReference.NONE
}
return this
}

setPath() {}
}

export default Track

+ 223
- 0
modules/history-track/TrackController.js 查看文件

@@ -0,0 +1,223 @@
/**
* @Author: Caven
* @Date: 2020-04-01 10:36:36
*/

import { Cesium } from '@dc-modules/namespace'
import { SceneEventType, TrackEventType } from '@dc-modules/event'
import TrackViewMode from './TrackViewMode'

class TrackController {
constructor(viewer) {
this._viewer = viewer
this._cache = {}
this._delegete = new Cesium.CustomDataSource('history-track-layer')
viewer.dataSources.add(this._delegete)
this._activedTrack = undefined
this._viewMode = undefined
this._viewOption = {}
this._stopTime = undefined
}

get delegate() {
return this._delegete.entities
}

/**
* @private
*/
_onPostRender() {
Object.keys(this._cache).forEach(key => {
let track = this._cache[key]
track.trackEvent &&
track.trackEvent.fire(TrackEventType.POST_RENDER, {
viewer: this._viewer,
viewOption: this._viewOption
})
})
this._viewer.scene.requestRender()
}

/**
*
* @param track
* @returns {TrackController}
*/
addTrack(track) {
if (
track &&
track.trackEvent &&
!this._cache.hasOwnProperty(track.trackId)
) {
track.trackEvent.fire(TrackEventType.ADD, this)
this._cache[track.trackId] = track
}
return this
}

/**
*
* @param tracks
* @returns {TrackController}
*/
addTracks(tracks) {
if (Array.isArray(tracks)) {
tracks.forEach(item => {
this.addTrack(item)
})
}
return this
}

/**
* Returns a track
* @param id
* @returns {*|undefined}
*/
getTrack(id) {
let filters = this.getTracks().filter(item => item.id === id)
return filters && filters.length ? filters[0] : undefined
}

/**
* Removes a track
* @param track
* @returns {TrackController}
*/
removeTrack(track) {
if (
track &&
track.trackEvent &&
this._cache.hasOwnProperty(track.trackId)
) {
track.trackEvent.fire(TrackEventType.REMOVE, this)
delete this._cache[track.trackId]
}
return this
}

/**
*
* @returns {*[]}
*/
getTracks() {
let result = []
Object.keys(this._cache).forEach(key => {
result.push(this._cache[key])
})
return result
}

/**
* Starts play all path
* @returns {TrackController}
*/
play() {
let now = Cesium.JulianDate.now()
Object.keys(this._cache).forEach(key => {
let track = this._cache[key]
track.startTime = now
track.viewed = false
})
this._activedTrack = undefined
this._stopTime = undefined
this._viewer.off(SceneEventType.POST_RENDER, this._onPostRender, this)
this._viewer.on(SceneEventType.POST_RENDER, this._onPostRender, this)
return this
}

/**
*
*/
pause() {
this._stopTime = Cesium.JulianDate.now()
this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._viewer.delegate.trackedEntity = undefined
this._viewer.off(SceneEventType.POST_RENDER, this._onPostRender, this)
return this
}

/**
*
*/
restore() {
if (this._stopTime) {
let now = Cesium.JulianDate.now()
Object.keys(this._cache).forEach(key => {
let track = this._cache[key]
track.trackEvent.fire(TrackEventType.RESET_TIME_LINE, {
stopTime: this._stopTime,
duration: Cesium.JulianDate.secondsDifference(this._stopTime, now)
})
})
}
this._viewer.off(SceneEventType.POST_RENDER, this._onPostRender, this)
this._viewer.on(SceneEventType.POST_RENDER, this._onPostRender, this)
return this
}

/**
*
* @param speed
* @returns {TrackController}
*/
changeSpeed(speed) {
this._viewer.clock.multiplier = speed
return this
}

/**
*
* @param track
* @param viewOption
* @returns {TrackController}
*/
viewTrack(track, viewOption = {}) {
if (!this._cache.hasOwnProperty(track.trackId)) {
throw new Error('TrackController: track does not added ')
}
this._viewOption = viewOption
if (this._activedTrack) {
this._activedTrack.viewed = false
}
track.viewed = true
this._activedTrack = track
if (viewOption.mode === TrackViewMode.FREE) {
this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._viewer.delegate.trackedEntity = undefined
}
return this
}

/**
*
* @param track
* @returns {TrackController}
*/
releaseTrack(track) {
if (!this._cache.hasOwnProperty(track.trackId)) {
throw new Error('TrackController: track does not added ')
}
if (track.viewed) {
track.viewed = false
}
this._activedTrack = undefined
this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._viewer.delegate.trackedEntity = undefined
return this
}

/**
*
* @returns {TrackController}
*/
clear() {
this._cache = {}
this._activedTrack && (this._activedTrack.viewed = false)
this._activedTrack = undefined
this._viewer.off(SceneEventType.POST_RENDER, this._onPostRender, this)
return this
}
}

export default TrackController

modules/roaming/RoamingViewMode.js → modules/history-track/TrackViewMode.js 查看文件

@@ -3,11 +3,11 @@
* @Date: 2020-08-05 10:51:13
*/

const RoamingViewMode = {
const TrackViewMode = {
FP: '1',
TP: '2',
TRACKED: 'track',
TRACKED: 'tracked',
FREE: 'free'
}

export default RoamingViewMode
export default TrackViewMode

+ 8
- 0
modules/history-track/index.js 查看文件

@@ -0,0 +1,8 @@
/**
* @Author: Caven
* @Date: 2020-04-13 09:32:31
*/

export { default as TrackController } from './TrackController'
export { default as Track } from './Track'
export { default as TrackViewMode } from './TrackViewMode'

+ 18
- 6
packages/core/src/components.js 查看文件

@@ -155,11 +155,17 @@ import {
*
* roaming
*/
import { RoamingController, RoamingPath } from '@dc-modules/roaming'

/**
*
* history-track
*/
import {
RoamingViewMode,
RoamingPath,
RoamingController
} from '@dc-modules/roaming'
TrackController,
Track,
TrackViewMode
} from '@dc-modules/history-track'

/**
*
@@ -337,9 +343,15 @@ const components = {
*
* roaming
*/
RoamingViewMode,
RoamingPath,
RoamingController,
RoamingPath,
/**
*
* track
*/
TrackController,
Track,
TrackViewMode,
/**
* weather
*/

正在加载...
取消
保存