はじめに
AppleのMapKitを使って、現在地近くのお店(MKMapItem)を取得する機会があったので、備忘録的にまとめます。
基本
- 2つのオプションがあって、自然言語で検索する場合、しない場合
- MKMapViewに対して使う方法は今回は記載してません。
自然言語で検索する場合
- MKLocalSearch.Requestを使用する
// locationはCLLocationCoordinate2D
let localSearch = MKLocalSearch.Request()
// この場合、centerを中心に100m * 100mの四角形の中を検索する
localSearch.region = MKCoordinateRegion(center: location, latitudinalMeters: 100, longitudinalMeters: 100)
localSearch.naturalLanguageQuery = "検索したい言葉"
let response = try? await MKLocalSearch(request: localSearch).start()
// または
MKLocalSearch(request: localSearch).start { response, error in }
// responseからMKMapItemを取得できる
response.mapItems
MKLocalSearch.Request()を使う場合はnaturalLanguageQueryがないと、Errorになるので注意
自然言語で検索しない場合
- MKLocalPointsOfInterestRequestを使用する
// locationはCLLocationCoordinate2D
// centerを中心に半径100mの円の中から取得する
let poiSearch = MKLocalPointsOfInterestRequest(center: location, radius: 100)
// または100m*100mの四角形の中から取得する
let poiSearch = MKLocalPointsOfInterestRequest(coordinateRegion: MKCoordinateRegion(center: location, latitudinalMeters: 100, longitudinalMeters: 100))
let response = try? await MKLocalSearch(request: poiSearch).start()
// または
MKLocalSearch(request: poiSearch).start { response, error in }
オプション
- MKPointOfInterestCategoryによるフィルタリング
カフェなどのカテゴリー分類されているMKPointOfInterestCategoryを使って、フィルターすることもできる
// カフェだけを取得する
localRequest.pointOfInterestFilter = .init(including: [.cafe])
// カフェだけを除外する
localRequest.pointOfInterestFilter = init(excluding: [.cafe])
// 全てを含める
localRequest.pointOfInterestFilter = .includingAll
// 全てを除外
localRequest.pointOfInterestFilter = .excludingAll
取得したMKMapItemのCategoryは
mapItem.pointOfInterestCategory
で取得できる
ただ、pointOfInterestCategoryがないものも多々ある
- 1回のリクエストで最大25件しか取れなさそう
試したところ、どんなに距離を伸ばしても1回のリクエストで最大25件しか取得できないかも
参考
終わり