반응형

 

1. 지형정보 가져오기

Leaflet 을 사용할때 layer는 보통 geojson을 사용하게 됩니다.

 

지형이나 특정 지역을 표시할때, geojson을 구해서 사용해야 하는데, OSM( open street map)을 이용하면, 이미 만들어진 지역의 정보를 구할수 있습니다. 

https://www.openstreetmap.org/#map=19/37.250567/127.078423

 

오픈스트리트맵

오픈스트리트맵 (OpenStreetMap)은 여러분과 같은 사람들이 만들어, 개방형 라이선스에 따라 자유롭게 사용할 수 있는 세계 지도입니다.

www.openstreetmap.org

 

open street map 접속하기

내보내기

 

OSM file 이 만들어집니다.

 

OSM 파일에는 해당 영역의 모든 데이터가 있습니다.

 

2.osm to geojson(OSM 파일을 geojson으로 바꾸기)

OSM 파일을 geojson으로 변경을 위해서는 이를 지원하는 서비스를 이용하거나 아니면 코드로 작성해야 겠죠..^^ (당연한 이야기죠. )

 

https://mygeodata.cloud/

 

MyGeodata Converter | MyGeodata Cloud

--> --> Uploaded Files Type Size Please note that your data will not be shared to anybody. Recently used data is your data that you have recently uploaded and can only be seen by you from your computer and your web browser. You can reuse them for a repeat

mygeodata.cloud

여기에서OSM 파일을 geojson으로 변경이 가능합니다.

그러나 가격 부담 ㅠ_ㅠ

 

 

그래서 저는 직접 만드는 쪽으로 선회했습니다. ^^

 

import codecs
import json
import osm2geojson

# 각 feature에 bbox 추가
def add_bbox_to_features(geojson):
    for feature in geojson['features']:
        geom = feature.get('geometry')
        if not geom:
            continue
        coords = geom.get('coordinates')

        def extract_coords(c):
            if isinstance(c[0], (float, int)):  # Point
                yield c
            else:
                for sub in c:
                    yield from extract_coords(sub)

        min_lat = min_lon = float('inf')
        max_lat = max_lon = float('-inf')

        for lon, lat in extract_coords(coords):
            min_lon = min(min_lon, lon)
            min_lat = min(min_lat, lat)
            max_lon = max(max_lon, lon)
            max_lat = max(max_lat, lat)

        feature['bbox'] = [min_lon, min_lat, max_lon, max_lat]

# OSM 파일 읽기 및 변환
with codecs.open('sample.osm', 'r', encoding='utf-8') as data:
    xml = data.read()

geojson = osm2geojson.xml2geojson(xml, filter_used_refs=False, log_level='INFO')

# feature 단위 bbox 추가
add_bbox_to_features(geojson)

# 저장
with open("result.json", "w", encoding="utf-8") as f:
    json.dump(geojson, f, ensure_ascii=False, indent=2)

 

 

osm2geojson이라는 python package가 있는데 이를 활용하여 간단하게 만들수 있습니다.

(bbox는 사실 필요 없는데, 저는 bbox 활용할 일이 있어서 추가 작성 했습니다.)

 

osm2geojson 예제에 text encoding 관련된 부분에 한글이 고려 안되어있는 부분이 있습니다. 그래서 unicode 텍스트 (이거 뭐랄까 ascii로 unicode를 하나하나 출력) 출력되는데, 이부분 주의가 필요합니다.

with open("result.json", "w", encoding="utf-8") as f:
    json.dump(geojson, f, ensure_ascii=False, indent=2)

 

아무튼 결과물은 다음과 같이 나오게 됩니다.

결과물 (일부만)

{
      "type": "Feature",
      "properties": {
        "type": "way",
        "id": 60274279,
        "tags": {
          "leisure": "park",
          "name": "반달공원",
          "name:en": "Bandal Park",
          "name:ko": "반달공원"
        },
        "nodes": [
          522283226,
          804659125,
          522283225,
          522283224,
          522283223,
          522283222,
          522283221,
          522283220,
          522283219,
          804658865,
          522283218,
          749481489,
          12597050520,
          1041086129,
          522283226
        ],
        "timestamp": "2025-02-17T23:25:53Z",
        "user": "VLD297",
        "uid": 22440181,
        "version": 6
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              127.0788144,
              37.2516044
            ],
            [
              127.0790588,
              37.2514582
            ],
            [
              127.0792253,
              37.251231
            ],
            [
              127.0792854,
              37.2509749
            ],
            [
              127.0792393,
              37.2507596
            ],
            [
              127.0791239,
              37.2505404
            ],
            [
              127.0786913,
              37.250087
            ],
            [
              127.0784826,
              37.2499406
            ],
            [
              127.0782648,
              37.2498577
            ],
            [
              127.077969,
              37.2498236
            ],
            [
              127.0776801,
              37.2498829
            ],
            [
              127.0773679,
              37.2500504
            ],
            [
              127.0777277,
              37.2504259
            ],
            [
              127.0780778,
              37.250814
            ],
            [
              127.0788144,
              37.2516044
            ]
          ]
        ]
      },
      "bbox": [
        127.0773679,
        37.2498236,
        127.0792854,
        37.2516044
      ]
    },

 

