import { getHost, getToken } from "../../on"; class DTH { constructor(sdk, options = {}) { this.sdk = sdk this.primitives = { building: [], unit: [], dth: [] } this.options = { ...options } this.options.host = this.options.host || getHost() this.temporaryDth = [] this.dth = {} this.PickBuildingEvent = new Cesium.Event(); this.initEvents() this.activeBuilding } /** * @description 注册点击的事件回调 * @memberOf DTH * */ PickCallback(that, cb) { this.PickBuildingEvent.addEventListener( cb, that ) } //场景事件 initEvents() { new Cesium.ScreenSpaceEventHandler(this.sdk.viewer.scene.canvas).setInputAction(((e) => { if (YJ.Measure.GetMeasureStatus()) { return } if (!this.isActivate) return; let pickFeature = this.sdk.viewer.scene.pick(e.position); if (pickFeature) { //点击了已有的分户单体化 if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && (pickFeature.id.type == "yj-dth-dth" || pickFeature.id.type == "yj-dth-highlight")) { this.getIDBypickFeature(pickFeature); //处理点击到的楼层 return; } if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && pickFeature.id.type == "yj-dth-unit") { this.highlightPrimitive && this.sdk.viewer.scene.primitives.remove(this.highlightPrimitive) this.handlePickEvent(pickFeature.id) return; } // if (pickFeature.id && pickFeature.id.type === 'yj-dth-highlight') { // return; // } } this.highlightPrimitive && this.sdk.viewer.scene.primitives.remove(this.highlightPrimitive) let position = this.sdk.viewer.scene.pickPosition(e.position); //屏幕坐标转为笛卡尔空间坐标 if (!position) return; let c = Cesium.Cartographic.fromCartesian(position); //笛卡尔坐标转为经纬度(弧度) let point = [Cesium.Math.toDegrees(c.longitude), Cesium.Math.toDegrees(c.latitude)]; //转为经纬度点 this.queryByPoint(point, c.height); }), Cesium.ScreenSpaceEventType.LEFT_CLICK); let coverLabelEntity = this.sdk.viewer.entities.getOrCreateEntity('yj-dth-cover-label') coverLabelEntity.show = false // this.sdk.viewer.entities.add({ // position: Cesium.Cartesian3.fromDegrees(-75.1641667, 39.9522222), // label: { // text: "Philadelphia", // font: "24px Helvetica", // fillColor: Cesium.Color.SKYBLUE, // outlineColor: Cesium.Color.BLACK, // outlineWidth: 2, // style: Cesium.LabelStyle.FILL_AND_OUTLINE, // }, // }); let lastPickTime = 0; let _this = this let timeoutEvent new Cesium.ScreenSpaceEventHandler(this.sdk.viewer.scene.canvas).setInputAction(((movement) => { if (YJ.Measure.GetMeasureStatus()) { return } try { const now = Date.now(); if (now - lastPickTime < 100) { clearTimeout(timeoutEvent) timeoutEvent = setTimeout(() => { pick(movement) }, 100); return } clearTimeout(timeoutEvent) lastPickTime = now; pick(movement) } catch (error) { } }), Cesium.ScreenSpaceEventType.MOUSE_MOVE); function pick(e) { let pickFeature = _this.sdk.viewer.scene.pick(e.endPosition); if (pickFeature) { let labelText = '' if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && (pickFeature.id.type === "yj-dth-dth" || pickFeature.id.type === "yj-dth-highlight")) { labelText = pickFeature.id.build_info.name + ' - ' + pickFeature.id.unit_info.name + ' - ' + pickFeature.id.room_num } else if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && pickFeature.id.type === "yj-dth-unit") { if (pickFeature.id.build_info.name) { labelText = pickFeature.id.build_info.name + ' - ' + pickFeature.id.name } } else if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && pickFeature.id.type === "yj-dth-build") { if (pickFeature.id.name) { labelText = pickFeature.id.name } } else if (pickFeature.primitive && pickFeature.primitive.id && pickFeature.primitive.id.id && pickFeature.primitive.id.id === 'yj-dth-cover-label') { coverLabelEntity.position = _this.sdk.viewer.scene.pickPosition(e.endPosition) return } else { coverLabelEntity.show = false return } if (labelText) { coverLabelEntity.position = _this.sdk.viewer.scene.pickPosition(e.endPosition) coverLabelEntity.label = new Cesium.LabelGraphics({ text: labelText, font: "20px Helvetica", pixelOffset: { x: 0, y: -30 }, fillColor: Cesium.Color.fromCssColorString('#ffffff'), outlineColor: Cesium.Color.BLACK, outlineWidth: 1, showBackground: true, backgroundColor: Cesium.Color.fromCssColorString('#000000').withAlpha(0.8), style: Cesium.LabelStyle.FILL_AND_OUTLINE, disableDepthTestDistance: Number.POSITIVE_INFINITY, }) coverLabelEntity.show = true } } } } /*根据用户信息查询单体化*/ queryByUserInfo(data) { this.queryByPoint([data.position.lng, data.position.lat], data.position.alt, data.id) } //点查询 点击查询是查询分层的数据 async queryByPoint(point) { let url = "" if (this.options.host.endsWith("yjearth4.0")) { url = this.options.host + '/api/v1/dth/build/query_by_point' } else { url = this.options.host + '/yjearth4.0/api/v1/dth/build/query_by_point' } url += '?point=' + JSON.stringify({ 'lng': point[0], 'lat': point[1] }) let response = await fetch(url, { method: 'get', // body: JSON.stringify({point: {'lng': point[0],'lat': point[1]}}), headers: { 'Content-Type': 'application/json', "token": getToken(), "Authorization": "Bearer " + getToken(), } }) if (response.status === 200) { let data = await response.json() if (data.code === 200 || data.code === 0) { this.processQueryByPointResults(data.data) } else { window.ELEMENT && window.ELEMENT.Message({ message: data.msg || data.message, type: 'warning', duration: 1500 }); } } } // 处理查询结果 async processQueryByPointResults(data, isflyto, offset = { heading: 0.0, pitch: -90.0, roll: 0.0 }) { data.build_info && this.handlePickEvent(data) let range this.clearAllDthPrimitive() this.clearAllUnitPrimitive() if (this.activeBuilding) { this.clearBuildingPrimitive(this.activeBuilding) this.activeBuilding = null } if (data.build_info) { range = JSON.parse(data.build_info.range) if (data.dan_yuan.length > 0) { for (let i = 0; i < data.dan_yuan.length; i++) { if (data.dan_yuan[i].children.length > 0) { this.addDthPrimitive(data.dan_yuan[i].children, data.build_info, data.dan_yuan[i]) } else { this.addUnitPrimitive([data.dan_yuan[i]], data.build_info, data.dan_yuan[i]) } } } else { this.activeBuilding = data.build_info.ID || data.build_info.id this.addBuildingPrimitive([data.build_info]) } if (isflyto) { if (data.info && data.info.dan_yuan) { range = JSON.parse(data.info.dan_yuan.range) } if (data.info && data.info.hu) { range = JSON.parse(data.info.hu.range) for (let i = 0; i < range.length; i++) { range[i].alt = data.info.hu.bottom } for (let i = 0; i < this.primitives.dth.length; i++) { await this.primitives.dth[i].readyPromise let primitivesData = this.primitives.dth[i]._primitiveOptions.geometryInstances[0].id if (primitivesData.ID === data.info.hu.ID && primitivesData.room_num === data.info.hu.room_num) { let pickFeature = { id: { ...data.info.hu, build_info: { ...data.build_info }, unit_info: data.info.dan_yuan }, primitive: this.primitives.dth[i] } this.getIDBypickFeature(pickFeature) break } } } this.flyTo(range, offset) } } } // 添加房屋Primitive async addBuildingPrimitive(array) { for (let i = 0; i < array.length; i++) { let fromDegreesArray = [] let extrudedHeight = 0 let positions = JSON.parse(array[i].range) for (let m = 0; m < positions.length; m++) { if (extrudedHeight < positions[m].alt) { extrudedHeight = positions[m].alt } fromDegreesArray.push(positions[m].lng, positions[m].lat, 0) } let polygonGeometry = new Cesium.PolygonGeometry({ polygonHierarchy: new Cesium.PolygonHierarchy( Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray) ), // perPositionHeight: true, //使用z坐标 否则高度从0开始 extrudedHeight: 100000000, //拉伸高度 }); this.primitives.building.push(this.sdk.viewer.scene.primitives.add( new Cesium.ClassificationPrimitive({ geometryInstances: new Cesium.GeometryInstance({ id: { type: 'yj-dth-build', ...array[i], }, geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometry), attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor( Cesium.Color.fromCssColorString('rgb(255, 235, 59, 0.4)') ), show: new Cesium.ShowGeometryInstanceAttribute(true), } }), classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, }) )) } } // 根据id删除房屋Primitive clearBuildingPrimitive(id) { for (let i = this.primitives.building.length - 1; i >= 0; i--) { if (id === this.primitives.building[i]._primitiveOptions.geometryInstances[0].id.ID || id === this.primitives.building[i]._primitiveOptions.geometryInstances[0].id.id) { this.sdk.viewer.scene.primitives.remove(this.primitives.building[i]) this.primitives.building.splice(i, 1) break } } } // 删除全部房屋Primitive clearAllBuildingPrimitive() { for (let i = this.primitives.building.length - 1; i >= 0; i--) { this.sdk.viewer.scene.primitives.remove(this.primitives.building[i]) } this.primitives.building = [] } // 添加单元Primitive async addUnitPrimitive(array, build_info, unit_info) { for (let i = 0; i < array.length; i++) { let fromDegreesArray = [] let extrudedHeight = 0 let positions = JSON.parse(array[i].range) for (let m = 0; m < positions.length; m++) { if (extrudedHeight < positions[m].alt) { extrudedHeight = positions[m].alt } fromDegreesArray.push(positions[m].lng, positions[m].lat, 0) } let polygonGeometry = new Cesium.PolygonGeometry({ polygonHierarchy: new Cesium.PolygonHierarchy( Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray) ), // perPositionHeight: true, //使用z坐标 否则高度从0开始 extrudedHeight: 100000000, //拉伸高度 }); this.primitives.unit.push(this.sdk.viewer.scene.primitives.add( new Cesium.ClassificationPrimitive({ geometryInstances: new Cesium.GeometryInstance({ id: { type: 'yj-dth-unit', ...array[i], build_info: { ...build_info }, unit_info: { ...unit_info } }, geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometry), attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor( Cesium.Color.fromCssColorString('rgb(255, 235, 59, 0.4)') ), show: new Cesium.ShowGeometryInstanceAttribute(true), } }), classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, }) )) this.primitives.unit.push(this.sdk.viewer.scene.primitives.add( new Cesium.GroundPolylinePrimitive({ geometryInstances: new Cesium.GeometryInstance({ geometry: new Cesium.GroundPolylineGeometry({ positions: Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray), width: 2.0 }), attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString('#00ff0a').withAlpha(0.8)) }, }), appearance: new Cesium.PolylineColorAppearance() }) )) } } // 根据id删除单元Primitive clearUnitPrimitive(id) { for (let i = this.primitives.building.length - 1; i >= 0; i--) { if (id === this.primitives.building[i]._primitiveOptions.geometryInstances[0].id.ID || id === this.primitives.building[i]._primitiveOptions.geometryInstances[0].id.id) { this.sdk.viewer.scene.primitives.remove(this.primitives.unit[i]) this.primitives.unit.splice(i, 1) break } } } // 删除全部单元Primitive clearAllUnitPrimitive() { for (let i = this.primitives.unit.length - 1; i >= 0; i--) { this.sdk.viewer.scene.primitives.remove(this.primitives.unit[i]) } this.primitives.unit = [] } // 添加单体化Primitive addDthPrimitive(array, build_info, unit_info) { for (let i = 0; i < array.length; i++) { let positions = JSON.parse(array[i].range) let fromDegreesArray = [] for (let m = 0; m < positions.length; m++) { fromDegreesArray.push(positions[m].lng, positions[m].lat, array[i].bottom + 0.3) } let polygonGeometry = new Cesium.PolygonGeometry({ polygonHierarchy: new Cesium.PolygonHierarchy( Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray) ), perPositionHeight: true, //使用z坐标 否则高度从0开始 extrudedHeight: array[i].height + array[i].bottom, //拉伸高度 }); let polygonGeometryBorder = new Cesium.PolygonGeometry({ polygonHierarchy: new Cesium.PolygonHierarchy( Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray) ), perPositionHeight: true, //使用z坐标 否则高度从0开始 extrudedHeight: array[i].bottom, //拉伸高度 }); this.primitives.dth.push(this.sdk.viewer.scene.primitives.add( new Cesium.ClassificationPrimitive({ geometryInstances: new Cesium.GeometryInstance({ id: { type: 'yj-dth-dth', ...array[i], build_info: { ...build_info }, unit_info: { ...unit_info } }, geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometry), attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor( Cesium.Color.fromCssColorString('rgb(0, 64, 255, 0.4)') ), show: new Cesium.ShowGeometryInstanceAttribute(true), } }), classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, }) )); this.primitives.dth.push(this.sdk.viewer.scene.primitives.add( new Cesium.ClassificationPrimitive({ geometryInstances: new Cesium.GeometryInstance({ id: { type: 'yj-dth-dth-border', ...array[i], }, geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometryBorder), attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor( Cesium.Color.fromCssColorString('rgb(0, 0, 0, 1)') ), show: new Cesium.ShowGeometryInstanceAttribute(true), } }), classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, }) )); } } // 根据id删除单体化Primitive clearDthPrimitive(id) { for (let i = this.primitives.dth.length - 1; i >= 0; i--) { if (id === this.primitives.dth[i]._primitiveOptions.geometryInstances[0].id.ID || id === this.primitives.dth[i]._primitiveOptions.geometryInstances[0].id.id) { this.sdk.viewer.scene.primitives.remove(this.primitives.dth[i]) this.primitives.dth.splice(i, 1) } } } // 删除全部单体化Primitive clearAllDthPrimitive() { this.highlightPrimitive && this.sdk.viewer.scene.primitives.remove(this.highlightPrimitive) for (let i = this.primitives.dth.length - 1; i >= 0; i--) { this.sdk.viewer.scene.primitives.remove(this.primitives.dth[i]) } this.primitives.dth = [] } getIDBypickFeature(pickFeature) { //恢复上一个贴对象面显示 if (this.clickHighlightPrimitive) { this.clickHighlightPrimitive.show = true; } this.highlightPrimitive && this.sdk.viewer.scene.primitives.remove(this.highlightPrimitive) this.highlightPrimitive = this.sdk.viewer.scene.primitives.add( new Cesium.ClassificationPrimitive({ geometryInstances: new Cesium.GeometryInstance({ id: { ...pickFeature.id, type: 'yj-dth-highlight', }, geometry: pickFeature.primitive._primitiveOptions.geometryInstances[0].geometry, attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString('#ff9800').withAlpha(0.8)), show: new Cesium.ShowGeometryInstanceAttribute(true), } }), classificationType: Cesium.ClassificationType.CESIUM_3D_TILE, }) ) this.highlightPrimitive.readyPromise.then(() => { //设置当前点击的贴对象面不显示 pickFeature.primitive.show = false; }) this.clickHighlightPrimitive = pickFeature.primitive; let range = pickFeature.id.range if (typeof pickFeature.id.range === 'string') { range = JSON.parse(pickFeature.id.range) } this.getHilightArea(range) this.handlePickEvent(pickFeature.id) } //处理点击事件 handlePickEvent(id) { this.PickBuildingEvent.raiseEvent(id); //触发选中事件 通知界面更新 } getHilightArea(points, radius = 1) { let arr = [] points.forEach((point) => { arr.push([(point.lng), (point.lat)]) }) arr.push(arr[0]) var poly = turf.polygon([arr]) var buffered = turf.buffer(poly, Number(radius) / 1000) return buffered.geometry.coordinates } async flyTo(positions, offset = { heading: 0.0, pitch: -90.0, roll: 0.0 }) { let tools = new YJ.Tools(this.sdk) let height = 0 let positionArray = [] for (let i = 0; i < positions.length; i++) { if (positions[i].alt) { height = positions[i].alt } else { height = await tools.getClampToHeight(positions[i]) } let a = Cesium.Cartesian3.fromDegrees(positions[i].lng, positions[i].lat, height) positionArray.push(a.x, a.y, a.z) } let BoundingSphere = await Cesium.BoundingSphere.fromVertices(positionArray) this.sdk.viewer.camera.flyToBoundingSphere(BoundingSphere, { offset: { heading: Cesium.Math.toRadians(offset.heading || 0), pitch: Cesium.Math.toRadians((offset.pitch || offset.pitch === 0) ? offset.pitch : -90), roll: Cesium.Math.toRadians(offset.roll || 0) } }) } activate() { this.isActivate = true; } deactivate() { this.isActivate = false; } } export default DTH