amap-cli 0.1.2__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {amap_cli-0.1.2 → amap_cli-0.1.3}/PKG-INFO +30 -2
  2. {amap_cli-0.1.2 → amap_cli-0.1.3}/README.md +29 -1
  3. {amap_cli-0.1.2 → amap_cli-0.1.3}/docs/manual-verification.md +32 -7
  4. {amap_cli-0.1.2 → amap_cli-0.1.3}/pyproject.toml +1 -1
  5. {amap_cli-0.1.2 → amap_cli-0.1.3}/skills/amap-cli/SKILL.md +40 -3
  6. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/cli.py +2 -0
  7. amap_cli-0.1.3/src/amap_cli/geocode_command.py +91 -0
  8. {amap_cli-0.1.2 → amap_cli-0.1.3}/uv.lock +1 -1
  9. {amap_cli-0.1.2 → amap_cli-0.1.3}/.gitignore +0 -0
  10. {amap_cli-0.1.2 → amap_cli-0.1.3}/.trae/specs/build-amap-cli/checklist.md +0 -0
  11. {amap_cli-0.1.2 → amap_cli-0.1.3}/.trae/specs/build-amap-cli/spec.md +0 -0
  12. {amap_cli-0.1.2 → amap_cli-0.1.3}/.trae/specs/build-amap-cli/tasks.md +0 -0
  13. {amap_cli-0.1.2 → amap_cli-0.1.3}/amap-gui-reference.md +0 -0
  14. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/__init__.py +0 -0
  15. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/__main__.py +0 -0
  16. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/api.py +0 -0
  17. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/config.py +0 -0
  18. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/distance.py +0 -0
  19. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/errors.py +0 -0
  20. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/geocode.py +0 -0
  21. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/output.py +0 -0
  22. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/params.py +0 -0
  23. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/route.py +0 -0
  24. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/search_poi.py +0 -0
  25. {amap_cli-0.1.2 → amap_cli-0.1.3}/src/amap_cli/skill.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: amap-cli
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Pure command-line CLI for Amap APIs.
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -13,6 +13,7 @@ Description-Content-Type: text/markdown
13
13
 
14
14
  - 纯命令行调用高德地图 API
15
15
  - 支持命令行写入和读取高德 API Key
16
+ - 支持地理编码
16
17
  - 支持两点直线距离计算
17
18
  - 支持路径规划
18
19
  - 支持 POI 搜索
@@ -35,6 +36,12 @@ uvx amap-cli --help
35
36
  uvx amap-cli config set --api-key <YOUR_AMAP_KEY>
36
37
  ```
37
38
 
39
+ 地理编码示例:
40
+
41
+ ```bash
42
+ uvx amap-cli geocode --address 北京南站
43
+ ```
44
+
38
45
  路径规划示例:
39
46
 
40
47
  ```bash
@@ -79,6 +86,7 @@ amap-cli --help
79
86
 
80
87
  ```bash
81
88
  amap-cli config set --api-key <YOUR_AMAP_KEY>
89
+ amap-cli geocode --address 北京南站
82
90
  amap-cli distance --from 116.397,39.909 --to 116.407,39.904
83
91
  amap-cli route --from 北京南站 --to 天安门 --type driving
84
92
  amap-cli search-poi --keyword 星巴克 --city 北京
@@ -90,7 +98,7 @@ amap-cli search-poi --keyword 星巴克 --city 北京
90
98
 
91
99
  - skill 的目标是让 Agent 直接通过 `uvx amap-cli` 调用本工具
92
100
  - 使用方式与上面的“直接使用 `uvx` 运行”一致
93
- - 使用前先配置高德 API Key,之后即可发起路径规划和 POI 搜索
101
+ - 使用前先配置高德 API Key,之后即可发起地理编码、路径规划和 POI 搜索
94
102
  - `distance` 命令在起终点都为坐标时可直接本地计算,不依赖 API Key
95
103
  - 建议 Agent 直接解析命令返回的 JSON 结果
96
104
 
@@ -152,6 +160,26 @@ amap-cli install-skill --dir <skills目录>
152
160
  - 当目标目录不存在时会自动创建
153
161
  - 当目标目录中已存在同名 skill 时,默认报错;追加 `--force` 后会覆盖
154
162
 
163
+ ### 地理编码
164
+
165
+ 基础格式:
166
+
167
+ ```bash
168
+ amap-cli geocode --address <结构化地址|地标名称>
169
+ ```
170
+
171
+ 可选参数:
172
+
173
+ - `--city`
174
+
175
+ 说明:
176
+
177
+ - 调用高德地理编码接口,将结构化地址或地标性名胜景区、建筑物名称解析为坐标
178
+ - 传入 `--city` 时,会优先在对应城市范围内解析
179
+ - 返回结果中的 `geocode.location` 为 `[经度, 纬度]`
180
+ - 返回结果中的 `geocode.formattedAddress` 为高德返回的标准化地址
181
+ - 对于较模糊的名称,建议补充更完整地址或增加 `--city`
182
+
155
183
  ### 路径规划
156
184
 
157
185
  基础格式:
@@ -6,6 +6,7 @@
6
6
 
7
7
  - 纯命令行调用高德地图 API
8
8
  - 支持命令行写入和读取高德 API Key
9
+ - 支持地理编码
9
10
  - 支持两点直线距离计算
10
11
  - 支持路径规划
11
12
  - 支持 POI 搜索
@@ -28,6 +29,12 @@ uvx amap-cli --help
28
29
  uvx amap-cli config set --api-key <YOUR_AMAP_KEY>
29
30
  ```
