테마 선택

📚 지식 노트

AI·하드웨어·주변기기·게임·컴퓨터 시스템·이론 컴퓨터 과학·수학·개발과 운영·보안·응용 분야에 대해 알아 두면 좋은 내용을 정리한 노트다. 위에서 분야를 고르고 아래에서 노트를 고른다.

GIS와 지도

지도 앱의 파란 점 하나 뒤에는 지구를 어떤 모양으로 볼지, 둥근 면을 어떻게 평면에 펼칠지, 좌표를 어떻게 저장하고 빨리 찾을지라는 질문이 겹쳐 있다. 타원체와 좌표계, 거리와 투영, 타일 지도, 공간 인덱스와 공간 질의, 경로 찾기와 위치 개인정보를 직접 계산한 그림으로 따라간다.

목차 (12)
  1. 지구의 모양: WGS84 타원체
  2. 위경도와 좌표계: EPSG 코드
  3. 거리 계산: 하버사인과 평면 근사
  4. 지도 투영: 메르카토르와 웹 메르카토르
  5. 벡터와 래스터
  6. 타일 지도: z/x/y
  7. 지오코딩
  8. 공간 인덱스: 지오해시, R-트리, H3
  9. 공간 질의: 점–다각형 판정
  10. 경로 찾기
  11. 위치 정보와 개인정보
  12. 핵심 자료

지구의 모양: WGS84 타원체

지구는 공이 아니다. 자전 때문에 적도 쪽이 조금 부풀어, 위아래로 살짝 눌린 회전 타원체에 가깝다. 지도와 위치 계산은 먼저 "어떤 타원체를 기준으로 할지"를 정해야 하고, 그 약속을 측지 기준계(datum)라 한다. GPS가 쓰는 기준이 WGS 84다. 적도 반지름 a = 6,378,137 m, 편평률의 역수 1/f = 298.257223563으로 정의하고, 극 반지름 b = a(1 − f)는 계산으로 나온다. 둘의 차이는 약 21.4 km다. 반지름 6,000 km가 넘는 공에서 그 정도라, 눈으로는 공과 구별되지 않는다.

타원체는 매끈한 수학 모형이고, 실제 해수면을 육지 아래까지 이은 울퉁불퉁한 면(지오이드)과는 곳에 따라 꽤 어긋난다. 그래서 GPS가 주는 타원체 기준 높이와 지도에 적힌 해발 고도는 다르다. 나라마다 자기 땅에 잘 맞는 기준계를 따로 두기도 하는데, 한국은 GRS80 타원체를 쓰는 KGD2002(한국 측지계 2002)를 쓴다. GRS80과 WGS 84는 거의 같아서 일상적인 정밀도에서는 구분하지 않아도 된다. 위성 신호로 위치를 재는 원리는 위치 측정 노트에 있다.

적도 반지름과 극 반지름이 다른 WGS84 타원체a(적도)b(극)북극점선 원 = 반지름 b인 구a = 6,378,137 m1/f = 298.257223563b = a(1 − f) ≈ 6,356,752.3 ma − b ≈ 21.4 km실제로는 공과 거의 구별이 안 될 만큼덜 납작하다 — 그림은 크게 과장했다구로 근사할 때 평균 반지름 6,371 km
WGS 84 타원체. 그림은 납작함을 크게 과장했다. 실제 차이는 반지름의 1/298 남짓이라, 거리를 구로 근사해도 대개 충분하다.

위경도와 좌표계: EPSG 코드

위도는 적도에서 남북으로 잰 각도(−90°~90°), 경도는 그리니치 본초 자오선에서 동서로 잰 각도(−180°~180°)다. 서울시청 부근은 대략 북위 37.5665°, 동경 126.978°다. 위경도는 각도라서 1도의 길이가 장소마다 다르다. 위도 1도는 어디서나 약 111.2 km지만, 경도 1도는 적도에서 가장 길고 극으로 갈수록 cos(위도)만큼 줄어 서울 위도에서는 약 88.1 km다. 그래서 위경도를 그대로 x·y처럼 쓰면 거리와 넓이가 틀린다.

