IDL/Mapping

LCC 투영법 기반의 데이터 표출 및 지도 윤곽 처리

이상우_IDL 2023. 8. 7. 16:25
728x90

LCC(Lambert Conformal Conic) 투영법 기반의 지도를 표출하는 방법에 관해서는 제가 예전에도 관련 게시물들을 통하여 몇번 다뤄본 적이 있습니다. 또한 LCC 투영법 기반으로 격자 분포를 하는 2차원 데이터를 지도와 함께 중첩 표출하는 예제들도 관련 게시물들을 통하여 소개했던 적이 있습니다. 따라서 LCC 투영법 기반의 지도를 표출하는 방법에 관한 기본적인 내용을 굳이 반복할 생각은 없지만, 추가적으로 다뤄보고 싶은 관련 주제가 있어서 오늘 소개해보고자 합니다.

 

IDL의 NG 체계에서 LCC 투영법으로 지도를 표출할 때 약간 골치아프게 다가오는 이슈가 있습니다. 바로 지도의 외곽 부분에 대한 처리인데요. LCC 투영법 자체의 특성상 경도 및 위도 격자선이 곡선 또는 기울어진 선이 됩니다. 따라서 경도 및 위도 방향으로 범위를 제한한 상태로 LCC 투영법의 지도를 표출하게 되면, 지도의 외곽 부분의 윤곽선도 곡선 및 기울어진 선으로 그려지는 것이 일반적입니다. 예를 들면 다음과 같이 경도 및 위도 범위가 제한된 LCC 투영법 기반의 지도를 표출해봅시다.

 

m = MAP('Lambert Conformal Conic', LIMIT=[20, 100, 60, 160], $
  STANDARD_PAR1=30, STANDARD_PAR2=60, $
  CENTER_LATITUDE=40, CENTER_LONGITUDE=130, $
  CLIP=0, HORIZON_LINESTYLE=0, ASPECT_RATIO=0, $
  MARGIN=0.1, /CURRENT)
mc = MAPCONTINENTS(/HIRES, FILL_COLOR='gold')
mg = m.MapGrid
mg.GRID_LATITUDE = 5
mg.GRID_LONGITUDE = 5
mg.LABEL_POSITION = 0
mg.LINESTYLE = 2

 

여기서는 경도 방향으로 +100~+160, 위도 방향으로 +20~+60의 범위를 갖도록 설정하였습니다. 표출된 결과는 다음과 같습니다.

 

 

일반적으로 IDL에서 LCC 투영법 기반의 지도를 표출하면 이와 같이 지도 전체의 윤곽선이 약간 부채꼴과 같은 형태를 띄게 됩니다. 물론 이대로 표출하는 것도 나쁘지 않지만, LCC 투영법의 지도를 사각형의 윤곽선이 되도록 표출할 수는 없을까에 대한 의문이 생길 수 있습니다. 일단 IDL의 LCC 투영법 지도 표출 기능에서는 기본적으로는 지도의 윤곽이 사각형이 되도록 하지는 못합니다. 다만 추가적인 코딩에 의하여 그렇게 구현하는 것은 좀 골치아프긴 하지만 가능은 합니다. 그래서 제가 예전에 그 방법에 관해서 설명을 하고 이러한 기능을 지원하는 커스텀 프로그램도 함께 첨부한 게시물을 올린 바 있습니다. 그 게시물의 링크는 다음과 같습니다.

 

https://swrush.tistory.com/379

 

이 게시물에서는 제가 직접 제작한 INSERT_GRID_LABELS_IN_LCC_MAP_NG라는 프로그램을 사용하였습니다. 그러면 이 프로그램을 추가적으로 활용하여 LCC 투영법의 지도를 사각형의 윤곽선으로 표시되도록 해봅시다. 그 과정은 다음과 같습니다.

 

m = MAP('Lambert Conformal Conic', LIMIT=[10, 90, 70, 170], $
  STANDARD_PAR1=30, STANDARD_PAR2=60, $
  CENTER_LATITUDE=40, CENTER_LONGITUDE=130, $
  XRANGE=[-2200000, 2200000], YRANGE=[-2400000, 2400000], $
  ASPECT_RATIO=0, MARGIN=0.1, /CURRENT)
