5 분 소요

Geo JSON 가공 :

Python을 사용하여 위치 데이터를 표준 형태인 GeoJSON로 가공하여 MongoDB에 저장해 보겠다.

1. GeoJSON

1.1. GeoJSON이란?

  • 위치정보를 갖는 점을 기반으로 체계적으로 지형을 표현하기 위해 설계된 개방형 공개 표준 형식
  • JSON을 사용하는 파일 포맷으로 국제 인터넷 표준화 기구 산하 워킹그룹에 의해 작성되고 유지
  • XML을 기반으로 한 GPX와 함께 사실상 표준처럼 사용
  • 특징
    • WGS 84가 권장하는 [경도(longitude), 위도(latitude)] 표기법을 지원한다.
      • 경도 : -180 <= 경도 <= 180
      • 위도 : -90 <= 위도 <= 90
    • 지형 공간 토폴로지를 인코딩하며 일반적으로 파일 크기가 더 작다.
  • Geo spatial query

    geojson 예시

  • 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]}}
...

[MongoDB 에 대해 더 궁금하다면?]

[Python 에 대해 더 궁금하다면?]

[데이터 가공에 대해 더 궁금하다면?]


REFERENCES