GeoJSON은 모든 현대 웹 지도가 읽을 수 있는 JSON 기반 포맷입니다. Leaflet 지도에 폴리곤을 그려본 적이 있거나, MapLibre에서 벡터 레이어를 스타일링했거나, PostGIS에 서비스 영역을 저장한 적이 있다면, 파일 확장자가 다른 이름이었더라도 GeoJSON으로 작업한 적이 있는 겁니다.
이 가이드는 GeoJSON이 실제로 무엇인지, 지오메트리 타입이 무엇을 의미하는지, 실제 시스템 어디에 등장하는지, 그리고 GeoJSON 파일이 개발자의 노트북을 떠나 프로덕션에 도달했을 때 팀을 괴롭히는 함정이 무엇인지 설명합니다.
GeoJSON의 본질
GeoJSON은 지리 데이터 구조를 인코딩하기 위한 오픈 포맷이며, 2016년 IETF에 의해 RFC 7946으로 표준화되었습니다. JSON의 엄격한 부분집합입니다. 모든 GeoJSON 문서는 유효한 JSON이지만, 명세는 어떤 키가 허용되는지, 지오메트리가 어떻게 구조화되는지, 좌표가 어떻게 정렬되는지에 대한 규칙을 추가합니다.
포맷은 의도적으로 작습니다. 명세 전체에 최상위 객체 타입이 9개뿐이고, 유능한 개발자라면 전부 머릿속에 담을 수 있습니다. 그 작음이 GeoJSON이 웹 매핑의 공용어가 된 이유입니다. 읽기 쉽고, 쓰기 쉽고, 검증하기 쉽습니다.
좌표는 항상 [longitude, latitude]로 작성되며(고도는 세 번째 값으로 선택적), 좌표 참조 시스템은 WGS84로 고정됩니다. 폰의 GPS가 사용하는 것과 같은 datum이죠. 협상도, 투영 메타데이터도, 축 순서 논쟁도 없습니다. 하나의 datum, 하나의 순서, 어디서나.
지오메트리 타입
GeoJSON은 7가지 지오메트리 타입을 정의합니다. 처음 세 가지는 프리미티브입니다.
- Point: 단일 좌표, 핀, 주소, 개별 센서에 사용
- LineString: 두 개 이상의 좌표로 된 정렬된 리스트, 경로, 도로, 강에 사용
- Polygon: 닫힌 좌표 링(첫 점과 마지막 점이 동일), 건물, 필지, 행정 경계에 사용
다음 세 가지는 그 프리미티브들의 컬렉션일 뿐입니다.
- MultiPoint: 하나의 지오메트리에 여러 점, 매장 체인을 단일 피처로 표현할 때 유용
- MultiLineString: 여러 line string, 분할된 경로나 강 시스템에 사용
- MultiPolygon: 여러 폴리곤, 섬이 있는 모든 국가(즉, 거의 모든 국가)에 적합한 선택
일곱 번째인 GeometryCollection은 위 어떤 것의 혼합도 담을 수 있습니다. 명세는 이를 권장하지 않는데, 대부분의 소비자가 잘 처리하지 못하고, 거의 필요할 일이 없기 때문입니다. GeometryCollection에 손이 간다면, 보통은 모델이 사실 FeatureCollection이고 싶어 한다는 신호입니다.
Feature와 FeatureCollection
지오메트리만으로는 거의 쓸모가 없습니다. 그게 무엇을 나타내는지 알아야 하죠. 그게 Feature의 역할입니다. Feature는 임의의 메타데이터를 담은 properties 객체로 지오메트리를 감쌉니다.
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [4.8952, 52.3702]
},
"properties": {
"name": "Amsterdam Centraal",
"type": "station",
"platforms": 15
}
}
FeatureCollection은 Feature들의 리스트입니다. 실제 GeoJSON 파일은 거의 모두 FeatureCollection인데, 실제 데이터셋에는 여러 가지가 들어 있기 때문입니다.
핵심 설계 결정은 properties가 열려 있다는 것입니다. 명세는 어떤 키를 담을 수 있는지, 그 값이 어떤 타입이어야 하는지에 대해 아무 말도 하지 않습니다. 이건 버그가 아니라 기능입니다. GeoJSON이 거리 시설물, 선거 경계, 배달 구역, AIS 선박 트랙에 대해서도 포맷을 확장할 필요 없이 동작하게 해줍니다. 동시에 이는 소비자가 조심해야 한다는 의미이기도 합니다. properties.population이 존재한다고 의존한다면 직접 검증하세요. RFC 7946은 검증해주지 않으니까요.
GeoJSON이 등장하는 곳
한번 보기 시작하면 GeoJSON은 지오스페이셜 스택 어디에나 있습니다.
- 지도 라이브러리: MapLibre GL, Mapbox GL, Leaflet, OpenLayers가 모두 GeoJSON을 레이어 데이터 소스로 네이티브 소비합니다
- 벡터 타일 파이프라인: Tippecanoe 같은 도구는 GeoJSON을 받아 MVT(Mapbox Vector Tile) 세트를 만듭니다
- 지도 스타일 명세: MapLibre가 사용하는 Mapbox Style Specification은 GeoJSON을 일급 소스 타입으로 참조합니다
- 공간 데이터베이스: PostGIS, BigQuery GIS, Snowflake가 모두 전용 함수를 통해 GeoJSON을 임포트하고 익스포트합니다
- API 출력: 대부분의 현대 geocoding, isochrone, 라우팅 API가 결과를 GeoJSON Feature로 반환해, 응답을 그대로 지도에 떨어뜨릴 수 있습니다
- 경로 폴리라인: 내비게이션 응답은 보통 경로용 LineString 지오메트리를 포함해 바로 렌더링할 수 있게 합니다
- 데이터 공유: 오픈 데이터 포털, OpenStreetMap 익스포트, 정부 경계 릴리즈가 웹 사용자 대상일 때 기본값으로 GeoJSON을 씁니다
도구가 어떤 지오스페이셜 포맷이든 말할 수 있다면, 거의 확실히 GeoJSON을 말합니다.
프로덕션의 함정
GeoJSON은 첫날에는 관대하지만 90일째에는 가차없습니다. 팀이 빠지는 함정은 다음과 같습니다.
경도가 먼저. RFC 7946은 순서를 [lon, lat]로 고정합니다. 사람, 주소, 그리고 대부분의 문서는 lat, lon으로 씁니다. 둘을 바꾸는 게 GeoJSON의 가장 흔한 단일 버그이고, 점이 엉뚱한 바다에 떨어집니다.
Polygon 권취 순서. RFC 7946은 외곽 링은 반시계 방향이고 내부 링(구멍)은 시계 방향이어야 한다고 명시합니다. 많은 오래된 GeoJSON 파일이 이를 무시합니다. 어떤 렌더러는 신경쓰지 않지만, 다른 렌더러(특히 antimeridian을 가로지르는 폴리곤이 있는 Mapbox GL)는 폴리곤을 의도와 정반대로 렌더링합니다. 작은 섬이 나머지 세계 전체를 덮는 바다 한가운데의 구멍이 되어버리는 식이죠.
Antimeridian 처리. 180/-180 자오선을 가로지르는 지오메트리는 명세에 따라 분할되어야 합니다. 태평양을 가로질러 그려진 단순한 폴리곤은 행성을 먼 길로 감싼 얇은 띠로 렌더링됩니다.
WGS84 너머의 네이티브 CRS 미지원. RFC 7946은 의도적으로 구식 crs 멤버를 제거했습니다. 데이터가 국가 그리드(British National Grid, RD New, EPSG:3857)에 있다면 직렬화 전에 WGS84로 재투영해야 합니다. WGS84가 아닌 GeoJSON을 내보내는 도구는 기술적으로 비준수입니다.
파일 크기. 수백만 개의 상세 폴리곤이 든 FeatureCollection은 기가바이트로 부풀어 오를 수 있습니다. 브라우저 전송용이라면 벡터 타일로 전환하거나, Douglas-Peucker로 지오메트리를 단순화하거나, 줄바꿈 구분 GeoJSON(.ndjson)으로 스트리밍하세요.
검증. GeoJSONLint나 geojson-validation 라이브러리 같은 린터를 CI에서 사용하세요. 잘못된 권취 순서나 바뀐 좌표를 빌드 타임에 잡는 게 고객 티켓에서 잡는 것보다 쌉니다.
MapAtlas의 GeoJSON
GeoJSON은 MapAtlas 플랫폼 전반의 기본 데이터 교환 포맷입니다. Dynamic Maps 제품은 커스텀 오버레이, 스타일링, 인터랙티브 레이어를 위한 GeoJSON 소스를 전처리 없이 직접 받습니다.
Geocoding API는 매칭된 주소를 GeoJSON Feature로 반환하므로, forward geocode 결과를 필드 재매핑 없이 지도에 그대로 올리거나 PostGIS에 저장할 수 있습니다. Isochrone API는 이동 시간 영역을 GeoJSON 폴리곤으로 반환하므로, "15분 안에 도달 가능한 곳" 쿼리가 한 번의 fetch와 한 번의 addSource 호출로 화면에 올라옵니다.
GeoJSON은 화려하지 않습니다. 고정된 좌표 순서와 한 줌의 지오메트리 타입을 가진 작고 의견 있는 JSON 부분집합일 뿐입니다. 하지만 공간 데이터베이스부터 지도 캔버스까지 현대 위치 스택의 모든 레이어가 장소가 무엇인지에 합의할 수 있게 해주는 포맷입니다. 경도 순서를 맞추고, 권취를 검증하면, 나머지 스택은 알아서 잘 돌아가는 경향이 있습니다.
자주 묻는 질문
GeoJSON이란 무엇인가요?
GeoJSON은 지리 데이터를 인코딩하기 위한 JSON 기반 오픈 포맷이며, IETF에 의해 RFC 7946으로 표준화되었습니다. 작은 지오메트리 타입 집합(Point, LineString, Polygon과 그 multi 변형)과 임의의 properties로 지오메트리를 감싸는 Feature 및 FeatureCollection 객체를 정의합니다. 좌표는 항상 WGS84 datum 기준으로 경도, 위도 순서로 작성되며, 이는 모든 현대 웹 지도 라이브러리가 기대하는 형식입니다.
GeoJSON과 JSON의 차이는 무엇인가요?
GeoJSON은 추가 규칙을 가진 JSON의 엄격한 부분집합입니다. 모든 GeoJSON 문서는 유효한 JSON이지만, 모든 JSON 문서가 유효한 GeoJSON은 아닙니다. 명세는 최상위 객체 타입, 지오메트리 객체의 구조, 좌표 순서(경도가 먼저), 좌표 참조 시스템(WGS84)을 고정합니다. 그 규칙 밖에 있는 것은 그저 지리 데이터를 담은 JSON일 뿐입니다.
Shapefile이나 KML 대신 GeoJSON을 언제 써야 하나요?
데이터가 웹 스택을 통과해야 할 때마다 GeoJSON을 쓰세요. API, 브라우저, PostGIS 같은 데이터베이스, 또는 MapLibre, Leaflet, Mapbox GL, OpenLayers 어느 것이든요. Shapefile은 데스크톱 GIS에서 여전히 흔하지만 4개 이상의 파일로 배포되고 1990년대 바이너리 포맷을 사용합니다. KML은 Google Earth에는 괜찮지만 장황하고 XML 기반입니다. JSON API에 닿는 어떤 것에도 GeoJSON이 이깁니다.
GeoJSON 좌표는 왜 경도가 먼저인가요?
RFC 7946은 순서를 경도, 위도, 선택적 고도로 고정합니다. 이는 대부분의 그래픽과 GIS 시스템이 사용하는 x, y, z 관례에 맞습니다. 사람이 좌표를 쓰는 방식(51.5, -0.1처럼 위도 먼저)과는 정반대이고, 손으로 GeoJSON을 짤 때 가장 흔한 단일 버그입니다. 두 값을 바꾸면 점이 잘못된 반구에 떨어지죠. GeoJSON에서는 항상 경도가 먼저입니다.

