expo-gaode-map-search 1.3.1-next.0 → 1.3.1-next.1

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.
@@ -11,7 +11,9 @@ export declare enum SearchType {
11
11
  /** 多边形搜索 */
12
12
  POLYGON = "polygon",
13
13
  /** 输入提示 */
14
- INPUT_TIPS = "inputTips"
14
+ INPUT_TIPS = "inputTips",
15
+ /** 逆地理编码 */
16
+ RE_GEOCODE = "reGeocode"
15
17
  }
16
18
  /**
17
19
  * 坐标点
@@ -50,6 +52,161 @@ export interface POI {
50
52
  adName?: string;
51
53
  /** 区域编码 */
52
54
  adCode?: string;
55
+ /**
56
+ * 深度信息 (Android SDK V9.4.0+ 新增)
57
+ * 包含评分、营业时间、人均消费等扩展信息
58
+ */
59
+ business?: {
60
+ opentime?: string;
61
+ opentimeToday?: string;
62
+ rating?: string;
63
+ cost?: string;
64
+ parkingType?: string;
65
+ tag?: string;
66
+ tel?: string;
67
+ alias?: string;
68
+ businessArea?: string;
69
+ };
70
+ /**
71
+ * 图片信息
72
+ */
73
+ photos?: Array<{
74
+ title?: string;
75
+ url?: string;
76
+ }>;
77
+ /** 室内地图信息 */
78
+ indoor?: {
79
+ /** 楼层 */
80
+ floor?: string;
81
+ /** 楼层名称 */
82
+ floorName?: string;
83
+ /** POI ID */
84
+ poiId?: string;
85
+ /** 是否有室内地图 */
86
+ hasIndoorMap?: boolean;
87
+ };
88
+ }
89
+ /**
90
+ * 商圈信息
91
+ */
92
+ export interface BusinessArea {
93
+ /** 名称 */
94
+ name: string;
95
+ /** 中心坐标 */
96
+ location: Coordinates;
97
+ }
98
+ /**
99
+ * 地址组成要素
100
+ */
101
+ export interface AddressComponent {
102
+ /** 省名称 */
103
+ province: string;
104
+ /** 市名称 */
105
+ city: string;
106
+ /** 区名称 */
107
+ district: string;
108
+ /** 乡镇名称 */
109
+ township: string;
110
+ /** 社区名称 */
111
+ neighborhood: string;
112
+ /** 建筑名称 */
113
+ building: string;
114
+ /** 城市编码 */
115
+ cityCode: string;
116
+ /** 区域编码 */
117
+ adCode: string;
118
+ /** 门牌信息 */
119
+ streetNumber: {
120
+ /** 街道名称 */
121
+ street: string;
122
+ /** 门牌号 */
123
+ number: string;
124
+ /** 坐标点 */
125
+ location?: Coordinates;
126
+ /** 方向 */
127
+ direction: string;
128
+ /** 距离 */
129
+ distance: number;
130
+ };
131
+ /** 商圈列表 */
132
+ businessAreas?: BusinessArea[];
133
+ }
134
+ /**
135
+ * 道路信息
136
+ */
137
+ export interface Road {
138
+ /** 道路ID */
139
+ id: string;
140
+ /** 道路名称 */
141
+ name: string;
142
+ /** 距离 */
143
+ distance: number;
144
+ /** 方向 */
145
+ direction: string;
146
+ /** 坐标点 */
147
+ location: Coordinates;
148
+ }
149
+ /**
150
+ * 道路交叉口信息
151
+ */
152
+ export interface RoadCross {
153
+ /** 距离 */
154
+ distance: number;
155
+ /** 方向 */
156
+ direction: string;
157
+ /** 交叉口坐标 */
158
+ location: Coordinates;
159
+ /** 第一条道路ID */
160
+ firstId: string;
161
+ /** 第一条道路名称 */
162
+ firstName: string;
163
+ /** 第二条道路ID */
164
+ secondId: string;
165
+ /** 第二条道路名称 */
166
+ secondName: string;
167
+ }
168
+ /**
169
+ * 兴趣区域信息
170
+ */
171
+ export interface AOI {
172
+ /** AOI ID */
173
+ id: string;
174
+ /** AOI 名称 */
175
+ name: string;
176
+ /** 区域编码 */
177
+ adCode: string;
178
+ /** 中心点坐标 */
179
+ location: Coordinates;
180
+ /** 面积 */
181
+ area: number;
182
+ }
183
+ /**
184
+ * 逆地理编码选项
185
+ */
186
+ export interface ReGeocodeOptions {
187
+ /** 经纬度坐标 */
188
+ location: Coordinates;
189
+ /** 搜索半径,默认 1000 米 */
190
+ radius?: number;
191
+ /** 是否返回扩展信息,默认 true */
192
+ requireExtension?: boolean;
193
+ }
194
+ /**
195
+ * 逆地理编码结果
196
+ */
197
+ export interface ReGeocodeResult {
198
+ /** 格式化地址 */
199
+ formattedAddress: string;
200
+ /** 地址组成要素 */
201
+ addressComponent: AddressComponent;
202
+ /** 兴趣点列表 */
203
+ pois: POI[];
204
+ /** 道路列表 */
205
+ roads: Road[];
206
+ /** 道路交叉口列表 */
207
+ roadCrosses: RoadCross[];
208
+ /** 兴趣区域列表 */
209
+ aois: AOI[];
53
210
  }