30
31
 
32
+ 地理编码示例:
33
+
34
+ ```bash
35
+ uvx amap-cli geocode --address 北京南站
36
+ ```
37
+
31
38
  路径规划示例:
32
39
 
33
40
  ```bash
@@ -72,6 +79,7 @@ amap-cli --help
72
79
 
73
80
  ```bash
74
81
  amap-cli config set --api-key <YOUR_AMAP_KEY>
82
+ amap-cli geocode --address 北京南站
75
83
  amap-cli distance --from 116.397,39.909 --to 116.407,39.904
76
84
  amap-cli route --from 北京南站 --to 天安门 --type driving
77
85
  amap-cli search-poi --keyword 星巴克 --city 北京
@@ -83,7 +91,7 @@ amap-cli search-poi --keyword 星巴克 --city 北京
83
91
 
84
92
  - skill 的目标是让 Agent 直接通过 `uvx amap-cli` 调用本工具
85
93
  - 使用方式与上面的“直接使用 `uvx` 运行”一致
86
- - 使用前先配置高德 API Key,之后即可发起路径规划和 POI 搜索
94
+ - 使用前先配置高德 API Key,之后即可发起地理编码、路径规划和 POI 搜索
87
95
  - `distance` 命令在起终点都为坐标时可直接本地计算,不依赖 API Key
88
96
  - 建议 Agent 直接解析命令返回的 JSON 结果
89
97
 
@@ -145,6 +153,26 @@ amap-cli install-skill --dir <skills目录>
145
153
  - 当目标目录不存在时会自动创建
146
154
  - 当目标目录中已存在同名 skill 时,默认报错;追加 `--force` 后会覆盖
147
155
 
156
+ ### 地理编码
157
+
158
+ 基础格式:
159
+
160
+ ```bash
161
+ amap-cli geocode --address <结构化地址|地标名称>
162
+ ```
163
+
164
+ 可选参数:
165
+
166
+ - `--city`
167
+
168
+ 说明:
169
+
170
+ - 调用高德地理编码接口,将结构化地址或地标性名胜景区、建筑物名称解析为坐标
171
+ - 传入 `--city` 时,会优先在对应城市范围内解析
172
+ - 返回结果中的 `geocode.location` 为 `[经度, 纬度]`
173
+ - 返回结果中的 `geocode.formattedAddress` 为高德返回的标准化地址
174
+ - 对于较模糊的名称,建议补充更完整地址或增加 `--city`
175
+
148
176
  ### 路径规划
149
177
 
150
178
  基础格式:
@@ -24,10 +24,35 @@ uv run python -m amap_cli --help
24
24
  结果:
25
25
 
26
26
  - `uv sync` 成功完成本地安装
27
- - `amap-cli --help` 正确显示 `config`、`distance`、`route`、`search-poi` 四个子命令
27
+ - `amap-cli --help` 正确显示 `config`、`geocode`、`distance`、`route`、`search-poi` 五个子命令
28
28
  - `python -m amap_cli --help` 与脚本入口行为一致
29
29
 
