최근 책을 보다가 지오해시에 대해 언급이 되어 정리하는 시간을 가져본다
지오해시(Geohash)는 공간 인덱싱(spatial indexing) 기법으로, 지리적 좌표(위도와 경도)를 이진수로 변환한 후, 다시 문자열로 인코딩하는 방식을 말한다. 이 방식은 위치 정보를 효율적으로 저장하고 검색할 수 있게 해주며, 특정한 패턴을 통해 근처 위치를 쉽게 식별할 수 있게 한다.
위도와 경도의 압축: 위도와 경도를 짧은 문자열로 압축하여 저장하거나 검색할 때 사용하기에 용이하다.
공간적 근접성 유지: 지오해시의 문자열 앞부분이 동일하다면, 해당 위치들이 가까운 지역에 있음을 나타낸다.
계층적 구조: 지오해시 문자열의 길이에 따라 위치의 정확도가 달지게된다 따라서 문자열이 길수록 더 세밀한 지역을 나타내고, 짧을수록 더 넓은 범위를 나타낸다.
Level 1: 지오해시의 첫 글자에 해당하는 부분으로, 지구 전체를 대략적으로 4개의 큰 구역으로 나눈다.
Level 2: 두 번째 글자가 추가되면서 각 구역이 더 작은 16개의 구역으로 세분화된다.
Level 3: 세 번째 글자가 추가되면 더 작은 구역으로 나뉘며, 점점 더 구체적인 위치를 나타내게 된다.
...
지오해시는 12단계 (level) 의 정밀도를 가지게되는데, 레벨에 따라 격자 크기를 결정하게된다.
| Geohash 레벨 | Geohash 문자열 길이 | 격자 너비 (동서 방향) | 격자 높이 (남북 방향) |
|---|---|---|---|
| 1 | 1 | 5,000 km | 5,000 km |
| 2 | 2 | 1,250 km | 625 km |
| 3 | 3 | 156 km | 156 km |
| 4 | 4 | 39.1 km | 19.5 km |
| 5 | 5 | 4.89 km | 4.89 km |
| 6 | 6 | 1.22 km | 0.61 km |
| 7 | 7 | 153 m | 153 m |
| 8 | 8 | 38.2 m | 19.1 m |
| 9 | 9 | 4.77 m | 4.77 m |
| 10 | 10 | 1.19 m | 0.597 m |
| 11 | 11 | 149 mm | 149 mm |
| 12 | 12 | 37.2 mm | 18.6 mm |
지오해시 작동원리에서 좀더 상세하게 다뤄보자
위도와 경도를 분리해 이진수로 변환

이미지 출처: Velog[사진속의 램프]
위도와 경도의 이진값을 교차 결합
결합된 이진수를 Base32로 인코딩
| 이진수 | Base32 문자 |
|---|---|
| 00000 | A |
| 00001 | B |
| 00010 | C |
| 00011 | D |
| 00100 | E |
| 00101 | F |
| 00110 | G |
| 00111 | H |
| 01000 | J |
| 01001 | K |
| 01010 | M |
| 01011 | N |
| 01100 | P |
| 01101 | Q |
| 01110 | R |
| 01111 | S |
| 10000 | T |
| 10001 | V |
| 10010 | W |
| 10011 | X |
| 10100 | Y |
| 10101 | Z |
| 10110 | 2 |
| 10111 | 3 |
| 11000 | 4 |
| 11001 | 5 |
| 11010 | 6 |
| 11011 | 7 |
| 11100 | 8 |
| 11101 | 9 |
서울의 대략적인 위치를 위도와 경도로 표기하였을때 위도: 37.5665° 경도: 126.9780°
위도는 -90 ~ +90 경도는 -180에서 +180 사이의 값이다. 위도값으로 범의를 좁혀 보겠다.
처음 범위는 [-90, +90]입니다. 중간값은 0으로, 서울의 위도는 0보다 크기 때문에 1을 할당하고, 범위를 [0, +90]으로 축소합니다.
[0, 90]에서 중간값은 45입니다. 37.5665는 45보다 작으므로 0을 할당하고, 범위를 [0, 45]로 축소합니다.
[0, 45]에서 중간값은 22.5입니다. 37.5665는 22.5보다 크므로 1을 할당하고, 범위를 [22.5, 45]로 축소합니다.
이 과정을 반복하여 위도의 이진값을 점차 좁혀 나갑니다.
이렇게 단계별로 위도 값을 이진수로 변환할 수 있으며, 경도도 유사한 방식으로 처리된다.
level6 까지 구하였을 때 위도 : 101101010110110, 경도 111001111001100
위도와 경도의 이진수의 교차결합 = 1110011110011001001110100110110
위도와 경도의 이진수 값을 5비트로 나눌경우 11100,11110,01100,10011,01001,10110
wy이를 Base32로 변환 하였을때 wydm9q

다시 한번 정리를 해보면서 어떻게 해시값을 구하고 세분화 하는지 정리해보는 시간을 가질 수 있었고, 지오해시관련 라이브러리를 사용해보거나 직접 한번 코드로 구현해보는 시간도 가져보면 좋겠다는 생각도 들었다.
또 시간을 내서 균등격자방식이나 쿼드트리 등 다른 위치를 식별하는 방법에 대해 다뤄볼 생각이다.