大屏BIM增加GIS功能

dev_xd
lj7788@126.com 2025-07-26 15:21:53 +08:00
parent 55c5ed4cbc
commit 46222fa681
6 changed files with 274 additions and 52 deletions

View File

@ -1,3 +1,5 @@
import bimTools from "./bimTools";
const options = {
taskMapping: {
progress: "percent",
@ -192,6 +194,7 @@ function initEngine(that) {
showAxes: true, // 是否显示XYZ轴线
};
bim4DApi.Plugin.initNavCube(mapOptions);
bimTools.initBimGis(that, bim4DApi)
}
);
}
@ -231,6 +234,7 @@ function initLoadModel(that) {
item.gis = JSON.parse(item.gisJson);
addModel(that, item.lightweightName);
});
bimTools.initLoadModel(that, bim4DApi)
}
});
}

View File

@ -0,0 +1,94 @@
function initBimCfg(that) {
if (!that.bimCfg) {
that.bimCfg = {}
}
if (!that.hideParts) {
that.hideParts = [];
}
let config = that.$tryToJson(that.selProject?.bimConfig, {})
that.bimCfg.background = config.background || ''
that.bimCfg.showGis = config.showGis || false
that.bimCfg.clientApi = config.clientApi || false
}
function initBimGis(that, api) {
if (that.bimCfg.showGis) {
api.Public.setGisState(true);
api.Public.setTerrainState(false, "http://113.201.2.107:9304/layer.json", false)
api.Public.setGisState(true);
} else if (that.bimCfg.background) {
api.Public.setGisState(false, that.bimCfg.background);
}
}
function initLoadModel(that, api) {
let fnInit = () => {
if (api.m_model.size > 0) {
setTimeout(() => {
initModelPosition(that, api)
}, 1000)
} else {
setTimeout(fnInit, 1000);
}
}
fnInit();
}
function initModelPosition(that, api) {
that.models.forEach(modelInfo => {
if (modelInfo) {
let modelId = modelInfo.lightweightName
let cfg = that.$tryToJson(modelInfo.bimConfig, {});
let x = cfg?.x || 0;
let y = cfg?.y || 0;
let z = cfg?.z || 0;
let rotateZ = cfg?.rotateZ || 0;
if (x * 1 + y * 1 + z * 1 != 0) {
console.log("移动模型", modelId, x, y, z)
api.Model.moveToPosition([x, y, z], 0, modelId)
}
if (rotateZ * 1 != 0) {
api.Model.rotate(0, 0, rotateZ, modelId)
}
if (cfg && cfg.hideParts) {
cfg.hideParts.forEach(it => {
that.hideParts.push(it);
})
}
setTimeout(() => {
api.Model.location(modelId);
setTimeout(() => {
that.resetScene();
}, 1000);
}, 1000);
}
initHideParts(that, api)
});
}
function initHideParts(that, api) {
let hideCnt = 0;
let hideFn = () => {
hideCnt++;
if (hideCnt > 30) {
return;
}
setTimeout(() => {
let featureIds = (that.hideParts || []).map(it => it.featureId);
if (featureIds.length > 0) {
api.Feature.setVisible(featureIds.join("#"), false);
}
hideFn();
}, 100)
};
hideFn();
}
export default {
initBimCfg,
initBimGis,
initLoadModel,
initModelPosition,
initHideParts
}

View File

