korean-transit-route

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

korean-transit-route

韩国公共交通路线规划

한국 대중교통(지하철+버스+도보) 도어투도어 길찾기 스킬. ODsay LIVE API + Kakao Local geocoding.
韩国公共交通(地铁+公交+步行)门到门路线查询工具。基于ODsay LIVE API + Kakao Local地理编码。

When to use

使用场景

  • "강남에서 잠실 지하철로 어떻게 가?"
  • "서울역 → 인천공항 대중교통 경로"
  • "환승 가장 적은 경로", "최소 시간 경로"
  • "강남에서 잠실 지하철로 어떻게 가?"(江南到蚕室地铁怎么走?)
  • "서울역 → 인천공항 대중교통 경로"(首尔站→仁川机场公共交通路线)
  • "환승 가장 적은 경로"(换乘最少的路线)、"최소 시간 경로"(耗时最短的路线)

Credentials

凭据配置

  • 환경변수
    ODSAY_API_KEY
    가 있으면 사용. 없으면
    ~/.config/k-skill/secrets.env
    에서 로드.
  • ODsay Server 키는 호출 IP 화이트리스트 등록 필수. 발급은 https://lab.odsay.com
  • Kakao Local geocoding은 기본 hosted
    k-skill-proxy
    경유로 호출하므로 사용자 쪽
    KAKAO_REST_API_KEY
    는 불필요하다. self-host proxy 운영자만
    KAKAO_REST_API_KEY
    를 서버에 설정한다.
  • 若存在环境变量
    ODSAY_API_KEY
    则直接使用,否则从
    ~/.config/k-skill/secrets.env
    加载。
  • ODsay Server密钥必须注册调用IP白名单,可通过https://lab.odsay.com申请。
  • Kakao Local地理编码默认通过托管的
    k-skill-proxy
    调用,因此用户无需配置
    KAKAO_REST_API_KEY
    ;仅自行托管代理的运营者需在服务器上设置
    KAKAO_REST_API_KEY

Inputs

输入处理

자연어 입력에서 출발/도착을 추출. 좌표가 없으면 반드시 geocoding 먼저 (ODsay는 좌표만 받음).
从自然语言输入中提取出发地/目的地。若无坐标,必须先进行地理编码(ODsay仅接受坐标输入)。

Geocoding (필수 선행 단계)

地理编码(必要前置步骤)

기본 hosted proxy를 사용한다. Proxy가 Kakao Local REST API 키를 서버에서만 주입하고, caller
apiKey
는 무시한다.
  1. https://k-skill-proxy.nomadamas.org/v1/kakao-local/geocode?q=<주소/장소명>
  2. proxy 내부 fallback: Kakao Local
    address.json
    → 결과 없으면
    keyword.json
응답
documents[0].x
(경도),
.y
(위도) 사용.
python
import os, urllib.parse, urllib.request, json
PROXY=os.environ.get('KSKILL_PROXY_BASE_URL','https://k-skill-proxy.nomadamas.org').rstrip('/')
def geocode(q):
    url=PROXY+'/v1/kakao-local/geocode?q='+urllib.parse.quote(q)
    with urllib.request.urlopen(url,timeout=10) as resp:
        d=json.loads(resp.read())
    if d.get('documents'):
        doc=d['documents'][0]
        return float(doc['x']), float(doc['y']), doc.get('place_name') or doc.get('address_name')
    return None
지하철역명만 정확히 알 때는 ODsay
searchStation
도 OK 하지만, 도어투도어 결과를 원하면 실제 출발지/도착지 좌표를 써야 첫/끝 도보 구간이 계산됨.
使用默认托管代理。代理仅在服务器端注入Kakao Local REST API密钥,调用者提供的
apiKey
将被忽略。
  1. https://k-skill-proxy.nomadamas.org/v1/kakao-local/geocode?q=<地址/场所名称>
  2. 代理内部降级逻辑:先调用Kakao Local
    address.json
    → 若无结果则调用
    keyword.json
使用响应中的
documents[0].x
(经度)、
.y
(纬度)。
python
import os, urllib.parse, urllib.request, json
PROXY=os.environ.get('KSKILL_PROXY_BASE_URL','https://k-skill-proxy.nomadamas.org').rstrip('/')
def geocode(q):
    url=PROXY+'/v1/kakao-local/geocode?q='+urllib.parse.quote(q)
    with urllib.request.urlopen(url,timeout=10) as resp:
        d=json.loads(resp.read())
    if d.get('documents'):
        doc=d['documents'][0]
        return float(doc['x']), float(doc['y']), doc.get('place_name') or doc.get('address_name')
    return None
若仅准确知道地铁站名,也可使用ODsay的
searchStation
接口,但如果需要门到门结果,必须使用实际出发地/目的地坐标,才能计算首尾步行路段。

Core call

核心调用

bash
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
    버스만
