API 文档

获取交路图图片

根据车次的交路表和首末站坐标生成交路图。默认返回 JSON 包装结构(含图片直链),也可以让接口直接返回 PNG 或 PDF 文件内容。

返回 API 列表
get/api/v2/timetable/train/{trainCode}/circulation/image
可匿名访问api.timetable.train.circulation.image.read

场景

适用场景

这个接口适合用在什么地方?下面的场景可以帮你判断它是不是你要找的那个。

  • 在页面里直接展示交路图:使用默认的 JSON 返回,取 imageUrl 放进 <img>。
  • 把交路图下载成 PDF 存档或打印:设置 format=pdf。
  • 程序直接保存图片文件:设置 binary=true 并写入本地文件。

问答

常见问题

接入时最常遇到的疑问,先看看这里能不能解答。

binary 应该怎么选?

需要图片直链时用 binary=false(默认);需要直接拿到文件内容时用 binary=true。两者都支持 format=png 或 format=pdf。

为什么有时扣费是 2 点,有时是 20 点?

交路图由上游编译服务渲染。缓存命中时按缓存档位扣费(较低),未命中时按完整渲染成本扣费(较高),失败时按失败档位扣费。

扣费

扣费规则

根据上游 Typst 编译是否命中缓存决定扣费档位。

缓存命中 2 点/次,缓存未命中 20 点/次,失败 2 点/次

实际扣费以响应头 x-api-cost 为准。

请求说明

参数

路径参数

trainCodestring 必填

要查询的车次号,例如 G2492、D2212 或 C2001。字母大小写都可以,服务端会做标准化处理。

示例:G2492

查询参数

formatpng | pdf

交路图的输出格式:png 或 pdf。不传时默认使用 png。

示例:png

binarytrue | false

是否直接返回图片或 PDF 的原始二进制内容。传 true 时响应体就是文件本身;不传或传 false 时返回 JSON 包装结构(包含图片直链)。

示例:false

响应说明

状态码与响应格式

200

交路图生成成功:JSON 包装结构或原始图片/PDF 文件。

响应头

x-api-remainx-api-costRetry-After
application/jsonobject

响应结构

{
    "type": "object",
    "required": [
        "meta",
        "data"
    ],
    "properties": {
        "meta": {
            "type": "object",
            "required": true,
            "shape": {
                "type": "object",
                "required": [
                    "remain",
                    "cost"
                ],
                "properties": {
                    "remain": {
                        "type": "integer",
                        "required": true
                    },
                    "cost": {
                        "type": "integer",
                        "required": true
                    },
                    "retryAfter": {
                        "type": "integer"
                    }
                }
            }
        },
        "data": {
            "type": "object",
            "required": true,
            "shape": {
                "type": "object",
                "required": [
                    "documentId",
                    "imageUrl"
                ],
                "properties": {
                    "requestTrainCode": {
                        "type": "object",
                        "shape": {
                            "type": "object",
                            "required": [
                                "prefix",
                                "number"
                            ],
                            "properties": {
                                "prefix": {
                                    "type": "string",
                                    "required": true
                                },
                                "number": {
                                    "type": "integer",
                                    "required": true
                                }
                            }
                        }
                    },
                    "trainCode": {
                        "type": "object",
                        "shape": {
                            "type": "object",
                            "required": [
                                "prefix",
                                "number"
                            ],
                            "properties": {
                                "prefix": {
                                    "type": "string",
                                    "required": true
                                },
                                "number": {
                                    "type": "integer",
                                    "required": true
                                }
                            }
                        }
                    },
                    "documentId": {
                        "type": "string",
                        "required": true
                    },
                    "imageUrl": {
                        "type": "string",
                        "required": true
                    },
                    "content": {
                        "type": "string"
                    },
                    "binaryContentType": {
                        "type": "string"
                    }
                }
            }
        }
    }
}

示例响应

{
    "meta": {
        "remain": 159,
        "cost": 2
    },
    "data": {
        "cacheHit": false,
        "requestTrainCode": {
            "prefix": "G",
            "number": 2492
        },
        "trainCode": {
            "prefix": "G",
            "number": 2492
        },
        "documentId": "8d2fca6e88c2a1e3c2106a4f28f0d5e7b3147427ec8d1b4af75a4b6b485b92ce",
        "imageUrl": "https://static.example.com/circulation/8d2fca6e88c2a1e3c2106a4f28f0d5e7b3147427ec8d1b4af75a4b6b485b92ce/png/1"
    }
}
image/pngstring