mc = MAPCONTINENTS(/HIRES, FILL_COLOR='gold')
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, $

  SHOW_LABEL=[1, 1, 1, 1], FONT_SIZE=9

 

당연한 얘기지만 INSERT_GRID_LABELS_IN_LCC_MAP_NG의 소스 프로그램 파일(.pro 파일)을 해당 게시물에서 받아서 함께 사용해야 합니다. 그리고 MAP 함수에서 XRANGE 및 YRANGE 속성을 추가적으로 사용하여 지도의 범위를 m 단위의 거리 기반으로 설정해야 한다는 것을 유의해야 합니다. 또한 이렇게 거리 기반으로 범위가 설정될 경우에는 경도 및 위도 범위도 적절히 조정하는 것이 좋은데, 의도했던 것보다 조금 더 넓게 설정하는 것이 좋습니다. 또한 MAP 함수로 정의된 지도 개체(여기서는 m)를 INSERT_GRID_LABELS_IN_LCC_MAP_NG의 인수로 투입해야 한다는 것을 반드시 유의해야 합니다. 그 외에도 INSERT_GRID_LABELS_IN_LCC_MAP_NG의 SHOW_LABEL 키워드로는 지도 외곽 사각형에서 각 축마다 라벨 문자들을 표시할지 여부를 설정하는데, 여기 부여되는 4개의 값들은 각각 [하단 X축, 상단 X축, 좌측 Y축, 우측 Y축]에 대한 라벨 문자 표시 여부를 1 또는 0으로 설정하는 방식입니다. 여기서와 같이 [1, 1, 1, 1]로 설정하면 모든 위치들에 라벨 문자들이 표시되도록 처리됩니다. 위의 과정에 의한 표출 결과는 다음과 같습니다.

 

 

이와 같이 LCC 투영법 기반의 지도 표출에 있어서도 윤곽선이 사각형이 되도록 할 수 있습니다. 다만 이러한 표출을 위해서는 INSERT_GRID_LABELS_IN_LCC_MAP_NG 프로그램을 추가적으로 사용해야 한다는 것만 유의하면 됩니다. 어쨌든 이러한 표출이 가능하기 때문에, 만약 이러한 LCC 투영법 지도 상에 존재하는 2차원 데이터가 있을 경우 함께 중첩하여 표출하는 것도 얼마든지 가능합니다. 2차원 데이터의 격자 분포가 경위도 기반일 경우도 있고 거리 기반일 경우도 있습니다. 먼저 경위도 기반의 격자 분포를 하는 2차원 데이터를 LCC 투영법 지도 상에 중첩하는 예제를 살펴봅시다.

 

m = MAP('Lambert Conformal Conic', LIMIT=[10, 90, 70, 170], $
  STANDARD_PAR1=30, STANDARD_PAR2=60, $
  CENTER_LATITUDE=40, CENTER_LONGITUDE=130, $
  XRANGE=[-2200000, 2200000], YRANGE=[-2400000, 2400000], $
  ASPECT_RATIO=0, MARGIN=0.1, /CURRENT)
data = HANNING(800, 600)*100
add = FLTARR(800, 600)
add[400, 300] = HANNING(400, 300)*50
data = data+add
ct = COLORTABLE(74, /REVERSE)

im = IMAGE(data, RGB_TABLE=ct, IMAGE_DIMENSIONS=[40, 30], $
  IMAGE_LOCATION=[110, 25], GRID_UNITS=2, ASPECT_RATIO=0, /OVERPLOT)
mc = MAPCONTINENTS(/HIRES)
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, $

  SHOW_LABEL=[1, 1, 1, 1], FONT_SIZE=9

 

