feat(tgu-ops-ui): display request polygons on 2D map
Добавлен слой заявок (КНС) на 2D карту ТГУ: - requestApi.ts — загрузка заявок постранично через GET /v1/requests/map с прогресс-коллбэком; автоматически собирает все страницы - wktParser.ts — парсинг WKT POLYGON/MULTIPOLYGON в массив координат - drawRequests.ts — Canvas-рендеринг полигонов заявок - Tgu2DMapLayers.ts — buildTgu2DMapScene строит MapPolygon[] из RequestMapItem[] - Tgu2DMapTab.tsx — состояние requestsState, кнопка «Загрузить», фильтры по дате - Tgu2DMapSidebar.tsx — панель слоя заявок: счётчик, ошибки, truncated-предупреждение - requestTypes.ts — RequestMapItem, RequestMapPage модели - Поддержка выбора заявки на карте (mapSelectionTypes, mapTypes) - nginx.conf, vite.config.ts — проксирование /v1 на pcp-request-service в dev Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import type { MapProjection } from "../geometry/mapProjection";
|
||||
import type { MapPolygon } from "../model/mapTypes";
|
||||
|
||||
const SURVEY_COLORS: Record<string, string> = {
|
||||
OPTICS: "#FFA040",
|
||||
RSA: "#40AFFF",
|
||||
COMBINED: "#C080FF"
|
||||
};
|
||||
const DEFAULT_COLOR = "#FFA040";
|
||||
|
||||
export function drawRequests(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
polygons: MapPolygon[],
|
||||
projection: MapProjection,
|
||||
viewport: { width: number; height: number }
|
||||
) {
|
||||
ctx.save();
|
||||
for (const polygon of polygons) {
|
||||
if (polygon.points.length < 3) continue;
|
||||
const screenPoints = polygon.points.map((point) => projection.project(point));
|
||||
if (!screenPoints.some((point) => point.x >= -32 && point.x <= viewport.width + 32 && point.y >= -32 && point.y <= viewport.height + 32)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const color = SURVEY_COLORS[polygon.surveyType ?? ""] ?? DEFAULT_COLOR;
|
||||
ctx.beginPath();
|
||||
screenPoints.forEach((point, index) => {
|
||||
if (index === 0) {
|
||||
ctx.moveTo(point.x, point.y);
|
||||
} else {
|
||||
ctx.lineTo(point.x, point.y);
|
||||
}
|
||||
});
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = hexToRgba(color, 0.18);
|
||||
ctx.strokeStyle = hexToRgba(color, 0.85);
|
||||
ctx.lineWidth = 1.5;
|
||||
ctx.setLineDash([4, 3]);
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
function hexToRgba(hex: string, alpha: number): string {
|
||||
const value = hex.replace("#", "");
|
||||
const red = Number.parseInt(value.slice(0, 2), 16);
|
||||
const green = Number.parseInt(value.slice(2, 4), 16);
|
||||
const blue = Number.parseInt(value.slice(4, 6), 16);
|
||||
return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
|
||||
}
|
||||
Reference in New Issue
Block a user