2025-10-01 22:10
-
geoJson은 지리 공간 데이터를 표현하기 위한 JSON 기반의 개방형 표준 형식이다.
-
위치 정보(좌표)와 속성 정보(데이터)를 결합하여 웹 지도 등에서 쉽게 활용할 수 있도록 설계되었다.
-
단순한 텍스트 기반 구조 덕분에 인간과 기계 모두가 읽고 쓰기 쉬워 현대 웹 개발에서 사실상의 표준으로 자리 잡았다.
웹 지도 데이터의 표준 GeoJSON 완벽 해부 핸드북
우리가 매일 사용하는 지도 애플리케이션, 맛집을 검색하고 길을 찾는 그 순간에도 데이터는 끊임없이 오간다. ‘어떤 카페가 어디에 있고, 영업시간은 몇 시까지인가?‘와 같은 지리적 정보는 어떻게 컴퓨터와 웹 브라우저에서 표현될까? 이 질문에 대한 가장 현대적이고 강력한 대답이 바로 GeoJSON이다. 이 핸드북은 GeoJSON이 왜 만들어졌는지, 어떤 구조로 이루어져 있으며, 어떻게 활용하여 세상을 데이터로 그려낼 수 있는지에 대한 모든 것을 담고 있다.
1. GeoJSON의 탄생 배경 웹을 위한 지도가 필요했다
과거 지리 정보 시스템(GIS)의 세계는 복잡한 바이너리 파일 형식들의 영역이었다. ESRI의 셰이프파일(Shapefile), 구글의 KML(Keyhole Markup Language) 등 강력한 형식들이 있었지만, 이들은 웹 환경에 완벽하게 들어맞지 않았다. 셰이프파일은 .shp, .shx, .dbf 등 여러 파일로 구성되어 웹에서 다루기 번거로웠고, KML은 XML 기반이라 파싱이 무겁고 자바스크립트와의 궁합이 썩 좋지 않았다.
2000년대 중반, 웹 2.0의 바람과 함께 AJAX 기술이 부상하면서 웹은 단순한 문서 표시를 넘어 동적인 애플리케이션 플랫폼으로 진화하기 시작했다. 이 흐름 속에서 개발자들은 더 가볍고, 더 빠르며, 자바스크립트와 완벽하게 호환되는 데이터 형식이 필요했다. 바로 **JSON(JavaScript Object Notation)**이 그 해답이었다.
이러한 배경 속에서 지리 공간 데이터 커뮤니티의 개발자 그룹은 다음과 같은 질문을 던졌다. “JSON의 단순함과 유연함을 지리 데이터에 적용할 수 없을까?” 이 고민의 결과물이 바로 2008년에 처음 명세가 만들어진 GeoJSON이다.
GeoJSON의 탄생 목표:
-
단순함: 하나의 텍스트 파일로 모든 지리 정보와 속성 정보를 표현한다.
-
웹 친화성: 자바스크립트에서 추가 라이브러리 없이 즉시 객체로 변환(
JSON.parse())하여 사용할 수 있다. -
인간 가독성: 텍스트 에디터로 열었을 때 사람이 쉽게 읽고 수정할 수 있다.
-
개방성: 특정 회사나 기술에 종속되지 않는 공개 표준을 지향한다.
이러한 철학 덕분에 GeoJSON은 복잡한 GIS 데이터를 웹 브라우저 위로 손쉽게 가져오는 교량 역할을 하게 되었고, 오늘날 웹 지도 기술의 핵심 표준으로 자리매김했다.
2. GeoJSON의 핵심 구조 해부하기
GeoJSON의 구조는 매우 직관적이다. 모든 GeoJSON 데이터는 기본적으로 하나의 JSON 객체이며, 이 객체는 type이라는 필수 속성을 가진다. 이 type 속성을 통해 해당 객체가 어떤 종류의 지리 정보를 담고 있는지 알 수 있다.
GeoJSON의 핵심 구성 요소는 크게 세 가지로 나눌 수 있다.
-
지오메트리 (Geometry): 순수한 위치 정보. 즉, ‘어디’에 해당하는 점, 선, 면.
-
피처 (Feature): 지오메트리에 ‘무엇’이라는 속성 정보를 결합한 단위.
-
피처 컬렉션 (FeatureCollection): 여러 개의 피처를 하나로 묶은 집합.
2.1 지오메트리 객체 (Geometry Objects) 공간의 형태를 정의하다
지오메트리는 지도 위의 실제 모양을 나타내는 가장 기본적인 단위다. 총 7가지 유형이 존재한다.
| 지오메트리 유형 | 설명 | 좌표 구조 | 비유 |
|---|---|---|---|
Point | 단일 점 | [경도, 위도] | 지도에 찍은 압정 하나 |
LineString | 점들을 이은 선 | [[경도1, 위도1], [경도2, 위도2], ...] | A에서 B로 가는 경로 |
Polygon | 닫힌 선으로 이루어진 면 | [[[경도1, 위도1], ..., [경도1, 위도1]]] | 호수나 공원의 경계 |
MultiPoint | 여러 개의 점 | [[경도1, 위도1], [경도2, 위도2], ...] | 여러 개의 나무 위치 |
MultiLineString | 여러 개의 선 | [[[...선1...]], [[...선2...]]] | 여러 갈래의 강줄기 |
MultiPolygon | 여러 개의 면 | [[[...면1...]], [[...면2...]]] | 여러 개의 섬으로 이루어진 군도 |
GeometryCollection | 서로 다른 유형의 지오메트리 집합 | - | 점, 선, 면을 포함한 도시 계획도 |
Point (점)
가장 단순한 형태로, 단 하나의 좌표를 표현한다.
JSON
{
"type": "Point",
"coordinates": [126.9780, 37.5665]
}
coordinates배열은 [경도(longitude), 위도(latitude)] 순서를 따른다. 이는 일반적인 (x, y) 좌표계와 일치한다.
LineString (선)
두 개 이상의 점을 연결한 선을 표현한다. 경로, 도로, 강 등을 나타내는 데 사용된다.
JSON
{
"type": "LineString",
"coordinates": [
[126.9780, 37.5665],
[127.0276, 37.4979]
]
}
Polygon (면)
닫힌 영역을 표현한다. 최소 4개 이상의 좌표 쌍이 필요하며, 시작점과 끝점은 동일해야 한다. 좌표 배열은 한 단계 더 깊은데, 첫 번째 배열은 외부 경계(Exterior Ring)를, 이후의 배열들은 내부의 구멍(Interior Rings, 예: 호수 안의 섬)을 정의한다.
JSON
{
"type": "Polygon",
"coordinates": [
/* 외부 경계 (Exterior Ring) */
[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],
/* 내부 구멍 (Interior Ring) - 선택 사항 */
[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]
]
}
💡 폴리곤의 ‘감는 방향’ (Winding Order)
GeoJSON 명세는 외부 경계는 **반시계 방향(counter-clockwise)**으로, 내부 구멍은 **시계 방향(clockwise)**으로 좌표를 나열하도록 권고한다. 이는 ‘오른손 법칙’으로 설명할 수 있는데, 진행 방향을 따라 걸을 때 폴리곤의 내부가 항상 왼쪽에 있도록 하는 규칙이다. 이 규칙을 지켜야 면의 내부와 외부를 명확히 구분하고 면적 계산 등에서 오류를 피할 수 있다.
2.2 피처 객체 (Feature Object) 위치에 의미를 부여하다
지오메트리가 ‘어디에’를 나타낸다면, 피처는 여기에 ‘무엇이’라는 정보를 더한 것이다. 즉, 지오메트리와 속성(Properties)의 결합체이다.
JSON
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [127.0055, 37.5834]
},
"properties": {
"name": "흥인지문",
"type": "국보",
"constructed_year": 1398
}
}
-
type: 항상"Feature"이다. -
geometry: 위에서 설명한 7가지 지오메트리 객체 또는null이 올 수 있다. -
properties: 해당 지오메트리가 가진 속성 정보를 담는 JSON 객체다. 어떤 키와 값이든 자유롭게 넣을 수 있어 확장성이 매우 뛰어나다.
이 구조 덕분에 우리는 ‘흥인지문이라는 국보가 특정 좌표에 있다’는 완전한 정보를 하나의 객체로 표현할 수 있다.
2.3 피처 컬렉션 (FeatureCollection) 데이터의 집합을 만들다
마지막으로, 피처 컬렉션은 여러 개의 피처 객체를 배열로 묶은 것이다. 지도에 여러 장소, 여러 경로를 한 번에 표시하고자 할 때 사용된다.
JSON
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [126.9770, 37.5798]
},
"properties": { "name": "경복궁" }
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [126.9918, 37.5790]
},
"properties": { "name": "창덕궁" }
}
]
}
-
type: 항상"FeatureCollection"이다. -
features: 피처 객체들이 담긴 배열이다.
이 세 가지 핵심 요소(지오메트리, 피처, 피처 컬렉션)의 조합으로 거의 모든 종류의 지리 공간 데이터를 명확하고 구조적으로 표현할 수 있다.
3. GeoJSON 활용법 지도에 생명을 불어넣다
GeoJSON의 진정한 힘은 실제 애플리케이션에서 발휘된다. 특히 웹 지도 라이브러리와의 결합은 환상적이다.
3.1 웹 지도 시각화 (feat. Leaflet.js)
가장 대표적인 활용 사례는 웹 지도 위에 GeoJSON 데이터를 시각화하는 것이다. 오픈소스 라이브러리인 Leaflet.js를 사용하면 단 몇 줄의 코드로 GeoJSON을 지도 위에 렌더링할 수 있다.
아래는 서울의 공원 위치를 나타내는 간단한 GeoJSON 데이터를 지도에 표시하는 예제 코드다.
seoul_parks.geojson
JSON
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [127.0048, 37.5404] },
"properties": { "name": "서울숲" }
},
{
"type": "Feature",
"geometry": { "type": "Point", "coordinates": [126.9186, 37.5501] },
"properties": { "name": "월드컵공원" }
}
]
}
map.html
HTML
<!DOCTYPE html>
<html>
<head>
<title>GeoJSON Map</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<style>
#map { height: 400px; }
</style>
</head>
<body>
<div id="map"></div>
<script>
// 1. 지도 초기화
const map = L.map('map').setView([37.56, 127.0], 11);
// 2. 배경 타일 레이어 추가
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// 3. GeoJSON 데이터
const parkData = { /* seoul_parks.geojson 내용 */ };
// 4. GeoJSON 레이어를 지도에 추가
L.geoJSON(parkData, {
onEachFeature: function (feature, layer) {
// 각 피처에 팝업 추가
layer.bindPopup(feature.properties.name);
}
}).addTo(map);
</script>
</body>
</html>
이처럼 L.geoJSON() 함수 하나만으로 GeoJSON 데이터를 파싱하고, 각 피처를 지도 위의 마커나 폴리곤으로 변환하며, properties의 정보를 팝업으로 연결하는 복잡한 과정이 자동으로 처리된다.
3.2 데이터 교환 및 API
GeoJSON은 서버와 클라이언트 간에 지리 데이터를 주고받는 표준 API 형식으로 널리 사용된다. 예를 들어, ‘내 주변 5km 이내의 카페 목록’을 요청하는 API는 그 응답을 GeoJSON FeatureCollection 형식으로 전달하는 것이 일반적이다.
클라이언트는 이 데이터를 받아 파싱하고 지도에 표시하거나 목록으로 보여줄 수 있다. 텍스트 기반이므로 HTTP 통신에 매우 적합하며, 다양한 프로그래밍 언어에서 쉽게 다룰 수 있다.
3.3 클라이언트 측 공간 분석 (feat. Turf.js)
Turf.js와 같은 라이브러리를 사용하면 서버의 도움 없이 브라우저에서 직접 간단한 공간 분석을 수행할 수 있다.
-
두 지점 사이의 거리 계산
-
사용자가 그린 폴리곤의 면적 계산
-
특정 반경 내에 포함되는 지점 찾기 (Buffer)
-
두 영역이 겹치는지 여부 확인 (Intersection)
이 모든 연산이 GeoJSON 객체를 입력받아 새로운 GeoJSON 객체를 결과로 반환하는 방식으로 이루어지기 때문에, 데이터 변환 없이 직관적인 분석 파이프라인을 구축할 수 있다.
4. 심화 탐구 더 깊이 알아보기
4.1 좌표 참조 시스템 (CRS) 지구를 평면에 옮기는 약속
지구는 둥근 구체이지만 우리가 사용하는 지도는 평면이다. 이 3차원 구체의 표면을 2차원 평면에 표현하는 방법을 **좌표 참조 시스템(CRS)**이라고 한다. 세상에는 수많은 CRS가 존재하지만, GeoJSON은 강력한 단순함을 위해 하나의 표준을 채택했다.
바로 **WGS 84 (EPSG:4326)**이다. 이는 우리가 흔히 아는 경도, 위도 좌표계이며 전 세계 GPS 시스템의 표준이다. GeoJSON 명세(RFC 7946)는 모든 좌표는 WGS 84 경위도 좌표여야 한다고 규정한다. 과거에는 crs라는 멤버를 통해 다른 좌표계를 명시할 수 있었지만, 이는 혼란을 야기하여 현재는 사용이 금지되었다. 이 ‘단일 CRS’ 원칙 덕분에 서로 다른 출처의 GeoJSON 데이터를 별도의 변환 과정 없이 바로 중첩하여 사용할 수 있다.
4.2 바운딩 박스 (Bounding Box) 데이터의 공간적 범위
GeoJSON 객체에는 bbox (bounding box)라는 선택적 멤버를 추가할 수 있다. 이는 해당 지오메트리나 피처 컬렉션 전체를 포함하는 가장 작은 사각형의 범위를 나타낸다.
[서쪽 경도, 남쪽 위도, 동쪽 경도, 북쪽 위도] 순서로 정의된다.
JSON
{
"type": "FeatureCollection",
"bbox": [126.9, 37.4, 127.1, 37.6],
"features": [ /* ... 서울 지역 피처들 ... */ ]
}
bbox는 데이터를 실제로 렌더링하기 전에 지도 화면을 해당 데이터의 중심으로 이동시키거나, 데이터가 현재 화면에 보이는지 여부를 빠르게 판단하는 등 공간 인덱싱 용도로 유용하게 사용된다.
4.3 GeoJSON의 형제들 KML, Shapefile, 그리고 TopoJSON
| 특징 | GeoJSON | Shapefile | KML | TopoJSON |
|---|---|---|---|---|
| 형식 | JSON (텍스트) | 바이너리 (여러 파일) | XML (텍스트) | JSON (텍스트) |
| 웹 친화성 | 매우 높음 | 매우 낮음 | 보통 | 매우 높음 |
| 파일 크기 | 상대적으로 큼 | 작음 | 큼 | 매우 작음 (최적화) |
| 편집 용이성 | 쉬움 (텍스트 에디터) | 어려움 (전문 S/W 필요) | 보통 | 어려움 (변환 필요) |
| 주 사용처 | 웹 매핑, API | 데스크톱 GIS 분석 | 구글 어스/맵 | 웹 매핑 (최적화) |
여기서 특히 주목할 만한 것은 TopoJSON이다. TopoJSON은 GeoJSON의 확장 형식으로, ‘위상(Topology)’ 개념을 도입하여 파일 크기를 획기적으로 줄인다. 인접한 폴리곤이 공유하는 경계선을 한 번만 저장하고, 각 폴리곤은 그 경계선을 참조하는 방식으로 중복을 제거한다.
예를 들어, 대한민국의 시도 경계 GeoJSON 데이터가 있다면, 서울과 경기도가 맞닿는 경계선은 두 폴리곤에 중복으로 저장된다. TopoJSON은 이 경계선을 한 번만 저장하여 파일 용량을 최대 80%까지 줄일 수 있다. 따라서 대규모 지리 데이터를 웹으로 전송할 때는 GeoJSON을 TopoJSON으로 변환하여 사용하는 것이 효율적이다.
5. 결론 현대 지리 정보의 링구아 프랑카
GeoJSON은 복잡했던 지리 공간 데이터의 세계에 웹의 단순함과 개방성을 불어넣었다. 특정 기술이나 플랫폼에 종속되지 않는 텍스트 기반의 명확한 구조는 개발자들이 지리 데이터를 그 어느 때보다 쉽게 다룰 수 있게 만들었다.
단순한 점 하나에서 시작하여 복잡한 도시의 모습을 그려내기까지, GeoJSON은 디지털 지도 위에 우리의 세계를 표현하는 강력하고 유연한 도구다. 비록 대용량 데이터 처리에는 TopoJSON과 같은 최적화 기법이 필요할 수 있지만, 그 직관성과 범용성 덕분에 GeoJSON은 앞으로도 오랫동안 웹 지리 정보 생태계의 중심에서 **‘공용어(Lingua Franca)‘**로서 그 역할을 다할 것이다.S]]