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

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

ただいまの
回答率

90.48%

  • Swift

    7485questions

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

配列の値の入る順番がおかしい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 817

Jidousya_364

score 23

前提・実現したいこと

私は今、一つ前のビューから入力された住所を元にmapkitを使って座標を取得し、その場所にピンを刺すコードを作りたいと考えています

発生している問題・エラーメッセージ

 住所が追加されている配列から住所を取得し、その住所から緯度と経度を取得し配列に保存するのですが、保存される値が例えばA地点とB地点を検索した場合にA地点から配列に保存されるはずがB地点から保存されるなどの問題が起きました。どうやら緯度と経度の配列の値の順番がバラバラに入ってしまうことが原因のようですが、正常に検索できる場合もあり、自分では解決の糸口が見当たらず質問した次第です。

該当のソースコード

swift

 遷移方法は
 let targetViewController = self.storyboard!.instantiateViewControllerWithIdentifier( "ViewController" )
 self.presentViewController(targetViewController, animated: false, completion: nil)
 で行いました

 import UIKit
 import MapKit
 import CoreLocation
 import QuartzCore
 let gamensize = UIScreen.mainScreen().bounds.size
 var ken = "千葉県"
 //配列
 var _ido = [CLLocationDegrees]()
 var _keido = [CLLocationDegrees]()
 var _name = ["東京ディズニーランド","群馬サファリパーク"]

 var _jyuusyo = ["千葉県浦安市舞浜1−1","群馬県富岡市岡本1"]

 var _jikan = [String]()
 var _syoyoujikan = [Int]()

 class ViewController: UIViewController, MKMapViewDelegate{

 //MapViewの生成
 let myMapView = MKMapView()
 var i = 0

 func Geocodering(jyuusyo: String) {
 // geocoderを作成.
 let myGeocoder = CLGeocoder()
 let myAddress = jyuusyo

 // 正ジオコーディング開始
 myGeocoder.geocodeAddressString(myAddress, completionHandler: { (placemarks, error) -> Void in
 if let placemark = placemarks?[0] as? CLPlacemark! {
 // 地名を入力して検索リストに有れば緯度経度を取得
 if placemark != nil {

 _ido.append(placemark!.location!.coordinate.latitude)
 _keido.append(placemark!.location!.coordinate.longitude)

 print("追加された緯度\(placemark!.location!.coordinate.latitude)")
 print("追加された経度\(placemark!.location!.coordinate.longitude)")

 let pin = MKPointAnnotation()
 //ピンを刺す座標
 let poji:CLLocationCoordinate2D = CLLocationCoordinate2DMake(_ido[self.i],_keido[self.i])
 //ピンに座標指定

 pin.coordinate = poji
 pin.title = "\(_name[self.i])"
 pin.subtitle = "\(_jyuusyo[self.i])"

 print("名前:\(_name[self.i])")
 print("住所:\(_jyuusyo[self.i])")
 print(_ido)
 print(_name)

 self.myMapView.addAnnotation(pin)

 self.i += 1

 //アノテーション(ピン)のtitle, subtitleにそれぞれ緯度経度をセット.

 if _jyuusyo.count == _keido.count {
 for var i = 0; i < _jyuusyo.count ; i++ {
 if i + 1 < _jyuusyo.count {
 //経路を順番に表示
 self.rutokensaku(_ido[i], keido: _keido[i], t_ido: _ido[i+1], t_keido: _keido[i+1])
 }else{
 //帰り道の表示
 self.rutokensaku(_ido[i], keido: _keido[i], t_ido: _ido[0], t_keido: _keido[0])
 }
 }
 }

 }else{
 print("見つかりません")
 }
 }
 })
 }

 //出発地点の緯度と経度、到達地点の緯度と経度で、ルートを表示(所要時間、距離も表示)
 func rutokensaku(ido: CLLocationDegrees, keido: CLLocationDegrees, t_ido: CLLocationDegrees, t_keido: CLLocationDegrees){
 // 出発点の緯度、経度を設定.
 let myLatitude: CLLocationDegrees = ido
 let myLongitude: CLLocationDegrees = keido
 // 目的地の緯度、経度を設定
 let requestLatitude: CLLocationDegrees = t_ido
 let requestLongitude: CLLocationDegrees = t_keido

 let fromCoordinate: CLLocationCoordinate2D = CLLocationCoordinate2DMake(myLatitude, myLongitude)
 let requestCoordinate: CLLocationCoordinate2D = CLLocationCoordinate2DMake(requestLatitude, requestLongitude)

 // PlaceMarkを生成して出発点、目的地の座標をセット.
 let fromPlace: MKPlacemark = MKPlacemark(coordinate: fromCoordinate, addressDictionary: nil)
 let toPlace: MKPlacemark = MKPlacemark(coordinate: requestCoordinate, addressDictionary: nil)
 // Itemを生成してPlaceMarkをセット.
 let fromItem: MKMapItem! = MKMapItem(placemark: fromPlace)
 let toItem: MKMapItem! = MKMapItem(placemark: toPlace)

 let myRequest:MKDirectionsRequest = MKDirectionsRequest()

 myRequest.source = fromItem
 myRequest.destination = toItem

 // 複数経路の検索
 myRequest.requestsAlternateRoutes = true
 // 移動手段を車に設定.
 myRequest.transportType = MKDirectionsTransportType.Automobile

 // MKDirectionsを生成してRequestをセット.
 let myDirections: MKDirections = MKDirections(request: myRequest)

 // 経路探索.
 myDirections.calculateDirectionsWithCompletionHandler { (response, error) -> Void in

 // NSErrorを受け取ったか、ルートがない場合.
 if error != nil || response!.routes.isEmpty {
 print("エラーもしくはルートが無い")
 _syoyoujikan.append(999999)
 return
 }

 let route: MKRoute = response!.routes[0] as MKRoute
 print("目的地まで \(route.distance)km")
 print("所要時間 \(Int(route.expectedTravelTime/60))分")
 _syoyoujikan.append(Int(route.expectedTravelTime/60))

 // mapViewにルートを描画.
 self.myMapView.addOverlay(route.polyline)
 }
 }

 func ken_settei(ken: String) {
 // geocoderを作成.
 let myGeocoder = CLGeocoder()
 let myAddress = ken
 // 正ジオコーディング開始
 myGeocoder.geocodeAddressString(myAddress, completionHandler: { (placemarks, error) -> Void in
 if let placemark = placemarks?[0] as? CLPlacemark! {
 // 地名を入力して検索リストに有れば緯度経度を取得
 if placemark != nil {
 // 中心点の緯度経度.
 let Lat: CLLocationDegrees = placemark!.location!.coordinate.latitude
 let Lon: CLLocationDegrees = placemark!.location!.coordinate.longitude
 let myCoordinate: CLLocationCoordinate2D = CLLocationCoordinate2DMake(Lat, Lon)

 print(placemark!.location!.coordinate.latitude)
 print(placemark!.location!.coordinate.longitude)

 // 縮尺.
 let myLatDist : CLLocationDistance = 200000
 let myLonDist : CLLocationDistance = 200000

 // Regionを作成.
 let Region: MKCoordinateRegion = MKCoordinateRegionMakeWithDistance(myCoordinate, myLatDist, myLonDist)

 //regionに設定したマップの表示設定をMapViewに反映
 self.myMapView.setRegion(Region, animated: true)

 }else{
 print("見つかりません")
 }
 }
 })

 }

 override func viewDidLoad() {
 super.viewDidLoad()

 //入力された県に画面を合わせる
 ken_settei(ken)

 for var i = 0; i <  _jyuusyo.count ; i++ {
 self.Geocodering(_jyuusyo[i])

 }

 myMapView.delegate = self
 myMapView.frame = self.view.frame
 self.view.addSubview(myMapView)
 }
 }

試したこと

緯度と経度の配列の値の順番がバラバラに入ってしまうことに対応しようとしたが、エラーを誘発

補足情報(言語/FW/ツール等のバージョンなど)

XcodeのVersionは7.3です

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • tikidunpon

    2016/04/14 20:43

    「緯度と経度の配列の値の順番がバラバラに入ってしまうこと」を確認されたのはコード上でいうとどの箇所になりますでしょうか?

    キャンセル

  • Jidousya_364

    2016/04/15 15:32

    Geocodering呼び出し直後の_ido.append の所です。printで出力すると保存されている値の順番がバラバラになっている場合がありました。

    キャンセル

回答 1

check解決した方法

0

自己解決しました。どうやら非同期で呼び出される geocodeAddressStringが原因のようで、非同期で呼び出されても良いようにコードを書き換えると上手くいきました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Swift

    7485questions

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