IDL/Mapping

MapForward, MapInverse 메서드의 이해와 활용

이상우_IDL 2019. 1. 10. 16:40
728x90

2019년 새해가 밝아온 지 며칠 되었습니다. 좀 늦었지만 여러분들도 새해 복 많이 받으시고 행복한 한 해 되시길 기원합니다. 저는 금년에도 이 블로그를 통해서 IDL과 관련된 여러가지 주제의 다양한 게시물들을 계속 소개할 수 있도록 최선을 하겠습니다.


오늘은 MapForward, MapInverse 메서드들에 관하여 소개를 해볼까 합니다. 이 메서드들은 NG 체계의 MAP 함수에서 지원되는 메서드들로서 지도상에서 경위도(Longitude/Latitude) 좌표와 Cartesian(X/Y) 좌표 사이의 변환을 담당합니다. 메서드의 이름에서 짐작할 수 있듯이 이 메서드들의 기능은 기존의 DG 체계의 지도 관련 기능들 중 MAP_PROJ_FORWARD, MAP_PROJ_INVERSE 함수와 유사하다고 보면 됩니다. MapForward 메서드는 경위도 좌표를 거리 기반의 Cartesian 좌표로 변환해주고 MapInverse 메서드는 Cartesian 좌표를 경위도 좌표로 변환해줍니다. 그러면 예제를 통해서 구체적으로 살펴봅시다. 먼저 지도 그림을 하나 그려 놓고 시작을 해야 합니다. 그래서 다음과 같이 LCC(Lambert Conformal Conic) 투영법으로 지도를 먼저 그려 봅시다.


win = WINDOW(DIMENSIONS=[600, 600], /NO_TOOLBAR)

limit = [25, 115, 45, 135]

m = MAP('Lambert Conformal Conic', LIMIT=limit, $

  CENTER_LONGITUDE=125, CENTER_LATITUDE=35, $

  STANDARD_PAR1=30, STANDARD_PAR2=60, CLIP=0, $

  ASPECT_RATIO=0, MARGIN=0.1, /CURRENT)

mc = MAPCONTINENTS(/HIRES)

m.MapGrid.LABEL_POSITION = 0

m.MapGrid.LINESTYLE = 1

m.MapGrid.GRID_LONGITUDE = 1

m.MapGrid.GRID_LATITUDE = 1


이 예제코드를 실행하면 다음과 같은 LCC 투영법의 지도가 표출됩니다.



이 지도를 그릴 때 사용된 예제코드의 내용을 보면 경도의 범위는 동경 115~135도, 위도의 범위는 북위 25~45도이고, 중심의 경도 및 위도는 각각 125도와 35도입니다. 그러면 먼저 MapForward 메서드를 사용해봅시다. 이 메서드는 MAP 함수에서 지원되므로 다음과 같은 방식으로 사용합니다. 경위도 좌표를 XY 좌표로 변환하는 기능이기 때문에, 원하는 경도와 위도 값을 인수로 주면 됩니다.


c = m.MapForward(125, 35)

PRINT, c


여기서는 중심 경위도인 125, 35를 넣어봤는데, PRINT로 출력된 값들은 다음과 같습니다.


   2.2805169e-09   9.3132257e-10


좀 요상해 보이는 값들이긴 한데 이 값들은 둘 다 사실상 0, 0이라고 보면 됩니다. 즉 경위도 좌표 (125, 35)는 XY좌표로는 (0, 0)에 대응된다는 뜻입니다. 이번에는 다음과 같이 위도만 36도로 바꿔서 결과를 출력해 봅시다.


c = m.MapForward(125, 36)

PRINT, c


그러면 출력된 값들은 다음과 같습니다.


   2.2459468e-09       108772.05