거리를 m로 바로 재고 싶을 때는 땅을 평면에 펼친 투영 좌표계를 쓴다. 좌표계가 워낙 많아서 번호로 부르는데, 그 목록이 EPSG 코드다. 위경도 WGS 84는 EPSG:4326, 웹 지도의 메르카토르는 EPSG:3857이다. 한국 지도에서 자주 보는 것은 KGD2002 기반 횡단 메르카토르(TM) 좌표계로, 중부 지역을 맡는 EPSG:5186은 원점을 동경 127°·북위 38°에 두고 음수가 나오지 않게 동쪽 200 km·북쪽 600 km를 더한다. 나라 전체를 한 장에 담는 EPSG:5179(UTM-K)는 127.5°를 중심으로 한다. 좌표 숫자만 보고는 어느 좌표계인지 알 수 없으니, 데이터를 주고받을 때는 늘 EPSG 코드를 함께 적는다.

EPSG 4326, 3857, 5186, 5179 좌표계의 이름과 단위, 쓰임코드이름 · 특징단위쓰임EPSG:4326WGS 84 (위경도)타원체 위의 각도 그대로도GPS, GeoJSONEPSG:3857WGS 84 / Pseudo-Mercator구로 펼친 메르카토르, ±85.06°까지m웹 지도 타일EPSG:5186KGD2002 / Central Belt 2010원점 127°E·38°N, 가산 동 200 km·북 600 kmm한국 중부 TMEPSG:5179KGD2002 / Unified CS127.5°E, 축척 0.9996, 가산 동 1,000 km·북 2,000 kmm한국 전역 한 장
자주 만나는 좌표계 넷. 각도(도)로 저장하는 4326과, m 단위 평면 좌표로 펼친 나머지 셋이 섞이면 점이 엉뚱한 바다에 찍힌다. 수치는 epsg.io의 정의를 옮겼다.

좌표계만큼 자주 틀리는 것이 순서다. 흔히 "위도, 경도" 순서로 말하지만, GeoJSON 표준(RFC 7946)은 좌표를 [경도, 위도] 순서로 적으라고 못 박는다. 서울시청은 [126.978, 37.5665]이다. 더 헷갈리는 것은 EPSG:4326의 공식 정의가 위도를 첫 축으로 둔다는 점이다. 그래서 GDAL 같은 라이브러리는 정의대로 위도 먼저 읽을지, 관례대로 경도 먼저 읽을지(OAMS_TRADITIONAL_GIS_ORDER)를 따로 정하게 한다(GDAL 좌표계 안내). 위도는 ±90을 넘을 수 없으니 한국 좌표는 순서가 뒤집히면 대개 범위 오류로 드러나지만, 경도와 위도가 둘 다 90 아래인 유럽·아프리카 좌표는 오류 없이 엉뚱한 곳에 찍힌다. 데이터를 받으면 알려진 점 하나를 지도에 찍어 보는 것이 가장 빠른 검사다.

  • GeoJSON의 다른 약속: 좌표계는 늘 WGS 84(경도·위도, 10진 도)이고 세 번째 값은 높이(m)다. 다각형의 바깥 고리는 반시계, 구멍은 시계 방향으로 돈다(오른손 법칙). 180° 경선을 가로지르는 도형은 그 선에서 잘라 둘로 나눠 적는다.

거리 계산: 하버사인과 평면 근사

지구 위 두 점 사이의 가장 짧은 길은 지구 중심을 지나는 평면이 지표를 자른 큰 원, 대원을 따른다. 지구를 반지름 6,371 km(평균 반지름)인 구로 보고 그 길이를 구하는 표준 공식이 하버사인이다. 위도 차와 경도 차의 반각 사인 제곱으로 a를 만들고, 중심각 c = 2·atan2(√a, √(1 − a))에 반지름을 곱한다. 작은 거리에서도 반올림 오차에 강한 것이 장점이다.