响应结构

{
    "type": "string"
}
application/pdfstring

响应结构

{
    "type": "string"
}
400

路径参数、binary 查询参数或 format 查询参数无效。

响应头

x-api-remainx-api-costRetry-After
application/jsonobject

响应结构

{
    "type": "object",
    "required": [
        "ok",
        "data",
        "error"
    ],
    "properties": {
        "ok": {
            "type": "boolean",
            "required": true
        },
        "data": {
            "type": "string",
            "required": true
        },
        "error": {
            "type": "string",
            "required": true
        }
    }
}

示例响应

{
    "ok": false,
    "data": "binary 必须是 true/false",
    "error": "invalid_param"
}
401

请求未携带有效的认证信息,或提供的 API Key 已失效。

响应头

x-api-remainx-api-costRetry-After
application/jsonobject

响应结构

{
    "type": "object",
    "required": [
        "ok",
        "data",
        "error"
    ],
    "properties": {
        "ok": {
            "type": "boolean",
            "required": true
        },
        "data": {
            "type": "string",
            "required": true
        },
        "error": {
            "type": "string",
            "required": true
        }
    }
}

示例响应

{
    "ok": false,
    "data": "API Key 无效或已过期。",
    "error": "invalid_api_key"
}
403

当前凭证缺少调用该接口所需的 scope。

响应头

x-api-remainx-api-costRetry-After
application/jsonobject

响应结构

{
    "type": "object",
    "required": [
        "ok",
        "data",
        "error"
    ],
    "properties": {
        "ok": {
            "type": "boolean",
            "required": true
        },
        "data": {
            "type": "string",
            "required": true
        },
        "error": {
            "type": "string",
            "required": true
        }
    }
}

示例响应

{
    "ok": false,
    "data": "缺少调用该接口所需的权限。",
    "error": "forbidden"
}
404

当前时刻表或交路数据不可用。

响应头

x-api-remainx-api-costRetry-After
application/jsonobject

响应结构

{
    "type": "object",
    "required": [
        "ok",
        "data",
        "error"
    ],
    "properties": {
        "ok": {
            "type": "boolean",
            "required": true
        },
        "data": {
            "type": "string",
            "required": true
        },
        "error": {
            "type": "string",
            "required": true
        }
    }
}

示例响应

{
    "ok": false,
    "data": "当前暂无交路数据",
    "error": "not_found"
}
422

今日时刻表数据不完整,无法生成交路图。

响应头

x-api-remainx-api-costRetry-After
application/jsonobject

响应结构

{
    "type": "object",
    "required": [
        "ok",
        "data",
        "error"
    ],
    "properties": {
        "ok": {
            "type": "boolean",
            "required": true
        },
        "data": {
            "type": "string",
            "required": true
        },
        "error": {
            "type": "string",
            "required": true
        }
    }
}

示例响应

{
    "ok": false,
    "data": "交路节点 G2492 的首末站缺少经纬度",
    "error": "invalid_schedule_data"
}
429

额度不足或请求过于频繁。

响应头

x-api-remainx-api-costRetry-After
application/jsonobject

响应结构

{
    "type": "object",
    "required": [
        "ok",
        "data",
        "error"
    ],
    "properties": {
        "ok": {
            "type": "boolean",
            "required": true
        },
        "data": {
            "type": "string",
            "required": true
        },
        "error": {
            "type": "string",
            "required": true
        }
    }
}

示例响应

{
    "ok": false,
    "data": "额度不足,请稍后再试。",
    "error": "rate_limited"
}
502

上游渲染服务不可用或编译失败。

响应头

x-api-remainx-api-costRetry-After
application/jsonobject

响应结构

{
    "type": "object",
    "required": [
        "ok",
        "data",
        "error"
    ],
    "properties": {
        "ok": {
            "type": "boolean",
            "required": true
        },
        "data": {
            "type": "string",
            "required": true
        },
        "error": {
            "type": "string",
            "required": true
        }
    }
}

示例响应

{
    "ok": false,
    "data": "交路图渲染服务暂时不可用",
    "error": "upstream_unavailable"
}