bash
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}"
参数说明:
  • 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[]
    (경유역)
result.path[]
数组,每个path包含:
  • pathType
    :1=地铁,2=公交,3=地铁+公交
  • info.totalTime
    (分钟)、
    info.payment
    (韩元)、
    info.subwayTransitCount
    info.busTransitCount
    info.totalWalk
    (米)、
    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
(최소환승) 옵션을 사용자가 선호 표시하면 그쪽으로 호출.
trafficType
展示
subPath
的每个路段。首尾步行路段代表从出发地/目的地到车站的实际步行路线,必须包含
🚇 범안로95번길 32 → SKT타워
路线1:54分钟 · 1,950韩元 · 换乘2次 · 步行688米
  🚶 步行1分钟
  🚌 19路 富川范朴山庄 → 谷洞站(9分钟)
  🚶 步行2分钟
  🚇 1号线 谷洞 → 钟阁(15站,35分钟)
  🚶 步行7分钟
建议最多展示3条路线进行对比。若用户明确偏好
OPT=4
(耗时最短)/
OPT=5
(换乘最少),则调用对应选项。

Done when

完成标准

  • 출발지와 도착지가 geocoding 되었거나, 좌표/역명이 명확히 확인되었다.
  • ODsay 응답에서 1개 이상 경로가 정리되었다.
  • 각 경로의 총 소요시간, 요금, 환승 횟수, 총 도보 거리가 포함되었다.
  • 첫/끝 도보 구간이 포함된 door-to-door 요약을 보여줬다.
  • upstream API 키가 응답에 노출되지 않았다.
  • 出发地和目的地已完成地理编码,或坐标/站名已明确确认。
  • 从ODsay响应中整理出1条及以上路线。
  • 每条路线包含总耗时、费用、换乘次数、总步行距离。
  • 展示包含首尾步行路段的门到门路线摘要。
  • 上游API密钥未在响应中泄露。

Helpers

辅助工具

좌표 모르고 역명만 아는 경우 —
searchStation
으로 변환:
bash
curl -s "https://api.odsay.com/v1/api/searchStation?apiKey=${KEY}&stationName=강남&CID=1000"
CID=1000
= 수도권. 결과
result.station[].x,y
가 좌표.
若仅知道站名而无坐标,可通过
searchStation
接口转换:
bash
curl -s "https://api.odsay.com/v1/api/searchStation?apiKey=${KEY}&stationName=강남&CID=1000"
CID=1000
= 首都圈。结果中的
result.station[].x,y
即为坐标。

Limits

限制说明

  • 현재 ODsay 공식 Basic 상품 기준 무료 체험은 일 1,000건(6개월)이다.
    searchPubTransPathT
    +
    searchStation
    호출이 합산되니 한 질문당 호출 최소화.
  • 응답에
    error
    키 있으면 즉시 사용자에게 표시(ApiKey/IP 문제 진단에 유용).
  • 한국 외 좌표는 지원 안 함.
  • 当前ODsay官方Basic套餐的免费体验额度为每日1000次(有效期6个月),
    searchPubTransPathT
    searchStation
    的调用次数会累加,因此需尽量减少单次查询的调用次数。
  • 若响应中包含
    error
    字段,需立即展示给用户(有助于诊断ApiKey/IP问题)。
  • 不支持韩国境外的坐标。

Failure modes

故障处理

  • ODsay
    error
    응답:
    msg
    필드를 그대로 사용자에게 표시하고, ApiKey 미등록 또는 IP 화이트리스트 누락 가능성을 안내한다.
  • Kakao geocoding 결과 없음: 주소/장소명을 다시 확인하거나 더 구체적인 표현을 요청한다.
  • 좌표는 있으나 ODsay 경로 없음: 대중교통 미개통 지역, 도보 가능 거리, 또는 해상/공항 구간일 수 있다. 사용자에게 확인한다.
  • quota 초과: 일일 한도 도달 시 추가 호출을 중단하고 사용자에게 알린다.
  • ODsay返回
    error
    响应:直接向用户展示
    msg
    字段内容,并提示可能存在ApiKey未注册或IP白名单遗漏的问题。
  • Kakao地理编码无结果:请求用户重新确认地址/场所名称,或提供更具体的表述。
  • 有坐标但ODsay无路线结果:可能是公共交通未覆盖区域、仅可步行区域,或涉及海上/机场路段,需向用户确认。
  • 配额超限:当日额度用尽时,停止后续调用并告知用户。

Don'ts

注意事项

  • 카카오맵/네이버지도 directions API로 대중교통 라우팅 시도하지 말 것 (둘 다 운전·도보만 공개).
  • 키를 절대 응답에 노출하지 말 것.
  • 请勿尝试使用 Kakao Map/Naver Map Directions API进行公共交通路线规划(二者仅公开驾车/步行路线)。
  • 绝对禁止在响应中泄露密钥。