서울시청(약 37.5665°N, 126.978°E)과 부산시청(약 35.1796°N, 129.0756°E) 부근을 넣으면 하버사인으로 약 325.1 km다. 경도 차에 평균 위도의 cos을 곱한 뒤 피타고라스로 푸는 등장방형 근사는 325.1 km로 거의 같다. 도시 안이나 나라 하나 크기에서는 이 근사로 충분하고 계산도 싸다. 반면 위경도의 "도"를 cos 없이 그대로 평면 좌표로 놓으면 353.3 km로 8.7% 길게 나온다. 경도 1도를 위도 1도와 같은 길이로 쳤기 때문이다. 구 모델 자체도 타원체와 다르지만, 그 오차는 대개 0.3% 아래이고 적도를 가로지르는 경우에도 0.55% 정도라는 것이 Movable Type 해설의 설명이다. 그보다 정밀해야 하면 타원체 위에서 반복 계산하는 빈센티 공식 같은 방법을 쓴다.

서울과 부산 사이 거리를 세 가지 방법으로 계산한 비교서울부산325 km경도 1도 ≈ 89.5 km, 위도 1도 ≈ 111.2 km(평균 위도)계산한 거리하버사인325.1 km등장방형 근사325.1 km (+0.01%)위경도 그대로353.3 km (+8.7%)구 모델 자체의 오차는 보통 0.3% 아래
서울–부산 거리를 세 방법으로 잰 결과. 등장방형 근사는 하버사인과 0.01% 안팎으로 같고, 위경도를 그냥 평면처럼 쓴 계산만 크게 틀린다.

지도 투영: 메르카토르와 웹 메르카토르

공의 껍질은 찢거나 늘이지 않고는 평면에 펼 수 없다. 그래서 모든 평면 지도는 각도·넓이·거리·방향 가운데 무언가를 희생한다. 이 펼치는 규칙이 투영이다. 1569년 게라르두스 메르카토르가 내놓은 메르카토르 투영은 각도를 지킨다(정각). 지도 위 직선이 일정한 나침반 방위로 가는 항로가 되어 항해에 쓰였다. 대가는 넓이다. 위도 φ에서 길이를 sec φ배, 넓이를 sec²φ배 부풀린다. 30°에서 넓이 ×1.33, 60°에서 ×4, 그린란드 중앙인 73° 부근에서 약 ×11.7이다. 지도에서 그린란드가 아프리카만 해 보이지만 실제로는 아프리카가 약 14배 크다.

구글 지도·OpenStreetMap 같은 웹 지도가 쓰는 것이 웹 메르카토르(EPSG:3857)다. 타원체 좌표를 구처럼 펼친 단순화된 메르카토르라, epsg.io는 이를 인정된 측지 좌표계가 아니라고 적고 쓰임을 웹 지도와 시각화로 한정한다. 정식 메르카토르(EPSG:3395)와 배율이 0.7% 정도 어긋나기 때문이다. 세계 전체가 정사각형이 되도록 위도 ±85.0511°에서 잘라 극지방은 아예 없다. 화면에서 길이를 재면 서울 위도에서는 실제보다 1.26배 길게 나오므로, 거리·넓이 계산은 투영 좌표가 아니라 위경도(하버사인)나 해당 지역용 좌표계(한국이면 5186·5179)로 한다. 넓이를 지키는 투영(알베르스·몰바이데 등)은 통계 지도에 쓴다. 단계구분도에서 넓은 땅이 커 보이는 문제는 데이터 시각화 노트에 있다.

메르카토르 지도에서 위도에 따라 커지는 같은 크기의 원과 위도별 넓이 배율0°30°50°65°땅 위에서는모두 같은 원넓이 배율 sec²φ적도×1.0030°×1.33서울 부근 37.5°×1.5960°×4.00그린란드 중앙 73°×11.70
메르카토르의 넓이 왜곡. 왼쪽은 지구 위에서 같은 크기인 원을 위도별로 놓은 것이다(티소 지시원). 위도가 높을수록 원이 커지고, 위도선 간격도 벌어진다.

벡터와 래스터

