浏览代码

Reconstruct the @dc-modules/roaming

tags/2.2.4
Caven Chen 4 年前
父节点
当前提交
171dc8d3d7
共有 4 个文件被更改,包括 177 次插入455 次删除
  1. 14
    0
      modules/roaming/KeyboardRoaming.js
  2. 62
    157
      modules/roaming/RoamingController.js
  3. 96
    295
      modules/roaming/RoamingPath.js
  4. 5
    3
      modules/roaming/index.js

+ 14
- 0
modules/roaming/KeyboardRoaming.js 查看文件

@@ -0,0 +1,14 @@
/**
* @Author: Caven
* @Date: 2021-06-08 20:41:51
*/

import { Cesium } from '@dc-modules/namespace'

class KeyboardRoaming {
constructor(viewer) {
this._viewer = viewer
}
}

export default KeyboardRoaming

+ 62
- 157
modules/roaming/RoamingController.js 查看文件

@@ -1,218 +1,128 @@
/**
* @Author: Caven
* @Date: 2020-04-01 10:36:36
* @Date: 2021-06-08 20:41:51
*/

import { Cesium } from '@dc-modules/namespace'
import { RoamingEventType } from '@dc-modules/event'
import { SceneEventType, PathEventType } from '@dc-modules/event'

class RoamingController {
constructor(viewer) {
this._viewer = viewer
this._roamingLayer = new Cesium.CustomDataSource('roaming-layer')
viewer.dataSources.add(this._roamingLayer)
this._postUpdateRemoveCallback = undefined
this._startTime = undefined
this._cache = {}
this._activePath = undefined
this._viewMode = undefined
this._viewOption = {}
}

get startTime() {
return this._startTime
}

get roamingLayer() {
return this._roamingLayer.entities
}

/**
* @private
*/
_onPostUpdate(scene, time) {
Object.keys(this._cache).forEach(key => {
let path = this._cache[key]
path.roamingEvent &&
path.roamingEvent.fire(RoamingEventType.POST_UPDATE, {
currentTime: time,
viewMode: this._viewMode,
viewOption: this._viewOption
})
})
this._cache = {}
this._activedPath = undefined
}

/**
*
* @returns {boolean}
* @private
*/
_addPostUpdateListener() {
this._postUpdateRemoveCallback && this._postUpdateRemoveCallback()
this._postUpdateRemoveCallback = this._viewer.scene.postUpdate.addEventListener(
this._onPostUpdate,
this
)
}

/**
* Sets time range
* @param startTime
* @returns {RoamingController}
*/
setStartTime(startTime) {
if (!startTime || !(startTime instanceof Date)) {
throw new Error('RoamingController: the start time invalid ')
_onPostRender() {
if (!this._activedPath) {
return false
}
this._startTime = Cesium.JulianDate.fromDate(startTime)
return this
}

/**
* Starts play all path
* @returns {RoamingController}
*/
play() {
this._viewer.clock.shouldAnimate = true
this._viewer.clock.currentTime = this._startTime || Cesium.JulianDate.now()
this._addPostUpdateListener()
return this
}

/**
*
*/
pause() {
this._viewer.clock.shouldAnimate = false
this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._viewer.delegate.trackedEntity = undefined
this._postUpdateRemoveCallback && this._postUpdateRemoveCallback()
this._postUpdateRemoveCallback = undefined
return this
this._activedPath.pathEvent &&
this._activedPath.pathEvent.fire(
PathEventType.POST_RENDER,
this._viewer,
this._viewOption
)
}

/**
*
* @param path
* @returns {RoamingController}
*/
restore() {
this._viewer.clock.shouldAnimate = true
this._postUpdateRemoveCallback && this._postUpdateRemoveCallback()
this._postUpdateRemoveCallback = this._viewer.scene.postUpdate.addEventListener(
this._onPostUpdate,
this
)
this._addPostUpdateListener()
addPath(path) {
if (path && !this._cache.hasOwnProperty(path.pathId)) {
path.pathEvent.fire(PathEventType.ADD)
this._cache[path.pathId] = path
}
return this
}

/**
*
* @param speed
* @param paths
* @returns {RoamingController}
*/
changeSpeed(speed) {
this._viewer.clock.multiplier = speed
addPaths(paths) {
if (Array.isArray(paths)) {
paths.forEach(item => {
this.addPath(item)
})
}
return this
}

/**
* Adds a path
*
* @param path
* @returns {RoamingController}
*/
addPath(path) {
if (
path &&
path.roamingEvent &&
!Object(this._cache).hasOwnProperty(path.id)
) {
path.roamingEvent.fire(RoamingEventType.ADD, this)
this._cache[path.id] = path
removePath(path) {
if (path && this._cache.hasOwnProperty(path.pathId)) {
delete this._cache[path.pathId]
path.pathEvent.fire(PathEventType.REMOVE)
}
return this
}

/**
* Returns a path
*
* @param id
* @returns {*|undefined}
*/
getPath(id) {
return this._cache[id] || undefined
}

/**
* removes a path
* @param path
* @returns {RoamingController}
*/
removePath(path) {
if (
path &&
Object(this._cache).hasOwnProperty(path.id) &&
path.roamingEvent
) {
path.roamingEvent.fire(RoamingEventType.REMOVE, this)
delete this._cache[path.id]
}
return this
let filters = this.getPaths().filter(item => item.id === id)
return filters && filters.length ? filters[0] : undefined
}

/**
*
* @returns {RoamingController}
* @returns {*[]}
*/
clearPath() {
getPaths() {
let result = []
Object.keys(this._cache).forEach(key => {
let path = this._cache[key]
path && this.removePath(path)
result.push(this._cache[key])
})
return this
return result
}

/**
*
* @param path
* @param viewMode
* @param viewOption
* @returns {RoamingController}
*/
trackedPath(path, viewMode, viewOption = {}) {
if (!this._cache[path.id]) {
throw new Error('RoamingController: path does not added ')
}
this._viewMode = viewMode
this._viewOption = viewOption
if (this._activePath && this._activePath.id === path.id) {
activate(path, viewOption = {}) {
if (
!path ||
path?.pathId === this._activedPath?.pathId ||
!this._cache.hasOwnProperty(path?.pathId)
) {
return this
}
if (this._activePath && this._activePath.roamingEvent) {
this._activePath.roamingEvent.fire(RoamingEventType.RELEASE, path.id)
}
this._activePath = path
if (this._activePath && this._activePath.roamingEvent) {
this._activePath.roamingEvent.fire(
RoamingEventType.ACTIVE,
this._activePath.id
)
}
this._viewOption = viewOption
this._activedPath && this.deactivate()
this._activedPath = path
this._activedPath.pathEvent &&
this._activedPath.pathEvent.fire(PathEventType.RESET_TIME_LINE)
this._viewer.on(SceneEventType.POST_RENDER, this._onPostRender, this)
return this
}

/**
*
* @param path
* @returns {RoamingController}
*/
releasePath(path) {
if (!this._cache[path.id]) {
throw new Error('RoamingController: path does not added ')
}
if (path && path.isActive && path.roamingEvent) {
path.roamingEvent.fire(RoamingEventType.RELEASE, path.id)
}
this._activePath = undefined
this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._viewer.delegate.trackedEntity = undefined
deactivate() {
this._activedPath && (this._activedPath.actived = false)
this._activedPath = undefined
this._viewer.off(SceneEventType.POST_RENDER, this._onPostRender, this)
return this
}

@@ -220,16 +130,11 @@ class RoamingController {
*
* @returns {RoamingController}
*/
releaseCamera() {
this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._viewer.delegate.trackedEntity = undefined
if (this._activePath && this._activePath.roamingEvent) {
this._activePath.roamingEvent.fire(
RoamingEventType.RELEASE,
this._activePath.id
)
}
this._activePath = undefined
clear() {
this._cache = {}
this._activedPath && (this._activedPath.actived = false)
this._activedPath = undefined
this._viewer.off(SceneEventType.POST_RENDER, this._onPostRender, this)
return this
}
}

+ 96
- 295
modules/roaming/RoamingPath.js 查看文件

@@ -1,73 +1,50 @@
/**
* @Author: Caven
* @Date: 2020-01-19 11:21:48
* @Date: 2021-06-08 20:41:51
*/

import { Cesium } from '@dc-modules/namespace'
import { RoamingEvent, RoamingEventType } from '@dc-modules/event'
import State from '@dc-modules/state/State'
import Parse from '@dc-modules/parse/Parse'
import { PathEventType, PathEvent } from '@dc-modules/event'
import { Util } from '@dc-modules/utils'
import { Transform } from '@dc-modules/transform'
import RoamingViewMode from './RoamingViewMode'

const DEF_OPTS = {
showPath: false,
pathWidth: 1,
pathMaterial: Cesium.Color.ORANGE.withAlpha(0.8),
pathLeadTime: 1
}
import { heading, distance } from '@dc-modules/math'

class RoamingPath {
constructor(id, duration, tickCallback, options) {
this._id = id || Util.uuid()
this._startTime = undefined
this._controller = undefined
this._duration = duration || 0
this._mode = 'speed'
this._delegate = new Cesium.Entity()
this._positions = []
this._sampledPosition = undefined
this._isActive = false
this._tickCallback = tickCallback
this._options = {
...DEF_OPTS,
...options
}
this._positionIndex = 0
constructor(positions, duration, pathMode) {
this._id = Util.uuid()
this._bid = undefined
this._positions = Parse.parsePositions(positions)
this._duration = duration || 20
this._pathMode = pathMode || 'speed'
this._timeLine = []
this._roamingEvent = new RoamingEvent()
this._roamingEvent.on(
RoamingEventType.POST_UPDATE,
this._onPostUpdate,
this
)
this._roamingEvent.on(RoamingEventType.ADD, this._onAdd, this)
this._roamingEvent.on(RoamingEventType.REMOVE, this._onRemove, this)
this._roamingEvent.on(RoamingEventType.ACTIVE, this._onActive, this)
this._roamingEvent.on(RoamingEventType.RELEASE, this._onRelease, this)
this._sampledPosition = undefined
this._actived = false
this._endTime = Cesium.JulianDate.now()
this._pathEvent = new PathEvent()
this._pathEvent.on(PathEventType.ADD, this._onAdd, this)
this._pathEvent.on(PathEventType.REMOVE, this._onRemove, this)
this._pathEvent.on(PathEventType.POST_RENDER, this._onPostRender, this)
this._pathEvent.on(PathEventType.RESET_TIME_LINE, this._resetTimeLine, this)
this._state = State.INITIALIZED
}

get id() {
get pathId() {
return this._id
}

get roamingEvent() {
return this._roamingEvent
}

get state() {
return this._state
set id(id) {
this._bid = id
return this
}

get isActive() {
return this._isActive
get id() {
return this._bid
}

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

@@ -75,194 +52,103 @@ class RoamingPath {
return this._positions
}

set startTime(startTime) {
if (!startTime || !(startTime instanceof Date)) {
throw new Error('Path: the start time invalid ')
}
this._startTime = Cesium.JulianDate.fromDate(startTime)
this._mountPosition()
set duration(duration) {
this._duration = duration
return this
}

get startTime() {
return this._startTime
get duration() {
return this._duration
}

/**
* add to entities
* @param controller
* @private
*/
_onAdd(controller) {
this._controller = controller
!this._startTime &&
(this._startTime = controller.startTime || Cesium.JulianDate.now())
this._mountPath()
!this._delegate.position && this._mountPosition()
this._mountedHook && this._mountedHook()
this._state = State.ADDED
set pathMode(pathMode) {
this._pathMode = pathMode
return this
}

/**
* remove from entities
* @private
*/
_onRemove() {
if (this._controller) {
this._controller.roamingLayer.remove(this._delegate)
this._isActive && this._controller.releaseCamera()
this._isActive = false
this._state = State.REMOVED
}
get pathMode() {
return this._pathMode
}

/**
* @param params
* @returns {boolean}
* @private
*/
_onPostUpdate(params) {
let currentTime = params.currentTime
let orientation = this._delegate.orientation.getValue(currentTime)
let timePos = this._timeLine[this._positionIndex]
if (timePos) {
let timeDiff = Cesium.JulianDate.secondsDifference(currentTime, timePos)
if (timeDiff >= 0 && timeDiff <= 1) {
let position = this._positions[this._positionIndex]
if (position && orientation) {
let mat = Cesium.Matrix3.fromQuaternion(orientation)
let mat4 = Cesium.Matrix4.fromRotationTranslation(
mat,
this._delegate.position.getValue(currentTime)
)
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._tickCallback &&
this._tickCallback(
position,
this._positionIndex + 1 === this._positions.length
)
this._positionIndex += 1
}
}
this._isActive &&
this._setCameraView(currentTime, params.viewMode, params.viewOption)
get pathEvent() {
return this._pathEvent
}

/**
* @private
*/
_onActive() {
this._isActive = true
set actived(actived) {
this._actived = actived
return this
}

/**
*
* @private
*/
_onRelease() {
this._isActive = false
get actived() {
return this._actived
}

get state() {
return this._state
}

_onAdd() {
this._state = State.ADDED
}

_onRemove() {
this._state = State.REMOVED
}

/**
* Sets camera position
* @param currentTime
* @param viewMode
*
* @param viewer
* @param viewOption
* @private
*/
_setCameraView(currentTime, viewMode, viewOption) {
let viewer = this._controller._viewer.delegate
let camera = this._controller._viewer.camera
let tickPosition = this._sampledPosition.getValue(currentTime)
let nextTickPosition = this._sampledPosition.getValue(
Cesium.JulianDate.addSeconds(currentTime, 1 / 60, new Cesium.JulianDate())
)
if (tickPosition && nextTickPosition && viewMode) {
if (viewMode === RoamingViewMode.TRACKED) {
viewer.trackedEntity = this._delegate
} else if (viewMode === RoamingViewMode.FP) {
let heading = Cesium.Math.heading(tickPosition, nextTickPosition)
let WGS84TickPosition = Transform.transformCartesianToWGS84(
tickPosition
)
if (!isNaN(viewOption.alt)) {
WGS84TickPosition.alt = viewOption.alt
}
camera.lookAt(
Transform.transformWGS84ToCartesian(WGS84TickPosition),
new Cesium.HeadingPitchRange(
heading,
Cesium.Math.toRadians(viewOption.pitch || 0),
viewOption.range || 10
)
)
} else if (viewMode === RoamingViewMode.TP) {
camera.lookAt(
tickPosition,
_onPostRender(viewer, viewOption) {
if (!this.actived) {
return false
}
let now = Cesium.JulianDate.now()
if (
Cesium.JulianDate.lessThan(now, this._endTime) &&
this._sampledPosition
) {
let p = this._sampledPosition.getValue(now)
let next_p = this._sampledPosition.getValue(
Cesium.JulianDate.addSeconds(now, 0.001, new Cesium.JulianDate())
)
if (p && next_p) {
viewer.camera.lookAt(
p,
new Cesium.HeadingPitchRange(
0,
Cesium.Math.toRadians(viewOption.pitch || -90),
viewOption.range || 1000
heading(p, next_p),
Cesium.Math.toRadians(viewOption?.pitch || -20),
viewOption?.range || 2000
)
)
}
} else {
camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
viewer.trackedEntity = undefined
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._actived = false
}
}

/**
* Mounts path
* @private
*/
_mountPath() {
if (this._options.showPath) {
this._delegate.availability = new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({
start: this._startTime,
stop: Cesium.JulianDate.addSeconds(
this._startTime,
this._duration,
new Cesium.JulianDate()
)
})
])
this._delegate.path = {
material: this._options.pathMaterial,
width: this._options.pathWidth,
leadTime: this._options.pathLeadTime
}
}
}

/**
* Mounts Position
*
* @private
*/
_mountPosition() {
if (
!this._startTime ||
!this._duration ||
!this._positions ||
!this._positions.length
) {
_resetTimeLine() {
if (!this._positions || !this._positions.length) {
return false
}
let now = Cesium.JulianDate.now()
let interval = 0
if (this._mode === 'speed') {
let v = Cesium.Math.distance(this._positions) / this._duration
this._timeLine = this._positions.map((item, index, arr) => {
let timeLine = []
if (this._pathMode === 'speed') {
let v = distance(this._positions) / this._duration
timeLine = this._positions.map((item, index, arr) => {
if (index !== 0) {
interval += Cesium.Math.distance([arr[index - 1], item]) / v
interval += distance([arr[index - 1], item]) / v
}
return Cesium.JulianDate.addSeconds(
this._startTime,
now,
interval,
new Cesium.JulianDate()
)
@@ -270,9 +156,9 @@ class RoamingPath {
} else {
let len = this._positions.length
let interval = (this._duration - (this._duration % len)) / len
this._timeLine = this._positions.map((item, index) => {
timeLine = this._positions.map((item, index) => {
return Cesium.JulianDate.addSeconds(
this._startTime,
now,
index * interval,
new Cesium.JulianDate()
)
@@ -280,102 +166,17 @@ class RoamingPath {
}
this._sampledPosition = new Cesium.SampledPositionProperty()
this._sampledPosition.addSamples(
this._timeLine,
timeLine,
Transform.transformWGS84ArrayToCartesianArray(this._positions)
)
this._delegate.position = this._sampledPosition
this._delegate.position.setInterpolationOptions({
interpolationDegree: 1,
interpolationAlgorithm: Cesium.LinearApproximation
this._sampledPosition.forwardExtrapolationType =
Cesium.ExtrapolationType.HOLD
this._sampledPosition.setInterpolationOptions({
interpolationDegree: 2,
interpolationAlgorithm: Cesium.HermitePolynomialApproximation
})
this._delegate.orientation = new Cesium.VelocityOrientationProperty(
this._sampledPosition
)
}

/**
* Mounted Hook
* @private
*/
_mountedHook() {
this._controller.roamingLayer.add(this._delegate)
}

/**
* Sets positions
* @param positions
* @returns {RoamingPath}
*/
setPositions(positions) {
this._positions = Parse.parsePositions(positions)
this._mountPosition()
return this
}

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

/**
* Sets mode
* @param mode
* @returns {RoamingPath}
*/
setMode(mode) {
this._mode = mode
this._mountPosition()
return this
}

/**
* Sets model
* @param modelPath
* @param style
* @returns {RoamingPath}
*/
setModel(modelPath, style) {
this._delegate.model = {
...style,
uri: modelPath
}
return this
}

/**
* Sets billboard
* @param icon
* @param style
* @returns {RoamingPath}
*/
setBillboard(icon, style) {
this._delegate.billboard = {
...style,
image: icon
}
return this
}

/**
* Sets label
* @param text
* @param style
* @returns {RoamingPath}
*/
setLabel(text, style) {
this._delegate.label = {
...style,
text: text
}
return this
this._endTime = timeLine[timeLine.length - 1]
this._actived = true
}
}


+ 5
- 3
modules/roaming/index.js 查看文件

@@ -1,8 +1,10 @@
/**
* @Author: Caven
* @Date: 2020-04-13 09:32:31
* @Date: 2021-06-08 20:41:51
*/

export { default as RoamingViewMode } from './RoamingViewMode'
export { default as RoamingPath } from './RoamingPath'
/**
* roaming
*/
export { default as RoamingController } from './RoamingController'
export { default as RoamingPath } from './RoamingPath'

正在加载...
取消
保存