|
@@ -0,0 +1,367 @@
|
|
|
+<template>
|
|
|
+ <div class="main-content" ref="content">
|
|
|
+ <div id="cesiumContainer" class="Container"></div>
|
|
|
+ <div class="TitleCtrl"></div>
|
|
|
+ <div class="header">
|
|
|
+ <div class="title-container">
|
|
|
+ <span class="title-content">
|
|
|
+ <span class="title">Smart City</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="btns-container">
|
|
|
+ <span class="btns-divider">|</span>
|
|
|
+ <a-dropdown :getPopupContainer="() => $refs.content">
|
|
|
+ <div class="btn">Model List</div>
|
|
|
+ <a-menu slot="overlay">
|
|
|
+ <a-menu-item v-for="modelItem in modelList" :key="modelItem.lightweightName">
|
|
|
+ <a href="javascript:;" @click="locationModel(modelItem.lightweightName)">{{ modelItem.name }}</a>
|
|
|
+ </a-menu-item>
|
|
|
+ </a-menu>
|
|
|
+ </a-dropdown>
|
|
|
+ <span class="btns-divider">|</span>
|
|
|
+ <div class="btn">Model View</div>
|
|
|
+ <span class="btns-divider">|</span>
|
|
|
+ <div @click="modalControl('ESG')" :class="['btn', showModule === 'ESG' ? 'activeMenu' : '']">ESG</div>
|
|
|
+ <span class="btns-divider">|</span>
|
|
|
+ <div
|
|
|
+ @click="modalControl('CarbonAndEnergy')"
|
|
|
+ :class="['btn', showModule === 'CarbonAndEnergy' ? 'activeMenu' : '']"
|
|
|
+ >
|
|
|
+ Carbon & Energy Management
|
|
|
+ </div>
|
|
|
+ <span class="btns-divider">|</span>
|
|
|
+ <div @click="modalControl('IAQ')" :class="['btn', showModule === 'IAQ' ? 'activeMenu' : '']">
|
|
|
+ IAQ Management
|
|
|
+ </div>
|
|
|
+ <span class="btns-divider">|</span>
|
|
|
+ <div
|
|
|
+ @click="modalControl('ThermalComfort')"
|
|
|
+ :class="['btn', showModule === 'ThermalComfort' ? 'activeMenu' : '']"
|
|
|
+ >
|
|
|
+ Thermal Comfort Management
|
|
|
+ </div>
|
|
|
+ <div class="date-container">
|
|
|
+ <div class="time">{{ time.hours }}:{{ time.minute }}:{{ time.second }}</div>
|
|
|
+ <div class="date">{{ time.year }}-{{ time.month }}-{{ time.day }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="ESG" v-if="showModule === 'ESG'"><ESG :showModule.sync="showModule" /></div>
|
|
|
+ <div class="ThermalComfort" v-if="showModule === 'ThermalComfort'">
|
|
|
+ <ThermalComfort :showModule.sync="showModule" />
|
|
|
+ </div>
|
|
|
+ <div class="IAQ" v-if="showModule === 'IAQ'"><IAQ :showModule.sync="showModule" /></div>
|
|
|
+ <div class="CarbonAndEnergy" v-if="showModule === 'CarbonAndEnergy'">
|
|
|
+ <CarbonAndEnergy :showModule.sync="showModule" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { loadModelScript } from '@/utils/util.js'
|
|
|
+import ESG from './ESG'
|
|
|
+import CarbonAndEnergy from './CarbonAndEnergy'
|
|
|
+import IAQ from './IAQ'
|
|
|
+import ThermalComfort from './ThermalComfort'
|
|
|
+export default {
|
|
|
+ components: { ESG, CarbonAndEnergy, IAQ, ThermalComfort },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ modelList: [], //模型列表
|
|
|
+ showModule: null,
|
|
|
+ time: {
|
|
|
+ year: '0',
|
|
|
+ month: '0',
|
|
|
+ day: '0',
|
|
|
+ hours: '0',
|
|
|
+ minute: '0',
|
|
|
+ second: '0',
|
|
|
+ },
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async mounted() {
|
|
|
+ await this.loadModelScript()
|
|
|
+ let data = localStorage.getItem(this.$route.query.id)
|
|
|
+ let list = JSON.parse(data)
|
|
|
+ this.modelList = list
|
|
|
+ this.$store.commit('SET_VIEWSINGLEMODEL', this.modelList)
|
|
|
+ this.$store.commit('SET_MAINMODELMSG', this.modelList[0])
|
|
|
+ this.InitScene()
|
|
|
+ this.getDate()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ loadModelScript,
|
|
|
+ async InitScene() {
|
|
|
+ const copyDefaults = JSON.parse(JSON.stringify(this.$store.state.model.defaults))
|
|
|
+ copyDefaults.openterrain = true
|
|
|
+ copyDefaults.openearth = true
|
|
|
+ copyDefaults.secretkey = this.$store.state.model.mainModelMsg.stationToken
|
|
|
+ this.$store.commit('SET_DEFAULTS', copyDefaults)
|
|
|
+
|
|
|
+ window.api = new window.API(this.$store.state.model.defaults) //api对象后面调用接口要全程使用,控制好作用域
|
|
|
+ window.api.Public.setSceneRenderState(false) //实时渲染
|
|
|
+ this.startTime = new Date()
|
|
|
+ await this.addModel([...this.modelList])
|
|
|
+ window.api.Model.offset(100, 100, 100, '5580063043121581866')
|
|
|
+ },
|
|
|
+ addModel(data) {
|
|
|
+ let that = this
|
|
|
+ if (data.length == 0) {
|
|
|
+ if (this.addNum == this.modelList.length) {
|
|
|
+ this.loadingCompleted = true
|
|
|
+ }
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var modelInfo = data.shift()
|
|
|
+ if (modelInfo.modelType == 'gis' && (modelInfo.fileOwnership == 'dom' || modelInfo.fileOwnership == 'dem')) {
|
|
|
+ fetch(data.modelAccessAddress + '/' + data.lightweightName + '.json')
|
|
|
+ .then((response) => response.json())
|
|
|
+ .then((jsonData) => {
|
|
|
+ if (data.fileOwnership == 'dem') {
|
|
|
+ window.api.Public.setTerrainState(true, data.modelAccessAddress)
|
|
|
+ var rectangle = new window.Cesium.Rectangle.fromDegrees(
|
|
|
+ jsonData.rectangle[0],
|
|
|
+ jsonData.rectangle[1],
|
|
|
+ jsonData.rectangle[2],
|
|
|
+ jsonData.rectangle[3]
|
|
|
+ )
|
|
|
+ window.api.viewer.camera.flyTo({
|
|
|
+ destination: rectangle,
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ window.api.Public.addImageryProvider(data.modelAccessAddress, false, {
|
|
|
+ serverType: 1,
|
|
|
+ rectangle: jsonData.rectangle_radians,
|
|
|
+ maximumLevel: jsonData.maxzoom,
|
|
|
+ flyto: true,
|
|
|
+ id: 'image' + data.lightweightName,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ this.addNum++
|
|
|
+ this.addModel(data)
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ // 处理错误
|
|
|
+ console.error(error)
|
|
|
+ })
|
|
|
+ } else if (modelInfo.modelType == 'cad') {
|
|
|
+ let that = this
|
|
|
+ window.api.Cad.Drawing.load(modelInfo.modelAccessAddress, modelInfo.lightweightName, {
|
|
|
+ flyto: true, //是否飞到图纸跟前
|
|
|
+ visualRange: 100000,
|
|
|
+ isShow3DDrawing: that.modelList.length > 1 ? true : false, // 是否以3D模式渲染,默认false (2D)
|
|
|
+ readyFunc: (res) => {
|
|
|
+ console.log('模型开始加载 回调:', res)
|
|
|
+ },
|
|
|
+ loadedFunc: (tag, obj) => {
|
|
|
+ that.addNum++
|
|
|
+ that.addModel(data)
|
|
|
+ console.log('loadedFunc 回调:', tag, obj)
|
|
|
+ },
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ window.api.Model.mergeModel(
|
|
|
+ modelInfo.modelAccessAddress,
|
|
|
+ modelInfo.lightweightName,
|
|
|
+ (res) => {},
|
|
|
+ (res) => {
|
|
|
+ that.addNum++
|
|
|
+ //平移
|
|
|
+ window.api.Model.offset(13, -5, -9, modelInfo.lightweightName)
|
|
|
+ //旋转
|
|
|
+ let modelCenterRotate = window.api.Model.getCenter(modelInfo.lightweightName).position
|
|
|
+ var point2 = [modelCenterRotate[0], modelCenterRotate[1], modelCenterRotate[2] + 0.00000001]
|
|
|
+ var options = {
|
|
|
+ tags: [modelInfo.lightweightName],
|
|
|
+ rotate: -30,
|
|
|
+ point1: modelCenterRotate,
|
|
|
+ point2: point2,
|
|
|
+ type: 0,
|
|
|
+ }
|
|
|
+ window.api.Model.rotateByAnyAxis(options)
|
|
|
+ that.addModel(data)
|
|
|
+ },
|
|
|
+ {
|
|
|
+ flyto: true,
|
|
|
+ osgbEdit: true,
|
|
|
+ maxspaceerror: 0.5,
|
|
|
+ matrix: 'matrix' in modelInfo ? computed(() => Objects(modelInfo.matrix)) : undefined,
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ modalControl(key) {
|
|
|
+ this.showModule = this.showModule === key ? null : key
|
|
|
+ },
|
|
|
+ locationModel(modelId) {
|
|
|
+ window.api.Model.location(modelId)
|
|
|
+ },
|
|
|
+ getDate() {
|
|
|
+ this.timer = setInterval(() => {
|
|
|
+ const date = new Date()
|
|
|
+ this.time.year = date.getFullYear().toString()
|
|
|
+ this.time.month = date.getMonth().toString()
|
|
|
+ this.time.day = date.getDate().toString()
|
|
|
+ this.time.hours = date.getHours().toString().padStart(2, '0')
|
|
|
+ this.time.minute = date.getMinutes().toString().padStart(2, '0')
|
|
|
+ this.time.second = date.getSeconds().toString().padStart(2, '0')
|
|
|
+ }, 1000)
|
|
|
+ },
|
|
|
+ },
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style scoped lang="less">
|
|
|
+/deep/ .ant-dropdown-menu {
|
|
|
+ background: rgba(58, 68, 87, 0.6);
|
|
|
+ .ant-dropdown-menu-item > a {
|
|
|
+ color: #e6e8fa;
|
|
|
+ &:hover {
|
|
|
+ color: #409eff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .ant-dropdown-menu-item:hover {
|
|
|
+ cursor: pointer;
|
|
|
+ background: rgba(0, 0, 0, 0.6);
|
|
|
+ box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.main-content {
|
|
|
+ height: 100vh;
|
|
|
+ width: 100vw;
|
|
|
+ position: relative;
|
|
|
+ .Container {
|
|
|
+ height: 100vh;
|
|
|
+ width: 100vw;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.TitleCtrl {
|
|
|
+ position: absolute;
|
|
|
+ top: 0vh;
|
|
|
+ width: 100vw;
|
|
|
+ height: 10vh;
|
|
|
+ background: linear-gradient(to bottom, rgb(9, 21, 20), rgb(9, 21, 45) 60%, rgba(13, 23, 43, 0));
|
|
|
+}
|
|
|
+
|
|
|
+.header {
|
|
|
+ position: absolute;
|
|
|
+ top: 1vh;
|
|
|
+ left: 1vw;
|
|
|
+ width: 99vw;
|
|
|
+ display: flex;
|
|
|
+ color: #fff;
|
|
|
+ .title-container {
|
|
|
+ background: url(~@/assets/img/smartCity/title.png) no-repeat left top;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ height: 56px;
|
|
|
+ width: 300px;
|
|
|
+
|
|
|
+ .title-content {
|
|
|
+ margin: 0 0 0 40px;
|
|
|
+ height: 75%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ .title {
|
|
|
+ margin-left: 20px;
|
|
|
+ font-size: 24px;
|
|
|
+ color: #fff;
|
|
|
+ text-shadow: 0 0 10px #409eff, 0 0 20px #409eff, 0 0 30px #409eff, 0 0 40px #409eff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .btns-container {
|
|
|
+ flex: 1;
|
|
|
+ height: 56px;
|
|
|
+ font-size: 16px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ position: relative;
|
|
|
+ background: url(~@/assets/img/smartCity/boder.gif) no-repeat left top;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ .btns-divider {
|
|
|
+ margin: 0 15px;
|
|
|
+ color: #e6e8fa88;
|
|
|
+ }
|
|
|
+ .btn {
|
|
|
+ background: rgba(58, 68, 87, 0.6);
|
|
|
+ padding: 4px 16px;
|
|
|
+ border-radius: 4px;
|
|
|
+ transform: scale(1);
|
|
|
+ transition: transform 0.3s ease;
|
|
|
+ &:hover {
|
|
|
+ background: #1a3f66;
|
|
|
+ text-shadow: 0 0 5px #265f99, 0 0 5px #265f99, 0 0 5px #265f99, 0 0 5px #265f99;
|
|
|
+ cursor: pointer;
|
|
|
+ transform: scale(1.05);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .activeMenu {
|
|
|
+ background: #1a3f66 ;
|
|
|
+ text-shadow: 0 0 5px #265f99, 0 0 5px #265f99, 0 0 5px #265f99, 0 0 5px #265f99;
|
|
|
+ transform: scale(1.05) ;
|
|
|
+ }
|
|
|
+ .date-container {
|
|
|
+ position: absolute;
|
|
|
+ right: 25px;
|
|
|
+ width: 150px;
|
|
|
+ height: 56px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-items: center;
|
|
|
+ .time {
|
|
|
+ font-size: 24px;
|
|
|
+ font-family: 'DS-Digital' !important;
|
|
|
+ }
|
|
|
+ .date {
|
|
|
+ font-size: 14px;
|
|
|
+ position: relative;
|
|
|
+ top: -8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+.ESG {
|
|
|
+ position: absolute;
|
|
|
+ top: 15vh;
|
|
|
+ right: 1vw;
|
|
|
+ height: 60vh;
|
|
|
+ width: 23vw;
|
|
|
+ background: rgba(9, 21, 45, 0.5);
|
|
|
+ border-radius: 5px;
|
|
|
+ z-index: 1;
|
|
|
+}
|
|
|
+.ThermalComfort {
|
|
|
+ position: absolute;
|
|
|
+ top: 15vh;
|
|
|
+ right: 1vw;
|
|
|
+ height: 50vh;
|
|
|
+ width: 23vw;
|
|
|
+ background: rgba(9, 21, 45, 0.5);
|
|
|
+ border-radius: 5px;
|
|
|
+ z-index: 1;
|
|
|
+}
|
|
|
+.IAQ {
|
|
|
+ position: absolute;
|
|
|
+ top: 15vh;
|
|
|
+ right: 1vw;
|
|
|
+ height: 60vh;
|
|
|
+ width: 23vw;
|
|
|
+ background: rgba(9, 21, 45, 0.5);
|
|
|
+ border-radius: 5px;
|
|
|
+ z-index: 1;
|
|
|
+}
|
|
|
+.CarbonAndEnergy {
|
|
|
+ position: absolute;
|
|
|
+ top: 15vh;
|
|
|
+ right: 1vw;
|
|
|
+ width: 23vw;
|
|
|
+ background: rgba(9, 21, 45, 0.5);
|
|
|
+ border-radius: 5px;
|
|
|
+ z-index: 1;
|
|
|
+}
|
|
|
+</style>
|