지리 데이터는 두 가지 모양으로 담는다. 벡터는 좌표로 그린 도형이다. 가게 위치는 점, 도로와 강은 선, 건물·행정 구역은 다각형(면)이다. 속성(이름, 도로 등급)을 도형마다 붙일 수 있고, 아무리 확대해도 깨지지 않는다. 웹에서 가장 흔한 형식은 JSON으로 도형을 적는 GeoJSON이다. Point·LineString·Polygon과 그 묶음(Multi…, GeometryCollection)을 쓰며, 좌표는 경도, 위도 순서다. "위도, 경도"로 말하는 습관 때문에 뒤집어 넣어 남극 근처에 점이 찍히는 실수가 아주 흔하다. 파일 기반의 셰이프파일·GeoPackage, 지도 타일용 벡터 타일도 있다.

래스터는 땅을 고른 격자로 나누고 칸마다 값 하나를 담은 것, 곧 이미지다. 위성·항공 사진, 기온·강수량 분포, 땅의 높이를 담은 수치 표고 모델(DEM)이 래스터다. 칸 크기가 해상도이고, 해상도를 두 배로 하면 칸 수는 네 배가 된다. DEM에서는 이웃 칸과의 높이 차로 경사·방향을 구하고, 물이 흘러갈 길과 산 그림자를 계산한다. 벡터는 "어디에 무엇이 있나", 래스터는 "곳곳의 값이 얼마인가"에 맞고, 둘을 겹쳐 분석하는 일이 GIS의 일상이다.

점, 선, 면으로 된 벡터 데이터와 높이 값 격자로 된 래스터 데이터벡터점(Point)선(LineString)면(Polygon){"type": "Point", "coordinates": [126.978, 37.5665]}GeoJSON은 경도, 위도 순서다래스터(DEM, m)120135150160150130130155185200175140135170220240190145125150190205170135110125140150135120칸 크기가 곧 해상도 · 진할수록 높다
왼쪽은 점·선·면 세 벡터 도형과 GeoJSON 한 줄, 오른쪽은 칸마다 높이(m)를 담은 작은 DEM 래스터다. 래스터의 진하기는 높이를 0~1로 정규화한 값이다.

타일 지도: z/x/y

세계 지도를 한 장의 거대한 이미지로 보내면 아무도 기다려 주지 않는다. 웹 지도는 웹 메르카토르로 편 세계를 256×256 픽셀 타일로 잘라 둔다. 줌 0에서는 세계 전체가 타일 하나이고, 줌이 하나 오를 때마다 타일 하나가 넷으로 쪼개진다. 줌 z의 타일은 축마다 2^z개, 모두 4^z개다. 줌 10이면 1,048,576개, 줌 18이면 68,719,476,736개다. 브라우저는 지금 화면에 보이는 몇 장만 /z/x/y.png 주소로 받아 붙이니, 줌과 이동이 빠르고 같은 타일을 모든 사용자가 캐시로 나눠 쓴다.

위경도에서 타일 번호를 구하는 공식은 OpenStreetMap 위키에 있다. n = 2^z일 때 x = n·(경도 + 180)/360, y = n·(1 − asinh(tan φ)/π)/2를 내림한다. x는 경도에 비례하지만 y는 메르카토르의 세로 좌표라 위도에 비례하지 않는다. 원점은 왼쪽 위(북서쪽)다. 요즘은 이미지 대신 도형 데이터를 타일로 보내 브라우저가 직접 그리는 벡터 타일도 흔하다. 글자 방향을 돌리고 색을 바꾸는 일을 서버를 다시 거치지 않고 할 수 있다.

