124 lines
6.5 KiB
Python
124 lines
6.5 KiB
Python
import json
|
|
import os
|
|
from typing import Optional, Tuple
|
|
|
|
class RegionCodeConverter:
|
|
"""위치 정보를 시군구 코드로 변환하는 유틸리티"""
|
|
|
|
def __init__(self):
|
|
"""지역 코드 데이터 로드"""
|
|
base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
# 전체 지역 코드 로드
|
|
with open(os.path.join(base_path, 'data', 'region_codes.json'), 'r', encoding='utf-8') as f:
|
|
self.full_codes = json.load(f)
|
|
|
|
# 간략 지역 코드 로드
|
|
with open(os.path.join(base_path, 'data', 'region_codes_simple.json'), 'r', encoding='utf-8') as f:
|
|
self.simple_codes = json.load(f)
|
|
|
|
def get_region_code(self, location: str) -> Tuple[Optional[str], Optional[str]]:
|
|
"""
|
|
위치 정보를 시군구 코드로 변환
|
|
|
|
Args:
|
|
location: 위치 텍스트 (예: "강남구", "서울 강남", "서울특별시 강남구")
|
|
|
|
Returns:
|
|
(지역코드, 매칭된 지역명) 튜플
|
|
"""
|
|
if not location:
|
|
return None, None
|
|
|
|
location = location.strip()
|
|
|
|
# 1. 정확한 매칭 시도 (전체 이름)
|
|
for full_name, code in self.full_codes.items():
|
|
if location in full_name or full_name in location:
|
|
return code, full_name
|
|
|
|
# 2. 간략 이름으로 매칭 시도
|
|
for simple_name, code in self.simple_codes.items():
|
|
if simple_name in location:
|
|
# 전체 이름 찾기
|
|
for full_name, full_code in self.full_codes.items():
|
|
if full_code == code:
|
|
return code, full_name
|
|
return code, simple_name
|
|
|
|
# 3. 부분 매칭 시도 (구, 시, 군 단위)
|
|
location_parts = location.split()
|
|
for part in location_parts:
|
|
# 구/시/군으로 끝나는 부분 찾기
|
|
if part.endswith('구') or part.endswith('시') or part.endswith('군'):
|
|
# 간략 코드에서 찾기
|
|
if part in self.simple_codes:
|
|
code = self.simple_codes[part]
|
|
# 전체 이름 찾기
|
|
for full_name, full_code in self.full_codes.items():
|
|
if full_code == code and part in full_name:
|
|
return code, full_name
|
|
return code, part
|
|
|
|
# 전체 코드에서 찾기
|
|
for full_name, code in self.full_codes.items():
|
|
if part in full_name:
|
|
return code, full_name
|
|
|
|
# 4. 동 이름으로 구 추정 (주요 동 매핑)
|
|
dong_to_gu = {
|
|
# 서울 강남구
|
|
'역삼': '강남구', '삼성': '강남구', '청담': '강남구', '논현': '강남구', '대치': '강남구',
|
|
'도곡': '강남구', '개포': '강남구', '일원': '강남구', '수서': '강남구', '세곡': '강남구',
|
|
# 서울 서초구
|
|
'반포': '서초구', '서초': '서초구', '방배': '서초구', '양재': '서초구', '잠원': '서초구',
|
|
'우면': '서초구', '내곡': '서초구',
|
|
# 서울 송파구
|
|
'잠실': '송파구', '신천': '송파구', '석촌': '송파구', '송파': '송파구', '가락': '송파구',
|
|
'문정': '송파구', '장지': '송파구', '방이': '송파구', '오금': '송파구', '풍납': '송파구',
|
|
# 서울 강동구
|
|
'천호': '강동구', '성내': '강동구', '길동': '강동구', '둔촌': '강동구', '암사': '강동구',
|
|
'명일': '강동구', '고덕': '강동구', '상일': '강동구',
|
|
# 서울 노원구
|
|
'상계': '노원구', '중계': '노원구', '하계': '노원구', '월계': '노원구', '공릉': '노원구',
|
|
# 서울 양천구
|
|
'목동': '양천구', '신정': '양천구', '신월': '양천구',
|
|
# 서울 영등포구
|
|
'여의도': '영등포구', '당산': '영등포구', '영등포': '영등포구', '문래': '영등포구',
|
|
'양평': '영등포구', '신길': '영등포구', '대림': '영등포구',
|
|
# 서울 마포구
|
|
'홍대': '마포구', '합정': '마포구', '상수': '마포구', '망원': '마포구', '연남': '마포구',
|
|
'서교': '마포구', '공덕': '마포구', '아현': '마포구', '도화': '마포구', '용강': '마포구',
|
|
# 서울 성동구
|
|
'성수': '성동구', '왕십리': '성동구', '행당': '성동구', '금호': '성동구', '옥수': '성동구',
|
|
# 서울 용산구
|
|
'이태원': '용산구', '한남': '용산구', '동빙고': '용산구', '서빙고': '용산구', '이촌': '용산구',
|
|
'한강로': '용산구', '효창': '용산구', '용문': '용산구',
|
|
# 서울 종로구
|
|
'광화문': '종로구', '종로': '종로구', '인사동': '종로구', '삼청': '종로구', '평창': '종로구',
|
|
'부암': '종로구', '무악': '종로구', '교남': '종로구',
|
|
# 서울 중구
|
|
'명동': '중구', '충무로': '중구', '을지로': '중구', '남대문': '중구', '회현': '중구',
|
|
'필동': '중구', '장충': '중구', '신당': '중구', '다산': '중구',
|
|
# 경기도 성남시 분당구
|
|
'판교': '분당구', '정자': '분당구', '서현': '분당구', '수내': '분당구', '야탑': '분당구',
|
|
'이매': '분당구', '분당': '분당구', '구미': '분당구', '금곡': '분당구',
|
|
# 경기도 용인시
|
|
'동백': '기흥구', '보정': '기흥구', '죽전': '수지구', '수지': '수지구',
|
|
# 경기도 수원시
|
|
'영통': '영통구', '광교': '영통구', '원천': '영통구', '매탄': '영통구',
|
|
# 경기도 고양시
|
|
'일산': '일산동구', '백석': '일산동구', '마두': '일산서구', '주엽': '일산서구'
|
|
}
|
|
|
|
for dong, gu in dong_to_gu.items():
|
|
if dong in location:
|
|
if gu in self.simple_codes:
|
|
code = self.simple_codes[gu]
|
|
# 전체 이름 찾기
|
|
for full_name, full_code in self.full_codes.items():
|
|
if full_code == code:
|
|
return code, full_name
|
|
return code, gu
|
|
|
|
return None, None |