You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Apple Maps中获取经纬度250米半径内的所有周边地点

获取指定半径内的所有地点(突破MKLocalSearchRequest的局限)

嘿,我完全懂你的困扰——MKLocalSearchRequest确实是为特定类型兴趣点查询设计的,必须传入naturalLanguageQuery,没法直接返回一块区域内的所有地点。不过有几个可行的方案可以绕过这个限制,帮你拿到目标区域内的大多数地点:

方案1:用宽泛的查询关键词组合查询(本地API)

既然单个关键词只能返回特定类型,那我们可以用一组覆盖绝大多数POI类别的关键词,分别发起查询,再合并结果去重。比如选择"point of interest""establishment"这类覆盖范围极广的词,把每个请求的结果汇总起来。

示例代码

// 目标经纬度和250米半径区域
let targetCoordinate = CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194)
let searchRegion = MKCoordinateRegion(center: targetCoordinate, latitudinalMeters: 250, longitudinalMeters: 250)

// 覆盖绝大多数POI类别的查询关键词
let broadSearchQueries = [
    "point of interest",
    "establishment",
    "store",
    "restaurant",
    "landmark",
    "building",
    "park",
    "address"
]

var collectedMapItems: [MKMapItem] = []
let dispatchGroup = DispatchGroup()

// 批量发起查询
for query in broadSearchQueries {
    dispatchGroup.enter()
    
    let searchRequest = MKLocalSearchRequest()
    searchRequest.naturalLanguageQuery = query
    searchRequest.region = searchRegion
    
    let search = MKLocalSearch(request: searchRequest)
    search.start { response, error in
        defer { dispatchGroup.leave() }
        
        guard let validResponse = response else {
            print("查询\(query)失败:\(error?.localizedDescription ?? "未知错误")")
            return
        }
        
        collectedMapItems.append(contentsOf: validResponse.mapItems)
    }
}

// 所有查询完成后去重并处理结果
dispatchGroup.notify(queue: .main) {
    // 用placeID或名称+坐标去重(避免同一个地点被多次返回)
    let uniqueMapItems = Array(
        Set(collectedMapItems.map { item in
            item.placeID ?? "\(item.name ?? "")-\(item.coordinate.latitude)-\(item.coordinate.longitude)"
        })
        .compactMap { identifier in
            collectedMapItems.first { item in
                item.placeID == identifier || "\(item.name ?? "")-\(item.coordinate.latitude)-\(item.coordinate.longitude)" == identifier
            }
        }
    )
    
    print("在目标区域内找到\(uniqueMapItems.count)个唯一地点")
    // 这里可以处理你的uniqueMapItems列表
}

注意事项

  • 这个方法能覆盖绝大多数常见地点,但可能会漏掉一些非常见的POI(比如某些小众场馆),毕竟关键词的覆盖范围有限。
  • 去重逻辑需要根据实际情况调整,placeID是最可靠的唯一标识,但部分地点可能没有placeID,这时候用名称+坐标兜底是个不错的选择。

方案2:使用Apple Maps Web Services Search API(网络请求)

如果需要更全面、更精准的结果,推荐使用Apple Maps Web Services的Search API。这个API支持直接根据经纬度和半径查询区域内的所有POI,不需要指定特定关键词。

核心参数说明

  • location:目标经纬度(格式:纬度,经度
  • radius:搜索半径(单位:米,这里填250)
  • types:可选,指定返回的地点类型,填poi可以返回所有兴趣点;如果不填,会返回包括地址、POI在内的所有相关地点
  • key:你的Apple Maps API密钥(需要在Apple Developer后台申请)

请求示例

你可以用URLSession发起GET请求,示例URL大概是这样的:

https://maps-api.apple.com/v1/search?location=37.7749,-122.4194&radius=250&types=poi&key=你的API密钥

注意事项

  • 这个方案需要网络权限,并且有API调用次数限制(免费额度足够大多数小型应用使用)。
  • 返回的是JSON格式数据,需要自己解析成模型,不像MKLocalSearch直接返回MKMapItem

总结

如果优先考虑本地无网络依赖,方案1是快速可行的折中方案;如果需要最全面的结果,方案2的Web API是更好的选择。

内容的提问来源于stack exchange,提问作者FE_Tech

火山引擎 最新活动