줌이 오를 때마다 쪼개지는 타일 격자와 서울이 든 타일 번호줌 z = 0n = 2^0 = 1타일 수 4^0 = 1x = n(경도 + 180)/360 = 0.85y = n(1 − asinh(tan φ)/π)/2 = 0.39내림 → 타일 0/0/0줌 z = 1n = 2^1 = 2타일 수 4^1 = 4x = n(경도 + 180)/360 = 1.71y = n(1 − asinh(tan φ)/π)/2 = 0.77내림 → 타일 1/1/0줌 z = 2n = 2^2 = 4타일 수 4^2 = 16x = n(경도 + 180)/360 = 3.41y = n(1 − asinh(tan φ)/π)/2 = 1.55내림 → 타일 2/3/1줌 z = 3n = 2^3 = 8타일 수 4^3 = 64x = n(경도 + 180)/360 = 6.82y = n(1 − asinh(tan φ)/π)/2 = 3.10내림 → 타일 3/6/3줌 z = 4n = 2^4 = 16타일 수 4^4 = 256x = n(경도 + 180)/360 = 13.64y = n(1 − asinh(tan φ)/π)/2 = 6.20내림 → 타일 4/13/6줌 z = 15n = 2^15 = 32,768타일 수 4^15 = 1,073,741,824x = n(경도 + 180)/360 = 27941.82y = n(1 − asinh(tan φ)/π)/2 = 12689.48내림 → 타일 15/27941/12689적도빨간 점 = 서울위아래 끝은 위도 ±85.0511°에서 자른다URL 예: …/{z}/{x}/{y}.png
1 / 6

줌 0: 세계 전체가 256×256 픽셀 타일 하나다. 서울(37.5665°N, 126.978°E)은 당연히 0/0/0.

웹 지도 타일. 줌 z에서 세계를 2^z × 2^z 칸으로 나누고, 왼쪽 위(북서쪽)부터 x는 동쪽으로, y는 남쪽으로 센다.

지오코딩

사람은 주소로 말하고 컴퓨터는 좌표로 계산한다. 주소 문자열을 좌표로 바꾸는 일이 지오코딩, 그 반대가 역지오코딩이다. 지오코딩은 생각보다 지저분하다. 먼저 입력을 정규화한다. 띄어쓰기·약칭("서울시" → "서울특별시")·오타를 고치고, 시·구·도로명·건물 번호로 쪼갠다. 그다음 주소 데이터베이스(건물마다 대표 좌표가 있다)와 맞춘다. 정확히 맞으면 그 건물의 좌표를, 번호만 없으면 도로 구간에서 번호 비율로 끼워 넣은 좌표를, 그것도 안 되면 동·구의 중심점을 돌려준다. 그래서 좋은 지오코더는 좌표와 함께 "건물 수준/도로 수준/행정 구역 수준" 같은 정확도 등급을 알려 준다.

한국에는 지번 주소와 도로명 주소가 함께 쓰여 한 건물에 주소가 둘 이상이고, 새로 난 길이나 건물은 데이터베이스에 늦게 들어간다. 역지오코딩은 좌표에서 가장 가까운 건물·도로를 찾는 공간 질의라, 아래의 공간 인덱스가 있어야 빠르다. 여러 주소를 한꺼번에 변환하는 일은 외부 서비스의 요청 한도와 이용 약관을 확인하고 한다.

주소에서 좌표로 가는 지오코딩과 반대 방향의 역지오코딩주소 문자열"○○시 △△구□□로 12"정규화·분해시·구·도로명·번호오타·약칭 바로잡기주소 DB와 맞추기정확히 일치?없으면 근사 일치좌표위도·경도+ 정확도 등급역지오코딩: 좌표 → 가장 가까운 주소·장소같은 건물에 주소가 여럿(지번·도로명)일 수 있고, 새 길은 DB에 늦게 들어간다
지오코딩의 흐름. 정규화와 맞추기에서 대부분의 실패가 생긴다. 역지오코딩(아래 화살표)은 좌표에서 가장 가까운 주소를 찾는 최근접 이웃 질의다.

공간 인덱스: 지오해시, R-트리, H3

"내 주변 1 km 안의 카페"를 찾을 때 가게 수백만 곳과 하나하나 거리를 잴 수는 없다. 데이터베이스의 B-트리는 값 하나의 크기 순서로 정렬하는데, 위치는 위도와 경도 두 값이라 그대로는 정렬이 안 된다. 공간 인덱스는 2차원을 다루는 요령이다. 가장 단순한 것이 지오해시다. 2008년 구스타보 니에메예르가 공개한 방식으로, 경도와 위도의 범위를 번갈아 반으로 나누며 "위쪽 절반이면 1, 아래쪽이면 0"을 적고, 이 비트를 5개씩 묶어 base32 글자(0–9와 a·i·l·o를 뺀 소문자)로 쓴다. 서울시청 부근은 6글자로 "wydm9q"이다.

