특정 지역에 대한 2차원적인 데이터가 있을 때, 먼저 그 지역의 지도를 표출하고 그 위에 2차원 데이터를 중첩하는 작업을 해야하는 경우는 꽤 많습니다. 통상적으로 2차원 데이터는 주로 이미지(Image) 또는 등위선(Contour)의 형태로 표출할 수 있습니다. 따라서 지도와 이미지를 중첩하는 경우 그리고 지도와 등위선을 중첩하는 경우로 나눌 수 있습니다. 사실 IDL에서 지도/이미지의 조합으로 중첩 표출을 하는 방법이나 예제는 제가 이 블로그에서 여러번 관련 게시물들을 통하여 소개한 바 있습니다. 반면 지도/등위선의 조합으로 중첩 표출하는 방법에 관해서는 상대적으로 언급이 좀 덜 되었던 측면이 있습니다. 그래서 오늘은 전반적으로 정리하는 의미에서, 지도/이미지의 조합과 지도/등위선의 조합을 함께 소개하면서 서로간의 차이점에 관해서도 관련 예제들과 함께 각각 소개해보고자 합니다.
오늘 예제로 사용할 2차원 데이터는 다음과 같이 HANNING 함수를 두번 사용하여 생성합니다. 이 데이터는 400x400의 구조를 갖는 실수형 배열이며, 경도 방향으로는 동경 120~140도 그리고 위도 방향으로는 북위 30~50도의 범위를 커버한다고 가정하였습니다. 따라서 이 데이터의 격자들은 경도 방향으로는 0.05도 간격이고 위도 방향으로도 0.05도 간격으로 분포하게 됩니다. 이러한 2차원 데이터 배열인 data를 다음과 같이 생성합니다.
data = HANNING(400, 400)*100
add = FLTARR(400, 400)
add[200, 200] = HANNING(200, 200)*50
data = data + add
그리고 여기서는 2차원 데이터의 격자들이 위치하는 경도값들 및 위도값들로 구성된 배열도 각각 만들어서 사용하고자 합니다. 즉 경도 방향으로 동경 120도부터 139.95도까지 0.05의 간격으로 총 400개의 경도값들로 구성된 배열 lons, 그리고 위도 방향으로 북위 30도부터 49.95도까지 0.05의 간격으로 총 400개의 위도값들로 구성된 배열 lats를 다음과 같이 생성합니다.
lons = 120+FINDGEN(400)*0.05
lats = 30+FINDGEN(400)*0.05
어차피 2차원 데이터 배열인 data는 반드시 필요합니다. 그런데 위와 같이 lons, lats와 같은 배열들까지도 추가적으로 사용하는 것은 지도/이미지 중첩 표출에서는 필수적인 것은 아닙니다. 즉 경위도 기반의 규칙격자 분포를 하는 2차원 데이터를 지도상에 이미지(Image)의 형태로 중첩 표출하는 경우에는 2차원 데이터 배열만 있어도 충분하며 lons, lats와 같은 배열들은 사용할 수도 있고 사용하지 않을 수도 있습니다. 그런데 경위도 기반의 규칙격자 분포를 하는 2차원 데이터를 지도상에 등위선(Contour)의 형태로 중첩 표출하는 경우에는 2차원 데이터 배열 뿐 아니라 lons, lats와 같은 배열들도 반드시 필요합니다. 즉 지도/등위선 조합의 경우에는 2차원 데이터 배열만으로는 중첩이 제대로 되지않기 때문에 반드시 lons, lats와 같은 배열들도 함께 생성해서 사용해야 한다는 뜻입니다.
< 지도/이미지 중첩 표출 >
그러면 지도/이미지 중첩 표출부터 먼저 살펴봅시다. 이 과정은 2차원 데이터의 분포 영역에 맞는 경도 및 위도 범위의 바탕 지도를 표출하고, 그 위에 이미지를 중첩하는 방식으로 진행하면 됩니다. 일단 바탕 지도를 표출하는 과정은 다음과 같습니다. 여기서 지도의 투영법은 LCC(Lambert Conformal Conic) 투영법을 적용합니다.
win = WINDOW(DIMENSIONS=[600, 600], /NO_TOOLBAR)
limit = [30, 120, 50, 140]
m = MAP('Lambert Conformal Conic', LIMIT=limit, $
STANDARD_PAR1=30, STANDARD_PAR2=60, $
ASPECT_RATIO=0, POSITION=[0.08, 0.20, 0.94, 0.96], $
CLIP=0, /CURRENT)
여기서는 WINDOW 및 MAP 함수를 사용하여 지도의 기본 바탕만 먼저 구현하였습니다. 원래는 MAPCONTINENTS 함수도 바로 이어서 사용하여 대륙경계선까지 표출해야 하겠지만, 이 과정은 이미지의 중첩 이후에 진행해야 합니다. 즉 이미지 중첩을 먼저 하고 대륙경계선 표시를 나중에 해야 대륙경계선이 이미지에 덮어지는 현상을 방지할 수 있습니다. 이제 이미지를 중첩해야 할텐데 두가지 방식이 있습니다. 먼저 이미지 중첩의 첫번째 방법은 다음과 같습니다.
im = IMAGE(data, RGB_TABLE=34, IMAGE_DIMENSIONS=[20, 20], $
IMAGE_LOCATION=[120, 30], GRID_UNITS=2, ASPECT_RATIO=0, /OVERPLOT)
첫번째 방법에서는 위와 같이 IMAGE_LOCATION 및 IMAGE_DIMENSION 속성들을 사용합니다. IMAGE_LOCATION 속성에 대해서는 이미지의 좌측 하단 꼭지점의 경위도 좌표를 부여합니다. 여기서는 [120, 30]이 됩니다. 그리고 IMAGE_DIMENSION 속성에 대해서는 이미지의 경도 및 위도 방향 크기를 도(Degree) 단위로 부여합니다. 여기서는 [20, 20]이 됩니다. 또한 GRID_UNITS 속성에 2라는 값을 부여하였는데, 이것은 앞서 IMAGE_LOCATION 및 IMAGE_DIMENSION 속성에 부여된 값들을 도(Degree) 단위로 인지해야 한다는 의미입니다. 따라서 이러한 작업에서는 GRID_UNITS 속성의 값을 2로 설정하는 것도 반드시 필요합니다. 이제 다음 과정에서는 대륙경계선의 표시 및 기타 자잘한 손질들 그리고 컬러바의 표출까지 다음과 같이 처리합니다.
mc = MAPCONTINENTS(/HIRES)
m.MapGrid.LABEL_POSITION = 0
m.MapGrid.LINESTYLE = 2
m.MapGrid.HORIZON_LINESTYLE = 0
cb = COLORBAR(TARGET=im, TITLE='Value', FONT_SIZE=10, $
POSITION=[0.2, 0.07, 0.8, 0.10])
여기까지의 과정에 의하여 얻어진 결과는 다음 그림과 같습니다.

