Map Kitでローカル検索ができるMKLocalSearchを試してみた

最近、[iOS位置情報プログラミング](http://www.shuwasystem.co.jp/products/7980html/4070.html)という本を買って読んでいます。

この本を読んで、iOS 6.1からMap Kitに<b>ローカル検索機能</b>が追加されたと知り、さっそくその性能を試してみました。（ここでローカル検索と呼んでいるのは、文字列から駅や飲食店などを検索できる検索機能のことです）

## 実装方法

ローカル検索には次のクラスを使用します。

- MKLocalSearch
- MKLocalSearchRequest
- MKLocalSearchResponse

まずは `MKLocalSearchRequest` インスタンスを生成し、検索文字列、検索範囲をセットします。

```objc
MKLocalSearchRequest *request =
    [[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = searchBar.text;
request.region = _mapView.region;
```

次に、このインスタンスから `MKLocalSearch` インスタンスを生成します。

```objc
MKLocalSearch *search =
    [[MKLocalSearch alloc] initWithRequest:request];
```

これでローカル検索の準備ができました。さっそく `startWithCompletionHandler` メソッドを使って検索してみます。

```objc
[search startWithCompletionHandler:
^(MKLocalSearchResponse *response, NSError *error)
 {
     for (MKMapItem *item in response.mapItems)
     {
         MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
         point.coordinate = item.placemark.coordinate;
         point.title = item.placemark.name;
         point.subtitle = item.placemark.title;

         [_mapView addAnnotation:point];
     }

     [_mapView showAnnotations:[_mapView annotations] animated:YES];
 }];
```

実行結果は blocks 内で受け取ることができます。第1引数の `MKLocalSearchResponse` が検索結果で、第2引数にはエラー情報がセットされます。`MKLocalSearchResponse` クラスの `mapItems` プロパティが配列形式になっており、検索にヒットした分だけ `MKMapItem` 形式で格納されています。この例では、検索結果を順に取り出して `MKMapView` に表示しています。

ちなみに、実装中に知ったのですが、iOS 7から次の便利なメソッドが使えるようになっていました。

```objc
// Position the map such that the provided array of annotations are
// all visible to the fullest extent possible.
- (void)showAnnotations:(NSArray *)annotations
                       animated:(BOOL)animated;
```

第1引数に `MKAnnotation` （赤いピン等）の配列を指定すると、その全てが地図上に表示されるように、自動で縮尺率を調整してくれます。今までだと、これを実現するためには一番端のピンを自分で求める必要があったので、だいぶ楽になりそうですね。

## 実行結果

まずは「渋谷駅」で検索してみました。

<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/k/koogawa/20140321/20140321172659.png" alt="f:id:koogawa:20140321172659p:plain" title="f:id:koogawa:20140321172659p:plain" class="hatena-fotolife" itemprop="image"></span></p>

ちゃんと検索できましたね！

次は「吉野家」で検索してみました。

<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/k/koogawa/20140321/20140321172851.png" alt="f:id:koogawa:20140321172851p:plain" title="f:id:koogawa:20140321172851p:plain" class="hatena-fotolife" itemprop="image"></span></p>

ちゃんとヒットしたのですが、なぜか1件しか返ってきません。全国に吉野家は何件もあるはずなのに不思議ですね。

今度は、割と新しい建物である「ヒカリエ」を検索してみました。

<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/k/koogawa/20140321/20140321172943.png" alt="f:id:koogawa:20140321172943p:plain" title="f:id:koogawa:20140321172943p:plain" class="hatena-fotolife" itemprop="image"></span></p>

茨城県の「光」という地域がヒットしました。。

そして最後に「スカイツリー」で検索してみましたが、結果件数はゼロでした。

## 使ってみた感想

最初に紹介した書籍でも書かれていましたが、日本での検索結果はまだ十分とは言えないと思いました。今後、より充実したエリア情報が検索できるようになることを期待しています。

今回作ったソースコードはこちらにアップしておきました。

* https://github.com/koogawa/MKLocalSearchSample

## 合わせて読みたい

* [iOS 7から追加されたMKDirectionsで経路検索を試してみる](http://qiita.com/koogawa/items/d047a8056a0db5b05771)