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 = '查询' 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 = '清除路线' 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