여기서 이미지 중첩의 두번째 방법을 살펴봅시다. 어차피 IMAGE 함수를 사용한다는 점은 같습니다. 앞서 IMAGE 함수가 사용되었던 부분을 다음과 같은 내용으로 대체하면 됩니다.
im = IMAGE(data, lons, lats, RGB_TABLE=34, GRID_UNITS=2, $
ASPECT_RATIO=0, /OVERPLOT)
이 방법에서는 위와 같이 IMAGE 함수에서 2차원 데이터 배열인 data 뿐 아니라 lons, lats 배열들까지 두번째 및 세번째 인수로 사용합니다. 그 대신 앞서 첫번째 방법에서 사용했던 IMAGE_LOCATION, IMAGE_DIMENSION 속성들은 전혀 사용하지 않습니다. 사실은 이 두번째 방법에서는 2차원 배열의 격자별 경위도 위치를 lons, lats 배열들로부터 직접 인지하게 됩니다. 그리고 앞서 첫번째 방법에서는 data 배열만 사용했을 뿐 lons, lats 배열들은 전혀 사용되지 않았음에 유의합시다. 어쨌든 이 경우에도 표출 결과는 위의 그림과 동일합니다.
< 지도/등위선 중첩 표출 >
지도/이미지 중첩 표출에 이어서 이번에는 지도/등위선 중첩 표출을 해봅시다. 이를 위하여 CONTOUR 함수를 사용해야 합니다. 그리고 앞서 제시했던 지도 표출과 관련된 예제 코드의 내용은 그대로 사용하면 됩니다. 다만 IMAGE 함수가 사용되었던 부분만 다음과 같이 CONTOUR 함수가 사용되는 내용으로 대체하면 됩니다.
conv = [0, 20, 30, 50, 60, 80]
cn = CONTOUR(data, lons, lats, RGB_TABLE=34, C_VALUE=conv, $
C_LABEL_SHOW=1, C_THICK=2, GRID_UNITS=2, /OVERPLOT)
그리고 컬러바를 표시하기 위하여 COLORBAR 함수가 사용된 부분에서는 다음과 같이 TARGET의 대상을 cn으로 바꿔야 하며 TAPER 속성을 추가로 사용하는 것이 좋습니다.
cb = COLORBAR(TARGET=cn, TITLE='Value', FONT_SIZE=10, $
POSITION=[0.2, 0.07, 0.8, 0.10], TAPER=0)
사실 등위선에 대한 컬러바의 경우 디폴트 설정상으로는 컬러바의 양 옆이 뾰족하게 표현됩니다. 물론 이러한 모습을 선호할 경우에는 그냥 디폴트 설정대로 두면 됩니다. 하지만 만약 뾰족한 모습 대신 통상적인 사각형의 모습처럼 보이게 하고 싶다면 위와 같이 TAPER 속성의 값을 0으로 직접 설정하면 됩니다. 이제 표출 결과를 보면 다음 그림과 같습니다.

