@maptec/cli 1.0.0

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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +284 -0
  3. package/bin/maptec.js +2 -0
  4. package/dist/chunk-K574OFFK.js +122 -0
  5. package/dist/chunk-K574OFFK.js.map +1 -0
  6. package/dist/cli.js +899 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/store-ZU7HLXCV.js +18 -0
  9. package/dist/store-ZU7HLXCV.js.map +1 -0
  10. package/package.json +47 -0
  11. package/skills/README.md +30 -0
  12. package/skills/jsapi-skills/README.md +60 -0
  13. package/skills/jsapi-skills/SKILL.md +145 -0
  14. package/skills/jsapi-skills/package.json +31 -0
  15. package/skills/jsapi-skills/references/controls.md +195 -0
  16. package/skills/jsapi-skills/references/events.md +222 -0
  17. package/skills/jsapi-skills/references/geocoding.md +184 -0
  18. package/skills/jsapi-skills/references/map-style.md +123 -0
  19. package/skills/jsapi-skills/references/map.md +154 -0
  20. package/skills/jsapi-skills/references/marker.md +136 -0
  21. package/skills/jsapi-skills/references/operate.md +138 -0
  22. package/skills/jsapi-skills/references/overlay.md +311 -0
  23. package/skills/jsapi-skills/references/place-search.md +411 -0
  24. package/skills/jsapi-skills/references/poi-categories.md +123 -0
  25. package/skills/jsapi-skills/references/popup.md +146 -0
  26. package/skills/jsapi-skills/references/re-geocoding.md +183 -0
  27. package/skills/jsapi-skills/references/routing.md +347 -0
  28. package/skills/jsapi-skills/references/track.md +240 -0
  29. package/skills/jsapi-skills/scripts/validate_jsapi_skill.py +160 -0
  30. package/skills/webapi-skills/README.md +73 -0
  31. package/skills/webapi-skills/SKILL.md +63 -0
  32. package/skills/webapi-skills/package.json +32 -0
  33. package/skills/webapi-skills/references/direction-api.md +175 -0
  34. package/skills/webapi-skills/references/geocoding.md +195 -0
  35. package/skills/webapi-skills/references/ip-location.md +87 -0
  36. package/skills/webapi-skills/references/matrix-api.md +149 -0
  37. package/skills/webapi-skills/references/nearby-search.md +223 -0
  38. package/skills/webapi-skills/references/places.md +239 -0
  39. package/skills/webapi-skills/references/quick-start-cn.md +219 -0
  40. package/skills/webapi-skills/references/reverse-geocoding.md +157 -0
  41. package/skills/webapi-skills/references/suggest.md +111 -0
  42. package/skills/webapi-skills/references/text-search.md +282 -0
  43. package/skills/webapi-skills/scripts/validate_webapi_skill.py +158 -0
