Geopy : 지리 정보 다루기

2025. 2. 10. 10:09·파이썬/Basic
반응형

Geopy는 파이썬에서 지리 정보를 쉽게 다룰 수 있게 해주는 강력한 라이브러리입니다. 주소를 좌표로 변환하거나, 두 지점 간의 거리를 계산하는 등 다양한 지리 정보 처리가 가능합니다.

기본 설치 및 설정

# 설치
pip install geopy

# 기본 임포트
from geopy.geocoders import Nominatim
from geopy.distance import geodesic
from geopy.exc import GeocoderTimedOut

주소를 좌표로 변환하기 (Geocoding)

from geopy.geocoders import Nominatim

def get_coordinates(address: str):
    # 지오코더 초기화
    geolocator = Nominatim(user_agent="my_app")

    try:
        # 주소로 위치 검색
        location = geolocator.geocode(address)

        if location:
            return {
                'address': location.address,
                'latitude': location.latitude,
                'longitude': location.longitude
            }
        return None

    except GeocoderTimedOut:
        return None

# 사용 예시
address = "서울특별시 강남구 테헤란로 427"
coordinates = get_coordinates(address)
print(coordinates)

좌표로 주소 찾기 (Reverse Geocoding)

def get_address(latitude: float, longitude: float):
    geolocator = Nominatim(user_agent="my_app")

    try:
        location = geolocator.reverse((latitude, longitude))
        return location.address
    except GeocoderTimedOut:
        return None

# 사용 예시
latitude = 37.5665
longitude = 126.9780
address = get_address(latitude, longitude)
print(address)

두 지점 간의 거리 계산

from geopy.distance import geodesic

def calculate_distance(point1: tuple, point2: tuple):
    """
    두 지점 간의 거리를 킬로미터 단위로 계산
    point1, point2: (latitude, longitude) 형식의 튜플
    """
    distance = geodesic(point1, point2).kilometers
    return round(distance, 2)

# 사용 예시
seoul = (37.5665, 126.9780)
busan = (35.1796, 129.0756)
distance = calculate_distance(seoul, busan)
print(f"서울-부산 거리: {distance}km")

다양한 지오코더 활용

from geopy.geocoders import Nominatim, GoogleV3, ArcGIS

class GeocodingService:
    def __init__(self, service='nominatim', api_key=None):
        if service == 'nominatim':
            self.geolocator = Nominatim(user_agent="my_app")
        elif service == 'google':
            self.geolocator = GoogleV3(api_key=api_key)
        elif service == 'arcgis':
            self.geolocator = ArcGIS()
        else:
            raise ValueError("Unsupported geocoding service")

    def geocode(self, address):
        try:
            location = self.geolocator.geocode(address)
            if location:
                return {
                    'address': location.address,
                    'latitude': location.latitude,
                    'longitude': location.longitude
                }
        except Exception as e:
            print(f"Error: {e}")
            return None

실전 활용 예시: 주변 장소 찾기

def find_nearby_locations(center_point: tuple, locations: list, max_distance: float):
    """
    주어진 중심점으로부터 특정 거리 내의 장소들을 찾습니다.

    Args:
        center_point: (latitude, longitude) 형식의 중심점
        locations: [(name, lat, lon)] 형식의 장소 리스트
        max_distance: 최대 거리 (km)
    """
    nearby = []

    for name, lat, lon in locations:
        point = (lat, lon)
        distance = calculate_distance(center_point, point)

        if distance <= max_distance:
            nearby.append({
                'name': name,
                'distance': distance,
                'coordinates': point
            })

    return sorted(nearby, key=lambda x: x['distance'])

# 사용 예시
my_location = (37.5665, 126.9780)
places = [
    ("명동", 37.5634, 126.9850),
    ("강남역", 37.4980, 127.0278),
    ("이태원", 37.5340, 126.9940)
]

nearby_places = find_nearby_locations(my_location, places, 5.0)
for place in nearby_places:
    print(f"{place['name']}: {place['distance']}km")

에러 처리와 최적화

from functools import lru_cache
import time

