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 | 1 | 0

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

示例:false

响应说明

状态码与响应格式

200

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

响应头

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

响应结构

{
    "type": "object",
    "required": [
        "ok",
        "data",
        "error"
    ],
    "properties": {
        "ok": {
            "type": "true",
            "required": true,
            "enum": [
                true
            ]
        },
        "data": {
            "type": "object",
            "required": true,
            "shape": {
                "type": "object",
                "required": [
                    "cacheHit",
                    "documentId",
                    "imageUrl"
                ],
                "properties": {
                    "cacheHit": {
                        "type": "boolean",
                        "required": true
                    },
                    "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
                    }
                }
            }
        },
        "error": {
            "type": "",
            "required": true,
            "enum": [
                ""
            ]
        }
    }
}

示例响应

{
    "ok": true,
    "data": {
        "cacheHit": false,
        "requestTrainCode": {
            "prefix": "G",
            "number": 2492
        },
        "trainCode": {
            "prefix": "G",
            "number": 2492
        },
        "documentId": "7d56fe674ce2c3f76bb7b3b619eff3ed45704c9711328e5553e50a00537d8cad",
        "imageUrl": "https://latex.lihugang.top/7d56fe674ce2c3f76bb7b3b619eff3ed45704c9711328e5553e50a00537d8cad/png/1"
    },
    "error": ""
}
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": "false",
            "required": true,
            "enum": [
                false
            ]
        },
        "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": "false",
            "required": true,
            "enum": [
                false
            ]
        },
        "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": "false",
            "required": true,
            "enum": [
                false
            ]
        },
        "data": {
            "type": "string",
            "required": true
        },
        "error": {
            "type": "string",
            "required": true
        }
    }
}

账号已被封禁。

{
    "ok": false,
    "data": "账号已被封禁",
    "error": "account_banned"
}

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

{
    "ok": false,
    "data": "当前 API Key 缺乏访问该接口的权限",
    "error": "forbidden_scope"
}

当前身份的额度上限低于接口最低调用成本。

{
    "ok": false,
    "data": "当前身份额度上限不足,无法调用该接口",
    "error": "cost_exceeds_quota_limit"
}
404

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

响应头

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

响应结构

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

示例响应

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

Accept 请求头不支持 JSON 响应。

响应头

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

响应结构

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

示例响应

{
    "ok": false,
    "data": "Accept 不支持 application/json 或 application/x-protobuf",
    "error": "not_acceptable"
}
422

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

响应头

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

响应结构

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

示例响应

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

额度不足或请求过于频繁,建议等 Retry-After 提示的时间后再试。

响应头

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

响应结构

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

示例响应

{
    "ok": false,
    "data": "额度不足,请稍后再试",
    "error": "quota_exceeded"
}
500

服务内部错误或响应编码失败。

响应头

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

响应结构

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

示例响应

{
    "ok": false,
    "data": "服务内部错误,请稍后再试",
    "error": "internal_error"
}
502

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

响应头

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

响应结构

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

示例响应

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