PKPM BIMViewer的使用
模型的使用,目前有两个方案,
一个是使用全局组件,在单页面的主页面中进行嵌套
<template> <div id="model"> <!-- 这样的写的目的是为了销毁的干净 --> <div :id="obvContainer" :class="{is_show:!isShow}"> <div :id="obv"></div> </div> </div> </template>
一个是使用iframe使用外部网页的嵌入
<template> <!-- 模型的嵌入 --> <iframe id="view3d" :src="iframeSrc" width="100%" height="100%" frameborder="0" scrolling="none" class="showmodelIframe"></iframe> </template>
iframe实际上嵌套的是另一个网页
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <title>galp_igbom_web_product_Obv</title> <!--OBV4.0修改地址 样式文件--> <link href="https://api.cloud.pkpm.cn/bimviewer/viewer/v4/locale/locale.properties"
rel="resource" type="application/l10n" /> <link rel="stylesheet" href="https://api.cloud.pkpm.cn/bimviewer/viewer/v4/obv.css"
type="text/css" /> <!--obv 的 JS--> <script src="https://api.cloud.pkpm.cn/bimviewer/viewer/v4/obv.js"
type="text/javascript" charset="utf-8" ></script> <script src="./utils/common/common.js" charset="utf-8"></script> <script src="./utils/bimJs/BimShow.js" charset="utf-8"></script> <script src="./utils/bimJs/ObvApiWrapper.js" charset="utf-8"></script> <script> var mapGuid = {}; //var camera_position = ""; var camera_position = '{"position":{"x":146518.99887679535,"y":-165402.77170371916,"z":43010.86008260351},"target":{"x":32979.83428482477,"y":-55016.90462385754,"z":25436.756957522586},"up":{"x":-0.07908594642234183,"y":0.07688951033799524,"z":0.9938980914955344},"aspect":0.8879668049792531,"fov":53.13010235415598,"orthoScale":159326.80454922342,"isPerspective":false,"pivotPoint":{"x":44460.192437633596,"y":-74092.20639070861,"z":-380.5984779546852}}'; function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 var r = window.location.search.substr(1).match(reg); //匹配目标参数 if (r != null) return unescape(r[2]); return null; //返回参数值 } function getAccessToken(cb) { var token = getUrlParam("token"); var expires = getUrlParam("expires"); cb(token, expires); } window.onload = function() { var container = document.getElementById("viewer-div"); EPM.BIM.loadBIMModelByUrn(container, getAccessToken, function( build, viewer3dApi, application ) { var obvApiWrapper = new ObvApiWrapper( build, viewer3dApi, application ); window.obvApiWrapper = obvApiWrapper; console.log("iframes-window", window); window.parent.setObvApiWrapper(obvApiWrapper); var obv = obvApiWrapper.getObvApi(); /* 监听事件这边OBV4.0写法都改了:加载标注插件的写法也改了 监听几何信息是否加载完全*/ obv.addEventListener( OBV.ViewerEventTypes.GeometryLoadedEvent, function handelGeometryLoaded() { //根据视角,模型位置进行更新 if (camera_position) { var camera = JSON.parse(camera_position); var viewer = obv.getViewer(); new OBV.Controllers.Viewer3d.ViewController( viewer ).setViewFromCameraInfoSync(camera, true); } else { obv.fitToView(); } if (obv.isGeometryLoaded && obv.isPropertyLoaded) { obvApiWrapper.getMapGuid(function(res) { mapGuid = res; window.parent.setMapGuid(mapGuid); }); } } ); //监听属性是否加载完成 obv.addEventListener( OBV.ViewerEventTypes.ProperiesLoadedEvent, function handelGeometryLoaded() { if (obv.isGeometryLoaded && obv.isPropertyLoaded) { obvApiWrapper.getMapGuid(function(res) { mapGuid = res; window.parent.setMapGuid(mapGuid); }); } } ); //监听模型大小变化事件 obv.addEventListener( OBV.ViewerEventTypes.CameraChangeEvent, function() { // that.$emit("resizeEvent"); } ); //监听构件选中事件 obv.addEventListener( OBV.ViewerEventTypes.SelectionChangedEvent, function(e) { console.log("modelObjects", e.nodeIdArray); //that.modelObjects = e.nodeIdArray; //that.$emit("modelObjects", e.nodeIdArray); } ); //加载标注的插件 window.OBV["AddinLibLoader"] .loadBuiltInAddinLib("OBVAddins.Marker") .then(event => { //初始化加载标注成功之后,再进行监听事件 obvApiWrapper.getMarkerAddin(function() { obvApiWrapper.getMarkerAnnotationClickedEventListener(function( val ) { var obj = val; window.parent.setClickMarkEvent(obj); //that.$emit("clickMarkEvent", obj); }); obvApiWrapper.getMarkerSelectedEventListener(function(val) { var obj = val; window.parent.setClickMarkEvent(obj); // that.$emit("selectedMarkEvent", obj); }); }); }); //监听鼠标监听事件 obv.addEventListener(OBV.ViewerEventTypes.MouseClickedEvent, function( e ) { //that.$emit("eventPosition", e.position); }); }); }; </script> </head> <style> html { width: 100%; height: 100%; } body { width: 100%; height: 100%; } .customizing-view-div { position: relative; width: 100%; height: 100%; } </style> <body oncontextmenu="return false"> <div id="viewer-div" class="customizing-view-div"></div> </body> </html>
iframe父子之间进行交互,子组件可以调用vue里面的方法向vue传数据,实现交互
mounted() { this.loadModel() if (this.moduleName) { this.getBimboxUrlRequest() } window['setObvApiWrapper'] = a => { this.setObvApiWrapper(a) } window['setMapGuid'] = a => { this.setMapGuid(a) } window['setClickMarkEvent'] = a => { this.setClickMarkEvent(a) } //setClickMarkEvent },
根据需要,我们都在封装好的model或者iframeModel组件中把对应的模型操作方法写好,然后调用组件的时候通过ref属性之间调用方法
methods: { /**如果页面有维绿大厦,原来也有维绿大厦 就不卸载维绿大厦,否则全部卸载 */ unloadModel() { var models = this.obvApiWrapper.getObvApi().getModels() for (var i = 0; i < models.length; i++) { this.obvApiWrapper.unloadModel(models[i].id) } }, /**点击标注的事件 */ setClickMarkEvent(a) { this.$emit('clickMarkEvent', a) }, /**初始化模型视图之后,将 obvApiWrapper模型操作对象传过来*/ setObvApiWrapper(a) { this.obvApiWrapper = a this.getBimboxUrlRequest() }, /**初始化模型视图之后,将 mapGuid传过来,这个时候模型肯定加载完成*/ setMapGuid(a) { this.mapGuid = a this.$emit('obvApiWrapper', this.obvApiWrapper) }, /**发送请求获取到模型地址,然后进行加载模型:满足多模型加载 */ async getBimboxUrlRequest() { var that = this var res = await ObvApi.getBimboxUrl(this.buildingId, this.moduleName) if (res.data.code == 200 && res.data.result && res.data.result.length > 0) { res.data.result.forEach(element => { if (element.name) { setTimeout(that.loadDocument(element.name), 2000) } }) } else { this.bimBoxUrl = this.defaultBimboxUrl } }, /**初始化模型环境,application、view */ loadModel() { console.log('loadModel') var that = this getAuth(this.$store.getters.bjInfo) getAccessToken(function(access_token, expires_in) { let url = '/static/obv/page/model/model.html?&token=' + access_token + '&expires=' + expires_in + '&r=' + Math.random() that.iframeSrc = url }) }, /**加载文档和模型 */ loadDocument(urn) { if (this.obvApiWrapper) { this.obvApiWrapper.loadDocumentByUrn( urn, function handleResolve() { //将obvApi返回父节点 }, function(err) { // that.$message(err); } ) } }, /**关联模型,传入 存有xdbguid的数组 */ linkObject(guidArr) { var that = this if (this.obvApiWrapper == '' && this.mapGuid == {}) { this.$message('模型未加载完,点击无法响应!') this.$emit('loading', false) return } //设置默认视角 var nodeIds = [] var count = 0 for (var k in this.mapGuid) { if (guidArr.indexOf(k) !== -1) { nodeIds.push(this.mapGuid[k]) count++ if (count == guidArr.length) { return nodeIds //this.obvApiWrapper.setIsolation() } } } }, //创建标注 createMarker(markerItem, item, message) { this.obvApiWrapper.createMarker(markerItem, item, message) this.$emit('loading', false) }, //清空标注 clearMarkers: function(obvApi) { this.obvApiWrapper.clearMarkers() this.markedNodeIds = [] this.$emit('loading', false) } }
组件的调用
<script> import Model from '@/components/IframeModel.vue' import jQuery from 'jquery' export default { name: 'ModelRunning', props: { moduleName: { type: String }, markDatas: { type: Array } }, components: { Model }, data() { return { BimModel: {}, obvApi: '' } }, mounted() { this.BimModel = this.$refs.BimModel this.$emit('BimModel', this.BimModel) }, watch: { markDatas(v) { this.loadMarkInfo() } }, methods: { /**获取模型对象 */ getObvApiWrapper(a) { //debugger this.obvApi = a this.$emit('obvApi', a) //设置视角 var camera_position = '{"position":{"x":166082.99897721765,"y":119934.73657508119,"z":114472.7609660573},"target":{"x":73992.4176136514,"y":-26028.709355075698,"z":39501.407713036824},"up":{"x":-0.21259922967969852,"y":-0.33696948924271614,"z":0.9171985231448544},"aspect":0.8879668049792531,"fov":53.13010235415598,"orthoScale":188166.69878667328,"isPerspective":false,"pivotPoint":{"x":79328.38981130453,"y":-19366.16670130758,"z":7522.623504414594}}' var camera = JSON.parse(camera_position) var viewer = this.obvApi.getViewer() new OBV.Controllers.Viewer3d.ViewController(viewer).setViewFromCameraInfoSync(camera, true) }, //点击那个标注点的事件 selectMarkEventData(val) { //debugger var that = this console.log('val', val) let id = val.numberedId var green = jQuery(window.frames['view3d'].contentDocument) .find('div#' + id + '.marker-annotation') .find('.green') console.log('green.hasClass', green.hasClass('success')) if (green.hasClass('success')) { green.removeClass('success') green .parents('.marker-annotation') .next('.marker-anchor') .addClass('active') } else { green.addClass('success') green .parents('.marker-annotation') .next('.marker-anchor') .removeClass('active') if (this.obvApi.getObvApi()) { this.obvApi.getObvApi().restoreObjectsColor() } } }, //加载标注,创建标注 loadMarkInfo: function() { //debugger if (this.markDatas.length == 0) { return } var that = this var markDataInfo = this.markDatas // that.BimModel.clearMarkers() for (var d in markDataInfo) { if (markDataInfo[d].objectId && markDataInfo[d].objectId.length > 0) { var nodeArray = new Array() var message = "<div class='shui deviceinfo'>" + "<div class='title'>" + markDataInfo[d].deviceName + "</div><div class='content'>" + "<div class='content_item'><label>编号:</label><span>1" + markDataInfo[d].deviceNO + '</span></div>' + "<div class='content_item'><label>系统:</label><span>" + markDataInfo[d].systemName + '</span></div>' + "<div class='content_item'><label>位置:</label><span>" + markDataInfo[d].floorName + '_' + markDataInfo[d].roomName + "</span></div><div class='content_item'><label>状态:</label><span class='state'>正在运行</span></div>" + "<div class='content_item2'></div>" + "<div class='content_item3'><span class='system'>系统运行状态</span><i class='icon'></i></div></div></div>" console.log('message', message) var node = that.BimModel.linkObject(markDataInfo[d].objectId) if (node && node.length > 0) { nodeArray = node that.BimModel.createMarker( { dtype: 10, position: nodeArray }, 'object', message ) } var green = jQuery(window.frames['view3d'].contentDocument) green .find('.deviceinfo') .parents('.marker-annotation') .next('.marker-anchor') .addClass('deviceinfo_anchor') } } } } } </script>