61 lines
2.0 KiB
TypeScript
61 lines
2.0 KiB
TypeScript
/**
|
|
* 정적 레이어 팩토리
|
|
*
|
|
* 주의: deck.gl Layer 인스턴스는 내부에 WebGL 프로그램/모델 캐시를 보유한다.
|
|
* 싱글턴으로 공유하면 페이지 전환 시 이전 WebGL 컨텍스트의 stale 참조가
|
|
* 새 컨텍스트에서 재사용되어 "parameter 1 is not of type 'WebGLProgram'" 에러 발생.
|
|
* → 매 호출마다 새 인스턴스 생성. deck.gl이 id 기반 diff로 GPU 전송을 최적화.
|
|
*/
|
|
import { PathLayer } from 'deck.gl';
|
|
import { EEZ_BOUNDARY, NLL_LINE, EEZ_STYLE, NLL_STYLE } from '../constants';
|
|
|
|
function toPath(points: readonly (readonly [number, number])[]): [number, number][] {
|
|
return points.map(([lat, lng]) => [lng, lat]);
|
|
}
|
|
|
|
function hexToRgba(hex: string, opacity: number): [number, number, number, number] {
|
|
const r = parseInt(hex.slice(1, 3), 16);
|
|
const g = parseInt(hex.slice(3, 5), 16);
|
|
const b = parseInt(hex.slice(5, 7), 16);
|
|
return [r, g, b, Math.round(opacity * 255)];
|
|
}
|
|
|
|
const EEZ_DATA = [{ path: toPath(EEZ_BOUNDARY) }];
|
|
const NLL_DATA = [{ path: toPath(NLL_LINE) }];
|
|
|
|
const EEZ_COLOR = hexToRgba(EEZ_STYLE.color, EEZ_STYLE.opacity);
|
|
const NLL_COLOR = hexToRgba(NLL_STYLE.color, NLL_STYLE.opacity);
|
|
|
|
/** EEZ 경계선 레이어 생성 */
|
|
export function createEEZStaticLayer() {
|
|
return new PathLayer({
|
|
id: 'eez-boundary',
|
|
data: EEZ_DATA,
|
|
getPath: (d: { path: [number, number][] }) => d.path,
|
|
getColor: EEZ_COLOR,
|
|
getWidth: EEZ_STYLE.weight * 2,
|
|
widthUnits: 'pixels' as const,
|
|
getDashArray: [6, 4],
|
|
dashJustified: true,
|
|
});
|
|
}
|
|
|
|
/** NLL 경계선 레이어 생성 */
|
|
export function createNLLStaticLayer() {
|
|
return new PathLayer({
|
|
id: 'nll-line',
|
|
data: NLL_DATA,
|
|
getPath: (d: { path: [number, number][] }) => d.path,
|
|
getColor: NLL_COLOR,
|
|
getWidth: NLL_STYLE.weight * 2,
|
|
widthUnits: 'pixels' as const,
|
|
getDashArray: [8, 4],
|
|
dashJustified: true,
|
|
});
|
|
}
|
|
|
|
/** 정적 기본 레이어 배열 (EEZ + NLL) — 매 호출마다 새 인스턴스 */
|
|
export function createStaticLayers() {
|
|
return [createEEZStaticLayer(), createNLLStaticLayer()];
|
|
}
|