서울 좌표를 지오해시로 인코딩하며 경도·위도 범위가 반씩 줄어드는 단계 그림경도-180180위도-9090[-180.000, 180.000][-90.000, 90.000]비트 (없음)지오해시 …[0.000, 180.000][-90.000, 90.000]비트 1지오해시 …[0.000, 180.000][0.000, 90.000]비트 11지오해시 …[90.000, 180.000][0.000, 90.000]비트 111지오해시 …[90.000, 180.000][0.000, 45.000]비트 1110지오해시 …[90.000, 135.000][0.000, 45.000]비트 11100지오해시 w[90.000, 135.000][22.500, 45.000]비트 11100 1지오해시 w[112.500, 135.000][22.500, 45.000]비트 11100 11지오해시 w[112.500, 135.000][33.750, 45.000]비트 11100 111지오해시 w[123.750, 135.000][33.750, 45.000]비트 11100 1111지오해시 w[123.750, 135.000][33.750, 39.375]비트 11100 11110지오해시 wy[123.750, 129.375][33.750, 39.375]비트 11100 11110 0지오해시 wy[123.750, 129.375][36.563, 39.375]비트 11100 11110 01지오해시 wy[126.563, 129.375][36.563, 39.375]비트 11100 11110 011지오해시 wy[126.563, 129.375][36.563, 37.969]비트 11100 11110 0110지오해시 wy[126.563, 127.969][36.563, 37.969]비트 11100 11110 01100지오해시 wyd
1 / 16

서울(37.5665, 126.978)을 인코딩한다. 경도 −180~180, 위도 −90~90 전체에서 시작한다.

지오해시. 경도·위도 범위를 번갈아 반씩 줄여 얻은 비트를 5개씩 묶어 글자로 쓴다. 글자가 길수록 칸이 작아진다.

지오해시는 그냥 문자열이라 일반 인덱스로 앞부분 일치 검색을 할 수 있고, 글자가 길수록 칸이 작아진다(6글자면 오차 약 ±0.61 km). 약점은 경계다. 바로 옆 점이라도 칸 경계(특히 적도·본초 자오선·180° 경선)를 넘으면 앞글자가 전혀 달라지므로, 실제로는 내 칸과 이웃 여덟 칸을 함께 찾는다. 앞글자가 같으면 가깝지만, 가깝다고 앞글자가 같지는 않다.

R-트리는 1984년 안토닌 구트만이 제안했다. 가까운 객체끼리 묶어 그 묶음을 감싸는 최소 경계 사각형(MBR)을 한 단계 위에 적고, 이를 B-트리처럼 균형 잡힌 나무로 쌓는다. 질의 영역과 겹치지 않는 사각형은 그 안을 통째로 건너뛰니, 점뿐 아니라 선·다각형도 색인할 수 있다. 사각형끼리 덜 겹치게 넣는 개량판 R*-트리도 널리 쓰인다. PostGIS의 GiST 인덱스, SQLite의 R*Tree 모듈이 이 계열이다. H3는 Uber가 만든 육각형 격자 인덱스다. 육각형은 이웃 여섯 칸의 중심이 모두 같은 거리에 있어, 이동·수요를 칸 단위로 모아 분석하고 이웃으로 퍼뜨리는 계산이 사각형 격자보다 고르다.

R-트리의 경계 사각형과 나무 구조, H3 육각형 격자R-트리: 묶고 겹겹이R1R2질의 영역: R1은 안 겹쳐 통째로 건너뜀abcdef뿌리R1abcR2defH3: 육각형 칸이웃 여섯 칸이 모두중심에서 같은 거리
왼쪽은 R-트리. 점 여섯 개를 사각형 R1·R2로 묶고, 점선의 질의 영역은 R2하고만 겹치므로 R1 쪽은 들여다보지 않는다. 오른쪽은 H3의 육각형 칸과 이웃 여섯 칸이다.

