Zoom Levels
- Leaflet은 위도, 경도 그리고 zoom level로 작동을 한다.
- 줌 레벨이 낮으면 지도가 대륙 전체를 표시하게되며, 줌 레벨이 높으면 지도가 도시의 세부 모습을 표시하게 된다.
- 줌 레벨의 작동방식을 이해하려면 먼저 측지학에 대한 기본 지식이 필요하다.
지구의 모양
- 줌 레벨 0으로 잠긴 간단한 지도를 살펴보자.
"전체 지구"는 가로 256픽셀, 세로 256픽셀 이미지 하나일 뿐이다.
하지만 진짜 지구는 사각형이 아니다. 오히려 지구는 구형과 비슷한것과 비슷한 불규칙한 모양을 가지고 있다.
그래서 우리는 지구가 대부분 둥글다고 가정한다. 평평하게 만들기 위해 가상의 원통을 주위에 놓고 펴고서 정사각형으로 보이도록 자른다.
위 방법은 평면에서 지구 표면을 표시하는 유일한 방법이 아니며, 장점과 단점이 다른 수백가지의 방법이 있다. 아래 6분짜리 비디오는 주제에 대해서 잘 설명해 주고 있다.
(한국어 자막이 있어 보기 좋다.)
측지학, 지도투영 및 좌표계와 같은 것은 많이 어렵다.(이 튜토리얼의 범위를 벗어남)
지구가 정사각형이라고 가정하는것이 항상 옮은것은 아니지만 대부분의 경우 충분히 잘 작동하고 일이 더 간단해지며 Leaflet (및 기타 지도 라이브러리)의 속도를 높일 수 있다.
2의 거듭제곱
지금은 지구가 정사각형 이라고 가정해 보겠다.
zoom level 0 에서 지구를 표현하면 가로/세로가 256 픽셀이다.
zoom level 1로 변경하면 가로/세로가 두배가 되고 256x256 픽셀 이미지 4대로 표현될 수 있다.
이러한 줌은 계속되어 타일 서비스는 적용 범위에 따라 zoom level 18 까지 제공되며, 이정도면 타일당 몇개의 도시 블록을 보기에 충분하다.
(Scale) 규모에 대한 참고사항
원통형 투영을 사용할 때의 단점 중에 하나는 배율이 일정하지 않고 특히 낮은 zoom level 에서 거리나 크기를 측정할 수 없다는 것이다.
기술적 용어로, 리플릿이 사용하는 원통형 투영은 등치형(모형을 보존함)이지만 등치형(거리를 보존하지 않음)은 아니며, 등치영역(적도 근처의 사물이 지금보다 작게 나타나므로 영역을 보존하지 않음)은 아니다.
지도에 L.Control.Scale 을 추가하여 적도에서 60도 북쪽으로 이동 시 축척 비율이 두배가 되는 것을 볼 수 있다.
zoom 컨트롤
leaflet 지도는 zoom 레벨을 컨트롤 하는 여러가지 방법이 있지만, 가장 확실한 방법은 setZoom() 을 사용하는 것이다.
- map.setZoom(0); 을 실행 시 zoom레벨이 0으로 셋팅된다.
zoom을 셋팅하는 다른 방법은 아래와 같다.
1. setView(center, zoom) - 지도 중심을 설정한다.
2. flyTo(center, zoom) - setView와 비슷하지만 부드러운 애니메이션으로 이동한다.
3. zoomIn()/zoomIn(delta) - delta 값의 zoom 확대 (기본값: 1)
4. zoomOut()/zoomOut(delta) - delta 값의 zoom 축소 (기본값: 1)
5. setZoomAround(fixedPoint, zoom) - 포인트를 고정하면서 zoom 레벨을 설정한다. (마우스 스크롤을 이용하여 zoom레벨 설정과 같다)
6. fitBounds(bounds) - 지도의 직사각형 영역에 맞게 zoom을 자동으로 계산한다.
(분수값)부분 확대(Fractional zoom)
Leaflet 1.0.0에 도입된 기능은 부분확대 개념이다. 그 전에는 zoom 레벨이 정수(0, 1, 2 등) 이었지만 이제는 1.5나 1.25와 같은 분수를 사용할 수 있다.
부분 zoom 기능은 기본적으로 비활성화 되어있으며, 활성화 하려면 지도의 zoomSnap 옵션을 사용하면 된다.
- zoomSnap 기본값은 1이며, 값은 0, 1, 2와 같은 값도 셋팅 가능하다.
- zoomSnap을 0.5로 설정 시 zoom레벨은 0 / 0.5 / 1 / 1.5 이런식이 될 것이다.
- zoomSnap을 0.1로 설정 시 zoom레벨은 0 / 0.1 / 0.2 와 같이 될 것이다.
Leaflet은 zoom레벨은 가장 가까운 유효한 zoomSnap 값으로 이동한다.
- 예를들어 zoomSnap 0.25 로 설정 후 map.setZoom(0.8) 수행 시 0.07로 zoom레벨이 셋팅된다.
- 이 상황은 map.fitBounds(bounds) 와 스크린에 손가락 제스쳐를 이용해 zoom레벨 변경시에도 동일하다.
zoomSnap을 0으로 맞출 수 있는데 이런경우 zoom레벨 변경 시 zoomSnap 값에 영향을 받지 않게된다.
추가적으로 zoomSnap과 관련있는 중요한 zoomDelta 옵션이 있다.
- 이 옵션은 zoom 버튼을 눌러 zoom in/out 동작 시 zoom레벨을 얼마나 변화할지에 대한 설정이다.
- 키보드 + / - 버튼을 누를 때도 마찬가지다.
마우스 휠의 zoom컨트롤은 wheelPxPerZoomLevel 옵션으로 zoom 확대/축소 속도 조절이 가능하다.
아래의 예제를 보고 다음의 zoom 레벨의 변화를 확인할 수 있다.
* 터치스크린의 핀치줌 (손가락 확대/축소)
* 마우스 휠을 이용한 확대/축소
* 박스 zoom (키보드 Shift 키를 누른상태에서 마우스 드래그)
* 왼쪽 위 확대/축소 버튼
참고: https://leafletjs.com/examples/zoom-levels/
댓글
댓글 쓰기