아까 위도가 35도일 경우와 달리 Y좌표값이 꽤 큽니다. XY좌표값의 단위는 m(meter)입니다. 따라서 이 얘기는 지금과 같은 투영법의 지도에서는 경위도 좌표 (125, 35)와 (125, 36)인 지점들에 대한 XY 좌표값에 의하면 두 지점 사이의 거리가 약 108.8km에 해당된다는 의미입니다. 위도만 37도로 바꿔서 계산해보면 그 결과는 다음과 같습니다.


c = m.MapForward(125, 37)

PRINT, c

   2.2114657e-09       217263.87


지금까지 변환된 XY 좌표값들을 보면 X값은 거의 그대로인 채 Y값만 계속 변화하고 있습니다. 인수로 사용되는 값은 위와 같이 단일값으로 넣어도 되지만 배열의 형태로도 가능합니다. 다음과 같이 위도만 일정 간격으로 변화하는 5개의 지점들에 대한 경도 및 위도 값 배열을 만들어서 인수로 투입해 봅시다.


lons = [125, 125, 125, 125, 125]

lats = [35, 37, 39, 41, 43]

c = m.MapForward(lons, lats)

HELP, c

PRINT, c


이렇게 하면 결과 역시 배열의 형태로 얻어집니다. 출력된 내용을 보면 결과 배열인 c는 2x5의 형태를 가지며 그 값들은 다음과 같습니다.


C               DOUBLE    = Array[2, 5]

   2.2805169e-09   9.3132257e-10

   2.2114657e-09       217263.87

   2.1427326e-09       433527.10

   2.0742407e-09       649030.95

   2.0059129e-09       864018.98


이 결과를 그림으로 표출해 볼 수 도 있습니다. 즉 다음과 같이 PLOT 함수를 사용하여 각 지점들을 심볼로 표시하는 것입니다. 물론 여기서는 인수로 들어가는 좌표값들은 경위도 단위가 되어야 하기 때문에 앞서 우리가 정의했던 lons, lats 배열을 사용해야 합니다.


p = PLOT(lons, lats, SYMBOL='circle', /SYM_FILLED, COLOR='blue', $

  LINESTYLE=6, /OVERPLOT)


그 결과는 다음 그림과 같습니다.



그러면 이번에는 다음과 같이 경도 좌표를 35로 고정한 채 위도 좌표만 변화하는 배열을 투입하여 결과를 얻어 봅시다.


lons = [125, 127, 129, 131, 133]

lats = [35, 35, 35, 35, 35]

c = m.MapForward(lons, lats)

HELP, c

PRINT, c


출력된 결과는 다음과 같습니다.


C               DOUBLE    = Array[2, 5]

   2.2805169e-09   9.3132257e-10

       179236.01       2238.9207

       358360.17       8954.2854

       537260.69       20141.904

       715825.94       35794.794


이 결과값들을 보면 경도가 커질 경우에는 당연히 X좌표의 값들이 그만큼 커지는 것을 볼 수 있습니다. 그런데 Y좌표의 값들을 보면 0으로 고정되지 않고 약간씩 커지는 것을 볼 수 있습니다. 그 이유는 지금의 투영법 지도에서는 위도선(동일 위도를 따라가는 선)이 굴곡이 있으므로 XY좌표의 관점에서 보면 Y좌표가 일정할 수는 없기 때문입니다. 이러한 현상에 대해서는 잠시후 MapInverse 메서드를 사용한 결과에서 더 확실하게 알 수 있습니다. 앞서 했던 것처럼 5개의 지점들을 지도상에 표시해보면 그 결과는 다음 그림과 같습니다.


p = PLOT(lons, lats, SYMBOL='circle', /SYM_FILLED, COLOR='blue', $

  LINESTYLE=6, /OVERPLOT)



이제 이번에는 MapInverse 메서드를 사용해 봅시다. 이 메서드를 사용하려면 MapForward와 반대로 XY 좌표값들을 인수로 넣어줘야 합니다. 그래서 다음과 같이 X좌표 값들은 0으로 고정시키고 Y좌표 값들만 일정 간격으로 떨어진 5개의 지점들을 가정하였습니다.


