·조회수 63

Nominatim을 이용해서 주소 경위도 변환 하기

들어가며

이번에 만들고 있는 개인 앱에서 주소를 위·경도로 변환하거나, 반대로 위·경도를 주소로 바꿔야 하는 기능이 필요해졌습니다. 처음에는 많은 개발자들이 그렇듯 구글 지도 API를 고려했는데, 1,000회 호출당 5달러라는 과금 체계가 부담이 되었습니다. 예를 들어 하루 1,000번씩 호출만 해도 한 달에 150달러(약 20만 원) 정도가 나오니, 테스트나 초기 운영 단계에서조차 비용 압박이 상당했죠.

반면, 네이버 지도 API1,000회에 500원으로 훨씬 저렴하지만 국내 서비스에 특화되어 있기 때문에 글로벌 타겟이라면 사용할 수 없다는 한계가 있습니다.

이런 고민 끝에, 오픈 스트리트맵(OpenStreetMap) 데이터를 활용해 무료로 주소 변환을 할 수 있는 Nominatim을 직접 호스팅하기로 결정했습니다. 구글이나 네이버와 달리 사용량에 따른 추가 과금이 없고, 전 세계 지도 정보를 바탕으로 원하는 대로 커스터마이징할 수 있다는 점이 가장 큰 장점입니다. 물론 초기 셋팅(서버 구축, 데이터 인덱싱, 운영 노하우) 과정이 번거롭긴 하지만, 한 번 경험해 두면 나중에는 훨씬 수월하게 적용할 수 있어 장기적인 운영 비용을 크게 절감할 수 있으리라 기대합니다.

Nominatim 소개

Nominatim오픈스트리트맵(OpenStreetMap) 프로젝트에서 제공되는 주소 검색(Geocoding) 및 역지오코딩(Reverse Geocoding) 엔진이다. 간단히 말해 "장소 이름이나 주소를 위·경도로 바꿔주고, 위·경도를 주소로 바꿔주는" 소프트웨어라고 생각하면 된다.

작업 순서

작업은 사실 별거 없었다. 도커로 이미지를 다운로드해서 띄우면 처음에 자동으로 초기화 과정을 진행하고 마무리되면 바로 사용할 수 있다. 다만, 전 세계 지도 데이터를 가지고 있다보니 원본 파일 용량만 80GB로 방대하다.

  1. 전체 OSM 파일 다운로드 (80GB)

    원본 파일의 용량은 80GB이지만, 사용하기 위해 DB에 초기화하면 800GB로 증가하므로 주의할 것

wget https://planet.openstreetmap.org/pbf/planet-latest.osm.pbf
  1. Docker.compose에 작성하기
  nominatim:
      image: mediagis/nominatim:4.3
      volumes:
        - nominatim-db:/var/lib/postgresql/14/main
        - nominatim-data:/nominatim
      environment:
        - PBF_PATH=/nominatim/planet-latest.osm.pbf
        - IMPORT_OSM=true

이렇게 docker-compose를 띄우면 약 20~30분 후에 서버가 사용할 수 있는 상태가 된다.

새롭게 알게 된 것

  1. 용량이 너무 큰 경우 필요에 따라 데이터를 필터링해서 줄일 수 있다. 나는 행정 지역 단위로도 충분했기에 이렇게 필터링하자 80GB의 데이터가 1GB로 줄었다. 이렇게 용량을 줄이는 것이 중요한 이유는 1GB의 필터링된 데이터 조차도 DB에 입력하면 40GB로 늘어나기 때문이다.

행정구역 단위로 필터링

osmium tags-filter planet-latest.osm.pbf nwr boundary=administrative -o=planet-admin.pbf
  1. 최초에 실행할경우 원본 지도 데이터를 이용해서 초기화하는 작업이 진행되는데 이때 많은 정보가 DB에 입력되므로, 네트워크 연결을 사용하지 말 것. 기존 대비 속도가 10배이상 느려질 수 있다. 도커 스웜을 사용하고 있어서 nfs를 사용해서 설정했는데, 30분이면 끝나는 작업이 4시간 이상 소요되었고, 이마저도 중간에 I/O 에러가 발생해서 끊어지는 문제가 발생했다.

마무리

확실히 활용할 수 있는 개인 서버가 생기니까 서비스 개발이 여러모로 더 편해진 것 같다. 이 정도의 서비스를 오픈소스로 하루만에 띄워서 사용할 수 있음에 감사하다.

김지식
김지식
웹, 앱 개발자입니다.

댓글

댓글을 불러오는 중...