본문 바로가기

Dev Stories/지리정보(Spatial)

[MapLibre] Projection 변환시 발생되는 렌더링 오류

반응형

투영법은 지구의 곡면을 2차원 평면으로 표현하는 방식이다. MapLibre GL JS에는 map.setProjection() API, Style Spec을 통해서 mercator, globe 2가지 종류의 투영법을 지정할 수 있다. 다음과 같은 API를 통해 mercator ↔ globe 전환을 쉽게 할 수 있다.

MapLibre GL JS의 투영법

// Globe 3D 지구본
map.setProjection({ type: 'globe' });

// Web Mercator 투영
map.setProjection({ type: 'mercator' })

 

하지만 투영법 전환시에 내부 렌더링 충돌로 오류가 발생된다. 해상도 변경(줌인,줌아웃)시 주로 발생되는데, 원인은 크게 2가지로 볼 수 있다.

첫째, 랜더링 파이프라인 차이로 mercator와 globe는 내부적으로 전혀 다른 셰이더와 좌표 변환 방식을 사용한다. 즉시 전환시에 기존 타일, 레이어 상태가 새로운 투영간에 불일치가 발생하면서 GPU렌더링 오류가 발생될 수 있다. Mercator는 각도보존(경위선의 각도를 정확히 유지하는 정각투영), Globe는 WebGL 기반 구면 렌더링이 적용되기 때문이다.

둘째, 일부 레이어 가시화 방법 중 Terrain-RGB DEM, Hillshade와 같은 특정 스타일 표현은 globe에서 완전히 지원하지 않는다. 이 상태에서 Projection을 강제로 변경하게 될 경우 브라우저 콘솔에 WebGL 오류가 발생되며 컨트롤이 작동하지 않는다. 

그래서 Projectiono 전환을 위해 안전한 처리를 해야한다. 투영법 전환시 발생되는 오류는 개발 커뮤니티에서는 일반적인 이슈로 언급되고 있으며 다양한 해결 방법을 제시하고 있지만 완전히 해결되지는 않은 것 같다.

몇번의 테스트를 통해 아래와 같은 방법을 이용하는 것이 가장 오류 빈도를 줄일 수 있어 정리를 한다.

const setProjectionSafely = () => {
	try {
        mapInstance.setProjection({ type: newType });
        console.log(`Projection changed to: ${newType}`);
    } catch (error) {
        console.error('Failed to set projection:', error);
        // 필요시 fallback 처리
	}
};

mapInstance.stop();
if (mapInstance.isStyleLoaded()) {
    setProjectionSafely();
    console.log('isStyleLoaded');
} else {
    mapInstance.once('style.load', () => {
        setProjectionSafely();
        console.log('on.style.load');
    });
}

위의 방법을 사용하면 문제가 100% 완전히 해결되면 좋겠지만 그렇지 않았다. 그런데 아주 간단한 방법으로 해결할 수 있는 방법이 있었다.

바로...

반응형