route stations update, timeouts in env
All checks were successful
release-tag / release-image (push) Successful in 1m6s

This commit is contained in:
2025-07-14 01:42:38 +03:00
parent 49576a0be7
commit 819246839f
4 changed files with 39 additions and 61 deletions

4
.env
View File

@ -1,6 +1,10 @@
# VUE_APP_API_URL=http://31.129.106.67:8080
# VUE_APP_GEO_URL=http://31.129.106.67:6001
# VUE_APP_WEATHER_URL=http://31.129.106.67:6002
VUE_APP_API_URL=http://127.0.0.1:8080
VUE_APP_GEO_URL=http://127.0.0.1:6001
VUE_APP_WEATHER_URL=http://127.0.0.1:6002
VUE_APP_VIDEO_TIMEOUT=120000
VUE_APP_TRACKING_TIMEOUT=15000

View File

@ -908,6 +908,8 @@ li.checked {
word-wrap: break-word;
word-break: break-word;
hyphens: auto;
max-height: 51px;
overflow-y: auto;
}
.sight-letter {

View File

@ -26,7 +26,7 @@
import * as PIXI from "pixi.js";
import { Viewport } from "pixi-viewport";
import { Text, TextStyle, FillGradient, Assets } from "pixi.js";
import { API_URL, GEO_URL } from "../config";
import { API_URL, GEO_URL, VIDEO_TIMEOUT, TRACKING_TIMEOUT } from "../config";
import sightIcon from "../icons/sight.svg";
import tramRight from "../icons/tram-right.svg";
import tramLeft from "../icons/tram-left.svg";
@ -77,7 +77,6 @@ export default {
isFollowingTram: false,
followTramTimer: null,
chooseTramDirection(canvasPt) {
// canvasPt: [x, y] in PIXI coords
let bestDir = "right";
let bestScore = Infinity;
const candidates = arrowTransforms;
@ -153,7 +152,7 @@ export default {
startInactivityCheck() {
if (this.inactivityInterval) return;
this.inactivityInterval = setInterval(() => {
if (Date.now() - this.lastActivityTime >= 120000) {
if (Date.now() - this.lastActivityTime >= VIDEO_TIMEOUT) {
this.showNearestSightVideo();
}
}, 1000);
@ -335,7 +334,7 @@ export default {
const minLng = Math.min(...lngs);
const padding = 40;
const scale = 35000;
const scale = 50000;
const midLat = (minLat + maxLat) / 2;
const latFactor = Math.cos((midLat * Math.PI) / 180);
console.log(
@ -360,6 +359,17 @@ export default {
this.routeGraphics.stroke();
},
// Calculate PIXI anchor based on the direction of the label offset
getAnchorFromOffset(offsetX, offsetY) {
if (offsetX === 0 && offsetY === 0) {
return { x: 0.5, y: 0.5 };
}
const length = Math.hypot(offsetX, offsetY) || 1;
const nx = offsetX / length / 1.5;
const ny = offsetY / length;
return { x: (1 - nx) / 2, y: (1 - ny) / 2 };
},
// Отрисовываем станции: PIXI-кружок + подпись (RU+EN)
drawStations(stationsRu, stationsEn) {
console.groupCollapsed(
@ -457,80 +467,40 @@ export default {
labelGroup._oy = oy;
node.addChild(labelGroup);
const stationPoint = { x, y };
const thresholdX = 15;
const thresholdY = 30;
let shiftX = 0,
shiftY = 0;
if (this.routeLatlngs && this.routeLatlngs.length > 1) {
for (let i = 0; i < this.routeLatlngs.length - 1; i++) {
const p1 = this.toCanvasPoint(this.routeLatlngs[i]);
const p2 = this.toCanvasPoint(this.routeLatlngs[i + 1]);
const vx = p2.x - p1.x,
vy = p2.y - p1.y;
const len2 = vx * vx + vy * vy;
const t =
((stationPoint.x - p1.x) * vx + (stationPoint.y - p1.y) * vy) /
(len2 || 1);
const tClamped = Math.max(0, Math.min(1, t));
const projX = p1.x + vx * tClamped;
const projY = p1.y + vy * tClamped;
const dx = stationPoint.x - projX,
dy = stationPoint.y - projY;
// elliptical distance check
const normDist =
(dx * dx) / (thresholdX * thresholdX) +
(dy * dy) / (thresholdY * thresholdY);
if (normDist < 1) {
// compute normal to segment
let nx = -vy,
ny = vx;
const nlen = Math.hypot(nx, ny) || 1;
nx /= nlen;
ny /= nlen;
// choose direction based on original offset
const dot = ox * nx + oy * ny;
const sign = dot >= 0 ? 1 : -1;
shiftX = nx * thresholdX * sign;
shiftY = ny * thresholdY * sign;
break;
}
}
}
// apply shift
labelGroup.x += shiftX;
labelGroup.y += shiftY;
labelGroup._ox += shiftX;
labelGroup._oy += shiftY;
let shiftX = 0;
let shiftY = 0;
const offX = ox + shiftX;
const offY = oy + shiftY;
// Anchor that depends on the final offset direction
const anchor = this.getAnchorFromOffset(offX, offY);
// RU
const ruStyle = new TextStyle({
fill: solidWhite,
fontSize: 20,
fontFamily: "Arial",
align: "right",
fontWeight: "bold",
});
const ruText = new Text({ text: st.name, style: ruStyle });
ruText.anchor.set(1, 0.5); // bottom-right
ruText.x = 24;
ruText.y = -35;
ruText.anchor.set(anchor.x, anchor.y);
ruText.x = 0;
ruText.y = 0;
labelGroup.addChild(ruText);
// EN
// ── EN name (optional) ──
const enName = enById[st.id];
if (enName) {
const enStyle = new TextStyle({
fill: lightGray,
fontSize: 12,
fontFamily: "Arial",
align: "right",
fontWeight: "bold",
});
const enText = new Text({ text: enName, style: enStyle });
enText.anchor.set(1, -1); // top-right
enText.x = 24;
enText.y = ruText.y + 2;
enText.anchor.set(anchor.x, anchor.y);
const verticalDir = oy + shiftY >= 0 ? 1 : -1;
enText.x = 0;
enText.y = verticalDir * (ruText.height + 2);
labelGroup.addChild(enText);
}
@ -1089,7 +1059,7 @@ export default {
this.inactivityTimer = setTimeout(() => {
this.isFollowingTram = true;
this.startFollowTram();
}, 15000);
}, TRACKING_TIMEOUT);
},
startFollowTram() {

View File

@ -1,3 +1,5 @@
export const API_URL = process.env.VUE_APP_API_URL;
export const GEO_URL = process.env.VUE_APP_GEO_URL;
export const WEATHER_URL = process.env.VUE_APP_WEATHER_URL;
export const VIDEO_TIMEOUT = process.env.VUE_APP_VIDEO_TIMEOUT || 120000;
export const TRACKING_TIMEOUT = process.env.VUE_APP_TRACKING_TIMEOUT || 15000;