Files
sdk4.0/src/Obj/Base/RoutePlanning/index.js
2025-07-03 13:54:01 +08:00

702 lines
22 KiB
JavaScript

import { getHost } from '../../../on'
import Base from '../index'
import Dialog from '../../../BaseDialog'
import MouseEvent from '../../../Event/index'
import MouseTip from '../../../MouseTip'
import { html, css } from './_element'
class RoutePlanning extends Base {
/**
* @constructor
* @param sdk
* @description 路径规划
* */
constructor(sdk, options = {}, _Dialog = {}) {
super(sdk, options)
YJ.RoutePlanningArrays.push(this)
this.options.width = options.width || 4
this.options.color = options.color || '#ff0000'
this.options.gps = options.gps || false
this.Dialog = _Dialog
this._elms = {}
this.start = {
lng: null,
lat: null
}
this.end = {
lng: null,
lat: null
}
this.init()
}
init() {
this.startEntity = this.sdk.viewer.entities.getOrCreateEntity(
'YJ-route-planning-start'
)
if (
this.start &&
(this.start.lng || this.start.lng === 0) &&
(this.start.lat || this.start.lat === 0)
) {
this.startEntity.show = true
} else {
this.startEntity.show = false
}
this.startEntity.position = new Cesium.CallbackProperty(() => {
let pos = this.sdk.viewer.scene.clampToHeight(
new Cesium.Cartesian3.fromDegrees(this.startLng, this.startLat)
)
return pos
}, false)
this.startEntity.billboard = {
image: this.getSourceRootPath() + '/img/start.png',
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
width: 32,
height: 32
}
this.endEntity = this.sdk.viewer.entities.getOrCreateEntity(
'YJ-route-planning-end'
)
if (
this.end &&
(this.end.lng || this.end.lng === 0) &&
(this.end.lat || this.end.lat === 0)
) {
this.endEntity.show = true
} else {
this.endEntity.show = false
}
this.endEntity.position = new Cesium.CallbackProperty(() => {
let pos = this.sdk.viewer.scene.clampToHeight(
new Cesium.Cartesian3.fromDegrees(this.endLng, this.endLat)
)
return pos
}, false)
this.endEntity.billboard = {
image: this.getSourceRootPath() + '/img/end.png',
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
width: 32,
height: 32
}
this.edit(true)
this.clear()
}
get startLng() {
return this.start.lng
}
set startLng(v) {
this.start.lng = v
if (
this.start &&
(this.start.lng || this.start.lng === 0) &&
(this.start.lat || this.start.lat === 0)
) {
this.startEntity && (this.startEntity.show = true)
} else {
this.startEntity && (this.startEntity.show = false)
}
this._elms.startLng &&
this._elms.startLng.forEach(item => {
item.value = v
})
}
get startLat() {
return this.start.lat
}
set startLat(v) {
this.start.lat = v
if (
this.start &&
(this.start.lng || this.start.lng === 0) &&
(this.start.lat || this.start.lat === 0)
) {
this.startEntity && (this.startEntity.show = true)
} else {
this.startEntity && (this.startEntity.show = false)
}
this._elms.startLat &&
this._elms.startLat.forEach(item => {
item.value = v
})
}
get endLng() {
return this.end.lng
}
set endLng(v) {
this.end.lng = v
if (
this.end &&
(this.end.lng || this.end.lng === 0) &&
(this.end.lat || this.end.lat === 0)
) {
this.endEntity && (this.endEntity.show = true)
} else {
this.endEntity && (this.endEntity.show = false)
}
this._elms.endLng &&
this._elms.endLng.forEach(item => {
item.value = v
})
}
get endLat() {
return this.end.lat
}
set endLat(v) {
this.end.lat = v
if (
this.end &&
(this.end.lng || this.end.lng === 0) &&
(this.end.lat || this.end.lat === 0)
) {
this.endEntity && (this.endEntity.show = true)
} else {
this.endEntity && (this.endEntity.show = false)
}
this._elms.endLat &&
this._elms.endLat.forEach(item => {
item.value = v
})
}
async edit(state) {
let _this = this
this.originalOptions = this.deepCopyObj(this.options)
this._element_style = null
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
if (state) {
this._element_style = document.createElement('style')
this._element_style.type = 'text/css'
this._element_style.setAttribute('data-name', 'YJ_style_dialog')
this._element_style.innerHTML = css()
this._DialogObject = await new Dialog(this.sdk.viewer._container, {
title: '路径规划',
closeCallBack: () => {
this.tip && this.tip.destroy()
this.event && this.event.destroy()
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
}
})
await this._DialogObject.init()
let div = document.createElement('div')
div.style.position = 'absolute'
div.style.left = '24px'
div.style.flet = '0'
div.style.display = 'flex'
this._DialogObject.footAppChild(div)
let queryBtn = document.createElement('button')
queryBtn.className = 'default'
queryBtn.innerHTML =
'<svg class="icon-query"><use xlink:href="#yj-icon-query"></use></svg>查询'
queryBtn.style.width = 'auto'
queryBtn.addEventListener('click', () => {
if (
(this.startLng || this.startLng === 0) &&
(this.startLat || this.startLat === 0) &&
(this.endLng || this.endLng === 0) &&
(this.endLat || this.endLat === 0)
) {
!this.startEntity &&
(this.startEntity = this.viewer.entities.add(
new Cesium.Entity({
position: new Cesium.CallbackProperty(() => {
let pos = this.sdk.viewer.scene.clampToHeight(
new Cesium.Cartesian3.fromDegrees(this.startLng, this.startLat)
)
return pos
}, false),
billboard: {
image: this.getSourceRootPath() + '/img/start.png',
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
width: 32,
height: 32
}
})
))
this.startEntity.show = true
!this.endEntity &&
(this.endEntity = this.viewer.entities.add(
new Cesium.Entity({
position: new Cesium.CallbackProperty(() => {
let pos = this.sdk.viewer.scene.clampToHeight(
new Cesium.Cartesian3.fromDegrees(this.endLng, this.endLat)
)
return pos
}, false),
billboard: {
image: this.getSourceRootPath() + '/img/end.png',
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
width: 32,
height: 32
}
})
))
this.endEntity.show = true
this.Dialog.queryCallBack &&
this.Dialog.queryCallBack({
start: [this.startLng, this.startLat],
end: [this.endLng, this.endLat]
})
} else {
console.error('请先设置起点和终点坐标!')
}
})
div.appendChild(queryBtn)
let cleanBtn = document.createElement('button')
cleanBtn.className = 'default'
cleanBtn.innerHTML =
'<svg class="icon-route"><use xlink:href="#yj-icon-route"></use></svg>清除路线'
cleanBtn.style.width = 'auto'
cleanBtn.style.marginLeft = '10px'
cleanBtn.addEventListener('click', () => {
this.clear()
})
div.appendChild(cleanBtn)
document.getElementsByTagName('head')[0].appendChild(this._element_style)
let contentElm = document.createElement('div')
contentElm.innerHTML = html()
this._DialogObject.contentAppChild(contentElm)
if (this.options.gps) {
let locateCurrentBtn = document.createElement('button')
locateCurrentBtn.innerHTML = '当前位置'
locateCurrentBtn.style.marginLeft = '10px'
locateCurrentBtn.setAttribute('data-is', 'start')
locateCurrentBtn.addEventListener('click', e => {
this.getLocateCurrent(e)
})
let startColElm = contentElm.getElementsByClassName('start-col')[0]
startColElm.appendChild(locateCurrentBtn)
let endPickBtnElm = this._DialogObject._element.body.getElementsByClassName(
'end-pick-btn'
)[0]
endPickBtnElm.style.marginRight = '91px'
}
let all_elm = contentElm.getElementsByTagName('*')
RoutePlanning.EventBinding(this, all_elm)
} else {
if (this._element_style) {
document
.getElementsByTagName('head')[0]
.removeChild(this._element_style)
this._element_style = null
}
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
}
}
clear() {
if (this.startEntity) {
this.sdk.viewer.entities.remove(this.startEntity)
this.startEntity = null
}
if (this.endEntity) {
this.sdk.viewer.entities.remove(this.endEntity)
this.endEntity = null
}
if (this.entity) {
this.sdk.viewer.entities.remove(this.entity)
this.entity = null
}
if (this.startExtensionEntity) {
this.sdk.viewer.entities.remove(this.startExtensionEntity)
this.startExtensionEntity = null
}
if (this.endExtensionEntity) {
this.sdk.viewer.entities.remove(this.endExtensionEntity)
this.endExtensionEntity = null
}
}
destroy() {
this.clear()
if (this._DialogObject && this._DialogObject.close) {
this._DialogObject.close()
this._DialogObject = null
}
}
getLocateCurrent(e) {
this.reconnecting && this.reconnecting.close()
this.options.host = this.options.host || getHost()
let url = ''
url = this.options.host + '/yjearth4.0/api/v1/gps/state'
this.reconnecting = new ReconnectingWebSocket('ws://' + url)
this.reconnecting.onopen = event => {
this.reconnecting.onmessage = event => {
this.data = JSON.parse(event.data)
if (this.data && this.data.rmc) {
this.reconnecting.close()
if (e.srcElement.getAttribute('data-is') === 'start') {
this.startLng = this.data.rmc.lng
this.startLat = this.data.rmc.lat
!this.startEntity &&
(this.startEntity = this.viewer.entities.add(
new Cesium.Entity({
position: new Cesium.CallbackProperty(() => {
let pos = this.sdk.viewer.scene.clampToHeight(
new Cesium.Cartesian3.fromDegrees(
this.startLng,
this.startLat
)
)
return pos
}, false),
billboard: {
image: this.getSourceRootPath() + '/img/start.png',
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
width: 32,
height: 32
}
})
))
this.startEntity.show = true
} else {
this.endLng = this.data.rmc.lng
this.endLat = this.data.rmc.lat
!this.endEntity &&
(this.endEntity = this.viewer.entities.add(
new Cesium.Entity({
position: new Cesium.CallbackProperty(() => {
let pos = this.sdk.viewer.scene.clampToHeight(
new Cesium.Cartesian3.fromDegrees(
this.endLng,
this.endLat
)
)
return pos
}, false),
billboard: {
image: this.getSourceRootPath() + '/img/end.png',
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
width: 32,
height: 32
}
})
))
this.endEntity.show = true
}
}
}
}
}
/**
* 绘制路径
*/
createRoute(positions) {
let fromDegreesArray = []
for (let i = 0; i < positions.length; i++) {
fromDegreesArray.push(positions[i].lng, positions[i].lat)
}
if (
(this.startLng || this.startLng === 0) &&
(this.startLat || this.startLat === 0) &&
(this.startLng !== positions[0].lng || this.startLat !== positions[0].lat)
) {
this.startExtension = [
this.startLng,
this.startLat,
positions[0].lng,
positions[0].lat
]
if (this.startExtensionEntity) {
this.startExtensionEntity.polyline.positions = Cesium.Cartesian3.fromDegreesArray(
this.startExtension
)
} else {
this.startExtensionEntity = this.sdk.viewer.entities.add({
show: this.options.show,
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray(this.startExtension),
width: this.options.width,
clampToGround: true,
material: this.getMaterial(this.options.color, 2),
zIndex: 99999999
}
})
}
}
if (
(this.endLng || this.endLng === 0) &&
(this.endLat || this.endLat === 0) &&
(this.endLng !== positions[positions.length - 1].lng ||
this.endLat !== positions[positions.length - 1].lat)
) {
this.endExtension = [
this.endLng,
this.endLat,
positions[positions.length - 1].lng,
positions[positions.length - 1].lat
]
if (this.endExtensionEntity) {
this.endExtensionEntity.polyline.positions = Cesium.Cartesian3.fromDegreesArray(
this.endExtension
)
} else {
this.endExtensionEntity = this.sdk.viewer.entities.add({
show: this.options.show,
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray(this.endExtension),
width: this.options.width,
clampToGround: true,
material: this.getMaterial(this.options.color, 2),
zIndex: 99999999
}
})
}
}
if (this.entity) {
this.entity.polyline.positions = Cesium.Cartesian3.fromDegreesArray(
fromDegreesArray
)
} else {
this.entity = this.sdk.viewer.entities.add({
show: this.options.show,
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray(fromDegreesArray),
width: this.options.width,
clampToGround: true,
material: this.getMaterial(this.options.color, 0),
zIndex: 99999999
}
})
}
}
/**
* 拾取起点
*/
pickStartPos(e) {
this.tip && this.tip.destroy()
this.event && this.event.destroy()
this.tip = new MouseTip('左键选择起点坐标,右键取消', this.sdk)
this.event = new MouseEvent(this.sdk)
this.event.mouse_move((movement, cartesian) => {
this.tip.setPosition(
cartesian,
movement.endPosition.x,
movement.endPosition.y
)
})
let leftEvent = (movement, cartesian) => {
let pos84 = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.startLng = pos84.lng
this.startLat = pos84.lat
!this.startEntity &&
(this.startEntity = this.viewer.entities.add(
new Cesium.Entity({
position: new Cesium.CallbackProperty(() => {
let pos = this.sdk.viewer.scene.clampToHeight(
new Cesium.Cartesian3.fromDegrees(this.startLng, this.startLat)
)
return pos
}, false),
billboard: {
image: this.getSourceRootPath() + '/img/start.png',
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
width: 32,
height: 32
}
})
))
this.startEntity.show = true
this.tip && this.tip.destroy()
this.event && this.event.destroy()
}
this.event.mouse_left(leftEvent)
this.event.mouse_right((movement, cartesian) => {
this.tip && this.tip.destroy()
this.event && this.event.destroy()
})
this.event.gesture_pinck_start((movement, cartesian) => {
let startTime = new Date()
let pos = {
position: {
x: (movement.position1.x + movement.position2.x) / 2,
y: (movement.position1.y + movement.position2.y) / 2
}
}
this.event.gesture_pinck_end(() => {
let endTime = new Date()
if (endTime - startTime >= 500) {
// 长按取消
this.tip && this.tip.destroy()
this.event && this.event.destroy()
} else {
leftEvent(pos, cartesian)
}
})
})
}
/**
* 拾取终点
*/
pickEndPos(e) {
this.tip && this.tip.destroy()
this.event && this.event.destroy()
this.tip = new MouseTip('左键选择终点坐标,右键取消', this.sdk)
this.event = new MouseEvent(this.sdk)
this.event.mouse_move((movement, cartesian) => {
this.tip.setPosition(
cartesian,
movement.endPosition.x,
movement.endPosition.y
)
})
this.event.mouse_left((movement, cartesian) => {
let pos84 = this.cartesian3Towgs84(cartesian, this.sdk.viewer)
this.endLng = pos84.lng
this.endLat = pos84.lat
!this.endEntity &&
(this.endEntity = this.viewer.entities.add(
new Cesium.Entity({
position: new Cesium.CallbackProperty(() => {
let pos = this.sdk.viewer.scene.clampToHeight(
new Cesium.Cartesian3.fromDegrees(this.endLng, this.endLat)
)
return pos
}, false),
billboard: {
image: this.getSourceRootPath() + '/img/end.png',
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
width: 32,
height: 32
}
})
))
this.endEntity.show = true
this.tip && this.tip.destroy()
this.event && this.event.destroy()
})
this.event.mouse_right((movement, cartesian) => {
this.tip && this.tip.destroy()
this.event && this.event.destroy()
})
}
static EventBinding(that, elements) {
for (let i = 0; i < elements.length; i++) {
let Event = []
let isEvent = false
let removeName = []
if (!elements[i] || !elements[i].attributes) {
continue
}
for (let m of elements[i].attributes) {
switch (m.name) {
case '@model': {
isEvent = true
if (elements[i].type == 'checkbox') {
Event.push(e => {
that[m.value] = e.target.checked
})
elements[i].checked = that[m.value]
} else {
Event.push(e => {
let value = e.target.value
if (e.target.type == 'number') {
if (e.data != '.' && (e.data != '-' || e.target.value)) {
value = Number(value)
if (e.target.max && value > Number(e.target.max)) {
value = Number(e.target.max)
}
if (e.target.min && value < Number(e.target.min)) {
value = Number(e.target.min)
}
that[m.value] = value
}
} else {
that[m.value] = value
}
})
if (elements[i].nodeName == 'IMG') {
elements[i].src = that[m.value]
} else {
elements[i].value = that[m.value]
}
}
if (that._elms[m.value]) {
that._elms[m.value].push(elements[i])
} else {
that._elms[m.value] = [elements[i]]
}
removeName.push(m.name)
break
}
case '@click': {
elements[i].addEventListener('click', e => {
if (typeof that[m.value] === 'function') {
that[m.value](e)
}
})
removeName.push(m.name)
// elements[i].attributes.removeNamedItem(m.name)
break
}
case '@change': {
isEvent = true
Event.push(e => {
let value = e.target.value
if (e.target.type == 'number' && value != '') {
value = Number(value)
e.target.value = value
}
if (typeof that[m.value] === 'function') {
that[m.value](e, value)
}
})
break
}
}
// elements[i].attributes[m] = undefined
}
for (let n = 0; n < removeName.length; n++) {
elements[i].attributes.removeNamedItem(removeName[n])
}
if (isEvent) {
let ventType = 'input'
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
ventType = 'change'
}
elements[i].addEventListener(ventType, e => {
for (let t = 0; t < Event.length; t++) {
Event[t](e)
}
})
}
}
}
flicker() {}
}
export default RoutePlanning