diff --git a/Frontend/_operation.html b/Frontend/_operation.html
index 1242fdf..0e6f5e6 100644
--- a/Frontend/_operation.html
+++ b/Frontend/_operation.html
@@ -1499,7 +1499,7 @@
$.each(res.data, function (i, v) {
msg = v.msgText != null ? ($.trim(v.msgText.toString()).length > 0 ? v.msgText.split(':')[0] : '') : '';
- strHtml += ``;
+ strHtml += ``;
});
if (res.count > 0)
$(pageAct.work_type == '1' ? '#inpErrCode' : '#inpErrCode_2').html(strHtml);
diff --git a/Frontend/_sysMonFloor.html b/Frontend/_sysMonFloor.html
index f378e12..f8d7481 100644
--- a/Frontend/_sysMonFloor.html
+++ b/Frontend/_sysMonFloor.html
@@ -1,1252 +1,1267 @@
-
-
\ No newline at end of file
diff --git a/Frontend/js/forge/forgemodel.js b/Frontend/js/forge/forgemodel.js
index d422166..765f1ff 100644
--- a/Frontend/js/forge/forgemodel.js
+++ b/Frontend/js/forge/forgemodel.js
@@ -8,8 +8,8 @@ var myDataList;
var lightDataList;
var lightList = [];//燈光清單
var levels;//剖面用
-var lowerIdx;//剖面的下方樓層
-var upperIdx;//剖面的上方樓層
+var lowerIdx = 0;//剖面的下方樓層
+var upperIdx = 0;//剖面的上方樓層
function launchViewer(urn, callback, failCallback, _selector = "#forgeViewer") {
selector = _selector;
@@ -340,12 +340,12 @@ class elevator3D {
}
}
+
function onDocumentLoadSuccess(doc, eleOption) {
var viewables = doc.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(doc, viewables).then(i => {
// documented loaded, any action?
-
});
// viewer.addEventListener(Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, (args) => {
// var currSelection = viewer.getSelection();
@@ -559,6 +559,7 @@ class ADHeatMaps {
this.roomDbIds = []; //房間 dbId
this.model = null;
this.dataVizExtn = null;
+ this.shadingData = null;
this.onComplete = option.onComplete ?? null;
this.init();
}
@@ -571,54 +572,78 @@ class ADHeatMaps {
this.model = viewer.model;
this.addHeatMaps()
}
+
async addHeatMaps() {
const {
SurfaceShadingData,
SurfaceShadingPoint,
SurfaceShadingNode,
+ SurfaceShadingGroup
} = Autodesk.DataVisualization.Core;
+ // test
+ const shadingGroup = new SurfaceShadingGroup('iot-heatmap');
+ const rooms = new Map();
+
+ for (const { id, roomDbId, position, sensorTypes } of this.devices) {
+ // console.log(id, roomDbId, position, sensorTypes)
+ if (!id || roomDbId == -1) {
+ continue;
+ }
+ if (!rooms.has(roomDbId)) {
+ const room = new SurfaceShadingNode(id, roomDbId);
+ shadingGroup.addChild(room);
+ rooms.set(roomDbId, room);
+ }
+ const room = rooms.get(roomDbId);
+ room.addPoint(new SurfaceShadingPoint(id, position, sensorTypes));
+ }
+ this.shadingData = new SurfaceShadingData();
+ this.shadingData.addChild(shadingGroup)
+ this.shadingData.initialize(this.model);
+ await this.dataVizExtn.setupSurfaceShading(this.model, this.shadingData);
+ this.dataVizExtn.renderSurfaceShading('iot-heatmap', "temperature", this.getSensorValue.bind(this));
//let nodeIds = await getNodeIdByDbIds(this.checkNodeString);
//nodeIds = Array.from(nodeIds);
//nodeIds = nodeIds.map(x => { return { room: x[0] , nodeId: x[1]} });
- this.roomDbIds = this.devices.filter(x => x.roomDbId != -1).map(x => x.roomDbId).Distinct();
+ // this.roomDbIds = this.devices.filter(x => x.roomDbId != -1).map(x => x.roomDbId).Distinct();
- // 建立一個 SurfaceShadingData 物件,並將 SurfaceShadingNode 加入到該物件中
- const heatmapData = new SurfaceShadingData();
+ // // 建立一個 SurfaceShadingData 物件,並將 SurfaceShadingNode 加入到該物件中
+ // const heatmapData = new SurfaceShadingData();
- $.each(this.roomDbIds, (idx, rDbid) => {
- // 建立一個名為 "Room Panel" 的 SurfaceShadingNode 物件,並將房間的模型給傳入,只在該房間呈現溫度
- const shadingNode = new SurfaceShadingNode("RoomPanel" + rDbid, rDbid);
+ // $.each(this.roomDbIds, (idx, rDbid) => {
+ // // 建立一個名為 "Room Panel" 的 SurfaceShadingNode 物件,並將房間的模型給傳入,只在該房間呈現溫度
+ // const shadingNode = new SurfaceShadingNode("RoomPanel" + rDbid, rDbid);
- // 遍歷每個設備,建立一個 SurfaceShadingPoint 物件並加入到 SurfaceShadingNode 中,透過這些設備渲染溫度
- this.devices.filter(x => x.roomDbId == rDbid).forEach((device) => {
- const shadingPoint = new SurfaceShadingPoint(
- device.id,
- undefined,
- device.sensorTypes
- );
- shadingPoint.positionFromDBId(this.model, device.roomDbId)
- shadingNode.addPoint(shadingPoint);
- // device.temp = 0;
- });
+ // // 遍歷每個設備,建立一個 SurfaceShadingPoint 物件並加入到 SurfaceShadingNode 中,透過這些設備渲染溫度
+ // this.devices.filter(x => x.roomDbId == rDbid).forEach((device) => {
+ // const shadingPoint = new SurfaceShadingPoint(
+ // device.id,
+ // undefined,
+ // device.sensorTypes
+ // );
+ // shadingPoint.positionFromDBId(this.model, device.roomDbId)
+ // shadingNode.addPoint(shadingPoint);
+ // // device.temp = 0;
+ // });
- heatmapData.addChild(shadingNode);
- })
+ // heatmapData.addChild(shadingNode);
+ // })
- // 將資料初始化並顯示在模型上
- heatmapData.initialize(this.model);
+ // // 將資料初始化並顯示在模型上
+ // heatmapData.initialize(this.model);
- // 對模型做表面顏色的渲染
- await this.dataVizExtn.setupSurfaceShading(this.model, heatmapData);
+ // // 對模型做表面顏色的渲染
+ // await this.dataVizExtn.setupSurfaceShading(this.model, heatmapData);
- // 對 "temperature" 的溫度設定兩種顏色:紅色和藍色
- this.dataVizExtn.registerSurfaceShadingColors("temperature", [0x0000ff, 0x00ff00, 0xffff00, 0xff0000]);
+ // // 對 "temperature" 的溫度設定兩種顏色:紅色和藍色
+ // this.dataVizExtn.registerSurfaceShadingColors("temperature", [0x0000ff, 0x00ff00, 0xffff00, 0xff0000]);
- $.each(this.roomDbIds, (idx, rDbid) => {
- this.dataVizExtn.renderSurfaceShading("RoomPanel" + rDbid, "temperature", this.getSensorValue.bind(this));
- })
+ // $.each(this.roomDbIds, (idx, rDbid) => {
+ // this.dataVizExtn.renderSurfaceShading("RoomPanel" + rDbid, "temperature", this.getSensorValue.bind(this));
+ // })
- /*this.changeTemp(this.tempVal);*/
+ // /*this.changeTemp(this.tempVal);*/
this.onComplete ? this.onComplete() : "";
}
@@ -629,7 +654,7 @@ class ADHeatMaps {
}
// 改變溫度
- changeTemp = function (devId, temp) {
+ changeTemp = async function (devId, temp) {
this.tempVal = temp;
// 透過 device id 取得 roomDbId
this.devices.forEach((dev) => {
@@ -637,9 +662,18 @@ class ADHeatMaps {
dev.temp = temp;
}
})
- $.each(this.roomDbIds, async (idx, rDbid) => {
- this.dataVizExtn.renderSurfaceShading("RoomPanel" + rDbid, "temperature", this.getSensorValue.bind(this));
- })
+
+ if (!this.shadingData) {
+ await this.addHeatMaps();
+ this.dataVizExtn.renderSurfaceShading('iot-heatmap', "temperature", this.getSensorValue.bind(this));
+ }
+ else {
+ this.dataVizExtn.updateSurfaceShading(this.getSensorValue.bind(this));
+ }
+ // $.each(this.roomDbIds, async (idx, rDbid) => {
+ // this.dataVizExtn.renderSurfaceShading("RoomPanel" + rDbid, "temperature", this.getSensorValue.bind(this));
+ // })
+
//if (rDbid != null) {
// // 取得新的溫度值
// let getSensorValue = (device, sensorType) => {
@@ -740,10 +774,11 @@ async function getLightData(data) {
}
async function testNewLight(dataList) {
+ console.log("dataList", dataList)
dataList.forEach((myData, index) => {
const position = JSON.parse(myData.device_coordinate_3d);
if (lightList.findIndex(x => x.device_guid == myData.device_guid) == -1) {
- lightList.push({ dbid: myData.forge_dbid, device_guid: myData.device_guid, lightObject: new THREE.SpotLight(0xe1cf18, 0, 20, 0.6, 0.5, 10) });
+ lightList.push({ dbid: myData.forge_dbid, device_guid: myData.device_guid, lightObject: new THREE.SpotLight(0xe1cf18, 10, 200, 1, 1, 2) });
}
lightList[index].lightObject.position.set(position.x, position.y, position.z);
@@ -917,6 +952,7 @@ async function changeScaleForHotspot(dbId, type = true) {
//------------------ 熱圖 -------------------------------
async function loadHeatmaps(model) {
+ //console.log("熱圖 loadHeat")
const dataVizExtn = await viewer.loadExtension("Autodesk.DataVisualization");
//取三個空調設備的位置打點
@@ -1082,28 +1118,73 @@ async function loadHeatmapForFloor() {
}
//------------ 剖面 ----------------------
-async function getRemoteLevels() {
- const aecData = await Autodesk.Viewing.Document.getAecModelData(this.viewer.model.getDocumentNode());
- if (!aecData || !aecData.levels) return null;
- const levels2 = aecData.levels;
- levels2.sort((a, b) => b.elevation - a.elevation);
- return levels2;
+function findLevels(model) {
+ return new Promise((resolve, reject) => {
+ model.search("layer", (nodeIds) => {
+ let levels = []
+ const tree = viewer.model.getInstanceTree();
+ for (let i = 0; i < nodeIds.length; i++) {
+ const dbId = nodeIds[i];
+ const name = tree.getNodeName(dbId);
+ if (!name || name.includes('<沒有層級>')) continue;
+ levels.push({
+ guid: dbId,
+ name,
+ dbId,
+ extension: {
+ buildingStory: true,
+ structure: false,
+ computationHeight: 0,
+ groundPlane: false,
+ hasAssociatedViewPlans: false,
+ }
+ });
+ }
+ resolve(levels)
+ }, (e) => { reject(e) })
+ });
+}
+
+
+async function getRemoteLevels() {
+
+ let aecData = await Autodesk.Viewing.Document.getAecModelData(this.viewer.model.getDocumentNode());
+
+ let levels;
+ if (!aecData || !aecData.levels) {
+ const levelExt = await viewer.loadExtension('Autodesk.AEC.LevelsExtension');
+ levelExt.setAecModelData(undefined, viewer.model); //!<<< Clear before reset
+ levels = await findLevels(viewer.model)
+ aecdata = Autodesk.AEC.AecModelData.computeLevels(levels, viewer.model); //!<<< Rebuild aec model data
+ } else {
+ levels = aecData.levels;
+ }
+ levels.sort((a, b) => b.elevation - a.elevation);
+ return levels;
}
async function getLevelsData(lowerFloor, upperFloor, callback = null) {
+ console.log(lowerFloor, upperFloor)
// 樓層正規化 取得樓層
const floorRegex = /[\d|\w]+F/gmi;
+ const floorRegex2 = /^FL[\d|\w]+/gmi;
const data = await this.getRemoteLevels();
+ console.log(data)
for (var i = 0; i < data.length; i++) {
- let name = data[i].name?.match(floorRegex);
- if (name && name[0] == lowerFloor) {
+ let name = data[i].name?.match(floorRegex) || data[i].name?.match(floorRegex2)[0].split("L")[1] + "F";
+ if (name && name[0] == lowerFloor || name == lowerFloor) {
lowerIdx = i;
}
- if (name && name[0] == upperFloor) {
- upperIdx = i;
+ if (name && name[0] == upperFloor || name == upperFloor) {
+ if (i > upperIdx && lowerFloor == upperFloor) {
+
+ } else {
+ upperIdx = i;
+ }
}
}
+
this.levels = data;
profile(callback);
}
@@ -1118,7 +1199,7 @@ function getCutPlaneParam(idx, n) {
const globalOffset = model.getData().globalOffset;
const units = model.getUnitString();
const elevRaw = Autodesk.Viewing.Private.convertUnits('ft', units, 1, level.elevation);
-
+ console.log(globalOffset, units, elevRaw)
let d = elevRaw - globalOffset.z - 0.5;
if (n == 1)
d = -1 * d;
diff --git a/Frontend/js/init.js b/Frontend/js/init.js
index fff4e71..c456b23 100644
--- a/Frontend/js/init.js
+++ b/Frontend/js/init.js
@@ -7,8 +7,8 @@ var baseImgUrl = "https://localhost:44376"; // 本地開發用
//var baseImgUrl = "http://220.132.206.5:8848"; // production 用
// WSP
-//var baseApiUrl = "http://220.132.206.5"; // production 用
-//var baseImgUrl = "http://220.132.206.5:8849"; // production 用
+// var baseApiUrl = "http://220.132.206.5:8001"; // production 用
+// var baseImgUrl = "http://220.132.206.5:8849"; // production 用
//var baseApiUrl = "http://localhost";
//var baseImgUrl = "http://localhost:8848";
@@ -31,11 +31,17 @@ var common = {
}
var objSendData = { Data: null };
// Mitsubishi
+var elevatorShow = true
+var port = "";
var initAreaTag = "TPE";
var n4Sup = "Mitsubishi_JACE8000";
+
// WSP
-//var initAreaTag = "NTPC";
-//var n4Sup = "Banqiao";
+// var elevatorShow = false
+// var port = "4912";
+// var initAreaTag = "NTPC";
+// var n4Sup = "WSP_Supervisor";
+
var forgeTokenBase = {
url: baseApiUrl + '/api/forge/oauth/token',
res_access_token: ["dictionary", "access_token"],