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 오버로딩
코샵
코샵
나의 코딩 일기장
    반응형
  • 코샵
    끄적끄적 코딩 공방
    코샵
    • 분류 전체보기 (725)
      • 스마트팜 (0)
      • 상품 추천 (223)
      • MongoDB (4)
      • 하드웨어 (17)
      • 일기장 (4)
      • 파이썬 (130)
        • Basic (41)
        • 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 (4)
      • 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)
  • 인기 글

  • 태그

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

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

티스토리툴바