wing-gis/frontend/wing-gis-web/src/lib/map/mapCore.ts
htlee b9d924e81e chore: 팀 워크플로우 기반 초기 프로젝트 구성
WING-GIS 해양경찰 통합 GIS 위치정보시스템.
모노레포: frontend(React 19 + MapLibre + deck.gl) + services(Spring Boot + Gradle).

- npm + Nexus 프록시 레지스트리 설정
- 팀 워크플로우 v1.6.1 부트스트랩 파일 배치
- .githooks (commit-msg, post-checkout)
- custom_pre_commit: true (모노레포 pre-commit 별도 관리)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 12:36:38 +09:00

77 lines
1.7 KiB
TypeScript

import maplibregl from 'maplibre-gl';
export function kickRepaint(map: maplibregl.Map | null) {
if (!map) return;
try {
if (map.isStyleLoaded()) map.triggerRepaint();
} catch {
// ignore
}
requestAnimationFrame(() => {
try {
if (map?.isStyleLoaded()) map.triggerRepaint();
} catch {
// ignore
}
});
}
export function onMapStyleReady(map: maplibregl.Map | null, callback: () => void) {
if (!map) return () => {};
if (map.isStyleLoaded()) {
callback();
return () => {};
}
let fired = false;
const runOnce = () => {
if (!map || fired || !map.isStyleLoaded()) return;
fired = true;
callback();
try {
map.off('style.load', runOnce);
map.off('styledata', runOnce);
} catch {
// ignore
}
};
map.on('style.load', runOnce);
map.on('styledata', runOnce);
return () => {
if (fired) return;
fired = true;
try {
map.off('style.load', runOnce);
map.off('styledata', runOnce);
} catch {
// ignore
}
};
}
export function sanitizeDeckLayerList(value: unknown): unknown[] {
if (!Array.isArray(value)) return [];
const seen = new Set<string>();
const out: unknown[] = [];
for (const layer of value) {
const isDeckLayerLike =
!!layer &&
typeof layer === 'object' &&
typeof (layer as { id?: unknown }).id === 'string' &&
typeof (layer as { clone?: unknown }).clone === 'function' &&
typeof (layer as { props?: unknown }).props === 'object';
if (!isDeckLayerLike) continue;
const layerId = (layer as { id: string }).id;
if (seen.has(layerId)) continue;
seen.add(layerId);
out.push(layer);
}
return out;
}