54
211
  /**
55
212
  * POI 搜索选项
@@ -16,4 +16,6 @@ var SearchType;
16
16
  SearchType["POLYGON"] = "polygon";
17
17
  /** 输入提示 */
18
18
  SearchType["INPUT_TIPS"] = "inputTips";
19
+ /** 逆地理编码 */
20
+ SearchType["RE_GEOCODE"] = "reGeocode";
19
21
  })(SearchType || (exports.SearchType = SearchType = {}));
@@ -1,7 +1,18 @@
1
+ import { AlongSearchOptions, InputTipsOptions, InputTipsResult, NearbySearchOptions, POI, POISearchOptions, PolygonSearchOptions, ReGeocodeOptions, ReGeocodeResult, SearchResult } from './ExpoGaodeMapSearch.types';
2
+ declare class ExpoGaodeMapSearchModuleType {
3
+ initSearch(): void;
4
+ searchPOI(options: POISearchOptions): Promise<SearchResult>;
5
+ searchNearby(options: NearbySearchOptions): Promise<SearchResult>;
6
+ searchAlong(options: AlongSearchOptions): Promise<SearchResult>;
7
+ searchPolygon(options: PolygonSearchOptions): Promise<SearchResult>;
8
+ getInputTips(options: InputTipsOptions): Promise<InputTipsResult>;
9
+ reGeocode(options: ReGeocodeOptions): Promise<ReGeocodeResult>;
10
+ getPoiDetail(id: string): Promise<POI>;
11
+ }
1
12
  /**
2
13
  * 高德地图搜索模块
3
14
  *
4
15
  * 提供 POI 搜索、周边搜索、沿途搜索、多边形搜索和输入提示功能
5
16
  */
6
- declare const ExpoGaodeMapSearchModule: any;
17
+ declare const ExpoGaodeMapSearchModule: ExpoGaodeMapSearchModuleType;
7
18
  export default ExpoGaodeMapSearchModule;
package/build/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Coordinates, POI, POISearchOptions, NearbySearchOptions, AlongSearchOptions, PolygonSearchOptions, InputTipsOptions, InputTip, SearchResult, InputTipsResult } from './ExpoGaodeMapSearch.types';
1
+ import type { Coordinates, POI, POISearchOptions, NearbySearchOptions, AlongSearchOptions, PolygonSearchOptions, InputTipsOptions, InputTip, SearchResult, InputTipsResult, ReGeocodeOptions, ReGeocodeResult, AddressComponent, Road, RoadCross, AOI } from './ExpoGaodeMapSearch.types';
2
2
  /**
3
3
  * 初始化搜索模块(可选)
4
4
  *
@@ -111,7 +111,36 @@ export declare function searchPolygon(options: PolygonSearchOptions): Promise<Se
111
111
  * ```
112
112
  */
113
113
  export declare function getInputTips(options: InputTipsOptions): Promise<InputTipsResult>;
