From 58dc3b44e29e52de145ca95569fa34c0ad48a06a Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期四, 26 二月 2026 11:13:21 +0800
Subject: [PATCH] #
---
src/main/webapp/views/locMap/locMap.html | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 200 insertions(+), 32 deletions(-)
diff --git a/src/main/webapp/views/locMap/locMap.html b/src/main/webapp/views/locMap/locMap.html
index 5d34f56..36fdee8 100644
--- a/src/main/webapp/views/locMap/locMap.html
+++ b/src/main/webapp/views/locMap/locMap.html
@@ -59,9 +59,9 @@
>
<div v-if="drawerLocNoData!=null">
<div style="margin: 10px;">
- <div style="margin-top: 5px;">鎺掞細{{drawerLocNoData.row}}</div>
- <div style="margin-top: 5px;">鍒楋細{{drawerLocNoData.bay}}</div>
- <div style="margin-top: 5px;">灞傦細{{drawerLocNoData.lev}}</div>
+<!-- <div style="margin-top: 5px;">鎺掞細{{drawerLocNoData.row}}</div>-->
+<!-- <div style="margin-top: 5px;">鍒楋細{{drawerLocNoData.bay}}</div>-->
+<!-- <div style="margin-top: 5px;">灞傦細{{drawerLocNoData.lev}}</div>-->
<div style="margin-top: 5px;">搴撲綅鍙凤細{{drawerLocNoData.locNo}}</div>
<div style="margin-top: 5px;">搴撲綅鐘舵�侊細{{drawerLocNoData.locSts}}</div>
</div>
@@ -101,7 +101,12 @@
let pixiStageList = [];
let pixiStaMap = new Map();
let objectsContainer;
+ let objectsContainer3;
+ let tracksGraphics;
+ let mapRoot;
+ let mapContentSize = { width: 0, height: 0 };
let graphics0;
+ let graphicsF;
let graphics3;
let graphics4;
let graphics5;
@@ -125,6 +130,12 @@
currentLevStaList: [],//褰撳墠妤煎眰绔欑偣list
drawerSta: false,
drawerStaData: null,
+ mapRotation: 0,
+ mapMirrorX: false,
+ mapConfigCodes: {
+ rotate: 'map_canvas_rotation',
+ mirror: 'map_canvas_mirror_x'
+ }
},
mounted() {
this.init()
@@ -157,6 +168,7 @@
ws.onclose = this.webSocketClose
+ this.loadMapTransformConfig()
this.initLev()//鍒濆鍖栨ゼ灞備俊鎭�
setTimeout(() => {
that.getMap(this.currentLev)
@@ -205,6 +217,7 @@
},
changeFloor(lev) {
this.currentLev = lev
+ this.loadMapTransformConfig()
this.reloadMap = true
this.getMap(lev)
},
@@ -229,13 +242,18 @@
graphics67 = pixiApp.renderer.generateTexture(getContainer(67));
graphicsLock = pixiApp.renderer.generateTexture(getContainer(-999));
+ mapRoot = new PIXI.Container();
+ pixiApp.stage.addChild(mapRoot);
// 鍒涘缓涓�涓鍣ㄦ潵绠$悊澶ф壒閲忕殑鏄剧ず瀵硅薄
objectsContainer = new PIXI.Container();
- pixiApp.stage.addChild(objectsContainer);
+ mapRoot.addChild(objectsContainer);
+
+ tracksGraphics = new PIXI.Graphics();
+ mapRoot.addChild(tracksGraphics);
// 鍒涘缓涓�涓鍣ㄦ潵绠$悊澶ф壒閲忕殑鏄剧ず瀵硅薄
objectsContainer3 = new PIXI.Container();
- pixiApp.stage.addChild(objectsContainer3);
+ mapRoot.addChild(objectsContainer3);
//*******************鎷栧姩鐢诲竷*******************
let stageOriginalPos;
@@ -285,16 +303,22 @@
pixiApp.view.addEventListener('wheel', (event) => {
event.stopPropagation();
event.preventDefault();
- const sx = event.clientX;
- const sy = event.clientY;
- const oldZoom = pixiApp.stage.scale.x;
+ const rect = pixiApp.view.getBoundingClientRect();
+ const sx = event.clientX - rect.left;
+ const sy = event.clientY - rect.top;
+ const oldZoomX = pixiApp.stage.scale.x || 1;
+ const oldZoomY = pixiApp.stage.scale.y || 1;
+ const oldZoomAbs = Math.abs(oldZoomX) || 1;
const delta = event.deltaY;
- let newZoom = oldZoom * 0.999 ** delta;
- const worldX = (sx - pixiApp.stage.position.x) / oldZoom;
- const worldY = (sy - pixiApp.stage.position.y) / oldZoom;
- const newPosX = sx - worldX * newZoom;
- const newPosY = sy - worldY * newZoom;
- pixiApp.stage.setTransform(newPosX, newPosY, newZoom, newZoom, 0, 0, 0, 0, 0);
+ let newZoomAbs = oldZoomAbs * 0.999 ** delta;
+ const mirrorX = this.mapMirrorX ? -1 : 1;
+ const newZoomX = mirrorX * newZoomAbs;
+ const newZoomY = newZoomAbs;
+ const worldX = (sx - pixiApp.stage.position.x) / oldZoomX;
+ const worldY = (sy - pixiApp.stage.position.y) / oldZoomY;
+ const newPosX = sx - worldX * newZoomX;
+ const newPosY = sy - worldY * newZoomY;
+ pixiApp.stage.setTransform(newPosX, newPosY, newZoomX, newZoomY, 0, 0, 0, 0, 0);
});
//*******************缂╂斁鐢诲竷*******************
@@ -328,6 +352,7 @@
pixiStageList = [map.length]//鍒濆鍖栧垪琛�
pixiStaMap = new Map();//閲嶇疆
objectsContainer.removeChildren()
+ if (tracksGraphics) { tracksGraphics.clear(); }
map.forEach((item,index) => {
pixiStageList[index] = [item.length]
for (let idx = 0; idx < item.length; idx++) {
@@ -388,21 +413,160 @@
});
const b1 = objectsContainer.getLocalBounds();
- const minX = Math.min(b1.x);
- const minY = Math.min(b1.y);
- const maxX = Math.max(b1.x + b1.width);
- const maxY = Math.max(b1.y + b1.height);
+ const minX = b1.x;
+ const minY = b1.y;
+ const maxX = b1.x + b1.width;
+ const maxY = b1.y + b1.height;
const contentW = Math.max(0, maxX - minX);
const contentH = Math.max(0, maxY - minY);
- const vw = pixiApp.view.width;
- const vh = pixiApp.view.height;
- let scale = Math.min(vw / contentW, vh / contentH) * 0.95;
- if (!isFinite(scale) || scale <= 0) { scale = 1; }
- const posX = (vw - contentW * scale) / 2 - minX * scale;
- const posY = (vh - contentH * scale) / 2 - minY * scale;
- pixiApp.stage.setTransform(posX, posY, scale, scale, 0, 0, 0, 0, 0);
+ mapContentSize = { width: contentW, height: contentH };
+ this.drawTracks(map);
+ this.applyMapTransform(true);
}
this.map = map;
+ },
+ isTrackCell(cell) {
+ if (!cell) { return false; }
+ const type = cell.type ? String(cell.type).toLowerCase() : '';
+ if (type === 'track' || type === 'crn' || type === 'dualcrn' || type === 'rgv') { return true; }
+ if (cell.trackSiteNo != null) { return true; }
+ const v = parseInt(cell.value, 10);
+ if (v === 3 || v === 9) { return true; }
+ if (cell.value != null) {
+ try {
+ const obj = (typeof cell.value === 'string') ? JSON.parse(cell.value) : cell.value;
+ if (obj && (obj.trackSiteNo != null || (obj.deviceNo != null && (type === 'crn' || type === 'dualcrn' || type === 'rgv')))) {
+ return true;
+ }
+ } catch (e) {}
+ }
+ return false;
+ },
+ drawTracks(map) {
+ if (!tracksGraphics || !Array.isArray(map)) { return; }
+ tracksGraphics.clear();
+ const railColor = 0x6c727a;
+ const railWidth = Math.max(1, Math.round(Math.min(width, height) * 0.08));
+ tracksGraphics.lineStyle(railWidth, railColor, 1);
+
+ for (let r = 0; r < map.length; r++) {
+ const row = map[r];
+ if (!Array.isArray(row)) { continue; }
+ for (let c = 0; c < row.length; c++) {
+ const cell = row[c];
+ if (!this.isTrackCell(cell)) { continue; }
+ const cx = c * width + width / 2;
+ const cy = r * height + height / 2;
+ const up = (r - 1 >= 0 && Array.isArray(map[r - 1])) ? map[r - 1][c] : null;
+ const right = (c + 1 < row.length) ? row[c + 1] : null;
+ const down = (r + 1 < map.length && Array.isArray(map[r + 1])) ? map[r + 1][c] : null;
+ const left = (c - 1 >= 0) ? row[c - 1] : null;
+ const hasN = this.isTrackCell(up);
+ const hasE = this.isTrackCell(right);
+ const hasS = this.isTrackCell(down);
+ const hasW = this.isTrackCell(left);
+ const seg = Math.min(width, height) * 0.5;
+ let drew = false;
+ if (hasN) { tracksGraphics.moveTo(cx, cy); tracksGraphics.lineTo(cx, cy - seg); drew = true; }
+ if (hasE) { tracksGraphics.moveTo(cx, cy); tracksGraphics.lineTo(cx + seg, cy); drew = true; }
+ if (hasS) { tracksGraphics.moveTo(cx, cy); tracksGraphics.lineTo(cx, cy + seg); drew = true; }
+ if (hasW) { tracksGraphics.moveTo(cx, cy); tracksGraphics.lineTo(cx - seg, cy); drew = true; }
+ if (!drew) {
+ tracksGraphics.moveTo(cx - seg * 0.4, cy);
+ tracksGraphics.lineTo(cx + seg * 0.4, cy);
+ }
+ }
+ }
+ },
+ parseRotation(value) {
+ const num = parseInt(value, 10);
+ if (!isFinite(num)) { return 0; }
+ const rot = ((num % 360) + 360) % 360;
+ return (rot === 90 || rot === 180 || rot === 270) ? rot : 0;
+ },
+ parseMirror(value) {
+ if (value === true || value === false) { return value; }
+ if (value == null) { return false; }
+ const str = String(value).toLowerCase();
+ return str === '1' || str === 'true' || str === 'y';
+ },
+ loadMapTransformConfig() {
+ if (!window.$ || typeof baseUrl === 'undefined') { return; }
+ $.ajax({
+ url: baseUrl + "/config/listAll/auth",
+ headers: { 'token': localStorage.getItem('token') },
+ dataType: 'json',
+ method: 'GET',
+ success: (res) => {
+ if (!res || res.code !== 200 || !Array.isArray(res.data)) {
+ if (res && res.code === 403) { parent.location.href = baseUrl + "/login"; }
+ return;
+ }
+ const byCode = {};
+ res.data.forEach((item) => {
+ if (item && item.code) { byCode[item.code] = item; }
+ });
+ const rotateCfg = byCode[this.mapConfigCodes.rotate];
+ const mirrorCfg = byCode[this.mapConfigCodes.mirror];
+ if (rotateCfg && rotateCfg.value != null) {
+ this.mapRotation = this.parseRotation(rotateCfg.value);
+ }
+ if (mirrorCfg && mirrorCfg.value != null) {
+ this.mapMirrorX = this.parseMirror(mirrorCfg.value);
+ }
+ if (mapContentSize && mapContentSize.width > 0 && mapContentSize.height > 0) {
+ this.applyMapTransform(true);
+ }
+ }
+ });
+ },
+ getViewportSize() {
+ if (!pixiApp || !pixiApp.renderer) { return { width: 0, height: 0 }; }
+ const screen = pixiApp.renderer.screen;
+ if (screen && screen.width > 0 && screen.height > 0) {
+ return { width: screen.width, height: screen.height };
+ }
+ const rect = pixiApp.view ? pixiApp.view.getBoundingClientRect() : null;
+ return { width: rect ? rect.width : 0, height: rect ? rect.height : 0 };
+ },
+ getTransformedContentSize() {
+ const size = mapContentSize || { width: 0, height: 0 };
+ const w = size.width || 0;
+ const h = size.height || 0;
+ const rot = ((this.mapRotation % 360) + 360) % 360;
+ const swap = rot === 90 || rot === 270;
+ return { width: swap ? h : w, height: swap ? w : h };
+ },
+ fitStageToContent() {
+ if (!pixiApp || !mapContentSize) { return; }
+ const size = this.getTransformedContentSize();
+ const contentW = size.width || 0;
+ const contentH = size.height || 0;
+ if (contentW <= 0 || contentH <= 0) { return; }
+ const viewport = this.getViewportSize();
+ const vw = viewport.width;
+ const vh = viewport.height;
+ let scale = Math.min(vw / contentW, vh / contentH) * 0.95;
+ if (!isFinite(scale) || scale <= 0) { scale = 1; }
+ const baseW = mapContentSize.width || contentW;
+ const baseH = mapContentSize.height || contentH;
+ const mirrorX = this.mapMirrorX ? -1 : 1;
+ const scaleX = scale * mirrorX;
+ const scaleY = scale;
+ const posX = (vw / 2) - (baseW / 2) * scaleX;
+ const posY = (vh / 2) - (baseH / 2) * scaleY;
+ pixiApp.stage.setTransform(posX, posY, scaleX, scaleY, 0, 0, 0, 0, 0);
+ },
+ applyMapTransform(fitToView) {
+ if (!mapRoot || !mapContentSize) { return; }
+ const contentW = mapContentSize.width || 0;
+ const contentH = mapContentSize.height || 0;
+ if (contentW <= 0 || contentH <= 0) { return; }
+ mapRoot.pivot.set(contentW / 2, contentH / 2);
+ mapRoot.position.set(contentW / 2, contentH / 2);
+ mapRoot.rotation = (this.mapRotation % 360) * Math.PI / 180;
+ mapRoot.scale.set(1, 1);
+ if (fitToView) { this.fitStageToContent(); }
},
rightEvent(x, y, e) {
this.drawerLocNo = true
@@ -520,12 +684,16 @@
sprite = new PIXI.Sprite(graphics0);
}
sprite.position.set(x, y);
- sprite.interactive = true; // 蹇呴』瑕佽缃墠鑳芥帴鏀朵簨浠�
- sprite.buttonMode = true; // 璁╁厜鏍囧湪hover鏃跺彉涓烘墜鍨嬫寚閽�
-
- sprite.on('pointerdown', (e) => {
- pointerDownEvent(e)
- })
+ const type = item && item.type ? String(item.type).toLowerCase() : '';
+ const numVal = parseInt(value, 10);
+ const isTrackCell = numVal === 3 || numVal === 9 || type === 'track' || type === 'crn' || type === 'dualcrn' || type === 'rgv';
+ if (!isTrackCell) {
+ sprite.interactive = true; // 蹇呴』瑕佽缃墠鑳芥帴鏀朵簨浠�
+ sprite.buttonMode = true; // 璁╁厜鏍囧湪hover鏃跺彉涓烘墜鍨嬫寚閽�
+ sprite.on('pointerdown', (e) => {
+ pointerDownEvent(e)
+ })
+ }
return sprite;
}
@@ -542,4 +710,4 @@
</script>
</body>
-</html>
\ No newline at end of file
+</html>
--
Gitblit v1.9.1