여기서는 이와 같이 800x600의 구조를 갖는 2차원 배열 데이터를 가정합니다. 그리고 이러한 데이터가 경도 방향으로 +110~+150 및 위도 방향으로 +25~+55의 범위 내에서 경위도 기반의 격자 분포를 한다고 가정한 것입니다. 그리고 중간에 IMAGE 함수를 사용하여 2차원 데이터를 중첩 표출하였습니다. 표출 결과는 다음과 같습니다.

 

 

이번에는 거리 기반의 격자 분포를 하는 2차원 데이터를 LCC 투영법 지도 상에 중첩하는 예제를 살펴봅시다.

 

m = MAP('Lambert Conformal Conic', LIMIT=[10, 90, 70, 170], $
  STANDARD_PAR1=30, STANDARD_PAR2=60, $
  CENTER_LATITUDE=40, CENTER_LONGITUDE=130, $
  XRANGE=[-2200000, 2200000], YRANGE=[-2400000, 2400000], $
  ASPECT_RATIO=0, MARGIN=0.1, /CURRENT)
data = HANNING(600, 600)*100
add = FLTARR(600, 600)
add[300, 300] = HANNING(300, 300)*50
data = data+add
ct = COLORTABLE(74, /REVERSE)

im = IMAGE(data, RGB_TABLE=ct, IMAGE_DIMENSIONS=[4000000, 4000000], $
  IMAGE_LOCATION=[-2000000, -2000000], GRID_UNITS=1, ASPECT_RATIO=0, /OVERPLOT)
mc = MAPCONTINENTS(/HIRES)
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, $

  SHOW_LABEL=[1, 1, 1, 1], FONT_SIZE=9

 

여기서도 2차원 데이터의 배열 구조는 600x600으로 가정하였습니다. 다만 이 데이터가 거리 기반의 격자 분포를 하며 X축 방향으로 -2000km~+2000km 그리고 Y축 방향으로 -2000km~+2000km의 범위가 되는 경우로 가정한 것입니다. 즉 거리 단위의 커버리지 영역의 크기가 4000kmx4000km가 되는 경우입니다. 참고로 여기서는 경도/위도 좌표가 (130, 40)인 지점이 거리 좌표로 (0, 0)인 지점이 됩니다. 그리고 중간에 IMAGE 함수를 사용하여 2차원 데이터를 중첩 표출하였습니다. 표출 결과는 다음과 같습니다.

 

 

예전에 제가 천리안 위성 2A호(GK2A)의 데이터를 지도와 함께 중첩 표출하는 예제들을 소개한 바 있습니다. 이 예제들에서도 바탕 지도는 LCC 투영법이고 그 위에 중첩되는 2차원 데이터는 거리 기반의 격자 분포를 합니다. 다만 이 예제들을 소개한 게시물들에서는 최종적인 표출 결과를 보면, LCC 투영법의 지도 상에 2차원 데이터를 중첩 표출하였으나 지도의 윤곽선은 사각형 처리가 되지는 않았습니다. 그러면 오늘 소개한 방법을 적용하여 윤곽선에 대한 사각형 처리까지 한번 해보기로 합시다. 그래서 GK2A 동남아시아 영역 자료를 대상으로 했던 해당 게시물의 내용을 기반으로 하되, netCDF 형식의 원시자료 파일을 읽고 처리하여 표출 직전까지 이르는 세부적인 과정에 대해서는 그 게시물의 내용을 참조하기로 하고 여기서는 설명을 생략하겠습니다. 다만 최종적인 표출의 방식에만 변화를 주도록 하겠습니다. 어쨌든 전체적인 과정은 좀 길 수 밖에 없지만 다음과 같습니다.

 