114
- export type { Coordinates, POI, POISearchOptions, NearbySearchOptions, AlongSearchOptions, PolygonSearchOptions, InputTipsOptions, InputTip, SearchResult, InputTipsResult, };
114
+ /**
115
+ * 逆地理编码(坐标转地址)
116
+ *
117
+ * @param options 逆地理编码选项
118
+ * @returns 逆地理编码结果
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * const result = await reGeocode({
123
+ * location: { latitude: 39.9, longitude: 116.4 },
124
+ * radius: 1000,
125
+ * });
126
+ * console.log(result.formattedAddress);
127
+ * ```
128
+ */
129
+ export declare function reGeocode(options: ReGeocodeOptions): Promise<ReGeocodeResult>;
130
+ /**
131
+ * POI 详情查询
132
+ *
133
+ * @param id POI ID
134
+ * @returns POI 详情
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const poi = await getPoiDetail('B000A83M61');
139
+ * console.log(poi.name, poi.address);
140
+ * ```
141
+ */
142
+ export declare function getPoiDetail(id: string): Promise<POI>;
143
+ export type { Coordinates, POI, POISearchOptions, NearbySearchOptions, AlongSearchOptions, PolygonSearchOptions, InputTipsOptions, InputTip, SearchResult, InputTipsResult, ReGeocodeOptions, ReGeocodeResult, AddressComponent, Road, RoadCross, AOI, };
115
144
  export { SearchType } from './ExpoGaodeMapSearch.types';