30
- ### 2. `distance` 坐标输入走本地直线距离计算
30
+ ### 2. `geocode` 典型输入通过 CLI 主入口走通到 handler
31
+
32
+ 说明:
33
+
34
+ - 使用 `amap_cli.cli.main(...)` 作为 CLI 主入口
35
+ - 通过 monkeypatch 将 `amap_cli.geocode_command.AmapApiClient` 替换为假 client
36
+ - 仍然走真实参数解析、handler 与统一 JSON 输出
37
+
38
+ 验证输入:
39
+
40
+ ```bash
41
+ geocode --address 北京南站
42
+ ```
43
+
44
+ 假 client 返回:
45
+
46
+ - `/v3/geocode/geo`:北京南站的坐标与标准化地址
47
+
48
+ 结果:
49
+
50
+ - CLI 返回 `success=true`
51
+ - `state.address` 正确保留原始查询
52
+ - `geocode.location` 返回坐标数组
53
+ - `geocode.formattedAddress` 正确透传
54
+
55
+ ### 3. `distance` 坐标输入走本地直线距离计算
31
56
 
32
57
  执行:
33
58
 
@@ -42,7 +67,7 @@ uv run amap-cli distance --from 116.397,39.909 --to 116.407,39.904
42
67
  - `state.mode=straight_line`
43
68
  - `summary.distance` 返回两点之间的直线距离(米)
44
69
 
45
- ### 3. 配置写入与自动读取
70
+ ### 4. 配置写入与自动读取
46
71
 
47
72
  为避免污染真实用户配置,验证时使用隔离 `HOME`:
48
73
 
@@ -59,7 +84,7 @@ HOME="$TMP_HOME" uv run amap-cli config show
59
84
  - 再次执行 `config show` 时可自动读取刚写入的配置
60
85
  - `api_key` 输出已脱敏
61
86
 
62
- ### 4. `route` 典型输入通过 CLI 主入口走通到 handler
87
+ ### 5. `route` 典型输入通过 CLI 主入口走通到 handler
63
88
 
64
89
  说明:
65
90
 
@@ -85,7 +110,7 @@ route --from 北京南站 --to 天安门 --type driving
85
110
  - 起终点地名与坐标正确进入输出
86
111
  - `summary.distance`、`summary.time`、`summary.steps` 正常生成
87
112
 
88
- ### 5. `search-poi` 典型输入通过 CLI 主入口走通到 handler
113
+ ### 6. `search-poi` 典型输入通过 CLI 主入口走通到 handler
89
114
 
90
115
  说明:
91
116
 
@@ -130,5 +155,5 @@ search-poi --keyword 星巴克 --city 北京 --pageSize 1
130
155
 
131
156
  结论:
132
157
 
133
- - 当前五项手动验证均已通过
134
- - CLI 主入口已完成 `distance`、`route`、`search-poi` 整合
158
+ - 当前六项手动验证均已通过
159
+ - CLI 主入口已完成 `geocode`、`distance`、`route`、`search-poi` 整合
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "amap-cli"
7
- version = "0.1.2"
7
+ version = "0.1.3"
8
8
  description = "Pure command-line CLI for Amap APIs."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,18 +1,20 @@
1
1
  ---
2
2
  name: amap-cli
3
- description: Use amap-cli for terminal-based Amap distance calculation, route planning, and POI search. Use when the user needs machine-readable map results in this project. Do not use for GUI-based map interaction.
3
+ description: Use amap-cli for terminal-based Amap geocoding, distance calculation, route planning, and POI search. Use when the user needs machine-readable map results in this project. Do not use for GUI-based map interaction.
4
4
  ---
5
5
 
6
6
  # Amap CLI
7
7
 
8
- 在需要高德地图直线距离计算、路径规划或 POI 搜索时,直接调用 `amap-cli`。
8
+ 在需要高德地图地理编码、直线距离计算、路径规划或 POI 搜索时,直接调用 `amap-cli`。
9
9
 
10
10
  ## 操作规则
11
11
 
12
12
  - 统一使用 `uvx amap-cli` 调用命令
13
13
  - 优先返回和解析 JSON 结果,不依赖自然语言输出
14
- - 在执行 `route` 或 `search-poi` 前,先确认高德 API Key 已配置
14
+ - 在执行 `geocode`、`route` 或 `search-poi` 前,先确认高德 API Key 已配置
15
15
  - 在执行 `distance` 前,若起终点包含地名,也需要先确认高德 API Key 已配置
