[특정 지역에 버스 한 번 타고 갈 수 있는 지역 찾기] 2. 버스 정류장, 버스 정류장에 정거하는 버스 및 이 버스의 정류장 찾기

2025. 5. 10. 18:55·프로젝트/버스 한 번으로 특정 지역에 갈 수 있는 지역 찾기

- 개요

영등포 타임스퀘어 3번 게이트에 버스 한 번으로 갈 수 있다라함은 3번 게이트 근처의 버스 정류장에서 내려서 짧은 거리를 걸어간다는 뜻입니다.

 

이번 포스트에서는 3가지 작업을 합니다.

1. 영등포 타임스퀘어 3번 게이트 근처 버스 정류장을 찾기

2. 근처 버스 정류장에 정거하는 모든 버스 찾기

3. 위에서 찾은 모든 버스가 정거하는 정류장 찾기

 

- 버스 정류소, 버스 데이터 필터링

이번 포스트의 코드와 설명은 짧은 편입니다.

설명할 것은 haversine 함수와 pandas에서 제공하는 isin() 메서드입니다.

 

1. haversine 함수

저는 영등포 타임스퀘어 3번 게이트에서 300 m 이내에 있다면 근처라고 정의했습니다.

300 m 이내를 계산하려면 두 지점의 거리를 구해야하는데요.

버스 정류소 데이터의 CRDNT_X는 경도, CRDNT_Y는 위도를 의미하고, 이는 구좌표계 값입니다.

우리가 구해야할 것은 거리인데 구좌표계의 경도, 위도는 각도이므로 실제 거리(km or m)를 구하는 공식을 써야합니다.

 

2. isin() 메서드

isin() 안에는 list와 같은 변수를 넣을 수 있는데요.

만약 제가 df['열1'].isin([1,2,3]) 이런 코드를 작성하면 '열1'에서 1, 2, 3인 경우에는 True, 아닌 경우에는 False를 반홥니다.

300 m 이내의 버스 정류장 데이터를 isin()에 넣어주는 식으로 사용하면 해당 정류소를 포함하는 행만 필터링할 수 있습니다.

 

"""
데이터 읽는 부분
"""
import pandas as pd
fn = r'C:\Users\zerot\Desktop\python\busVisSystem\metadata\TBIS_MS_ROUTE_NODE.csv'
df_rn = pd.read_csv(fn, encoding='utf-8-sig')

fn =  r'C:\Users\zerot\Desktop\python\busVisSystem\metadata\TBIS_MS_STTN.csv'
df_s = pd.read_csv(fn, encoding='utf-8-sig')

fn = r'C:\Users\zerot\Desktop\python\busVisSystem\metadata\TBIS_MS_ROUTE.csv'
df_r = pd.read_csv(fn, encoding='utf-8-sig')

import math

def haversine(lat1, lon1, lat2, lon2):
"""
(lat1, lon1) 좌표와 (lat2, lon2) 좌표간 거리를 km로 반환
"""
    R = 6371  # 지구 반지름 (km)
    phi1 = math.radians(lat1)
    phi2 = math.radians(lat2)
    delta_phi = math.radians(lat2 - lat1)
    delta_lambda = math.radians(lon2 - lon1)

    a = math.sin(delta_phi / 2) ** 2 + \
        math.cos(phi1) * math.cos(phi2) * \
        math.sin(delta_lambda / 2) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))

    return R * c

# 영등포 타임스퀘어 3번 게이트 위치
lat, lon = 37.5181, 126.9036 

"""
1. 3번 게이트 근처 버스 정류장 찾기
"""
# haversine 함수를 이용해서 영등포 타임스퀘어 3번 게이트와 각 버스 정류소의 거리는 dist 열로 저장
df_s['dist'] = df_s.apply(lambda row: haversine(row['CRDNT_Y'], row['CRDNT_X'], lat, lon), axis=1)
# 0.3 km, 300 m 이내의 버스 정류소를 df_s_near로 저장
df_s_near = df_s[['STTN_ID', 'CRDNT_X', 'CRDNT_Y']][df_s['dist'] <= 0.3]

"""
2. 근처 버스 정류장에 정거하는 모든 버스 (ROUTE_ID) 찾기
"""

df_routeId_near = df_rn['ROUTE_ID'][df_rn['STTN_ID'].isin(df_s_near['STTN_ID'])].unique()
"""
3. 모든 버스가 정거하는 정류장 찾기
"""
stn_list = df_rn['STTN_ID'][df_rn['ROUTE_ID'].isin(df_routeId_near)].tolist()

 

- 시각화

1. 영등포 타임스퀘어 3번 출구 근처 버스 정류장