xs = [0, 0, 0, 0, 0]

ys = [0, 2E5, 4E5, 6E5, 8E5]

c = m.MapInverse(xs, ys)

HELP, c

PRINT, c


여기서는 Y방향으로 2E5(m) 즉 20만m 또는 200km 만큼 간격이 떨어지도록 하였습니다. 거리 단위로 값을 주었기 때문에 이러한 지점들의 경위도 좌표가 어떻게 나올지는 결과를 봐야 알 수 있습니다. 실제로 출력된 결과는 다음과 같습니다.


C               DOUBLE    = Array[2, 5]

       125.00000       35.000000

       125.00000       36.840712

       125.00000       38.689425

       125.00000       40.544462

       125.00000       42.404075


이 결과를 보면 위도 좌표 값들은 35도부터 시작해서 약 1.8도 정도의 간격으로 떨어져 있음을 알 수 있습니다. 물론 간격이 일정하지는 않은데, 이는 투영법의 특성으로 인한 것입니다. 이 5개의 지점들의 실제 위치를 표시하려면 앞서와 같이 PLOT 함수를 사용하면 됩니다. 다만좌표는 경위도로 줘야 하기 때문에, 이번에는 다음과 같이 결과 배열인 c를 인덱싱하여 PLOT 함수에 인수로 투입해야 합니다.


p = PLOT(c[0, *], c[1, *], SYMBOL='circle', /SYM_FILLED, COLOR='red', $

  LINESTYLE=6, /OVERPLOT)


이렇게 표출된 그림은 다음과 같습니다.



이번에는 다음과 같이 Y좌표를 0으로 고정한 채 X좌표만 일정 간격으로 떨어진 5개의 지점들을 가정하여 결과를 얻어봅시다.


xs = [0, 2E5, 4E5, 6E5, 8E5]

ys = [0, 0, 0, 0, 0]

c = m.MapInverse(xs, ys)

HELP, c

PRINT, c


먼저 출력된 결과를 보면 다음과 같습니다.


C               DOUBLE    = Array[2, 5]

       125.00000       35.000000

       127.23088       34.974416

       129.45831       34.897736

       131.67885       34.770170

       133.88914       34.592071


이 결과를 보면 5개의 지점들의 경도 값들이 증가하는 것은 충분히 이해가 됩니다. 그런데 위도 값들을 보면 처음엔 35도였다가 점점 조금씩 낮아지는 것을 볼 수 있습니다. 이 역시 앞서 언급했던 투영법의 특성으로 인한 효과입니다. 5개의 지점들을 지도상에 표시한 그림을 그려보면 그 이유를 쉽게 이해할 수 있습니다.


p = PLOT(c[0, *], c[1, *], SYMBOL='circle', /SYM_FILLED, COLOR='red', $

  LINESTYLE=6, /OVERPLOT)



이 그림에서 보는 것처럼 XY 좌표계 기준으로는 Y좌표가 고정된 채 X방향으로 일정 간격으로 떨어진 지점들이지만, 경위도 좌표의 관점에서 보면 경위도선의 굴곡 또는 휘어짐에 의하여 X좌표가 커질수록 위도 좌표는 조금씩 낮아진다는 것을 알 수 있습니다. 따라서 거리 기반의XY좌표가 경위도 좌표로 어떻게 변환될 것인가는 당연히 지도 자체의 투영법의 특성에 따라 달라질 수 밖에 없습니다.


오늘은 NG 체계의 지도에서 MapForward, MapInverse 메서드를 활용하여 경위도 좌표와 Cartesian 좌표 사이의 변환을 하는 방법을 살펴보았습니다. 이와 유사한 변환 작업은 DG 체계의 지도에서도 유사 기능들인 MAP_PROJ_FORWARD, MAP_PROJ_INIT 함수들로 구현할 수 있습니다. 그래서 DG 체계에서의 변환 방법에 관해서는 조만간 게시물을 올릴 예정입니다.

LIST