質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

478閲覧

【swift】MKDirectionsの経路探査が50回しか使えません

street

総合スコア34

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/08/26 09:49

編集2017/08/26 09:51

MKDirectionsを用いて経路探査後の距離を取得しようとしているのですが、なぜか50回しか取得できません。
コードは以下の通りです。拠点の緯度と経度を格納した要素数89個の配列を用いてそれぞれ2点間の距離を求めようとしています。
緯度と経度が設定されているJSONファイルからLocationDataInfoの構造体の配列へ格納しています。
念のため格納した配列の要素数は確認しましたが,89個でした。

MKDirectionsに使用制限回数はあるのでしょうか?

lang

1/*-------------------- 2 各種構造体情報. 3 ---------------------*/ 4 5// ■ ロケーション情報 6struct LocationDataInfo { 7 var locationID: Int = 0 8 var location: String = "" 9 var name: String = "" 10 var url: String = "" 11 var latitude:Double = 0.0 12 var longitude:Double = 0.0 13 14 init() { 15 self.locationID = 0 16 self.location = "" 17 self.name = "" 18 self.url = "" 19 self.latitude = 0.0 20 self.longitude = 0.0 21 } 22 23 // ■ JSONデータを設定. 24 mutating func setJsonData(object: JSON){ 25 self.locationID = object["locationID"].intValue 26 self.location = object["location"].stringValue 27 self.name = object["name"].stringValue 28 self.url = object["url"].stringValue 29 self.latitude = object["latitude"].doubleValue 30 self.longitude = object["longitude"].doubleValue 31 } 32} 33 34// ■ 到達地点の歩数 35struct WalkingStepsDataInfo { 36 var locationID: Int = 0 37 var nextLocationID: Int = 0 38 var steps: Int = 0 39 40 init( id:Int, nextId:Int, steps:Int ){ 41 self.locationID = id 42 self.nextLocationID = nextId 43 self.steps = steps 44 } 45} 46 // ■ 到達地点の情報を取得 47 func GetWalkingStepsData(callback: @escaping (WalkingStepsDataInfo) -> Void ) -> Void { 48 49 // ■ Jsonからロケーション情報を取得. 50 var locationList = GetLocationDataList() 51 52 // ■ CoreLocationを用いて到達地点情報を取得(時間がかかるので非同期処理). 53 let semaphore = DispatchSemaphore(value: 0) // 処理を待つためにセマフォを生成. 54 DispatchQueue.global().async 55 { 56 // While用スレッド生成. 57 var isWait = true 58 while isWait 59 { 60 // データ取得用スレッド生成. 61 DispatchQueue.main.async 62 { 63 if (false == locationList.isEmpty) 64 { 65 let location = locationList.first 66 var locationNext = location 67 debugPrint("locationID \(String(describing: location?.locationID))") 68 debugPrint(locationList.count) 69 locationList.removeFirst() 70 71 if (false == locationList.isEmpty){ 72 locationNext = locationList.first 73 } else {} 74 75 var data = WalkingStepsDataInfo(id: 0,nextId: 0,steps: 0) 76 77 // 現在の地点、次の地点、2点間の歩数を設定. 78 data.locationID = (location?.locationID)! 79 data.nextLocationID = (locationNext?.locationID)! 80 81 self.GetDistance_(la: (location?.latitude)!, lo: (location?.longitude)!, nextla: (locationNext?.latitude)!, nextlo: (locationNext?.longitude)!, callback: { distance in 82 83 data.steps = self.GetSteps_(distance: distance) 84 debugPrint("\(data.locationID), \(data.nextLocationID), \(data.steps)") 85 callback(data) // コールバック 86 semaphore.signal() 87 }) 88 } else { 89 isWait = false 90 } 91 } 92 93 // データ取得用スレッドの処理を待つ. 94 semaphore.wait() 95 Thread.sleep(forTimeInterval: 0.01) 96 } 97 } 98 } 99 100 // ■ 経路より2点間の距離を取得. 101 private func GetDistance_(la:Double, lo:Double, nextla: Double, nextlo: Double, callback:@escaping (Double) -> Void ) -> Void { 102 var distance:Double = 0.0 103 104 // 目的地の座標を指定. 105 let fromCoordinate: CLLocationCoordinate2D = CLLocationCoordinate2DMake(la, lo) 106 let requestCoordinate: CLLocationCoordinate2D = CLLocationCoordinate2DMake(nextla, nextlo) 107 108 // PlaceMarkを生成して出発点、目的地の座標をセット. 109 let fromPlace: MKPlacemark = MKPlacemark(coordinate: fromCoordinate, addressDictionary: nil) 110 let toPlace: MKPlacemark = MKPlacemark(coordinate: requestCoordinate, addressDictionary: nil) 111 112 // Itemを生成してPlaceMarkをセット. 113 let fromItem: MKMapItem = MKMapItem(placemark: fromPlace) 114 let toItem: MKMapItem = MKMapItem(placemark: toPlace) 115 116 // MKDirectionsRequestを生成. 117 let myRequest: MKDirectionsRequest = MKDirectionsRequest() 118 119 // 出発地のItemをセット. 120 myRequest.source = fromItem 121 122 // 目的地のItemをセット. 123 myRequest.destination = toItem 124 125 // 移動手段を徒歩に設定. 126 myRequest.transportType = MKDirectionsTransportType.walking 127 128 // MKDirectionsを生成してRequestをセット. 129 let myDirections: MKDirections = MKDirections(request: myRequest) 130 131 // 経路探索. 132 myDirections.calculate { (response, error) in 133 134 // NSErrorを受け取ったか、ルートがない場合. 135 if error != nil || response!.routes.isEmpty { 136 return 137 } 138 139 let route: MKRoute = response!.routes[0] as MKRoute 140 print("目的地まで \(route.distance)m") 141 print("所要時間 \(Int(route.expectedTravelTime/60))分") 142 143 distance = route.distance 144 145 callback(distance) // クロージャからのコールバック. 146 } 147 148 } 149 150 // ■ 歩数を取得. 151 private func GetSteps_(distance: Double) -> Int { 152 let tmpheight:Double = (167/1000) 153 let steps:Int = Int(distance / (tmpheight*0.45)) 154 debugPrint("\(steps) 歩数") 155 return steps 156 } 157 158

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Stripe

2017/08/27 08:58

51回目の取得でエラーでも出るんですか?
street

2017/08/27 09:50

はい、上記コードの if error != nil || response!.routes.isEmpty の箇所でエラーとなっていました。元データが悪いのか確認するために51回目に探索するデータを一番目に持ってくると成功します。。。確認環境としてはシミュレータなのですが。。。。
Stripe

2017/08/27 13:40

それで、そのerrorの内容は?
Stripe

2017/08/27 13:42

ちなみに、DispatchQueueで非同期でタスクを実行しているのにsemaphoreで待ち受けるぐらいだったら、最初から同期でタスクを実行した方がいいですよ。
guest

回答1

0

ベストアンサー

それはMKDirectionsの仕様だと思います。
50回という回数は特に決まっていませんが、同じ端末から短期間に多くのリクエストをAppleのサーバに送ると、アクセス制限を受けて、loadingThrottledエラーが返ります。

投稿2017/08/28 11:17

Stripe

総合スコア2183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

street

2017/08/29 01:01

返事が遅れてしまいすみません。 ご回答有難うございます。 時間を空けて実施すると、エラーが発生することなく全て経路探査することができました。 お忙しい中ご回答していただき本当に有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問