import folium
m = folium.Map(location=[df_s_near['CRDNT_Y'].mean(),  df_s_near['CRDNT_X'].mean()], 
                tiles='CartoDB dark_matter', # 빨간색이 잘보이게 타일 바꿈
               zoom_start=17)
for idx, row in df_s_near.iterrows():
    folium.CircleMarker(
        location=[row['CRDNT_Y'], row['CRDNT_X']],  # (lat, lon)
        radius=3,  # 반경 크기
        color="red",  # 원의 색상
        fill=True,  # 채우기 여부
        fill_color="red",  # 채우기 색상
        fill_opacity=0.7,  # 채우기 투명도
        popup=f"Calc:({idx})"  # 마커를 클릭했을 때 표시될 텍스트
    ).add_to(m)
m

 

영등포 타임스퀘어 300 m 이내 버스 정류장

 

 

2. 영등포 타임스퀘어 3번 출구 근처 버스 정류장에 한 번에 갈 수 있는 버스를 탈 수 있는 정류장

참고로 영등포 타임스퀘어 3번 출구 근처 버스 정류장에 정거하는 버스의 수는 60개입니다.

import folium

df = pd.DataFrame({'STTN_ID': stn_list})
df_merged = pd.merge(df, df_s, how='left', on='STTN_ID')

m = folium.Map(location=[df_merged['CRDNT_Y'].mean(),  df_merged['CRDNT_X'].mean()], 
               tiles='CartoDB dark_matter', # 빨간색이 잘보이게 타일 바꿈
               zoom_start=10)
for idx, row in df_merged.iterrows():
    folium.CircleMarker(
        location=[row['CRDNT_Y'], row['CRDNT_X']],  # (lat, lon)
        radius=1,  # 반경 크기
        color="red",  # 원의 색상
        fill=True,  # 채우기 여부
        fill_color="red",  # 채우기 색상
        fill_opacity=0.7,  # 채우기 투명도
        popup=f"Calc:({idx})"  # 마커를 클릭했을 때 표시될 텍스트
    ).add_to(m)
m

영등포 타임스퀘어 3번 게이트 정류장에 한 번에 가는 버스를 탈 수 있는 버스 정류소

 

영등포 타임스퀘어의 위치가 서울 서쪽이므로 수도권 서부, 북부, 남부 지역에게 접근하기 쉽습니다.

다음 포스트에서는 버스 정류장의 위치로 한 번에 갈 수 있는 곳을 시각화하는 것이 아니라

지역 경계로 폴리곤을 그려 시각화하겠습니다.

'프로젝트 > 버스 한 번으로 특정 지역에 갈 수 있는 지역 찾기' 카테고리의 다른 글

[특정 지역에 버스 한 번 타고 갈 수 있는 지역 찾기] 3. 버스 정류장이 속한 지역 찾기: geopandas.sjoin()  (0) 2025.05.12
[특정 지역에 버스 한 번 타고 갈 수 있는 지역 찾기] 1. 버스, 버스 정류장 데이터 수집과 확인  (0) 2025.05.08
[특정 지역에 버스 한 번 타고 갈 수 있는 지역 찾기] 0. 목표 설정  (0) 2025.05.07
'프로젝트/버스 한 번으로 특정 지역에 갈 수 있는 지역 찾기' 카테고리의 다른 글
  • [특정 지역에 버스 한 번 타고 갈 수 있는 지역 찾기] 3. 버스 정류장이 속한 지역 찾기: geopandas.sjoin()
  • [특정 지역에 버스 한 번 타고 갈 수 있는 지역 찾기] 1. 버스, 버스 정류장 데이터 수집과 확인
  • [특정 지역에 버스 한 번 타고 갈 수 있는 지역 찾기] 0. 목표 설정
레까
레까
  • 레까
    데이터 조아
    레까
  • 전체
    오늘
    어제
    • 전체 (97)
      • 일기장 (0)
      • 대기과학 (49)
        • 프로그래밍 (45)
        • 개념 (2)
        • 칼럼 (2)
      • 여러가지 데이터 (5)
        • 프로그래밍 & 분석 (5)
      • 프로그래밍 (17)
        • 파이썬 (8)
        • 시각화 (8)
        • 유용 (1)
      • 프로젝트 (21)
        • 기계학습 기반 서울 기온 예측 (9)
        • 사과게임 매크로 만들기 (4)
        • 버스 한 번으로 특정 지역에 갈 수 있는 지역 찾.. (4)
        • 메이플스토리 챌린저스 월드 시즌 1 분석 (4)
      • 데이터리안 SQL 공부 (4)
      • 주제별 링크 모음 (1)
      • 백업 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
레까
[특정 지역에 버스 한 번 타고 갈 수 있는 지역 찾기] 2. 버스 정류장, 버스 정류장에 정거하는 버스 및 이 버스의 정류장 찾기
상단으로

티스토리툴바