概要
ios版のYMapKit(YahooのMap SDK)を使うことになったのですが、ググってもSwift版のサンプルコードが一つも見つからなかったので、書いておきます。(いろいろハマってたので、ごちゃごちゃして汚いですが)
- 参考記事: 本家チュートリアル(Objective-C)
実装上の注意
SDKに付属されている画像ファイルは、Images.xcassetsに追加しても表示されない。
マニュアル通りにプロジェクトのリソースに追加すること。
http://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/iphonesdk/tutorial1.html
実装方法
地図の表示
Hoge-Bridging-Header.h
#import <YMapKit/YMapKit.h>
YahooMapViewController.swift
import UIKit
class YahooMapViewController: UIViewController, YMKMapViewDelegate {
var map: YMKMapView?
override func viewDidLoad() {
super.viewDidLoad()
// YMKMapViewのインスタンスを作成
map = YMKMapView(frame: CGRectMake(0, 0, 320, 320), appid: "アプリケーションID")
// 地図のタイプを指定 標準の地図を指定
map!.mapType = UInt(YMKMapTypeStandard)
// YMKMapViewを追加
self.view = map!
// YMKMapViewDelegateを登録
map!.delegate = self
// 地図の位置と縮尺を設定
var center = CLLocationCoordinate2D.init();
center.latitude = 35.6657214;
center.longitude = 139.7310058;
map!.region = YMKCoordinateRegionMake(center, YMKCoordinateSpanMake(0.002, 0.002));
// Do any additional setup after loading the view.
}
}
ルート案内
YahooMapViewController.swift
import UIKit
class MyAnnotation: NSObject, YMKAnnotation {
var coordinate: CLLocationCoordinate2D
var annotationTitle: String!
var annotationSubtitle: String!
var annotationIndex: Int
init(locationCoordinate: CLLocationCoordinate2D, title: String!, subtitle: String!, index: Int) {
coordinate = locationCoordinate
annotationTitle = title
annotationSubtitle = subtitle
annotationIndex = index
}
func title() -> String! {
return annotationTitle
}
func subtitle() -> String! {
return annotationSubtitle
}
}
class YahooMapViewController: BaseMapViewController, YMKMapViewDelegate, YMKRouteOverlayDelegate, YMKNaviControllerDelegate {
var mapView: YMKMapView!
var naviController: YMKNaviController? //ルート案内インスタンス
override func viewDidLoad() {
super.viewDidLoad()
// YMKMapViewを生成する
mapView = YMKMapView(frame: self.view.bounds, appid: "アプリケーションID"))
// 地図のタイプを指定 標準の地図を指定
mapView.mapType = UInt(YMKMapTypeStandard)
mapView.showsUserLocation = true
mapView.delegate = self
self.view.addSubview(mapView)
let startLocation = CLLocation.init(latitude: 35.6657214, longitude: 139.7310058) // Midtoun
let goalLocation = CLLocation.init(latitude: 35.710063, longitude: 139.8107)
locate(startLocation)
navigate(startLocation, goalLocation: goalLocation, startTitle: "現在地", goalTitle: "スカイツリー")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
mapView.frame = self.view.bounds
self.view.layoutIfNeeded()
}
// 指定された座標を表示する
override func locate(location: CLLocation) {
// 地図の位置と縮尺を設定
let center = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
mapView.region = YMKCoordinateRegionMake(center, YMKCoordinateSpanMake(0.002, 0.002));
mapView.invalidateIntrinsicContentSize()
// MyAnnotationの初期化
// MyAnnotation* myAnnotation = [[MyAnnotation alloc] initWithLocationCoordinate:coordinate title:[[NSString alloc] initWithString:@"ミッドタウン"] subtitle:[[NSString alloc] initWithString:@"ミッドタウンです。"]];l
//let myAnnotation = MyAnnotation.init(coord: center, title: "ミッドタウン", subTitle: "ミッドタウンです")
// AnnotationをYMKMapViewに追加
// mapView.addAnnotation(myAnnotation)
// 地図上のマーカー表示用のアノテーション配列を作成
var annotations: [AnyObject] = []
annotations.append(MyAnnotation(locationCoordinate: center, title: "bbb", subtitle: "aaa", index: 0))
setAnnotations(annotations)
//showPolyline()
}
func setAnnotations(annotations: [AnyObject]!) {
mapView.removeAnnotations(mapView.annotations)
if annotations != nil && annotations.count > 0 {
mapView.addAnnotations(annotations)
}
}
func mapView(mapView: YMKMapView!, viewForAnnotation annotation: YMKAnnotation!) -> YMKAnnotationView! {
if annotation is MyAnnotation {
// マーカーのビューを引数のannotationを用いて作成する
let pin = YMKPinAnnotationView(annotation: annotation, reuseIdentifier: "Pin")
//アイコンイメージの変更
pin.image = UIImage.init(named: "goal");
pin.animatesDrop = true
// アイコンのイメージのどこを基準点にするか設定
let centerOffset = CGPointMake(15, 15);
pin.centerOffset = centerOffset
return pin
}
return nil
}
// ルート案内をする
override func navigate(startLocation: CLLocation, goalLocation: CLLocation, startTitle: String, goalTitle: String) {
let startPos = CLLocationCoordinate2DMake(startLocation.coordinate.latitude, startLocation.coordinate.longitude);
let goalPos = CLLocationCoordinate2DMake(goalLocation.coordinate.latitude, goalLocation.coordinate.longitude);
// YMKRouteOverlayを作成
let routeOverlay = YMKRouteOverlay.init(appid: "アプリケーションID")
//YMKRouteOverlayDelegateを設定
routeOverlay.delegate = self
// 出発地ピンの吹き出し設定
routeOverlay.setStartTitle(startTitle)
// 目的地ピンの吹き出し設定
routeOverlay.setGoalTitle(goalTitle)
// 出発地、目的地、移動手段を設定
routeOverlay.setRouteStartPos(startPos, withGoalPos: goalPos, withTraffic: TRAFFIC_WALK)
// ルートの検索
routeOverlay.search()
}
func showPolyline() {
// YMKPolylineを作成
var coords: [CLLocationCoordinate2D] = []
coords.append(CLLocationCoordinate2D.init(latitude: 35.6657214, longitude: 139.7310058))
coords.append(CLLocationCoordinate2D.init(latitude: 35.670168, longitude: 139.702687))
coords.append(CLLocationCoordinate2D.init(latitude: 35.683061, longitude: 139.702687))
coords.append(CLLocationCoordinate2D.init(latitude: 35.690921, longitude: 139.700258))
let line = YMKPolyline.init(coordinates: &coords, count: 4)
// YMKPolylineをYMKMapViewに追加
mapView.addOverlay(line)
}
// ルート検索が正常に終了した場合
func finishRouteSearch(routeOverlay: YMKRouteOverlay) {
// YMKRouteOverlayをYMKMapViewに追加
mapView.addOverlay(routeOverlay)
// // YMKNaviControllerを作成しYMKRouteOverlayインスタンスを設定
// naviController = YMKNaviController.init(routeOverlay: routeOverlay)
//
// // YMKMapViewインスタンスを設定
// naviController!.setMapView(mapView)
//
// // YMKNaviControllerDelegateを設定
// naviController!.delegate = self
//
// // 案内処理を開始
// naviController!.start()
}
// ルート検索が正常に終了しなかった場合
func errorRouteSearch(routeOverlay: YMKRouteOverlay!, withError error: Int32) {
let alert = UIAlertView.init(title: "エラー", message: "ルート検索エラー", delegate: self, cancelButtonTitle: "OK")
alert.show()
}
// overlay追加イベント
func mapView(mapView: YMKMapView!, viewForOverlay overlay: YMKOverlay!) -> YMKOverlayView! {
print("mapView:viewForOverlay")
// 追加されたoverlayがYMKPolylineか確認
if overlay.isKindOfClass(YMKPolyline) {
let line: YMKPolyline = overlay as! YMKPolyline
//YMKPolylineViewを作成
let wkYMKPolylineView = YMKPolylineView.init(overlay: overlay)
//ラインの色を青に設定
wkYMKPolylineView.strokeColor = UIColor.init(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0)
wkYMKPolylineView.fillColor = UIColor.init(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0)
//ラインの太さ
wkYMKPolylineView.lineWidth = 5
return wkYMKPolylineView;
}
// 追加されたoverlayがYMKRouteOverlayか確認
if overlay.isKindOfClass(YMKRouteOverlay) {
// YMKRouteOverlayViewを作成
let wkYMKOverlayView: YMKRouteOverlayView = YMKRouteOverlayView.init(routeOverlay: overlay as! YMKRouteOverlay)
// 出発地ピンを非表示
wkYMKOverlayView.startPinVisible = true
// 目的地ピンを非表示
wkYMKOverlayView.goalPinVisible = true
// 経由点ピンを非表示
wkYMKOverlayView.routePinVisible = true
return wkYMKOverlayView;
}
return nil;
}
// 現在位置更新された場合
func naviController(naviController: YMKNaviController!, didUpdateUserLocation userLocation: YMKUserLocation!) {
print("naviController:didUpdateUserLocation")
}
// 現在位置取得エラーが発生した場合
func naviController(naviController: YMKNaviController!, didFailToLocateUserWithError error: NSError!) {
print("naviController:didFailToLocateUserWithError")
}
// 現在位置の精度が悪い場合
func naviControllerAccuracyBad(naviController: YMKNaviController!, didUpdateUserLocation userLocation: YMKUserLocation!) {
print("naviControllerAccuracyBad")
}
// ルートから外れたと判断された場合
func naviControllerRouteOut(naviController: YMKNaviController!, didUpdateUserLocation userLocation: YMKUserLocation!) {
print("naviControllerRouteOut")
}
// 目的地に到着した場合
func naviControllerOnGoal(naviController: YMKNaviController!, didUpdateUserLocation userLocation: YMKUserLocation!) {
print("naviControllerOnGoal")
// 案内処理を継続しない場合は停止させる
naviController.stop()
}
}