Virtual Earth(maps.live.com) 지도는 메르카토르 도법을 쓴다.

PHP & etc./Windows Live 2008.01.08 12:08

Virtual Earth의 지도 이미지들을 이용한 실버라이트 어플리케이션을 만들기 위해서
요즘 한참 공부하고 있습니다.

며칠 전에는 어느 정도 구현이 끝나서, 서울을 화면에 띄워 보려고,
경도 127도(E), 위도 37도 3분 을 입력했더니, 한반도 북부가 화면 중심에 뜨는 겁니다.
위도를 20도 정도로 입력을 했더니, 그제서야 서울이 보이는 겁니다.

엥? 왜이럴까?
지도 이미지 상에서의 위치가 위도와 정비례 한다고 가정하고 구현했기 때문에 맞지가 않는 거였습니다.

구글링으로 Virtual Earth가 사용한 도법이 'mercator projection'이라는 것을 알아냈습니다.

사용자 삽입 이미지

Wiki에서 찾은 자료로 이 문제를 해결할 수 있었습니다.
원문 : http://en.wikipedia.org/wiki/Mercator_projection

중간의 계산은 생략하고,
지도의 수직적 위치 y와 위도 φ (파이) 사이에는 다음과 같은 관계가 있습니다.

y = ln(tan(φ) + sec(φ))    .... (1)

φ = tan-¹(sinh(y))           .... (2)


(1)번 식을 C# 코드로 표현하면, 아래와 같습니다.

// dVerticalPosition = PI ~ - PI
double dRad = AngleToRadian(dLatitude);
double dVerticalPosition = Math.Log(Math.Tan(dRad) + 1 / Math.Cos(dRad));  
   


dLatitude : 위도 [단위 : 도]
dRad : 위도 [단위 : Radian]


(2)번 식은 아래와 같습니다.

double dRad = Math.Atan(Math.Sinh(dVerticalPosition));
double dLatitude = RadianToAngle(dRad);

dLatitude : 위도 [단위 : 도]
dRad : 위도 [단위 : Radian]


이때 알아두셔야 할 점은 위도가 90나 -90일 때는 엄청나게 큰 dVerticalPosition 값을 가지게 되어,
90일 때는 Infinity(무한대), -90일 때는 -Infinity(-무한대)를 가지게 됩니다.

따라서 어느 정도 제한이 있어야 하는데요.

위도의 최대 값은 y value가 π 값을 가질 때인,
dVerticalPosition = +/- 85.0511287798066로 한다고 합니다.


버추얼어스에서 보여주는 지도의 꼭대기 부분은 위도가 90도가 아니라
85.0511287798066도 였던 것입니다.


위에서 계산한 dVerticalPosition(π ~ -π)은 다음과 같이 사용할 수 있습니다.
지도 이미지 높이가 MAP_HEIGHT라 가정하면

dPosY =  (1 - dVerticalPosition / Math.PI) / 2 * MAP_HEIGHT;

dPosY : MAP_HEIGHT의 높이를 갖는 지도 이미지 상의 Y좌표


결론적으로 위 공식들을 적용하니 위도/경도를 입력했을 때 정확하게 그 위치를
화면 중앙에 위치시킬 수 있었습니다.



한편, 각도와 Radian 변환은 다음과 같이 하시면 됩니다.

static double AngleToRadian(double dAngle)
{
    return  dAngle / 180 * Math.PI;
}

static double RadianToAngle(double dRadian)
{
    return  dRadian / Math.PI * 180;
}


메르카토르 도법의 지도의 경우 아래와 같은 재미난 특성을 보인다고 하네요.

- 그린란드는 아프리카보다 커보인다. 하지만 사실 아프리카의 면적은 그린란드의 약 14배다.

- 알래스카는 브라질이랑 비슷하게 또는 약간 더 커보이지만, 브라질의 면적은 알래스카의 5배다.


설정

트랙백

댓글

  • BlogIcon 공도 2008.01.08 13:55 신고 ADDR 수정/삭제 답글

    오우 심플하네요!
    역시 수학식보다 코드가 편해요 ㅠ.ㅜ

  • BlogIcon 길버트 2008.01.08 16:20 신고 ADDR 수정/삭제 답글

    네~ 동감입니다! ^^

  • I뽀하하 2008.01.25 14:02 신고 ADDR 수정/삭제 답글

    감사합니다. 올린글 잘 읽고 갑니다.^^

  • BlogIcon 길버트 2008.01.26 09:27 신고 ADDR 수정/삭제 답글

    네! 도움이 되었으면 좋겠네요. ^^