[MongoDB] Python으로 GeoJSON 가공
Geo JSON 가공 :
Python을 사용하여 위치 데이터를 표준 형태인 GeoJSON로 가공하여 MongoDB에 저장해 보겠다.
1. GeoJSON
1.1. GeoJSON이란?
- 위치정보를 갖는 점을 기반으로 체계적으로 지형을 표현하기 위해 설계된 개방형 공개 표준 형식
- JSON을 사용하는 파일 포맷으로 국제 인터넷 표준화 기구 산하 워킹그룹에 의해 작성되고 유지
- XML을 기반으로 한 GPX와 함께 사실상 표준처럼 사용
- 특징
- WGS 84가 권장하는 [경도(longitude), 위도(latitude)] 표기법을 지원한다.
- 경도 : -180 <= 경도 <= 180
- 위도 : -90 <= 위도 <= 90
- 지형 공간 토폴로지를 인코딩하며 일반적으로 파일 크기가 더 작다.
- WGS 84가 권장하는 [경도(longitude), 위도(latitude)] 표기법을 지원한다.
-
Geo spatial query
- GeoJSON 형태
<field>: { type: <GeoJSON type> , coordinates: <coordinates> }
1.2. MongoDB의 위치 필터링
- MongoDB는 GeoJSON 개체 타입을 지원
- MongoDB는 GeoJSON 개체에 대한 geo spatial query 에 WGS84 reference 시스템을 사용한다.
Point
(점),LineString
(선),Polygon
(면),MultiPoint
,MultiLineString
,MultiPolygon
,GeometryCollection
형태의 데이터를 저장 가능하다.
- MongoDB의 위치 필터링 기능
- MongoDB에 GeoJSON 형식의 위치 데이터를 저장하면 추후 특정 지점과 반경만 입력하면 해당 지점을 기준으로 반경 내에 존재하는 데이터를 모두 가져올 수 있다.
- 이 기능을 사용하면 간단한 쿼리문으로도 쉽게 위치 데이터 추출이 가능하다.
2. GeoJSON 가공 및 저장
이 포스팅에서는 Point type의 GeoJSON 형식으로 변환해 보겠다.
2.1. 가공 전 데이터
{"store_list": [{"doro_address": "서울특별시 강남구 역삼로 310 (역삼동)", "lat": "37.499367", "lot": "127.048425", "s_name": "역삼이마트", "tel": "1522-3232"}, {"doro_address": "서울특별시 강남구 영동대로96길 12 (삼성동)", "lat": "37.510843366121534", "lot": "127.06363342044263", "s_name": "삼성동", "tel": "1522-3232"}, {"doro_address": "서울특별시 강남구 강남대로 512 (논현동)", "lat": "37.5078978596254", "lot": "127.023338614644", "s_name": "강남논현", "tel": "1522-3232"}, {"doro_address": "서울특별시 강남구 테헤란로 311 (역삼동)", "lat": "37.50383", "lot": "127.04487", "s_name": "테헤란로아남타워", "tel": "1522-3232"}, {"doro_address": "서울특별시 강남구 강남대로 396 (역삼동)", "lat": "37.4970572543978", "lot": "127.028180714381", "s_name": "강남역신분당역사", "tel": "1522-3232"}, {"doro_address": "서울특별시 강남구 영동대로 237 (대치동)", "lat": "37.500313", "lot": "127.066961", "s_name": "대치삼성프라자", "tel": "1522-3232"}, ... , {"doro_address": "서울특별시 강남구 헌릉로569길 18 (세곡동)", "lat": "37.467274319644", "lot": "127.099929726", "s_name": "강남세곡", "tel": "1522-3232"}, {"doro_address": "서울특별시 강남구 언주로 727 (논현동)", "lat": "37.51966", "lot": "127.0341", "s_name": "도산사거리", "tel": "1522-3232"}]}
2.2. 데이터 가공
from pymongo import MongoClient
import json
from pprint import pprint
with open('starbucks.json', 'r', encoding='utf8') as file:
json_data = file.readline()
dict_data = json.loads(json_data)
#pprint(dict_data)
geo_list = list()
for data in dict_data['store_list']:
geo_dict = dict()
geo_dict['doro_address'] = data['doro_address']
geo_dict['s_name'] = data['s_name']
geo_dict['tel'] = data['tel']
coordinates = [float(data['lot']), float(data['lat'])]
geo_dict['location'] = {'type': 'Point', 'coordinates': coordinates}
geo_list.append(geo_dict)
#pprint(geo_list)
2.3. 가공 후 데이터
[{'doro_address': '서울특별시 강남구 역삼로 310 (역삼동)',
'location': {'coordinates': [127.048425, 37.499367], 'type': 'Point'},
's_name': '역삼이마트',
'tel': '1522-3232'},
{'doro_address': '서울특별시 강남구 영동대로96길 12 (삼성동)',
'location': {'coordinates': [127.06363342044263, 37.510843366121534],
'type': 'Point'},
's_name': '삼성동',
'tel': '1522-3232'},
{'doro_address': '서울특별시 강남구 강남대로 512 (논현동)',
'location': {'coordinates': [127.023338614644, 37.5078978596254],
'type': 'Point'},
's_name': '강남논현',
'tel': '1522-3232'},
{'doro_address': '서울특별시 강남구 테헤란로 311 (역삼동)',
'location': {'coordinates': [127.04487, 37.50383], 'type': 'Point'},
's_name': '테헤란로아남타워',
'tel': '1522-3232'}]
2.4. MongoDB 에 저장
- MongoDB에 데이터 저장
client = MongoClient('mongodb://localhost:27017')
db = client.test
starbucks02 = db.starbucks02
# res = starbucks02.insert_many(geo_list)
# print(res.inserted_ids)
- 저장한 데이터 불러와서 확인
starbucks_all = starbucks02.find({}, {'_id': 0})
for starbucks in starbucks_all:
print(starbucks)
{'doro_address': '서울특별시 강남구 역삼로 310 (역삼동)', 's_name': '역삼이마트', 'tel': '1522-3232', 'location': {'type': 'Point', 'coordinates': [127.048425, 37.499367]}}
{'doro_address': '서울특별시 강남구 영동대로96길 12 (삼성동)', 's_name': '삼성동', 'tel': '1522-3232', 'location': {'type': 'Point', 'coordinates': [127.06363342044263, 37.510843366121534]}}
...