class GeocodingManager:
    def __init__(self, retry_count=3, retry_delay=1):
        self.geolocator = Nominatim(user_agent="my_app")
        self.retry_count = retry_count
        self.retry_delay = retry_delay

    @lru_cache(maxsize=100)
    def geocode_with_retry(self, address: str):
        """
        주소 검색을 재시도하며 결과를 캐싱합니다.
        """
        for attempt in range(self.retry_count):
            try:
                location = self.geolocator.geocode(address)
                if location:
                    return {
                        'address': location.address,
                        'latitude': location.latitude,
                        'longitude': location.longitude
                    }
            except GeocoderTimedOut:
                if attempt < self.retry_count - 1:
                    time.sleep(self.retry_delay)
                continue
            except Exception as e:
                print(f"Error: {e}")
                break
        return None

유용한 지리 정보 처리 유틸리티

def get_bounding_box(center: tuple, radius_km: float):
    """
    중심점으로부터 특정 반경의 경계 상자를 계산합니다.
    """
    from math import radians, degrees, cos, sin, asin, sqrt

    lat, lon = center
    radius = radius_km / 111.32  # 1도당 약 111.32km

    min_lat = lat - radius
    max_lat = lat + radius

    # 위도에 따른 경도 범위 조정
    radius_lon = radius / cos(radians(lat))
    min_lon = lon - radius_lon
    max_lon = lon + radius_lon

    return {
        'min_lat': min_lat,
        'max_lat': max_lat,
        'min_lon': min_lon,
        'max_lon': max_lon
    }

# 사용 예시
seoul_center = (37.5665, 126.9780)
search_area = get_bounding_box(seoul_center, 5.0)  # 5km 반경

Geopy는 지리 정보 처리에 필수적인 도구이며, 특히 위치 기반 서비스를 개발할 때 매우 유용합니다. API 제한과 에러 처리에 주의하면서 사용하면 효과적인 지리 정보 처리 시스템을 구축할 수 있습니다.

저작자표시 비영리 변경금지 (새창열림)

'파이썬 > Basic' 카테고리의 다른 글

Python의 UnicodeDecodeError 해결하기: cp949 코덱 오류  (0) 2025.05.09
Python JSON 라이브러리 비교: json vs ujson vs orjson  (0) 2025.02.26
lru_cache : 캐싱 메모리  (0) 2025.02.08
함수 하나로 여러 가지 처리하기? Python 오버로딩  (2) 2024.12.27
자료구조 : deque, Queue, heapq  (0) 2024.12.10
'파이썬/Basic' 카테고리의 다른 글
  • Python의 UnicodeDecodeError 해결하기: cp949 코덱 오류
  • Python JSON 라이브러리 비교: json vs ujson vs orjson
  • lru_cache : 캐싱 메모리
  • 함수 하나로 여러 가지 처리하기? Python 오버로딩
코샵
코샵
나의 코딩 일기장
    반응형
  • 코샵
    끄적끄적 코딩 공방
    코샵
    • 분류 전체보기 (730)
      • 스마트팜 (1)
      • 상품 추천 (223)
      • DataBase (0)
        • MongoDB (4)
        • PostgreSQL (0)
      • 하드웨어 (19)
      • 일기장 (4)
      • 파이썬 (131)
        • Basic (42)
        • OpenCV (8)
        • Pandas (15)
        • PyQT (3)
        • SBC(Single Board Computer) (1)
        • 크롤링 (14)
        • Fast API (29)
        • Package (6)
      • Unity (138)
        • Tip (41)
        • Project (1)
        • Design Pattern (8)
        • Firebase (6)
        • Asset (2)
      • Linux (5)
      • C# (97)
        • Algorithm (11)
        • Window (7)
      • TypeScript (51)
        • CSS (10)
      • Git (11)
      • SQL (5)
      • Flutter (10)
        • Tip (1)
      • System (1)
      • BaekJoon (6)
      • Portfolio (2)
      • MacOS (1)
      • 유틸리티 (1)
      • 서비스 (6)
      • 자동화 (3)
      • Hobby (10)
        • 물생활 (10)
        • 식집사 (0)
  • 인기 글

  • 태그

    리뷰관리
    스크립트 실행
    파이썬
    programming101
    쇼핑몰리뷰
    appdevelopment
    rtsp
    ipcamera
    Python
    카페24리뷰
    라떼우유
    codingtips
    유니티
    상품 리뷰 크롤링
    긴유통기한우유
    programmerlife
    리스트
    믈레코비타멸균우유
    스마트스토어리뷰
    learntocode
    리뷰이관
    list
    셀레니움
    codingcommunity
    cv2
    스크립트 실행 순서
    C#
    카페24리뷰이관
    devlife
    unity
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코샵
Geopy : 지리 정보 다루기
상단으로

티스토리툴바