16
+ - 如果同一个地点后续还要重复用于 `distance`、`route` 或 `search-poi` 周边搜索,先调用 `geocode` 或 `search-poi` 获取坐标,后续优先传 `经度,纬度`,不要重复传地名,以减少地理编码 API 调用量
17
+ - 结构化地址、地标性名胜景区或建筑物名称优先使用 `geocode` 获取坐标;较模糊的地点名称优先使用 `search-poi` 获取目标坐标
16
18
  - 如果返回 `MISSING_CONFIG`,先执行配置命令,再继续业务调用
17
19
 
18
20
  ## 初始化
@@ -35,6 +37,32 @@ uvx amap-cli config set --api-key <YOUR_AMAP_KEY>
35
37
  uvx amap-cli config show
36
38
  ```
37
39
 
40
+ ## Geocode
41
+
42
+ 需要将结构化地址或地标名称解析为坐标时,使用 `geocode`:
43
+
44
+ ```bash
45
+ uvx amap-cli geocode --address 北京南站
46
+ ```
47
+
48
+ 如果需要缩小解析范围,可追加城市:
49
+
50
+ ```bash
51
+ uvx amap-cli geocode --address 软件园二期 --city 厦门
52
+ ```
53
+
54
+ 关键参数:
55
+
56
+ - `--address`:必填,结构化地址、地标性名胜景区或建筑物名称
57
+ - `--city`:可选,用于缩小地理编码范围
58
+
59
+ 关键约束:
60
+
61
+ - 地理编码仅支持详细的结构化地址,以及地标性名胜景区、建筑物名称
62
+ - 返回结果中的 `geocode.location` 为 `[经度, 纬度]`
63
+ - 返回结果中的 `geocode.formattedAddress` 可用于判断解析是否符合预期
64
+ - 对于较模糊的名称,优先补充更完整的地址信息或追加 `--city`
65
+
38
66
  ## Route
39
67
 
40
68
  需要路径规划时,使用 `route`:
@@ -71,10 +99,17 @@ uvx amap-cli route \
71
99
  - `--type transit` 必须显式传 `--city`
72
100
  - `--waypoints` 和 `--policy` 只能和 `--type driving` 一起使用
73
101
  - `--strategy` 只能和 `--type transit` 一起使用
102
+ - 如果起点、终点或途经点后续会复用,先用 `geocode` 或 `search-poi` 拿到坐标,再将坐标传给 `--from`、`--to`、`--waypoints`
74
103
  - 地理编码仅支持详细的结构化地址,以及地标性名胜景区、建筑物名称
75
104
  - 当输入为上述名称时,可从 `state.from.formattedAddress`、`state.to.formattedAddress` 以及 `state.waypoints[*].formattedAddress` 判断解析是否符合预期
76
105
  - 对于其他较模糊的名称,先使用 `search-poi` 获取目标坐标,再调用 `route`
77
106
 
107
+ 推荐流程:
108
+
109
+ 1. 首次解析地点时,使用 `geocode` 或 `search-poi` 获取坐标
110
+ 2. 后续多次规划路线时,统一复用坐标
111
+ 3. 如需保留地点语义,可配合 `--from-name` / `--to-name`
112
+
78
113
  ## Distance
79
114
 
80
115
  需要计算两个地点之间的直线距离时,使用 `distance`:
@@ -103,6 +138,7 @@ uvx amap-cli distance \
103
138
 
104
139
  - 当 `--from` 和 `--to` 都是坐标时,直接本地计算,不依赖 API Key
105
140
  - 任一输入为结构化地址或地标性名胜景区、建筑物名称时,会先调用地理编码接口解析坐标
141
+ - 如果某个地点后续还会继续参与其他计算,首次解析后应复用坐标,避免再次以地名触发地理编码
106
142
  - 当输入为上述名称时,可从 `state.from.formattedAddress` / `state.to.formattedAddress` 判断地理编码是否符合预期
107
143
  - 对于其他较模糊的名称,先使用 `search-poi` 获取目标坐标,再调用 `distance`
108
144
  - 结果中的 `summary.distance` 单位为米
@@ -141,6 +177,7 @@ uvx amap-cli search-poi \
141
177
  - 传入 `--center` 时执行周边搜索
142
178
  - 未传入 `--center` 时执行关键词搜索
143
179
  - `--radius` 只有在传入 `--center` 时才应该使用
180
+ - 如果要围绕某个地点反复做周边搜索,先使用 `geocode` 或 `search-poi` 获取该地点坐标,再持续复用 `--center`,不要每次都传地点名称重新解析
144
181
 
145
182
  ## 输出约定
146
183
 
@@ -8,6 +8,7 @@ from typing import Any, Sequence
8
8
  from amap_cli.config import get_config_path, load_config, save_config
9
9
  from amap_cli.distance import register_distance_command
10
10
  from amap_cli.errors import AmapCliError, ValidationError
11
+ from amap_cli.geocode_command import register_geocode_command
11
12
  from amap_cli.output import emit_error, emit_success
12
13
  from amap_cli.route import register_route_command
13
14
  from amap_cli.search_poi import register_search_poi_command
@@ -31,6 +32,7 @@ def build_parser() -> JsonArgumentParser:
31
32
 
32
33
  _register_config_command(subparsers)
33
34
  register_install_skill_command(subparsers)
35
+ register_geocode_command(subparsers)
34
36
  register_distance_command(subparsers)
35
37
  register_route_command(subparsers)
36
38
  register_search_poi_command(subparsers)
@@ -0,0 +1,91 @@
1
+ """Geocode command registration and handlers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ from dataclasses import dataclass
7
+ from typing import Any
8
+
9
+ from amap_cli.api import AmapApiClient
10
+ from amap_cli.geocode import GeocodeResult, geocode_text
11
+ from amap_cli.params import normalize_text_argument
12
+
13
+
14
+ @dataclass(frozen=True, slots=True)
15
+ class GeocodeRequest:
16
+ """Validated geocode command input."""
17
+
18
+ address: str
19
+ city: str | None
20
+
21
+ @classmethod
22
+ def from_args(cls, args: argparse.Namespace) -> "GeocodeRequest":
23
+ """Build a validated geocode request from parsed CLI arguments."""
24
+ return cls(
25
+ address=normalize_text_argument(args.address, "address"),
26
+ city=(
27
+ normalize_text_argument(args.city, "city")
28
+ if args.city is not None
29
+ else None
30
+ ),
31
+ )
32
+
33
+ def build_state(self) -> dict[str, Any]:
34
+ """Build CLI-facing state metadata."""
35
+ state: dict[str, Any] = {"address": self.address}
36
+ if self.city is not None:
37
+ state["city"] = self.city
38
+ return state
39
+
40
+
41
+ def register_geocode_command(
42
+ subparsers: argparse._SubParsersAction[argparse.ArgumentParser],
43
+ ) -> argparse.ArgumentParser:
44
+ """Register the `geocode` command on a subparser collection."""
45
+ parser = subparsers.add_parser(
46
+ "geocode",
47
+ help="将地点名称解析为坐标",
48
+ description="调用高德地理编码接口,将结构化地址或地标名称解析为坐标。",
49
+ )
50
+ parser.add_argument(
51
+ "--address",
52
+ required=True,
53
+ help="待解析的结构化地址或地标名称",
54
+ )
55
+ parser.add_argument(
56
+ "--city",
57
+ help="可选城市,用于缩小地理编码范围",
58
+ )
59
+ parser.set_defaults(handler=handle_geocode_command)
60
+ return parser
61
+
62
+
63
+ def handle_geocode_command(
64
+ args: argparse.Namespace,
65
+ *,
66
+ client: AmapApiClient | None = None,
67
+ ) -> dict[str, Any]:
68
+ """Handle the `geocode` command and normalize the response."""
69
+ request = GeocodeRequest.from_args(args)
70
+ result = geocode_text(
71
+ request.address,
72
+ client=client or AmapApiClient(),
73
+ city=request.city,
74
+ )
75
+ return {
76
+ "state": request.build_state(),
77
+ "geocode": _normalize_geocode_result(result),
78
+ }
79
+
80
+
81
+ def _normalize_geocode_result(result: GeocodeResult) -> dict[str, Any]:
82
+ """Normalize the geocode result to the CLI output shape."""
83
+ payload: dict[str, Any] = {
84
+ "location": [
85
+ round(result.coordinate.longitude, 6),
86
+ round(result.coordinate.latitude, 6),
87
+ ]
88
+ }
89
+ if result.formatted_address is not None:
90
+ payload["formattedAddress"] = result.formatted_address
91
+ return payload
@@ -4,5 +4,5 @@ requires-python = ">=3.11"
4
4
 
5
5
  [[package]]
6
6
  name = "amap-cli"
7
- version = "0.1.2"
7
+ version = "0.1.3"
8
8
  source = { editable = "." }
File without changes
File without changes
File without changes
File without changes
File without changes