116
145
  declare const _default: {
117
146
  initSearch: typeof initSearch;
@@ -120,5 +149,6 @@ declare const _default: {
120
149
  searchAlong: typeof searchAlong;
121
150
  searchPolygon: typeof searchPolygon;
122
151
  getInputTips: typeof getInputTips;
152
+ reGeocode: typeof reGeocode;
123
153
  };
124
154
  export default _default;
package/build/index.js CHANGED
@@ -10,6 +10,8 @@ exports.searchNearby = searchNearby;
10
10
  exports.searchAlong = searchAlong;
11
11
  exports.searchPolygon = searchPolygon;
12
12
  exports.getInputTips = getInputTips;
13
+ exports.reGeocode = reGeocode;
14
+ exports.getPoiDetail = getPoiDetail;
13
15
  const ExpoGaodeMapSearchModule_1 = __importDefault(require("./ExpoGaodeMapSearchModule"));
14
16
  /**
15
17
  * 初始化搜索模块(可选)
@@ -135,6 +137,39 @@ async function searchPolygon(options) {
135
137
  async function getInputTips(options) {
136
138
  return await ExpoGaodeMapSearchModule_1.default.getInputTips(options);
137
139
  }
140
+ /**
141
+ * 逆地理编码(坐标转地址)
142
+ *
143
+ * @param options 逆地理编码选项
144
+ * @returns 逆地理编码结果
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const result = await reGeocode({
149
+ * location: { latitude: 39.9, longitude: 116.4 },
150
+ * radius: 1000,
151
+ * });
152
+ * console.log(result.formattedAddress);
153
+ * ```
154
+ */
155
+ async function reGeocode(options) {
156
+ return await ExpoGaodeMapSearchModule_1.default.reGeocode(options);
157
+ }
158
+ /**
159
+ * POI 详情查询
160
+ *
161
+ * @param id POI ID
162
+ * @returns POI 详情
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * const poi = await getPoiDetail('B000A83M61');
167
+ * console.log(poi.name, poi.address);
168
+ * ```
169
+ */
170
+ async function getPoiDetail(id) {
171
+ return await ExpoGaodeMapSearchModule_1.default.getPoiDetail(id);
172
+ }
138
173
  var ExpoGaodeMapSearch_types_1 = require("./ExpoGaodeMapSearch.types");
139
174
  Object.defineProperty(exports, "SearchType", { enumerable: true, get: function () { return ExpoGaodeMapSearch_types_1.SearchType; } });
140
175
  // 默认导出
@@ -145,4 +180,5 @@ exports.default = {
145
180
  searchAlong,
146
181
  searchPolygon,
147
182
  getInputTips,
183
+ reGeocode,
148
184
  };
@@ -43,6 +43,9 @@ public class ExpoGaodeMapSearchModule: Module {
43
43
  request.types = types
44
44
  request.page = pageNum
45
45
  request.offset = pageSize
46
+ // SDK 9.4.0+ 使用 showFieldsType 控制返回字段
47
+ // AMapPOISearchShowFieldsTypeAll (返回所有扩展信息)
48
+ request.showFieldsType = AMapPOISearchShowFieldsType.all
46
49
 
47
50
  self.searchDelegate.currentPromise = promise
48
51
  self.searchAPI.aMapPOIKeywordsSearch(request)
@@ -81,6 +84,7 @@ public class ExpoGaodeMapSearchModule: Module {
81
84
  request.types = types
82
85
  request.page = pageNum
83
86
  request.offset = pageSize
87
+ request.showFieldsType = AMapPOISearchShowFieldsType.all
84
88
 
85
89
  self.searchDelegate.currentPromise = promise
86
90
  self.searchAPI.aMapPOIAroundSearch(request)
@@ -170,6 +174,7 @@ public class ExpoGaodeMapSearchModule: Module {
170
174
  let pageSize = options["pageSize"] as? Int ?? 20
171
175
  let pageNum = options["pageNum"] as? Int ?? 1
172
176
 
177
+ // 转换路线点
173
178
  var points: [AMapGeoPoint] = []
174
179
  for point in polygon {
175
180
  if let lat = point["latitude"] as? Double,
@@ -187,6 +192,7 @@ public class ExpoGaodeMapSearchModule: Module {
187
192
  request.types = types
188
193
  request.page = pageNum
189
194
  request.offset = pageSize
195
+ request.showFieldsType = AMapPOISearchShowFieldsType.all
190
196
 
191
197
  self.searchDelegate.currentPromise = promise
192
198
  self.searchAPI.aMapPOIPolygonSearch(request)
@@ -214,10 +220,61 @@ public class ExpoGaodeMapSearchModule: Module {
214
220
  self.searchDelegate.currentPromise = promise
215
221
  self.searchAPI.aMapInputTipsSearch(request)
216
222
  }
223
+
224
+ /**
225
+ * 逆地理编码(坐标转地址)
226
+ */
227
+ AsyncFunction("reGeocode") { (options: [String: Any], promise: Promise) in
228
+ self.initSearchAPI()
229
+
230
+ guard let location = options["location"] as? [String: Any],
231
+ let latitude = location["latitude"] as? Double,
232
+ let longitude = location["longitude"] as? Double else {
233
+ promise.reject("SEARCH_ERROR", "location is required")
234
+ return
235
+ }
236
+
237
+ let radius = options["radius"] as? Int ?? 1000
238
+ let requireExtension = options["requireExtension"] as? Bool ?? true
239
+
240
+ let request = AMapReGeocodeSearchRequest()
241
+ request.location = AMapGeoPoint.location(withLatitude: CGFloat(latitude), longitude: CGFloat(longitude))
242
+ request.radius = limitReGeocodeRadius(radius)
243
+ request.requireExtension = requireExtension
244
+
245
+ self.searchDelegate.currentPromise = promise
246
+ self.searchAPI.aMapReGoecodeSearch(request)
247
+ }
248
+
249
+ /**
250
+ * POI ID 搜索(详情查询)
251
+ */
252
+ AsyncFunction("getPoiDetail") { (id: String, promise: Promise) in
253
+ self.initSearchAPI()
254
+
255
+ if id.isEmpty {
256
+ promise.reject("SEARCH_ERROR", "id is required")
257
+ return
258
+ }
259
+
260
+ let request = AMapPOIIDSearchRequest()
261
+ request.uid = id
262
+
263
+ self.searchDelegate.currentPromise = promise
264
+ self.searchAPI.aMapPOIIDSearch(request)
265
+ }
217
266
  }
267
+
218
268
 
219
269
  // MARK: - Private Methods
220
270
 
271
+ private func limitReGeocodeRadius(_ radius: Int) -> Int {
272
+ // AMapReGeocodeSearchRequest radius property is NSInteger
273
+ // The documentation doesn't specify a strict limit but usually it's around 0-3000m for regeocode.
274
+ // We just cast it safely.
275
+ return radius
276
+ }
277
+
221
278
  /**
222
279
  * 初始化搜索 API(延迟初始化)
223
280
  */
@@ -230,7 +287,7 @@ public class ExpoGaodeMapSearchModule: Module {
230
287
  searchAPI = AMapSearchAPI()
231
288
  searchAPI.delegate = searchDelegate
232
289
 
233
- let apiKey = AMapServices.shared().apiKey
290
+ _ = AMapServices.shared().apiKey
234
291
  }
235
292
  }
236
293
 
@@ -266,7 +323,7 @@ class SearchDelegate: NSObject, AMapSearchDelegate {
266
323
  guard let promise = currentPromise else { return }
267
324
 
268
325
  if let response = response {
269
- promise.resolve(convertPOISearchResponse(response))
326
+ promise.resolve(convertPOISearchResponse(response, request: request))
270
327
  } else {
271
328
  promise.reject("SEARCH_ERROR", "Search failed")
272
329
  }
@@ -304,6 +361,21 @@ class SearchDelegate: NSObject, AMapSearchDelegate {
304
361
  currentPromise = nil
305
362
  }
306
363
 
364
+ /**
365
+ * 逆地理编码回调
366
+ */
367
+ func onReGeocodeSearchDone(_ request: AMapReGeocodeSearchRequest!, response: AMapReGeocodeSearchResponse!) {
368
+ guard let promise = currentPromise else { return }
369
+
370
+ if let response = response {
371
+ promise.resolve(convertReGeocodeResponse(response))
372
+ } else {
373
+ promise.reject("SEARCH_ERROR", "ReGeocode failed")
374
+ }
375
+
376
+ currentPromise = nil
377
+ }
378
+
307
379
  /**
308
380
  * 搜索失败回调
309
381
  */
@@ -320,8 +392,41 @@ class SearchDelegate: NSObject, AMapSearchDelegate {
320
392
  /**
321
393
  * 转换 POI 搜索结果
322
394
  */
323
- private func convertPOISearchResponse(_ response: AMapPOISearchResponse) -> [String: Any] {
395
+ private func convertPOISearchResponse(_ response: AMapPOISearchResponse, request: AMapPOISearchBaseRequest!) -> Any {
396
+ // 检查是否是 ID 搜索(只有 1 个结果且不是列表)
397
+ // 但 AMapPOISearchResponse 总是返回列表
398
+ // 我们约定如果是 ID 搜索,我们在 JS 层处理,这里依然返回列表格式,或者如果是单个 POI,我们取第一个
399
+
400
+ // 注意:ID 搜索返回的也是 AMapPOISearchResponse
401
+
324
402
  let pois = response.pois?.map { poi -> [String: Any] in
403
+ return convertPOI(poi)
404
+ } ?? []
405
+
406
+ // 如果是 ID 搜索,通常 pois 只有一个
407
+ // 为了保持 searchPOI 接口返回结构一致,我们总是返回列表结构
408
+ // 但对于 getPoiDetail,我们需要单个对象。
409
+ // 由于 native 无法区分当前是 searchPOI 还是 getPoiDetail 调用的回调(除非用不同 delegate 方法,但 SDK 都是 onPOISearchDone)
410
+ // 我们可以根据 request 类型判断?SDK 回调中 request 参数是基类 AMapPOISearchBaseRequest
411
+
412
+ if request is AMapPOIIDSearchRequest {
413
+ if let first = pois.first {
414
+ return first
415
+ } else {
416
+ return [:] // 没找到
417
+ }
418
+ }
419
+
420
+ return [
421
+ "pois": pois,
422
+ "total": response.count,
423
+ "pageNum": response.pois?.first?.uid != nil ? 1 : 0,
424
+ "pageSize": response.pois?.count ?? 0,
425
+ "pageCount": (response.count + 19) / 20
426
+ ]
427
+ }
428
+
429
+ private func convertPOI(_ poi: AMapPOI) -> [String: Any] {
325
430
  var result: [String: Any] = [
326
431
  "id": poi.uid ?? "",
327
432
  "name": poi.name ?? "",
@@ -335,20 +440,79 @@ class SearchDelegate: NSObject, AMapSearchDelegate {
335
440
  "tel": poi.tel ?? "",
336
441
  "distance": poi.distance,
337
442
  "cityName": poi.city ?? "",
443
+ "cityCode": poi.citycode ?? "",
338
444
  "provinceName": poi.province ?? "",
339
445
  "adName": poi.district ?? "",
340
- "adCode": poi.adcode ?? ""
446
+ "adCode": poi.adcode ?? "",
447
+ "businessArea": poi.businessArea ?? "",
448
+ "parkingType": poi.parkingType ?? "",
449
+ "website": poi.website ?? "",
450
+ "email": poi.email ?? "",
451
+ "postcode": poi.postcode ?? ""
452
+ ]
453
+
454
+ // 图片信息
455
+ if let images = poi.images {
456
+ result["photos"] = images.map { image in
457
+ return [
458
+ "title": image.title ?? "",
459
+ "url": image.url ?? ""
460
+ ]
461
+ }
462
+ }
463
+
464
+ // 室内信息
465
+ if let indoor = poi.indoorData {
466
+ result["indoor"] = [
467
+ "floor": indoor.floor,
468
+ "floorName": indoor.floorName ?? "",
469
+ "poiId": indoor.pid ?? "",
470
+ "hasIndoorMap": poi.hasIndoorMap
471
+ ]
472
+ }
473
+
474
+ // 深度信息 (Business)
475
+ // 只有当有扩展信息或特定业务字段时才返回
476
+ var business: [String: Any] = [
477
+ "tel": poi.tel ?? "",
478
+ "parkingType": poi.parkingType ?? "",
479
+ "businessArea": poi.businessArea ?? ""
341
480
  ]
481
+
482
+ // 合并 extensionInfo
483
+ if let ext = poi.extensionInfo {
484
+ business["rating"] = String(format: "%.1f", ext.rating)
485
+ business["cost"] = String(format: "%.1f", ext.cost)
486
+ business["opentime"] = ext.openTime ?? ""
487
+ }
488
+
489
+ // 合并 businessData (SDK 9.4.0 新增)
490
+ if let biz = poi.businessData {
491
+ business["alias"] = biz.alias ?? ""
492
+ business["tag"] = biz.tag ?? ""
493
+
494
+ // 如果 extensionInfo 没有这些字段,优先使用 businessData
495
+ if business["rating"] == nil || (business["rating"] as? String) == "0.0" {
496
+ business["rating"] = biz.rating ?? ""
497
+ }
498
+ if business["cost"] == nil || (business["cost"] as? String) == "0.0" {
499
+ business["cost"] = biz.cost ?? ""
500
+ }
501
+ if business["opentime"] == nil || (business["opentime"] as? String) == "" {
502
+ business["opentime"] = biz.opentimeWeek ?? ""
503
+ }
504
+
505
+ business["opentimeToday"] = biz.opentimeToday ?? ""
506
+
507
+ // 如果外层没有 tel/parkingType/businessArea,尝试从 businessData 获取
508
+ if (business["tel"] as? String) == "" { business["tel"] = biz.tel ?? "" }
509
+ if (business["parkingType"] as? String) == "" { business["parkingType"] = biz.parkingType ?? "" }
510
+ if (business["businessArea"] as? String) == "" { business["businessArea"] = biz.businessArea ?? "" }
511
+ }
512
+
513
+ result["business"] = business
514
+
342
515
  return result
343
- } ?? []
344
-
345
- return [
346
- "pois": pois,
347
- "total": response.count,
348
- "pageNum": response.pois?.first?.uid != nil ? 1 : 0,
349
- "pageSize": response.pois?.count ?? 0,
350
- "pageCount": (response.count + 19) / 20
351
- ]
352
516
  }
353
517
 
354
518
  /**
@@ -378,12 +542,126 @@ class SearchDelegate: NSObject, AMapSearchDelegate {
378
542
  return ["tips": tips]
379
543
  }
380
544
 
545
+ /**
546
+ * 转换逆地理编码结果
547
+ */
548
+ private func convertReGeocodeResponse(_ response: AMapReGeocodeSearchResponse) -> [String: Any] {
549
+ guard let regeocode = response.regeocode else {
550
+ return [:]
551
+ }
552
+
553
+ var result: [String: Any] = [
554
+ "formattedAddress": regeocode.formattedAddress ?? ""
555
+ ]
556
+
557
+ if let addressComponent = regeocode.addressComponent {
558
+ let streetNumber = addressComponent.streetNumber
559
+ let streetNumberDict: [String: Any] = [
560
+ "street": streetNumber?.street ?? "",
561
+ "number": streetNumber?.number ?? "",
562
+ "direction": streetNumber?.direction ?? "",
563
+ "distance": streetNumber?.distance ?? 0
564
+ ]
565
+
566
+ let businessAreas = addressComponent.businessAreas?.map { area -> [String: Any] in
567
+ return [
568
+ "name": area.name ?? "",
569
+ "location": [
570
+ "latitude": area.location?.latitude ?? 0,
571
+ "longitude": area.location?.longitude ?? 0
572
+ ]
573
+ ]
574
+ } ?? []
575
+
576
+ result["addressComponent"] = [
577
+ "province": addressComponent.province ?? "",
578
+ "city": addressComponent.city ?? "",
579
+ "district": addressComponent.district ?? "",
580
+ "township": addressComponent.township ?? "",
581
+ "neighborhood": addressComponent.neighborhood ?? "",
582
+ "building": addressComponent.building ?? "",
583
+ "cityCode": addressComponent.citycode ?? "",
584
+ "adCode": addressComponent.adcode ?? "",
585
+ "streetNumber": streetNumberDict,
586
+ "businessAreas": businessAreas
587
+ ]
588
+ }
589
+
590
+ if let pois = regeocode.pois {
591
+ result["pois"] = pois.map { poi -> [String: Any] in
592
+ return [
593
+ "id": poi.uid ?? "",
594
+ "name": poi.name ?? "",
595
+ "typeCode": poi.typecode ?? "",
596
+ "typeDes": poi.type ?? "",
597
+ "tel": poi.tel ?? "",
598
+ "distance": poi.distance,
599
+ "direction": poi.direction ?? "",
600
+ "address": poi.address ?? "",
601
+ "location": [
602
+ "latitude": poi.location?.latitude ?? 0,
603
+ "longitude": poi.location?.longitude ?? 0
604
+ ]
605
+ ]
606
+ }
607
+ }
608
+
609
+ if let aois = regeocode.aois {
610
+ result["aois"] = aois.map { aoi -> [String: Any] in
611
+ return [
612
+ "id": aoi.uid ?? "",
613
+ "name": aoi.name ?? "",
614
+ "adCode": aoi.adcode ?? "",
615
+ "location": [
616
+ "latitude": aoi.location?.latitude ?? 0,
617
+ "longitude": aoi.location?.longitude ?? 0
618
+ ],
619
+ "area": aoi.area
620
+ ]
621
+ }
622
+ }
623
+
624
+ if let roads = regeocode.roads {
625
+ result["roads"] = roads.map { road -> [String: Any] in
626
+ return [
627
+ "id": road.uid ?? "",
628
+ "name": road.name ?? "",
629
+ "distance": road.distance,
630
+ "direction": road.direction ?? "",
631
+ "location": [
632
+ "latitude": road.location?.latitude ?? 0,
633
+ "longitude": road.location?.longitude ?? 0
634
+ ]
635
+ ]
636
+ }
637
+ }
638
+
639
+ if let roadinters = regeocode.roadinters {
640
+ result["roadCrosses"] = roadinters.map { cross -> [String: Any] in
641
+ return [
642
+ "distance": cross.distance,
643
+ "direction": cross.direction ?? "",
644
+ "location": [
645
+ "latitude": cross.location?.latitude ?? 0,
646
+ "longitude": cross.location?.longitude ?? 0
647
+ ],
648
+ "firstId": cross.firstId ?? "",
649
+ "firstName": cross.firstName ?? "",
650
+ "secondId": cross.secondId ?? "",
651
+ "secondName": cross.secondName ?? ""
652
+ ]
653
+ }
654
+ }
655
+
656
+ return result
657
+ }
658
+
381
659
  /**
382
660
  * 转换沿途 POI 搜索结果
383
661
  */
384
662
  private func convertRoutePOISearchResponse(_ response: AMapRoutePOISearchResponse) -> [String: Any] {
385
663
  let pois = response.pois?.map { poi -> [String: Any] in
386
- var result: [String: Any] = [
664
+ let result: [String: Any] = [
387
665
  "id": poi.uid ?? "",
388
666
  "name": poi.name ?? "",
389
667
  "address": "",