여기서 CONTOUR 함수 내에 투입된 인수들을 보면, 앞서 지도/이미지 중첩의 두번째 방법에서와 같이 data, lons, lats 배열들을 모두 사용하였음에 주목해야 합니다. 지도/등위선 중첩 표출에서 CONTOUR 함수를 사용하는 방법은 오직 이 방법 뿐입니다. 즉 앞서 지도/이미지 중첩의 첫번째 방법에서 IMAGE 함수 내에 오직 data 배열만 투입했던 것과 같은 방법은 지도/등위선 중첩에서는 사용할 수 없다는 뜻입니다. 따라서 지도/등위선 중첩 작업을 위해서는 데이터 배열 뿐 아니라 경도 및 위도 격자값들로 구성된 배열들까지도 만들어서 사용하는 것이 필수임을 유의해야 합니다.
그리고 위의 그림은 등위선을 선의 형태로만 표시하면서 선의 색상들이 특정 컬러테이블을 기반으로 적용된 경우입니다. 만약 컬러테이블의 색상으로 선과 선 사이가 채워지는(Filled) 형태로 표출하고자 한다면, CONTOUR 함수를 두 번 사용하는 것이 좋습니다. 즉 첫번째 CONTOUR 함수는 색상이 채워진 등위선(Filled Contour)을 표출하는 역할을 하고, 두번째 CONTOUR 함수는 그 위에 선 및 라벨 문자들만 표시하는 역할을 하도록 합니다. 그 과정은 다음과 같습니다. 앞서 CONTOUR 함수가 사용되었던 부분을 이 내용으로 대체하면 됩니다.
conv = [0, 20, 30, 50, 60, 80]
cn = CONTOUR(data, lons, lats, RGB_TABLE=34, C_VALUE=conv, $
/FILL, GRID_UNITS=2, /OVERPLOT)
cno = CONTOUR(data, lons, lats, COLOR='black', C_VALUE=conv, $
C_LABEL_SHOW=1, C_THICK=2, GRID_UNITS=2, /OVERPLOT)
굳이 이렇게 CONTOUR 함수를 두번 사용하는 이유는, /FILL 속성을 사용하여 선과 선 사이가 색상으로 채워지도록 표출하게 되면 선과 라벨문자 등이 색상으로 덮어지기 때문입니다. 따라서 선과 라벨문자만으로 구성된 등위선을 후속 표출하는 방법을 사용하는 것이 효과적입니다. 그 결과는 다음 그림과 같습니다.

지금까지 경위도 기반의 규칙 격자 분포를 하는 2차원 데이터에 대하여 지도/이미지 중첩 및 지도/등위선 중첩을 하는 방법에 관하여 예제와 함께 소개해보았습니다. 각각의 방법에 대하여 정리를 해보면 다음과 같습니다.
1. 지도/이미지 중첩 (IMAGE 함수 사용)
(1) data 배열만 투입하면서 IMAGE_LOCATION, IMAGE_DIMENSION 속성을 사용하는 방법
(2) data, lons, lats 배열들을 모두 투입하는 방법 (IMAGE_LOCATION, IMAGE_DIMENSION 속성은 사용하지 않음)
2. 지도/등위선 중첩 (CONTOUR 함수 사용)
(1) data, lons, lats 배열들을 모두 투입하는 방법 (오직 이 방법뿐)
'IDL > Mapping' 카테고리의 다른 글
| GOES-R 투영법을 이용한 지도 표출 (0) | 2021.10.28 |
|---|---|
| Near Side Perspective 투영법을 이용한 지도 표출 (0) | 2021.10.26 |
| IDL에서 대한민국 행정구역 경계선 표시하기 (0) | 2020.06.04 |
| 천리안 위성 2A호(GK2A)의 데이터 표출 [2] (0) | 2020.03.13 |
| 천리안 위성 2A호(GK2A)의 데이터 표출 [1] (3) | 2020.03.11 |