LoginSignup
12
12

More than 5 years have passed since last update.

Yahoo! iOSマップSDKをSwiftで使ってみる

Last updated at Posted at 2016-05-31

概要

ios版のYMapKit(YahooのMap SDK)を使うことになったのですが、ググってもSwift版のサンプルコードが一つも見つからなかったので、書いておきます。(いろいろハマってたので、ごちゃごちゃして汚いですが)

実装上の注意

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()
  }
}
12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12