@@ -0,0 +1,183 @@
1
+ # 逆地理编码能力参考
2
+
3
+ 当用户要求把经纬度坐标转换为详细地址、点击地图显示地址、或将用户当前位置坐标转换为地址信息时,使用本参考。本文件只覆盖功能 **逆地理编码**。
4
+
5
+ 地址、地名、地标转坐标请读取 `geocoding.md`。
6
+
7
+ ## 能力入口
8
+
9
+ | 用户需求 | 优先实现 |
10
+ |---|---|
11
+ | “将用户当前位置坐标转换为详细地址” | 先获取 `[lng, lat]`,再 `Geocode.getAddress` |
12
+ | “点击地图显示地址” | `map.on("click")` 获取坐标,再 `Geocode.getAddress` |
13
+ | “根据坐标反查地址” | `Geocode.getAddress(lngLatLike, options, callback)` |
14
+
15
+ ## Geocode 服务
16
+
17
+ 逆地理编码和地理编码使用同一个服务类 `Maptec.Geocode`,但方法不同:逆地理编码使用 `getAddress`。
18
+
19
+ ```js
20
+ const geocode = new Maptec.Geocode({
21
+ language: "zh-CN",
22
+ region: "SG",
23
+ timeout: 10000
24
+ });
25
+ ```
26
+
27
+ ## getAddress
28
+
29
+ 调用模式:
30
+
31
+ ```js
32
+ geocode.getAddress(lngLatLike, callback);
33
+ geocode.getAddress(lngLatLike, options, callback);
34
+ ```
35
+
36
+ 示例:
37
+
38
+ ```js
39
+ geocode.getAddress([103.84748, 1.30002], {
40
+ language: "zh-CN",
41
+ region: "SG"
42
+ }, (error, result) => {
43
+ if (error) {
44
+ console.error("逆地理编码失败", error);
45
+ return;
46
+ }
47
+
48
+ const address = result?.results?.[0]?.formattedAddress;
49
+ if (!address) {
50
+ console.warn("没有逆地理编码结果", result?.status);
51
+ return;
52
+ }
53
+
54
+ console.log(address);
55
+ });
56
+ ```
57
+
58
+ ## 点击地图显示地址
59
+
60
+ ```js
61
+ let popup = null;
62
+
63
+ const onMapClick = (event) => {
64
+ const position = Maptec.LngLat.convert(event.lngLat).toArray();
65
+
66
+ geocode.getAddress(position, {
67
+ language: "zh-CN",
68
+ region: "SG"
69
+ }, (error, result) => {
70
+ if (error) {
71
+ console.error("逆地理编码失败", error);
72
+ return;
73
+ }
74
+
75
+ const address = result?.results?.[0]?.formattedAddress || "未找到地址";
76
+
77
+ if (!popup) {
78
+ popup = new Maptec.Popup({
79
+ position,
80
+ text: address,
81
+ closeButton: true,
82
+ closeOnClick: false
83
+ });
84
+ map.addOverlay(popup);
85
+ } else {
86
+ popup.position = position;
87
+ popup.text = address;
88
+ }
89
+ });
90
+ };
91
+
92
+ map.on("click", onMapClick);
93
+ ```
94
+
95
+ ## 当前位置反查地址
96
+
97
+ ```js
98
+ function reverseGeocodeCurrentPosition() {
99
+ if (!navigator.geolocation) {
100
+ console.warn("当前浏览器不支持定位");
101
+ return;
102
+ }
103
+
104
+ navigator.geolocation.getCurrentPosition(
105
+ (position) => {
106
+ const lngLat = [
107
+ position.coords.longitude,
108
+ position.coords.latitude
109
+ ];
110
+
111
+ geocode.getAddress(lngLat, { language: "zh-CN", region: "SG" }, (error, result) => {
112
+ if (error) {
113
+ console.error("逆地理编码失败", error);
114
+ return;
115
+ }
116
+
117
+ console.log(result?.results?.[0]?.formattedAddress);
118
+ });
119
+ },
120
+ (error) => {
121
+ console.error("定位失败", error);
122
+ },
123
+ { enableHighAccuracy: true, timeout: 10000 }
124
+ );
125
+ }
126
+ ```
127
+
128
+ ## ReverseGeocodeOptions
129
+
130
+ 逆地理编码参数可能包含以下过滤字段,具体可用值以 SDK 文档和运行时为准:
131
+
132
+ - `language?: string`:覆盖服务默认语言。
133
+ - `region?: string`:覆盖服务默认区域。
134
+ - `resultType?: string`:一个或多个地址结果类型,用 `|` 分隔。
135
+ - `locationType?: string`:一个或多个精度过滤值,用 `|` 分隔。
136
+
137
+ ```js
138
+ geocode.getAddress([103.84748, 1.30002], {
139
+ resultType: "street_address|premise",
140
+ locationType: "ROOFTOP|INTERPOLATED"
141
+ }, callback);
142
+ ```
143
+
144
+ 常见 `resultType`:
145
+
146
+ - `"country"`
147
+ - `"region"`
148
+ - `"subregion"`
149
+ - `"locality"`
150
+ - `"sublocality"`
151
+ - `"neighborhood"`
152
+ - `"thoroughfare"`
153
+ - `"premise"`
154
+ - `"subpremise"`
155
+ - `"postalCode"`
156
+ - `"intersection"`
157
+
158
+ ## 结果类型
159
+
160
+ `ReverseGeocodeCallback = (error, result?) => void`。
161
+
162
+ 逆地理编码结果结构与 `GeocodeResult` 一致,常用字段:
163
+
164
+ - `status`
165
+ - `results`
166
+ - `results[0].formattedAddress`
167
+ - `results[0].geometry.location`
168
+ - `results[0].addressComponents`
169
+ - `error`
170
+
171
+ ## 注意事项
172
+
173
+ - 输入坐标必须是 `[lng, lat]`。
174
+ - `resultType` 和 `locationType` 只过滤返回结果,不改变输入坐标,也不设置搜索半径。
175
+ - 必须处理无地址结果、定位失败和权限拒绝。
176
+ - 用户当前位置来自浏览器定位,不是 Maptec 逆地理编码自动获取的。
177
+
178
+ ## Agent 规则
179
+
180
+ - 坐标反查地址必须使用 `Maptec.Geocode.getAddress`,不能用地理编码方法替代。
181
+ - 输入坐标必须是 `[lng, lat]`;浏览器定位结果需要转换为 `[longitude, latitude]`。
182
+ - 用户当前位置必须通过浏览器定位或业务传入坐标获取,逆地理编码不会自动定位。
183
+ - 必须处理定位权限拒绝、服务错误和无地址结果。
@@ -0,0 +1,347 @@
1
+ # Maptec Route Planning Reference
2
+
3
+ Use this reference when planning or rendering driving routes, truck routes, waypoint routes, alternative routes, route styling, route summaries, or turn-by-turn steps.
4
+
5
+ ## 中文能力入口
6
+
7
+ 本文件对应功能 **路线规划**:面向路线规划场景,支持驾车路线规划和路线展示。
8
+
9
+ | 用户需求 | 优先实现 |
10
+ |---|---|
11
+ | “绘制一个新加坡国立大学到乌节路的驾车路线” | 先分别地理编码起终点,再 `Maptec.Driving.search` |
12
+ | “展示驾车路线” | `new Maptec.Driving({ map, enableDrawRoute: true })` |
13
+ | “避开高速/收费路” | 使用 `avoid` 参数 |
14
+ | “货车路线” | 使用 `Maptec.TruckDriving` 和车辆规格参数 |
15
+
16
+ ## Capability Selection
17
+
18
+ - Use `Maptec.Driving` for normal driving routes.
19
+ - Use `Maptec.TruckDriving` when the scenario mentions truck, freight, vehicle height/weight/length, cargo constraints, or truck-specific restrictions.
20
+ - If the user provides addresses or place names instead of coordinates/place ids, geocode them first with `Maptec.Geocode.getLocation(...)`, then pass `[lng, lat]` coordinates into route search.
21
+ - Do not use a hand-drawn `Polyline` as a substitute for route planning when the requirement is a real route. Use `Driving`/`TruckDriving`; optionally render or restyle the returned path afterward.
22
+ - Route planning results must mark direction with start/end icons. Use `Maptec.Marker` at origin/destination or the returned route path endpoints, for example green "起" and red "终"; include these markers in cleanup.
23
+
24
+ ## DrivingOptions
25
+
26
+ Create the service with a map instance:
27
+
28
+ - `map: Map`
29
+ - `enableDrawRoute?: boolean`. Default `true`; when true, SDK draws the selected route.
30
+ - `strokeColor?: string`. Default `"#3FB1CE"`.
31
+ - `strokeWeight?: number`. Default `6`.
32
+ - `timeout?: number`. Default `10000`.
33
+
34
+ ```js
35
+ const driving = new Maptec.Driving({
36
+ map,
37
+ enableDrawRoute: true,
38
+ strokeColor: "#2563eb",
39
+ strokeWeight: 6,
40
+ timeout: 10000
41
+ });
42
+ ```
43
+
44
+ ## Driving.search
45
+
46
+ Supported call patterns:
47
+
48
+ ```js
49
+ driving.search(origin, destination, callback);
50
+ driving.search(origin, destination, options, callback);
51
+ ```
52
+
53
+ `origin` and `destination` can be `LngLatLike` coordinates or supported place id strings. Prefer `[lng, lat]` coordinates after geocoding user-provided addresses.
54
+
55
+ ```js
56
+ const origin = [103.8318, 1.3048];
57
+ const destination = [103.7764, 1.2966];
58
+
59
+ driving.search(origin, destination, {
60
+ strategy: "fastest",
61
+ alternatives: true,
62
+ language: "en-GB",
63
+ units: "metric"
64
+ }, (error, result) => {
65
+ if (error) {
66
+ console.error("Driving search failed", error);
67
+ return;
68
+ }
69
+
70
+ const route = result?.routes?.[0];
71
+ if (!route) {
72
+ console.warn("No route found", result?.status);
73
+ return;
74
+ }
75
+
76
+ console.log(route.summary.distanceMeters, route.summary.durationSeconds);
77
+ });
78
+ ```
79
+
80
+ ## 起终点方向标识
81
+
82
+ 路线绘制完成后,应使用 `Maptec.Marker` 标识起点和终点,帮助用户确认路线方向。推荐起点使用绿色“起”,终点使用红色“终”。如果起终点来自地址或地名,先解析为坐标;如果路线结果返回 `route.path`,也可以用路径首尾点标识。
83
+
84
+ ```js
85
+ function createRouteEndpointElement(label, color) {
86
+ const element = document.createElement("div");
87
+ element.textContent = label;
88
+ Object.assign(element.style, {
89
+ width: "30px",
90
+ height: "30px",
91
+ borderRadius: "999px",
92
+ border: "2px solid #ffffff",
93
+ background: color,
94
+ color: "#ffffff",
95
+ display: "flex",
96
+ alignItems: "center",
97
+ justifyContent: "center",
98
+ fontWeight: "800"
99
+ });
100
+ return element;
101
+ }
102
+
103
+ const startMarker = new Maptec.Marker({
104
+ position: origin,
105
+ element: createRouteEndpointElement("起", "#16a34a"),
106
+ anchor: "bottom"
107
+ });
108
+
109
+ const endMarker = new Maptec.Marker({
110
+ position: destination,
111
+ element: createRouteEndpointElement("终", "#dc2626"),
112
+ anchor: "bottom"
113
+ });
114
+
115
+ map.addOverlay(startMarker);
116
+ map.addOverlay(endMarker);
117
+ ```
118
+
119
+ ## DirectionsCommonSearchOptions
120
+
121
+ `DrivingSearchOptions = DirectionsCommonSearchOptions`.
122
+
123
+ Fields:
124
+
125
+ - `waypoints?: LngLatLike[]`. Intermediate points.
126
+ - `departureTime?: string`. ISO 8601, for example `"2025-10-31T10:00:00Z"`.
127
+ - `strategy?: "fastest" | "shortest" | "eco" | "balanced"`. Default `"fastest"`.
128
+ - `alternatives?: boolean`. Default `false`.
129
+ - `language?: string`. Default `"en-GB"`.
130
+ - `units?: "metric" | "imperial"`. Default `"metric"`.
131
+ - `avoid?: DrivingAvoid`.
132
+ - `bearing?: number`. Origin heading `0..359`, helps road snapping.
133
+ - `radius?: number`. Origin/destination matching radius in meters.
134
+
135
+ ```js
136
+ driving.search(origin, destination, {
137
+ waypoints: [[103.82, 1.31]],
138
+ strategy: "shortest",
139
+ alternatives: true,
140
+ avoid: { criteria: ["tolls", "ferries"] },
141
+ bearing: 90,
142
+ radius: 50
143
+ }, callback);
144
+ ```
145
+
146
+ ## DrivingAvoid
147
+
148
+ `DrivingAvoid`:
149
+
150
+ - `criteria?: ("tolls" | "highways" | "ferries")[]`
151
+ - `areas?: string[]`. AI-defined areas such as `["high_crime_zones"]`.
152
+ - `polygons?: any[]`. GeoJSON Polygon Geometry objects.
153
+
154
+ ```js
155
+ const avoid = {
156
+ criteria: ["tolls", "ferries"],
157
+ polygons: [
158
+ {
159
+ type: "Polygon",
160
+ coordinates: [[
161
+ [100.505, 13.760],
162
+ [100.515, 13.760],
163
+ [100.515, 13.768],
164
+ [100.505, 13.768],
165
+ [100.505, 13.760]
166
+ ]]
167
+ }
168
+ ]
169
+ };
170
+ ```
171
+
172
+ ## TruckDriving
173
+
174
+ `Maptec.TruckDriving` uses the same search pattern as `Driving`, with truck-specific `vehicleSpec`.
175
+
176
+ `TruckDrivingSearchOptions = DirectionsCommonSearchOptions & { vehicleSpec?: DrivingVehicleSpec }`.
177
+
178
+ Use `TruckDrivingSearchOptions` when the route must consider truck dimensions, gross weight, cargo, or truck-restricted roads. If `vehicleSpec` is omitted, the server plans with generic truck defaults.
179
+
180
+ `DrivingVehicleSpec`:
181
+
182
+ - `heightMeters?: number`
183
+ - `lengthMeters?: number`
184
+ - `weightTons?: number`
185
+ - `payloadType?: string[]`
186
+
187
+ ```js
188
+ const truck = new Maptec.TruckDriving({
189
+ map,
190
+ enableDrawRoute: true
191
+ });
192
+
193
+ truck.search(origin, destination, {
194
+ vehicleSpec: {
195
+ heightMeters: 4.2,
196
+ weightTons: 40,
197
+ lengthMeters: 16
198
+ },
199
+ avoid: { criteria: ["ferries"] },
200
+ alternatives: true
201
+ }, callback);
202
+ ```
203
+
204
+ Truck search supports the same call patterns:
205
+
206
+ ```js
207
+ truck.search(origin, destination, callback);
208
+ truck.search(origin, destination, truckOptions, callback);
209
+ ```
210
+
211
+ Truck-specific option example:
212
+
213
+ ```js
214
+ truck.search(origin, destination, {
215
+ vehicleSpec: {
216
+ heightMeters: 3.8,
217
+ weightTons: 20,
218
+ lengthMeters: 12
219
+ },
220
+ avoid: { criteria: ["ferries"] },
221
+ alternatives: true,
222
+ strategy: "shortest"
223
+ }, (error, result) => {
224
+ if (error) return console.error(error);
225
+ console.log(result?.routes);
226
+ });
227
+ ```
228
+
229
+ ## Result Types
230
+
231
+ `DrivingCallback = (error, result?) => void`.
232
+
233
+ `DrivingError`:
234
+
235
+ - `code: string`
236
+ - `message: string`
237
+
238
+ `DrivingResult`:
239
+
240
+ - `status: "OK" | "NO_ROUTE_FOUND" | "ERROR"`
241
+ - `routes?: DrivingRoute[]`
242
+ - `error?: DrivingError`
243
+
244
+ `DrivingRoute`:
245
+
246
+ - `summary: DrivingSummary`
247
+ - `legs: DrivingLeg[]`
248
+ - `path?: LngLat[]`. Route coordinates for custom drawing if needed.
249
+ - `warnings?: string[]`
250
+
251
+ `DrivingSummary`:
252
+
253
+ - `distanceMeters: number`
254
+ - `durationSeconds: number`
255
+ - `trafficDurationSeconds?: number`
256
+
257
+ `DrivingLeg`:
258
+
259
+ - `startAddress: string`
260
+ - `endAddress: string`
261
+ - `summary: DrivingSummary`
262
+ - `steps: DrivingStep[]`
263
+
264
+ `DrivingStep`:
265
+
266
+ - `instruction: string`
267
+ - `startLocation: LngLatLike`
268
+ - `endLocation: LngLatLike`
269
+ - `distanceMeters: number`
270
+ - `durationSeconds: number`
271
+ - `polyline: string`
272
+ - `turnType: string`
273
+
274
+ ## Route From Natural Language Addresses
275
+
276
+ Use geocoding first, then route planning:
277
+
278
+ ```js
279
+ const geocode = new Maptec.Geocode({ region: "SG", language: "en" });
280
+ const driving = new Maptec.Driving({ map, enableDrawRoute: true });
281
+
282
+ function getFirstLocation(query) {
283
+ return new Promise((resolve, reject) => {
284
+ geocode.getLocation(query, { region: "SG" }, (error, result) => {
285
+ if (error) {
286
+ reject(error);
287
+ return;
288
+ }
289
+ const location = result?.results?.[0]?.geometry?.location;
290
+ if (!location) {
291
+ reject(new Error(`No geocode result for ${query}`));
292
+ return;
293
+ }
294
+ resolve([location.longitude, location.latitude]);
295
+ });
296
+ });
297
+ }
298
+
299
+ Promise.all([
300
+ getFirstLocation("Orchard Road, Singapore"),
301
+ getFirstLocation("National University of Singapore")
302
+ ]).then(([origin, destination]) => {
303
+ driving.search(origin, destination, { strategy: "fastest" }, (error, result) => {
304
+ if (error) return console.error(error);
305
+ const route = result?.routes?.[0];
306
+ if (route?.path?.length) {
307
+ const bounds = route.path.reduce((nextBounds, point) => [
308
+ [
309
+ Math.min(nextBounds[0][0], point[0]),
310
+ Math.min(nextBounds[0][1], point[1])
311
+ ],
312
+ [
313
+ Math.max(nextBounds[1][0], point[0]),
314
+ Math.max(nextBounds[1][1], point[1])
315
+ ]
316
+ ], [route.path[0], route.path[0]]);
317
+ map.fitBounds(bounds, { padding: 80 });
318
+ }
319
+ });
320
+ });
321
+ ```
322
+
323
+ ## Service Methods
324
+
325
+ Route services expose:
326
+
327
+ - `search(...)`
328
+ - `clear()`: clear drawn route.
329
+ - `setActiveRoute(index)`: switch active route by route index when alternatives exist.
330
+ - `setStyle(style)`: update route drawing style when supported.
331
+
332
+ ## Pitfalls
333
+
334
+ - Do not decompose a route request into only markers. A route request must call `Driving.search` or `TruckDriving.search`.
335
+ - Do not pass address strings to route search unless the SDK explicitly supports them. Use `Geocode.getLocation` first.
336
+ - If `enableDrawRoute` is `true`, avoid also drawing a duplicate custom `Polyline` unless product intentionally needs a second visual.
337
+ - When `alternatives: true`, render route selection UI or call `setActiveRoute(...)`; otherwise the user cannot compare alternatives.
338
+ - Truck constraints belong in `vehicleSpec`, not in normal `DrivingSearchOptions`.
339
+ - Do not use `TruckDriving` for normal passenger-car routing unless the user specifically needs truck restrictions.
340
+
341
+ ## Agent 规则
342
+
343
+ - 真实路线规划必须使用 `Maptec.Driving.search` 或 `Maptec.TruckDriving.search`,不能用手写折线冒充。
344
+ - 起终点是地址、地名或 POI 名称时,必须先使用 `Maptec.Geocode.getLocation` 转换为 `[lng, lat]`。
345
+ - 货车路线只有在用户明确提到货车、载重、限高、限宽、货运等约束时才使用 `TruckDriving`。
346
+ - 路线结果必须处理 `NO_ROUTE_FOUND`、错误和空 `routes`,不能渲染假路线。
347
+ - 路线规划必须使用 `Maptec.Marker` 增加起终点图标,起点标识“起”,终点标识“终”,并在清理阶段移除这两个 Marker。