공간 질의: 점–다각형 판정

GIS의 흔한 질문은 도형 사이의 관계다. 이 점이 이 구역 안에 있나(배달 가능 지역, 행정 구역 찾기), 두 도형이 겹치나, 이 점에서 가장 가까운 것은 무엇인가, 이 선에서 100 m 이내는 어디인가(버퍼). PostGIS·SpatiaLite 같은 공간 데이터베이스는 이런 관계를 ST_Contains·ST_Intersects·ST_DWithin 같은 함수로 제공하고, 먼저 공간 인덱스로 사각형이 겹치는 후보만 추린 뒤 정확한 도형 계산을 한다. 데이터베이스의 인덱스와 질의 실행 일반은 데이터베이스 노트에 있다.

"점이 다각형 안에 있나"를 푸는 고전이 광선 투사(짝홀 규칙)다. 늦어도 1962년 시므랏의 알고리즘으로 알려졌다. 점에서 한 방향으로 광선을 쏘아 다각형의 변을 몇 번 건너는지 센다. 안에 있는 점은 밖으로 나가려면 홀수 번 건너야 하므로 홀수면 안, 짝수면 밖이다. 오목한 다각형에도 그대로 통한다. 까다로운 것은 광선이 꼭짓점을 정확히 지날 때다. 한 꼭짓점을 두 변이 공유하니 두 번 세일 수 있는데, 변의 한쪽 끝만 포함하는 반열린 구간으로 세면 해결된다. 경계 위의 점이나 부동소수점 오차는 따로 허용 오차를 두어 다룬다.

오목한 다각형 안팎의 두 점에서 쏜 광선과 변을 건너는 횟수AA: 3번(x = 90, 130, 200) → 안BB: 2번(x = 130, 200) → 밖빨간 점 = 광선이변을 건넌 곳광선이 꼭짓점을 지나면두 번 세지 않도록변의 한쪽 끝만 포함한다오목한 다각형이어도 같은 규칙이 통한다 — 구멍 난 다각형은 고리마다 센다
광선 투사. A에서 쏜 광선은 변을 세 번(홀수) 건너므로 안이고, 오목하게 파인 곳의 B는 두 번(짝수) 건너므로 밖이다. 교차 위치는 판정 함수가 계산했다.

경로 찾기

길 찾기는 도로망을 그래프로 보는 데서 시작한다. 교차로가 노드, 도로 구간이 간선이고, 간선에는 길이 대신 예상 소요 시간을 무게로 붙인다. 일방통행은 방향 있는 간선, 회전 금지는 교차로 안의 특별한 규칙이다. 그 위에서 최단 시간 경로를 찾는 기본이 다익스트라 알고리즘이다. 출발점에서 가장 가까운 확정되지 않은 노드를 하나씩 확정하며 이웃의 거리를 고친다. 동작과 증명, 우선순위 큐로 빠르게 만드는 법은 알고리즘 › 그래프의 다익스트라 절에 있다.

나라 하나의 도로망은 노드가 아주 많아 다익스트라를 그대로 돌리면 느리다. A*는 "목적지까지 직선거리" 같은 낙관적 추정을 더해 목적지 쪽으로 먼저 뻗는다. 하버사인 거리는 실제 도로 거리보다 길 수 없으니 좋은 추정치다. 실제 길 찾기 서비스는 여기에 미리 계산을 더한다. 중요하지 않은 노드를 지름길 간선으로 건너뛰게 해 두는 축약 계층(contraction hierarchies) 같은 기법으로 대륙 규모 경로를 아주 짧은 시간에 답한다. 실시간 교통으로 간선 무게가 계속 바뀌는 것이 또 다른 어려움이다.

도로망 그래프에서 다익스트라로 찾은 최단 시간 경로4분2분5분1분9분2분6분3분출발가나다라도착최단: 출발 → 나 → 가 → 다 → 라 → 도착 = 13분확정 순서: 출발, 나, 가, 다, 라, 도착 — 가까운 교차로부터 하나씩 확정한다
도로망의 최단 시간 경로. 나 → 라로 바로 가는 길(9분)보다 가·다를 돌아가는 길이 1분 빠르다. 다익스트라는 가까운 교차로부터 하나씩 확정하며 이를 찾는다.

