| name | korean-transit-route |
| description | Korean door-to-door public transit routing (subway + bus + walking) via ODsay LIVE API with Kakao geocoding for address-to-address queries. Use when the user asks for ์งํ์ฒ /๋ฒ์ค/๋์ค๊ตํต ๊ธธ์ฐพ๊ธฐ, ํ์น ๊ฒฝ๋ก, ์์์๊ฐ, or transit directions between two places in Korea. |
| license | MIT |
| metadata | {"category":"transit","locale":"ko-KR","phase":"v1"} |
korean-transit-route
ํ๊ตญ ๋์ค๊ตํต(์งํ์ฒ +๋ฒ์ค+๋๋ณด) ๋์ดํฌ๋์ด ๊ธธ์ฐพ๊ธฐ ์คํฌ. ODsay LIVE API + Kakao Local geocoding.
When to use
- "๊ฐ๋จ์์ ์ ์ค ์งํ์ฒ ๋ก ์ด๋ป๊ฒ ๊ฐ?"
- "์์ธ์ญ โ ์ธ์ฒ๊ณตํญ ๋์ค๊ตํต ๊ฒฝ๋ก"
- "ํ์น ๊ฐ์ฅ ์ ์ ๊ฒฝ๋ก", "์ต์ ์๊ฐ ๊ฒฝ๋ก"
Credentials
- ํ๊ฒฝ๋ณ์
ODSAY_API_KEY ๊ฐ ์์ผ๋ฉด ์ฌ์ฉ. ์์ผ๋ฉด ~/.config/k-skill/secrets.env ์์ ๋ก๋.
- ODsay Server ํค๋ ํธ์ถ IP ํ์ดํธ๋ฆฌ์คํธ ๋ฑ๋ก ํ์. ๋ฐ๊ธ์ https://lab.odsay.com
Inputs
์์ฐ์ด ์
๋ ฅ์์ ์ถ๋ฐ/๋์ฐฉ์ ์ถ์ถ. ์ขํ๊ฐ ์์ผ๋ฉด ๋ฐ๋์ geocoding ๋จผ์ (ODsay๋ ์ขํ๋ง ๋ฐ์).
Geocoding (ํ์ ์ ํ ๋จ๊ณ)
KAKAO_REST_API_KEY ์ฌ์ฉ. ๋ ์๋ํฌ์ธํธ๋ฅผ ์์๋๋ก ์๋:
https://dapi.kakao.com/v2/local/search/address.json?query=<์ฃผ์> โ ๋๋ก๋ช
/์ง๋ฒ ์ฃผ์
- ๊ฒฐ๊ณผ ์์ผ๋ฉด
https://dapi.kakao.com/v2/local/search/keyword.json?query=<์ฅ์๋ช
> โ ์ํธ๋ช
/๋๋๋งํฌ
ํค๋: Authorization: KakaoAK <KAKAO_REST_API_KEY>. ์๋ต documents[0].x(๊ฒฝ๋), .y(์๋) ์ฌ์ฉ.
import os, urllib.parse, urllib.request, json
H={'Authorization':'KakaoAK '+os.environ['KAKAO_REST_API_KEY']}
def geocode(q):
for ep,name in [('address','address_name'),('keyword','place_name')]:
url=f'https://dapi.kakao.com/v2/local/search/{ep}.json?query='+urllib.parse.quote(q)
d=json.loads(urllib.request.urlopen(urllib.request.Request(url,headers=H),timeout=10).read())
if d.get('documents'):
x=d['documents'][0]; return float(x['x']), float(x['y']), x.get(name) or x['address_name']
return None
์งํ์ฒ ์ญ๋ช
๋ง ์ ํํ ์ ๋๋ ODsay searchStation ๋ OK ํ์ง๋ง, ๋์ดํฌ๋์ด ๊ฒฐ๊ณผ๋ฅผ ์ํ๋ฉด ์ค์ ์ถ๋ฐ์ง/๋์ฐฉ์ง ์ขํ๋ฅผ ์จ์ผ ์ฒซ/๋ ๋๋ณด ๊ตฌ๊ฐ์ด ๊ณ์ฐ๋จ.
Core call
set -a; . ~/.config/k-skill/secrets.env; set +a
KEY=$(python3 -c "import os,urllib.parse;print(urllib.parse.quote(os.environ['ODSAY_API_KEY'],safe=''))")
curl -s "https://api.odsay.com/v1/api/searchPubTransPathT?apiKey=${KEY}&SX=${SX}&SY=${SY}&EX=${EX}&EY=${EY}&OPT=0&SearchPathType=${TYPE}"
Parameters:
SX,SY ์ถ๋ฐ ๊ฒฝ๋/์๋, EX,EY ๋์ฐฉ ๊ฒฝ๋/์๋ (WGS84)
OPT: 0 ์ถ์ฒ์(๊ธฐ๋ณธ), 4 ์ต์์๊ฐ, 5 ์ต์ํ์น
SearchPathType: 0 ์งํ์ฒ +๋ฒ์ค, 1 ์งํ์ฒ ๋ง, 2 ๋ฒ์ค๋ง
Response shape
result.path[] ๋ฐฐ์ด, ๊ฐ path:
pathType: 1=์งํ์ฒ , 2=๋ฒ์ค, 3=์งํ์ฒ +๋ฒ์ค
info.totalTime(๋ถ), info.payment(์), info.subwayTransitCount, info.busTransitCount, info.totalWalk(m), info.firstStartStation, info.lastEndStation
subPath[]: ๊ตฌ๊ฐ๋ณ. trafficType 1=์งํ์ฒ 2=๋ฒ์ค 3=๋๋ณด. ์งํ์ฒ ์ด๋ฉด lane[0].name, startName, endName, passStopList.stations[](๊ฒฝ์ ์ญ)
Recommended output (door-to-door)
subPath ์ ๊ฐ ๊ตฌ๊ฐ์ trafficType ๋ณ๋ก ํ์. ์ฒซ/๋ ๋๋ณด ๊ตฌ๊ฐ์ ์ถ๋ฐ์งยท๋์ฐฉ์ง์์ ์ญ๊น์ง ์ค์ ๋๋ณด๋ฅผ ์๋ฏธํ๋ฏ๋ก ๋ฐ๋์ ํฌํจ.
๐ ๋ฒ์๋ก95๋ฒ๊ธธ 32 โ SKTํ์
๊ฒฝ๋ก 1: 54๋ถ ยท 1,950์ ยท ํ์น 2ํ ยท ๋๋ณด 688m
๐ถ ๋๋ณด 1๋ถ
๐ 19๋ฒ ๋ถ์ฒ๋ฒ๋ฐํ์คํ
์ดํธ โ ์ญ๊ณก์ญ (9๋ถ)
๐ถ ๋๋ณด 2๋ถ
๐ 1ํธ์ ์ญ๊ณก โ ์ข
๊ฐ (15์ ๊ฑฐ์ฅ, 35๋ถ)
๐ถ ๋๋ณด 7๋ถ
3๊ฐ ์ด๋ด ๊ฒฝ๋ก ๋น๊ต ๊ถ์ฅ. OPT=4(์ต์์๊ฐ) / OPT=5(์ต์ํ์น) ์ต์
์ ์ฌ์ฉ์๊ฐ ์ ํธ ํ์ํ๋ฉด ๊ทธ์ชฝ์ผ๋ก ํธ์ถ.
Helpers
์ขํ ๋ชจ๋ฅด๊ณ ์ญ๋ช
๋ง ์๋ ๊ฒฝ์ฐ โ searchStation ์ผ๋ก ๋ณํ:
curl -s "https://api.odsay.com/v1/api/searchStation?apiKey=${KEY}&stationName=๊ฐ๋จ&CID=1000"
CID=1000 = ์๋๊ถ. ๊ฒฐ๊ณผ result.station[].x,y ๊ฐ ์ขํ.
Limits
- ๋ฌด๋ฃ ์ผ 5,000๊ฑด.
searchPubTransPathT + searchStation ํธ์ถ์ด ํฉ์ฐ๋๋ ํ ์ง๋ฌธ๋น ํธ์ถ ์ต์ํ.
- ์๋ต์
error ํค ์์ผ๋ฉด ์ฆ์ ์ฌ์ฉ์์๊ฒ ํ์(ApiKey/IP ๋ฌธ์ ์ง๋จ์ ์ ์ฉ).
- ํ๊ตญ ์ธ ์ขํ๋ ์ง์ ์ ํจ.
Don'ts
- ์นด์นด์ค๋งต/๋ค์ด๋ฒ์ง๋ directions API๋ก ๋์ค๊ตํต ๋ผ์ฐํ
์๋ํ์ง ๋ง ๊ฒ (๋ ๋ค ์ด์ ยท๋๋ณด๋ง ๊ณต๊ฐ).
- ํค๋ฅผ ์ ๋ ์๋ต์ ๋
ธ์ถํ์ง ๋ง ๊ฒ.