file = 'gk2a_ami_le1b_ir112_ea020lc_202002280300.nc'
id = NCDF_OPEN(file)
NCDF_VARGET, id, 'image_pixel_values', img
NCDF_ATTGET, id, 'origin_latitude', latc, /GLOBAL
NCDF_ATTGET, id, 'central_meridian', lonc, /GLOBAL
NCDF_ATTGET, id, 'standard_parallel1', latsp1, /GLOBAL
NCDF_ATTGET, id, 'standard_parallel2', latsp2, /GLOBAL
NCDF_ATTGET, id, 'upper_left_easting', x_ul, /GLOBAL
NCDF_ATTGET, id, 'upper_right_easting', x_ur, /GLOBAL
NCDF_ATTGET, id, 'upper_left_northing', y_ul, /GLOBAL
NCDF_ATTGET, id, 'lower_left_northing', y_ll, /GLOBAL
NCDF_ATTGET, id, 'image_width', nx, /GLOBAL
NCDF_ATTGET, id, 'image_height', ny, /GLOBAL
NCDF_ATTGET, id, 'pixel_size', dx, /GLOBAL
NCDF_ATTGET, id, 'pixel_size', dy, /GLOBAL
NCDF_ATTGET, id, 'file_name', fname, /GLOBAL
NCDF_CLOSE, id
fname = STRJOIN(STRING(fname))

 

limit = [10, 75, 65, 177]
m = MAP('Lambert Conformal Conic', LIMIT=limit, $
  STANDARD_PAR1=latsp1, STANDARD_PAR2=latsp2, $
  CENTER_LONGITUDE=lonc, CENTER_LATITUDE=latc, $
  XRANGE=[-2200000, 2200000], YRANGE=[-2400000, 2400000], $
  ASPECT_RATIO=0, MARGIN=0.1, /CURRENT)
m.MapGrid.GRID_LONGITUDE = 10
m.MapGrid.GRID_LATITUDE = 10
m.MapGrid.LINESTYLE = 2
m.MapGrid.LABEL_POSITION = 0
xs = FINDGEN(nx)*dx+x_ul
ys = FINDGEN(ny)*dy+y_ll
ctnum = COLORTABLE(74, /REVERSE)
im = IMAGE(REVERSE(img, 2), xs, ys, RGB_TABLE=ctnum, $
  GRID_UNITS=1, ASPECT_RATIO=0, /OVERPLOT)
mc = MAPCONTINENTS(/HIRES)
tx = TEXT(0.5, 0.95, fname, COLOR='blue', ALIGNMENT=0.5, $
  FONT_SIZE=14, /NORMAL)
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, $

  SHOW_LABEL=[1, 1, 1, 1], FONT_SIZE=9

 

여기서는 원시자료 파일인 gk2a_ami_le1b_ir112_ea020lc_202002280300.nc로부터 각종 정보들을 추출하는 과정으로 시작하여 LCC 투영법 기반의 지도를 그리고 그 위에 거리 기반의 격자 분포를 하는 2차원 데이터를 중첩하는 과정까지 이어집니다. 물론 앞서 소개했던 것과 같이 LCC 투영법 지도임에도 불구하고 윤곽선이 사각형으로 표시되도록 하기 위하여 INSERT_GRID_LABELS_IN_LCC_MAP_NG 루틴도 함께 사용하였습니다. 표출 결과는 다음과 같습니다.

 

 

여기서 사용된 원시자료 파일은 GK2A 동남아시아 영역의 자료가 담긴 netCDF 형식의 파일인데, 이러한 자료 파일은 GK2A 데이터 웹페이지에서 직접 받아야 한다는 점을 유의하시기 바랍니다(제가 여기서 직접 제공할 수는 없습니다). 어쨌든 이러한 원시자료 파일를 읽고 표출하는 과정을 소개했던 예전 게시물에서 표출했던 결과와 비교해보면 그 차이를 금방 알 수 있습니다. 물론 어느 쪽이 더 낫다 못하다라는 가치 판단을 할 문제는 절대 아니라고 봅니다. 연구자의 의도에 따라 어떤 방식으로 가는 것이 좋을까를 결정하여 거기에 맞게 결과를 얻으면 되는 문제라고 보는 것이 맞을 것입니다. 어쨌든 IDL의 NG 체계에서 LCC 투영법의 지도를 표출하는데 있어서 이렇게 외곽 부분을 직사각형 형태로 처리하는 것도 가능은 하다는 것을 보여주는 예제로서 염두에 두시면 될 것 같습니다.

LIST