위치 정보와 개인정보

위치는 가장 민감한 개인정보 가운데 하나다. 밤에 머무는 곳은 집, 낮에 머무는 곳은 직장이고, 병원·종교 시설·집회 장소 방문은 건강·신념을 드러낸다. 이름을 지운 위치 기록도 집·직장처럼 자주 머무는 점 몇 개로 사람을 다시 알아낼 수 있어서, 단순히 이름만 지우는 것은 익명화가 되지 못한다. 한국에는 위치 정보만 따로 다루는 법률(위치정보의 보호 및 이용 등에 관한 법률)이 있을 만큼 별도로 보호한다.

  • 정밀도 줄이기: 기능에 필요한 만큼만 남긴다. 날씨는 도시, 동네 소식은 동 수준이면 된다. 위도 소수 자릿수 하나가 칸 크기를 10배 바꾼다.
  • 모아서 보여 주기: 개인 점 대신 칸(H3·지오해시) 단위 개수로 집계하고, 사람이 적은 칸은 숨긴다.
  • 덜 오래 두기: 실시간 위치는 쓰고 나면 지우고, 기록은 보관 기간을 정한다.
  • 새는 곳 막기: 사진의 EXIF에 촬영 위치가 남고, 운동 기록 앱의 경로 공개로 집 위치가 드러나기도 한다. 올리기 전에 위치 메타데이터를 지운다.
  • 동의와 표시: 브라우저·OS는 위치 권한을 따로 묻고, 앱은 왜 필요한지와 언제 쓰는지를 보여 준다. 브라우저가 위치를 어떻게 고르는지는 위치 측정 노트, GPS 신호와 무선 측위는 무선 통신 노트에 있다.
위도 소수점 자릿수에 따른 위치 정밀도위도 값한 칸의 크기(로그 눈금)대략 이만큼37소수 0자리111.2 km나라·지방37.5소수 1자리11.1 km도시37.56소수 2자리1.1 km동네37.566소수 3자리111.2 m거리·큰 건물37.5665소수 4자리11.1 m건물·나무37.56650소수 5자리1.1 m사람 한 명공유할 때는 필요한 만큼만(예: 동네 수준 2자리) 남기고 자른다
위도 소수 자릿수와 정밀도(구 근사). 소수 셋째 자리면 약 111 m, 다섯째 자리면 약 1.1 m 칸이다. 경도 칸은 cos(위도)만큼 더 좁다.

핵심 자료

지도 위에 데이터를 칠하는 법은 데이터 시각화 노트, 위치를 재는 원리는 위치 측정 노트에 있다.

자료종류요지링크
EPSG:5186 KGD2002 / Central Belt 2010좌표계 정의한국 중부 지역 TM 좌표계. GRS80 타원체, 원점 127°E·38°N, 가산 동 200,000 m·북 600,000 m. 같은 사이트에서 다른 코드도 찾아볼 수 있다.epsg.io
EPSG:3857 WGS 84 / Pseudo-Mercator좌표계 정의웹 지도가 쓰는 구형 메르카토르. 측지 좌표계로 인정되지 않으며 쓰임을 웹 지도와 시각화로 적어 둔 이유가 나온다.epsg.io
Slippy map tilenames위키위경도 ↔ 타일 번호 공식, 줌별 타일 수, 위도 한계 85.0511°, 여러 언어의 예제 코드.OpenStreetMap Wiki
Calculate distance, bearing and more between Latitude/Longitude points해설하버사인·등장방형 근사·방위각·중간점 공식을 자바스크립트로 설명하고, 구 모델의 오차 범위를 적었다.Movable Type Scripts
H3공식 문서지구를 육각형 칸으로 나누는 계층형 공간 인덱스. Uber가 데이터 분석을 위해 만들어 Apache 2 라이선스로 공개했다.h3geo.org