@ -73,6 +73,7 @@ import debounce from "lodash.debounce";
import ganttElastic from "gantt-elastic";
import ganttHeader from "gantt-elastic-header";
import bim4DTools from "./bim/bim4DTools";
import bimTools from "./bim/bimTools";
export default {
components: {
@ -167,6 +168,7 @@ export default {
},
initEngine() {
this.elId++;
bimTools.initBimCfg(this);
setTimeout(() => {
bim4DTools.initEngine(this);
}, 10);

View File

@ -12,19 +12,10 @@
模型结构树
</div>
<div class="model-tree scroll">
<el-tree
:key="treeKey"
ref="tree"
:default-expanded-keys="treeExpendedKeys"
:props="{
<el-tree :key="treeKey" ref="tree" :default-expanded-keys="treeExpendedKeys" :props="{
children: 'children',
label: 'title',
}"
node-key="key"
@check="onCheckTree"
:load="loadNode"
lazy
show-checkbox></el-tree>
}" node-key="key" @check="onCheckTree" :load="loadNode" lazy show-checkbox></el-tree>
</div>
</div>
</div>
@ -119,7 +110,8 @@
<div class="hide-item-state">{{ item.show ? "隐藏" : "显示" }}</div>
<el-switch v-model="item.show" @change="changeSwitch(item)"></el-switch>
<div class="hide-item-id">{{ item.id }}</div>
<div class="hide-item-delete"><i class="el-icon-delete command" @click="deleteFeature(item)" /></div>
<div class="hide-item-delete"><i class="el-icon-delete command" @click="deleteFeature(item)" />
</div>
</div>
</div>
</template>
@ -227,6 +219,8 @@ import debounce from "lodash.debounce";
import { MergeArray, DelArray } from "@/utils/tools";
import briefingTools from "./bim/briefingTools";
import SvgIcon from "@/components/SvgIcon.vue";
import BimTools from './bim/bimTools'
import bimTools from "./bim/bimTools";
export default {
components: { SvgIcon },
name: "BimBriefing",
@ -513,6 +507,7 @@ export default {
this.viewPoint = [];
this.info = [];
this.attributeInformation = "";
bimTools.initBimCfg(this);
setTimeout(() => {
this.loadEngine();
}, 10);
@ -566,6 +561,7 @@ export default {
showAxes: true, // XYZ线
};
bimBriefingApi.Plugin.initNavCube(mapOptions);
bimTools.initBimGis(this, bimBriefingApi)
}
);
},
@ -608,6 +604,7 @@ export default {
}, 3000);
});
this.treeKey++;
bimTools.initLoadModel(this, bimBriefingApi)
}
});
this.init();
@ -715,30 +712,37 @@ export default {
.bim-briefing {
height: 100%;
position: relative;
#bimBriefing {
height: 100%;
#bimBriefingContainer {
height: 100%;
}
}
.div-left {
top: 10vh;
left: 5%;
position: absolute;
height: 70vh;
width: 14%;
&.isHide {
left: 0%;
wdith: 0%;
#arrowLeft {
left: 0px !important;
}
}
#arrowLeft {
top: calc(50% - 50px);
right: -21px;
left: unset !important;
}
.div-row {
height: 100%;
}
@ -750,45 +754,56 @@ export default {
position: absolute;
height: 70vh;
width: 14%;
&.isHide {
right: 0%;
width: 0%;
}
#arrowRight {
top: calc(50% - 50px);
left: -21px;
}
.div-row {
&.r33 {
height: 180px;
}
&.r66 {
height: calc(100% - 180px);
}
&.r100 {
height: 100%;
}
}
.clear-all-btn {
margin: 10px;
}
.hide-list {
height: calc(100% - 60px);
overflow-y: auto;
padding: 0px 10px;
.hide-item {
font-size: 12px;
display: flex;
margin-bottom: 8px;
align-items: center;
.hide-item-state {
color: #e4e7edcc;
}
.hide-item-id {
flex-grow: 1;
margin: 0px 10px;
color: #22d3f4;
}
.hide-item-delete {
font-size: 20px;
color: #48f800;
@ -799,14 +814,17 @@ export default {
.data-content {
height: 100%;
.div-row {
border: solid 1px #75fbfdaa;
background-color: #06445b81;
.row-title {
background: linear-gradient(0deg, #105696, #c0dafb00, #1765ae);
padding-left: 10px;
height: 36px;
line-height: 36px;
.svg-icon {
fill: #75fbfd;
}
@ -822,23 +840,28 @@ export default {
display: flex;
background: #00000080;
border-radius: 10px;
.tool-item {
display: flex;
flex-flow: column;
padding: 10px;
align-items: center;
cursor: pointer;
&.is-selected {
.icon {
background: #097fca94;
.svg-icon {
fill: #75fbfd;
}
}
.sp-text {
color: #75fbfd;
}
}
.icon {
width: 30px;
height: 30px;
@ -847,11 +870,13 @@ export default {
justify-content: center;
align-items: center;
border-radius: 15px;
.svg-icon {
width: 20px;
height: 20px;
}
}
.sp-text {
margin-top: 4px;
font-size: 12px;
@ -862,21 +887,26 @@ export default {
.model-tree {
height: calc(100% - 36px);
overflow-y: auto;
.el-tree {
background: transparent;
color: #eee;
.el-checkbox {
color: #45fdfe;
}
.el-tree-node {
&:focus {
&>.el-tree-node__content {
background: #3489d966;
&:hover {
background: #3489d966;
}
}
}
.el-tree-node__content:hover {
background: #3489d966;
}
@ -888,19 +918,24 @@ export default {
height: calc(100% - 46px);
overflow-y: auto;
padding-bottom: 10px;
.model-property-nav {
text-align: left;
margin: 8px;
}
.model-property-list {
padding: 0px 10px;
}
.info-list {
padding: 10px;
}
}
.model-progress {
padding: 10px;
.el-progress-bar {
.el-progress-bar__innerText {
color: #fff !important;
@ -915,17 +950,22 @@ export default {
text-align: center;
color: #edffff85;
}
.group-info {
padding: 4px 0px;
.svg-icon {
fill: #45fdfe;
}
span {
font-size: 14px;
}
}
.my-table {
border-collapse: collapse;
td,
th {
border: solid 1px #0e0f0f88;
@ -934,19 +974,23 @@ export default {
font-size: 12px;
text-align: left;
}
th {
color: #22d3f4;
}
}
@media (min-width: 2561px) {
.data-content {
.div-row {
&.r33 {
height: 210px;
}
&.r66 {
height: calc(100% - 210px);
}
.row-title {
height: 48px;
line-height: 48px;
@ -954,36 +998,45 @@ export default {
}
}
}
.div-right {
.clear-all-btn {
font-size: 20px;
margin: 12px;
}
.hide-list {
height: calc(100% - 80px);
.hide-item {
font-size: 20px;
margin-bottom: 12px;
.hide-item-delete {
font-size: 24px;
}
}
}
}
.div-tools {
margin-left: -300px;
border-radius: 10px;
.tool-item {
padding: 10px 20px;
.icon {
width: 60px;
height: 60px;
border-radius: 30px;
.svg-icon {
width: 40px;
height: 40px;
}
}
.sp-text {
margin-top: 10px;
font-size: 24px;
@ -994,18 +1047,23 @@ export default {
.model-tree {
.el-tree {
font-size: 24px;
.el-tree-node__content {
height: 36px;
}
.el-tree-node__expand-icon {
font-size: 24px;
}
.el-checkbox {
font-size: 24px;
}
.el-tree-node__label {
font-size: 24px;
}
.el-tree__empty-text {
font-size: 24px;
}
@ -1017,6 +1075,7 @@ export default {
width: 30px;
height: 30px;
}
span {
font-size: 20px;
position: relative;
@ -1025,6 +1084,7 @@ export default {
}
.my-table {
td,
th {
font-size: 20px;

View File

@ -393,7 +393,7 @@ export default {
showGis: false,
clientApi: false,
},
hideParts: []
hideParts: [],//
};
},
beforeDestroy() {

View File

@ -12,20 +12,11 @@
模型结构树
</div>
<div class="model-tree scroll">
<el-tree
:key="treeKey"
ref="tree"
:default-expanded-keys="treeExpendedKeys"
:props="{
<el-tree :key="treeKey" ref="tree" :default-expanded-keys="treeExpendedKeys" :props="{
children: 'children',
label: 'title',
isLeaf: 'leaf',
}"
node-key="key"
@check="onCheckTree"
:load="loadNode"
lazy
show-checkbox></el-tree>
}" node-key="key" @check="onCheckTree" :load="loadNode" lazy show-checkbox></el-tree>
</div>
</div>
</div>
@ -43,7 +34,8 @@
</div>
<div class="roaming-list scroll">
<div v-if="roamingLoading" class="loading"></div>
<div v-for="(item, index) in roamingList" :key="index" :class="{ 'is-selected': item.play != 0 }" class="roaming-item">
<div v-for="(item, index) in roamingList" :key="index" :class="{ 'is-selected': item.play != 0 }"
class="roaming-item">
<el-tooltip :content="item.name">
<span class="roam-text">{{ item.name }}</span>
</el-tooltip>
@ -72,7 +64,9 @@
</div>
<div class="view-point-list scroll">
<div v-if="viewPointLoading" class="loading"></div>
<div v-for="(item, index) in viewpointList" :key="index" :class="{ 'is-selected': selectedViewpoint == item }" class="viewpoint-item" @click="ZoomViewpoint(item)">
<div v-for="(item, index) in viewpointList" :key="index"
:class="{ 'is-selected': selectedViewpoint == item }" class="viewpoint-item"
@click="ZoomViewpoint(item)">
<div class="viewpoint-content">
<el-image :src="item.imgPath" alt class="viewpoint-image" fit="scale-down" />
<el-tooltip :content="item.remark" v-if="item.remark">
@ -102,6 +96,7 @@
<script>
import debounce from "lodash.debounce";
import { MergeArray, DelArray } from "@/utils/tools";
import bimTools from './bim/bimTools'
export default {
name: "BIMRoaming",
data() {
@ -377,8 +372,12 @@ export default {
initEngine() {
this.elId++;
this.activeMenu = 0;
bimTools.initBimCfg(this);
setTimeout(() => {
if (this.bimCfg.clientApi) {
} else {
this.loadEngine();
}
}, 10);
},
loadEngine() {
@ -430,6 +429,7 @@ export default {
showAxes: true, // XYZ线
};
bimRoadmApi.Plugin.initNavCube(mapOptions);
bimTools.initBimGis(this, bimRoadmApi)
}
);
},
@ -471,6 +471,9 @@ export default {
}, 3000);
});
this.treeKey++;
bimTools.initLoadModel(this, bimRoadmApi)
}
});
this.init();
@ -621,8 +624,10 @@ export default {
.bim-roaming {
height: 100%;
position: relative;
#bimRoaming {
height: 100%;
#bimRoamingContainer {
height: 100%;
}
@ -634,40 +639,49 @@ export default {
position: absolute;
height: 70vh;
width: 14%;
&.isHide {
left: 0%;
wdith: 0%;
#arrowLeft {
left: 0px !important;
}
}
#arrowLeft {
top: calc(50% - 50px);
right: -21px;
left: unset !important;
}
.div-row {
height: 100%;
}
}
.div-right {
top: 10vh;
right: 5%;
position: absolute;
height: 70vh;
width: 14%;
&.isHide {
right: 0%;
width: 0%;
}
#arrowRight {
top: calc(50% - 50px);
left: -21px;
}
.div-row {
&.r33 {
height: 33.33%;
}
&.r66 {
height: 66.66%;
}
@ -676,14 +690,17 @@ export default {
.data-content {
height: 100%;
.div-row {
border: solid 1px #75fbfdaa;
background-color: #06445b81;
.row-title {
background: linear-gradient(0deg, #105696, #c0dafb00, #1765ae);
padding-left: 10px;
height: 36px;
line-height: 36px;
.svg-icon {
fill: #75fbfd;
}
@ -699,23 +716,28 @@ export default {
display: flex;
background: #00000080;
border-radius: 10px;
.tool-item {
display: flex;
flex-flow: column;
padding: 10px;
align-items: center;
cursor: pointer;
&.is-active {
.icon {
background: #097fca94;
.svg-icon {
fill: #75fbfd;
}
}
.sp-text {
color: #75fbfd;
}
}
.icon {
width: 30px;
height: 30px;
@ -724,61 +746,74 @@ export default {
justify-content: center;
align-items: center;
border-radius: 15px;
.svg-icon {
width: 20px;
height: 20px;
}
}
.sp-text {
margin-top: 4px;
font-size: 12px;
}
}
}
.model-tree {
height: calc(100% - 36px);
overflow-y: auto;
.el-tree {
background: transparent;
color: #eee;
.el-checkbox {
color: #75fbfd;
}
.el-tree-node {
&:focus {
&>.el-tree-node__content {
background: #3489d966;
&:hover {
background: #3489d966;
}
}
}
.el-tree-node__content:hover {
background: #3489d966;
}
}
}
}
.view-point-list {
height: calc(100% - 36px);
overflow-y: auto;
.viewpoint-item {
margin: 10px 10px 0px;
&.is-selected {
.viewpoint-content {
background: #3489d966;
border: solid 1px #75fbfd;
}
}
.viewpoint-content {
position: relative;
border-radius: 4px;
background: #ffffff2e;
.el-image {
height: 120px;
width: 100%;
}
.viewpoint-title {
position: absolute;
bottom: 0px;
@ -796,9 +831,11 @@ export default {
}
}
}
.roaming-list {
height: calc(100% - 36px);
overflow-y: auto;
.roaming-item {
display: flex;
flex-flow: row;
@ -809,9 +846,11 @@ export default {
padding: 0px 10px;
font-size: 14px;
position: relative;
&.is-selected {
background: #00aaff;
}
.roam-text {
color: #fff;
flex-grow: 1;
@ -819,10 +858,12 @@ export default {
overflow: hidden;
text-overflow: ellipsis;
}
.roam-tool {
margin-left: 10px;
display: flex;
align-items: center;
.svg-icon {
margin-right: 5px;
fill: #75fbfd;
@ -830,6 +871,7 @@ export default {
}
}
}
.loading {
height: 50px;
margin: 10px;
@ -838,12 +880,13 @@ export default {
color: #edffff85;
}
@media (max-width: 1920px) {
}
@media (max-width: 1920px) {}
@media (min-width: 2561px) {
.data-content {
.div-row {
min-height: 420px;
.row-title {
height: 48px;
line-height: 48px;
@ -851,20 +894,25 @@ export default {
}
}
}
.div-tools {
margin-left: -68px;
border-radius: 10px;
.tool-item {
padding: 10px 20px;
.icon {
width: 60px;
height: 60px;
border-radius: 30px;
.svg-icon {
width: 40px;
height: 40px;
}
}
.sp-text {
margin-top: 10px;
font-size: 24px;
@ -875,23 +923,29 @@ export default {
.model-tree {
.el-tree {
font-size: 24px;
.el-tree-node__content {
height: 36px;
}
.el-tree-node__expand-icon {
font-size: 24px;
}
.el-checkbox {
font-size: 24px;
}
.el-tree-node__label {
font-size: 24px;
}
.el-tree__empty-text {
font-size: 24px;
}
}
}
.view-point-list {
height: calc(100% - 48px);
@ -900,10 +954,12 @@ export default {
.viewpoint-content {
border-radius: 4px;
.el-image {
height: 160px;
width: 100%;
}
.viewpoint-title {
width: calc(100% - 10px);
line-height: 30px;
@ -915,20 +971,25 @@ export default {
}
}
}
.roaming-list {
height: calc(100% - 48px);
.roaming-item {
margin: 10px;
line-height: 48px;
border-radius: 10px;
padding: 0px 10px;
font-size: 14px;
.roam-text {
max-width: calc(100% - 40px);
font-size: 24px;
}
.roam-tool {
margin-left: 10px;
.svg-icon {
margin-right: 5px;
width: 24px;
@ -937,6 +998,7 @@ export default {
}
}
}
.loading {
font-size: 24px;
}