오늘 다뤄볼 주제는 LCC(Lambert Conformal Conic) 투영법 지도의 표출 방법에 관한 내용입니다. 사실 LCC 투영법 지도의 표출에 관해서는 전에 시리즈로 연재했던 "IDL에서 지도의 표출 및 활용법에 관하여"라는 타이틀의 일련의 게시물들(이 블로그에서 Mapping 카테고리에 있음)에서 소개했던 적이 있습니다. 그래서 제목만 보면 그닥 새로울 것이 없는 내용일 수도 있겠지만, 여기서는 LCC 투영법만이 갖고 있는 특성들을 고려한 좀 다른 방식의 표출 방법을 알아보고자 합니다. 먼저 LCC 투영법 지도 표출의 가장 기본적인 예제부터 시작해보기로 합시다. 다음은 한반도 및 주변 지역을 LCC 투영법 지도로 표출하는 예제 코드입니다.
win = WINDOW(DIMENSIONS=[600, 500])
m = MAP('Lambert Conformal Conic', LIMIT=[20, 110, 60, 150], $
STANDARD_PAR1=30, STANDARD_PAR2=60, $
ASPECT_RATIO=0, MARGIN=0.1, CLIP=0, /CURRENT)
mc = MAPCONTINENTS(THICK=2)
mg = m.MapGrid
mg.GRID_LATITUDE=5
mg.GRID_LONGITUDE=5
mg.LABEL_SHOW = 1
mg.LABEL_POSITION = 0
mg.Linestyle = 2
이 코드의 전반적인 내용은 위에서 언급한 예전 관련 게시물에서 사용했던 방식과 같습니다. 경도의 범위는 동경 110~150도이고 위도의 범위는 북위 20~60도입니다. 경위도 격자선의 간격은 5도이고, 경위도값 라벨들이 X 및 Y축에 표시되도록 하였습니다. 이 코드를 실행하면 다음과 같은 그림을 얻을 수 있습니다.
위 예제 코드의 MAP 함수에서 LCC 투영법과 관련된 설정들이 정의가 되는데, 그 중 STANDARD_PAR1, STANDARD_PAR2는 LCC 투영법에서 등장하는 Standard Parallels의 개념으로서 두 개의 위도값이 주어집니다. 물론 이 위도값에 따라 지도의 모습은 좀 다르게 나타납니다. 위의 코드에서는 30과 60 두 값을 주었는데, 만약 이 두 값을 10과 30으로 대체할 경우에는 다음과 같은 모습의 지도로 그려집니다.
어떤 차이가 발생했는지는 아마 눈으로 쉽게 판단이 가능할 것입니다. 바로 세로 방향의 경도선들의 기울기가 좀 더 완만해진 것을 확인할 수 있습니다. 이 차이의 원인을 이해하려면 LCC 투영법에서 Standard Parallel의 개념에 대한 이해가 필요합니다. 이와 관련된 자세한 내용은 여기를 참조하시면 됩니다.
그런데 위의 두 그림을 보면 기울기의 차이는 있지만 경도선 자체가 기울어져 있다는 사실은 변함이 없습니다. 따라서 이런 LCC 투영법의 지도를 그리면 항상 부채꼴과 같은 형태로 그려집니다. 투영법의 특성상 그럴 수 밖에 없습니다. 그런데 투영법 자체는 LCC이면서도 지도의 윤곽 자체는 사각형(Square)의 형태로 나타나도록 표출하는 것이 필요할 경우가 있습니다. 실제로 이런 식으로 표출된 지도들이 많이 사용이 되고 있기도 합니다. 그렇다면 IDL에서 이러한 방식의 표출이 가능할까요?
일단 결론부터 먼저 얘기한다면, "가능은 한데 좀 골치가 아프다"라고 할 수 있겠습니다. IDL의 지도 표출은 경위도 기반의 격자선 위주로 구현되는 것이 기본입니다. 물론 좌표를 다루는데 있어서는 경위도 체계 및 거리 체계를 모두 다룰 수 있지만, 기본 표출 방식에 있어서는 경위도 격자 기반을 중심으로 하기 때문에, 거리 기반의 표출을 하려면 약간 복잡한 코딩이 필요합니다. 하지만 이러한 작업을 조금이나마 간편하게 처리할 수 있는 방법을 소개하려고 합니다. 일단 간단한 부분부터 먼저 살펴보겠습니다. 우선 LCC 투영법의 지도를 사각형 프레임 기반으로 그리는 작업을 수행하는 예제 코드부터 보면 다음과 같습니다.
win = WINDOW(DIMENSIONS=[600, 500])
m = MAP('Lambert Conformal Conic', LIMIT=[20, 110, 60, 150], $
STANDARD_PAR1=10, STANDARD_PAR2=30, $
CENTER_LATITUDE=40, CENTER_LONGITUDE=130, $
XRANGE=[-2000000, 2000000], YRANGE=[-2000000, 2000000], $
ASPECT_RATIO=0, MARGIN=0.1, /CURRENT)
mc = MAPCONTINENTS(THICK=2)
mg = m.MapGrid
mg.GRID_LATITUDE=5
mg.GRID_LONGITUDE=5
mg.LABEL_SHOW = 1
mg.LABEL_POSITION = 0
mg.Linestyle = 2
앞서 처음에 소개했던 예제 코드의 내용과 가장 큰 차이가 나는 부분은 총 네 개의 새로운 속성들이 사용이 되었다는 점인데요. 먼저 CENTER_LONGITUDE, CENTER_LATITUDE는 지도의 중심이 될 지점의 경도와 위도를 명시적으로 설정하는 역할입니다.그리고 XRANGE, YRANGE 키워드에 부여된 값들을 보면 + 또는 -로 2백만이라는 값을 갖고 있는데, 이 값은 m 단위의 거리에 해당됩니다. 즉 2000km가 되는 셈입니다. 그래서 여기서 추가된 네 개의 속성들은 경도 130, 위도 40인 지점을 중심으로 수평 및 수직 방향으로 400km의 범위를 갖는 영역을 표시하라는 의미가 됩니다. 경위도 기반 대신 거리 기반의 표출을 위한 설정입니다. 그리고 표출의 편의상 이유로 CLIP=0 속성은 제거하였습니다. 이와 같은 코드를 실행하면 그 결과는 다음 그림과 같습니다.
그런데 이 그림을 보면 아직 해야 할 작업들이 더 있겠다는 생각이 들게 됩니다. 우선 지도의 사각형 윤곽이 전혀 표시가 안되어 있는 문제가 있는데, 안타깝게도 이 부분은 자동적으로 해결이 되지 않습니다. 따라서 직접 윤곽선을 그려줘야 하는데, 이를 위하여 다음과같이 PLOT 함수를 추가로 사용해야 합니다.
box = PLOT(m.Xrange, m.Yrange, /NODATA, POSITION=m.Position, /CURRENT, $
XTICKFORMAT='(A1)', YTICKFORMAT='(A1)', XTICKLEN=0, YTICKLEN=0)
이렇게 하면 다음 그림과 같은 결과를 얻게 됩니다.
물론 이 상태 역시 아직 완성된 버전이 아닙니다. 먼저 경위도선들이 덜 표시가 된 문제가 보이고, 사각형 윤곽 안에서 라벨 문자들이 쓸데없이 보이는 문제도 있습니다. 경위도선들의 부족 현상은 MAP 함수의 LIMIT 속성에 부여된 경도 범위를 더 늘려주는 것으로 해결됩니다. 그리고 라벨 문자들의 제거는 LABEL_SHOW 속성을 0으로 설정하면 해결됩니다. 따라서 아예 애초에 다음과 같은 내용의 코드로 실행을 하는 것이 좋습니다.
win = WINDOW(DIMENSIONS=[600, 500])
m = MAP('Lambert Conformal Conic', LIMIT=[20, 100, 60, 160], $
STANDARD_PAR1=10, STANDARD_PAR2=30, $
CENTER_LATITUDE=40, CENTER_LONGITUDE=130, $
XRANGE=[-2000000, 2000000], YRANGE=[-2000000, 2000000], $
ASPECT_RATIO=0, MARGIN=0.1, /CURRENT)
mc = MAPCONTINENTS(THICK=2)
mg = m.MapGrid
mg.GRID_LATITUDE=5
mg.GRID_LONGITUDE=5
mg.LABEL_SHOW = 0
mg.Linestyle = 2
box = PLOT(m.Xrange, m.Yrange, /NODATA, POSITION=m.Position, /CURRENT, $
XTICKFORMAT='(A1)', YTICKFORMAT='(A1)', XTICKLEN=0, YTICKLEN=0)
여기서는 경도의 범위를 110~150 대신 100~160으로 늘렸습니다. 그리고 LABEL_SHOW 속성을 0으로 설정하여 라벨값들이 표시되지 않도록 처리하였습니다. 이 코드를 실행하면 그 결과는 다음 그림과 같은데, 그래도 좀 더 나은 결과를 얻은 것 같습니다.
물론 아직도 해결해야 할 문제가 남아 있습니다. 사각형 윤곽선의 외곽 부분에 경위도 라벨 문자들이 있어야 할텐데 아직 없습니다. 그런데 이게 꽤 복잡한 난제입니다. 나중에 덧그린 PLOT 함수에서는 기존에 그렸던 지도상의 격자들에 대한 정보를 인식하지 못하기 때문입니다. 그렇다고 지도 자체에 라벨링을 하게 되면, 이미 보았듯이 기본적인 LCC 투영법 지도상에 표시하는 방식을 따르게 되는데, 이건 지금 우리가 구현하고자 하는 방식과는 전혀 다릅니다. 그래서 원래는 이 부분의 처리를 위해서는 사각형 윤곽선상에서 라벨 문자들이 붙어야 할 위치의 계산 및 표시 작업을 위한 별도의 코딩이 필요합니다. 사실 이 부분은 상당히 복잡한 작업이기 때문에 구체적인 내용은 제가 여기서 언급은 하지 않겠습니다.
그 대신 이 작업을 수행하는 코드를 만들어서 여기에 첨부해 놓겠습니다. 그냥 이 코드 파일을 받아서 사용하시면 됩니다. 코드의 이름은 INSERT_GRID_LABELS_IN_LCC_MAP_NG로 좀 깁니다. 그러면 이 코드를 활용하여 좀 더 그럴듯한 결과를 얻도록 해봅시다. 전체적인 내용을 다음과 같이 코드를 작성하여 실행하면 됩니다. 그러면 다음과 같은 그림을 얻게 됩니다.
win = WINDOW(DIMENSIONS=[600, 500])
m = MAP('Lambert Conformal Conic', LIMIT=[20, 100, 60, 160], $
STANDARD_PAR1=10, STANDARD_PAR2=30, $
CENTER_LATITUDE=40, CENTER_LONGITUDE=130, $
XRANGE=[-2000000, 2000000], YRANGE=[-2000000, 2000000], $
ASPECT_RATIO=0, MARGIN=0.1, /CURRENT)
mc = MAPCONTINENTS(THICK=2)
mg = m.MapGrid
mg.GRID_LATITUDE=5
mg.GRID_LONGITUDE=5
mg.LABEL_SHOW = 0
mg.Linestyle = 2
INSERT_GRID_LABELS_IN_LCC_MAP_NG, m
제가 작성해서 올린 이 코드는 LCC 투영법 지도를 사각형 프레임으로 그려놓은 상태에서 사용하면 됩니다. PLOT 함수로 윤곽선을 그리는 작업도 이 안에 포함되어 있기 때문에 별도로 수행할 필요가 없습니다. 어쨌든 이 코드를 사용하면, 사각형 윤곽선상에서 경위도 라벨 문자들이 붙어야 할 위치를 계산하여 표시해줍니다. 그리고 추가적으로 SHOW_LABEL, FONT_SIZE 키워드의 사용이 가능한데요. FONT_SIZE 키워드는 말 그대로 라벨 문자들의 크기이며 기본은 10으로 되어 있습니다. SHOW_LABEL 키워드는 라벨 문자들을 하단 X축, 상단 X축, 왼쪽 Y축, 오른쪽 Y축에 표시할 것인가의 여부를 결정하는 1 또는 0의 값 네 개로 이루어진 배열의 형태로 받습니다. 따라서 만약 폰트 크기는 9로 하고, 라벨 문자들을 네 부분 모두 표시하려면 다음과 같이 사용하면 됩니다.
INSERT_GRID_LABELS_IN_LCC_MAP_NG, m, SHOW_LABEL=[1, 1, 1, 1], FONT_SIZE=9
그러면 다음과 같은 그림을 얻게 됩니다.
쓰다보니 내용이 상당히 길어졌는데, 오늘은 LCC 투영법의 지도를 사각형 프레임안에 표출하는 방법에 관하여 살펴보았습니다. 이러한 방식의 구현이 기본적으로 지원되지 않는 부분이 좀 있어서 별도의 코딩을 필요로 하고, 그 코딩이 상당히 좀 복잡하기 때문에 이러한 작업을 위한 별도의 코드를 만들어서 이 게시물에 첨부해놓겠습니다. 필요하신 분들은 받아서 사용하시면 됩니다. 이제 주제를 좀 더 확대해 본다면 아무래도 이러한 방식으로 구현된 지도상에 2차원 데이터를 중첩하는 작업이 될텐데요. 이와 관련해서는 또 상당한 양의 내용이 될 것 같아서 나중에 기회가 되면 다뤄 보기로 하겠습니다.
* 오늘 소개한 INSERT_GRID_LABELS_IN_LCC_MAP_NG 코드 파일은 아래에 첨부합니다. 그리고 초기 버전에서는 X, Y축의 경도, 위도 라벨 값들의 표시 위치 오류가 있었는데 뒤늦게나마(2023. 7) 이 문제가 수정된 버전입니다.
'IDL > Mapping' 카테고리의 다른 글
ESRI Shapefile의 활용 및 해독에 관하여 (Part 1) (0) | 2018.03.24 |
---|---|
Satellite 투영법으로 지도 그리기 (1) | 2016.10.27 |
LL_ARC_DISTANCE 함수의 사용법 (0) | 2015.08.28 |
지도 이미지를 3차원 구체(Sphere) 폴리곤상에 입히기 [2] (0) | 2015.07.02 |
지도 이미지를 3차원 구체(Sphere) 폴리곤상에 입히기 [1] (0) | 2015.06.29 |