이렇게 나온 geojson을 leaflet 을 이용하여 layer로 추가하면 멋진 커스터마이징이 가능해지죠!!

 

 

# 해피코딩!!

반응형

 

OSM : Open Street Map

https://planet.openstreetmap.org/

 

Planet OSM

Supporting OSM OSM data is free to use, but is not free to make or host. The stability and accuracy of OSM.org depends on its volunteers and donations from its users. Please consider making an annual recurring gift to OSM to support the infrastructure, too

planet.openstreetmap.org

 

 

구글 맵, 다음 지도, 네이버 맵등을 이용해서 지도 정보를 화면에 출력할 수도 있지만, OSM(Open Street Map)을 이용해보고자 합니다.

(뭔가 더 자유도가 있는 것 같음..)

 

 

OSM 은 우선 사용하는데에는 무료 입니다.

OSM는 어떻게 무료인가요?

OpenStreetMap은 크라우드소싱으로 만들어진 오픈 데이터베이스

ODbL(Open Database License) 하에 무료로 사용할 수 있습니다.

누구든지 상업/비상업 목적으로 자유롭게:

데이터를 보고,

복사하고,

수정하고,

앱/웹에서 사용할 수 있어요.

 

하지만 다음은 꼭 주의하세요

항목설명

🔌 타일 서버 (tile.openstreetmap.org) OSM 데이터는 무료지만 기본 타일 서버는 “공공 기여 기반”이라 과도한 사용 금지
📈 상업적 서비스 웹사이트/앱에서 많은 트래픽이 예상되면 타일 서버를 직접 운영하거나 외부 제공업체(MapTiler 등)를 사용해야 함
📝 저작권 표시 필수 지도에 “© OpenStreetMap contributors” 표기 필요
💥 Rate Limit 기본 서버는 과도한 호출 시 차단당할 수 있음 (특히 앱에서 다수 사용자일 경우)

 

 

 대안 서비스 (타일 서버 대체용)

서비스설명

MapTiler 상업적 사용 OK, 다양한 스타일 제공
OpenMapTiles 자체 호스팅 가능, OSM 기반
Carto 지도 + 데이터 시각화 전문
Mapbox 고성능 상업용 지도 SDK (유료 요금제 있음)

 

 

 

 

실무 예시

작은 규모의 내부 대시보드나 개인 프로젝트 → tile.openstreetmap.org 사용 OK

상업 서비스, 앱 배포, 사용자 많은 시스템 → 별도 타일 서버나 상용 서비스 이용 권장

 

 

OSM 타일 서버 직접 구축하는 법

도구설명

TileServer GL 벡터/래스터 타일 서버, Docker로 간편 구축 가능
Tegola Go 기반 고성능 벡터 타일 서버
openmaptiles.org 미리 생성된 벡터 타일 다운로드 or Docker 배포

 

 

타일 서버 구축

1. 프로젝트 디렉토리 구성

osm-tileserver/
├── docker-compose.yml
└── data/
    └── south-korea.mbtiles   ← 원하는 지역 타일 파일

 

2. docker-compose.yml

 

version: "3"

services:
  tileserver:
    image: klokantech/tileserver-gl
    ports:
      - "8080:80"
    volumes:
      - ./data:/data
    environment:
      - MAPBOX_STYLES=local

 

3. 실행 방법

# 프로젝트 폴더로 이동
cd osm-tileserver

# 실행
docker-compose up -d

 

 

 

4. 접속 확인

 

브라우저에서 접속: http://localhost:8080

 

제공 기능:

웹 기반 지도 뷰어

벡터 타일 (PBF)

래스터 PNG 타일 (/styles/basic/{z}/{x}/{y}.png)

Leaflet/OpenLayers 연동용 URL 자동 제공

 

5. Leaflet 연동 예시

L.tileLayer('http://localhost:8080/styles/basic/{z}/{x}/{y}.png', {
  maxZoom: 18,
  attribution: '© OpenStreetMap contributors'
}).addTo(map);

 

 

.mbtiles 파일은 어디서 받나요?

https://openmaptiles.org/downloads/

대한민국: south-korea.mbtiles 다운로드

용량 수백 MB ~ 수 GB

 

 

6. OSM file을 geojson 으로 변경하기

OSM 맵의 특정 부분을 geojson으로 변경해서 사용하고 싶을 때가 있습니다.

특정 영역의 색상을 표시한다거나 할때, 지도상에서 해당 영역을 찾아서 표시 하고 싶을 때가 있죠.

 

 

# 해피코딩 !!

 

 

 

 

+ Recent posts