2016年9月30日金曜日

[iOS]How to change the scale of the Map

さて前回に続いてMkMapViewのお話です。
今回はプログラムでMkMapViewの縮尺を変更する方法についてご紹介します。
I'm writing the method of MkMapView from last time.
I introduce how to change the scale of MkMapView in program this time.


写真はPocket Note(These are pictures of Pocket Note.)

環境(Environtment):Xcode 8,Swift 3

MkMapViewの縮尺はregion.span.latitudeDelta(上下の緯度の差)、region.span.longitudeDelta(左右の経度の差)で定義されています。
これらの値を小さくするとMkMapViewの縮尺が大きくなり、値を大きくするとMkMapViewの縮尺が小さくなります。
The scale of MkMapView is decided by region.span.latitudeDelta(distance between the top of the latitude and bottom of the latitude) and region.span.longitudeDelta(distance between the right of the longitude and the left of the longitude).
If these values are downed, the scale of MkMapView is upped.
If these values are upped, the scale of MkMapView is downed.

・地図の縮尺を拡大(The scale of MkMapView is upped)
import MapKit
・・・・・・・・
let mkMapView:MKMapView = MKMapView()
・・・・・・・・
var latitudeDelta = mkMapView.region.span.latitudeDelta
var longitudeDelta = mkMapView.region.span.longitudeDelta
latitudeDelta = latitudeDelta/5
longitudeDelta = longitudeDelta/5
        
let span = MKCoordinateSpan(latitudeDelta: latitudeDelta,longitudeDelta: longitudeDelta)
let region = MKCoordinateRegion(center: mkMapView.region.center,span: span)

mkMapView.setRegion(region, animated: true)

・地図の縮尺を縮小(The scale of MkMapView is downed)
import MapKit
・・・・・・・・
let mkMapView:MKMapView = MKMapView()
・・・・・・・・
var latitudeDelta = mkMapView.region.span.latitudeDelta
var longitudeDelta = mkMapView.region.span.longitudeDelta
latitudeDelta = latitudeDelta*5
longitudeDelta = longitudeDelta*5
        
let span = MKCoordinateSpan(latitudeDelta: latitudeDelta,longitudeDelta: longitudeDelta)
let region = MKCoordinateRegion(center: mkMapView.region.center,span: span)

mkMapView.setRegion(region, animated: true)

コード全文は以下の様になります。
The full text of code is below.

ViewController.swift

import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController,CLLocationManagerDelegate {

    let mkMapView:MKMapView = MKMapView()
    let buttonCurrentPlace:UIButton = UIButton()
    let buttonScaleUp:UIButton = UIButton()
    let buttonScaleDown:UIButton = UIButton()
    var locationManager: CLLocationManager?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        mkMapView.frame = CGRect(x:10,y:50,width:350,height:500)
        self.view.addSubview(mkMapView)
        
        buttonCurrentPlace.frame = CGRect(x:10,y:600,width:350,height:50)
        buttonCurrentPlace.setTitle("Show Current Place", for: .normal)
        buttonCurrentPlace.setTitleColor(UIColor.blue, for: .normal)
        buttonCurrentPlace.titleLabel?.adjustsFontSizeToFitWidth = true
        buttonCurrentPlace.addTarget(self, action: #selector(self.touchUpButtonCurrentPlace), for: .touchUpInside)
        self.view.addSubview(buttonCurrentPlace)
        
        buttonScaleUp.frame = CGRect(x:10,y:660,width:350,height:50)
        buttonScaleUp.setTitle("Scale Up", for: .normal)
        buttonScaleUp.setTitleColor(UIColor.blue, for: .normal)
        buttonScaleUp.titleLabel?.adjustsFontSizeToFitWidth = true
        buttonScaleUp.addTarget(self, action: #selector(self.touchUpButtonScaleUp), for: .touchUpInside)
        self.view.addSubview(buttonScaleUp)
        
        buttonScaleDown.frame = CGRect(x:10,y:720,width:350,height:50)
        buttonScaleDown.setTitle("Scale Down", for: .normal)
        buttonScaleDown.setTitleColor(UIColor.blue, for: .normal)
        buttonScaleDown.titleLabel?.adjustsFontSizeToFitWidth = true
        buttonScaleDown.addTarget(self, action: #selector(self.touchUpButtonScaleDown), for: .touchUpInside)
        self.view.addSubview(buttonScaleDown)
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    //Tap Show Current Place Button
    func touchUpButtonCurrentPlace(){
        locationManager = CLLocationManager()
        locationManager!.requestAlwaysAuthorization()
        locationManager!.delegate = self
        
        if CLLocationManager.locationServicesEnabled(){
            locationManager!.startUpdatingLocation()
        }
    }
    
    //Get Current Place
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        //Get Details of Current Place
        let location = locations[0]
        let latitude = location.coordinate.latitude
        let longitude = location.coordinate.longitude
        let newlocation = CLLocationCoordinate2DMake(latitude,longitude)
        let span = MKCoordinateSpan(latitudeDelta: 0.005,longitudeDelta: 0.005)
        let region = MKCoordinateRegion(center: newlocation,span: span)
        
        //Show Current Place on Map
        mkMapView.setRegion(region, animated: true)
        locationManager!.stopUpdatingLocation()
        locationManager = nil
        mkMapView.showsUserLocation = false
    }
    
    //The scale of MapKitView is upped
    func touchUpButtonScaleUp(){
        var latitudeDelta = mkMapView.region.span.latitudeDelta
        var longitudeDelta = mkMapView.region.span.longitudeDelta
        latitudeDelta = latitudeDelta/5
        if (latitudeDelta < 0.0001){
            latitudeDelta = 0.0001
        }
        longitudeDelta = longitudeDelta/5
        if (longitudeDelta < 0.0001){
            longitudeDelta = 0.0001
        }
        
        let span = MKCoordinateSpan(latitudeDelta: latitudeDelta,longitudeDelta: longitudeDelta)
        let region = MKCoordinateRegion(center: mkMapView.region.center,span: span)
        mkMapView.setRegion(region, animated: true)
    }
    
    //The scale of MapKitView is downed
    func touchUpButtonScaleDown(){
        var latitudeDelta = mkMapView.region.span.latitudeDelta
        var longitudeDelta = mkMapView.region.span.longitudeDelta
        latitudeDelta = latitudeDelta*5
        if (latitudeDelta > 27.77){
            latitudeDelta = 27.77
        }
        longitudeDelta = longitudeDelta*5
        if (longitudeDelta > 16.69){
            longitudeDelta = 16.69
        }
        
        let span = MKCoordinateSpan(latitudeDelta: latitudeDelta,longitudeDelta: longitudeDelta)
        let region = MKCoordinateRegion(center: mkMapView.region.center,span: span)
        mkMapView.setRegion(region, animated: true)
    }
}

[関連記事(Articles)]
[iOS]How to show current place on Map

にほんブログ村 ライフスタイルブログ クリエイティブライフへ
にほんブログ村

クリエイティブライフ ブログランキングへ

2016年9月29日木曜日

[iOS]How to show current place on Map

Pocket Noteには地図上に現在地を表示する機能があります。今回はこの現在地の取得方法についてご紹介します。
Pocket Note can be shown current place on map.I introduce how to get current place this time.


環境[Environment]:Xcode 8, Swift 3

まず地図を表示する為にMapKitをImportし、MkMapViewを貼り付けます。
At first,Import MapKit and add MkMapView for showing map.

import MapKit
・・・・・・・・
let mkMapView:MKMapView = MKMapView()

次に現在地を取得する為にCoreLocationをimportし、CLLocationManagerを宣言します。
またCLLocationManagerのイベントを受け取る為にCLLocationManagerDelegateを継承します。
Next,import CoreLocation and declare CLLocationManager.
And inherit CLLocationManagerDelegate for receiving events of CLLocationManager.

import CoreLocation
・・・・・・・・
var locationManager: CLLocationManager?


現在地を取得するにはまず、CLLocationManagerのrequestAlwaysAuthorizationメソッドでユーザーから現在地情報を取得する許可を得る必要があります。
Execute requestAlwaysAuthorization of CLLocationManager for getting user's permission to access to current place information.

locationManager = CLLocationManager()
locationManager!.requestAlwaysAuthorization()

この為に、info.plistにNSLocationAlwaysUsageキーを追加し、現在地情報にアクセスする理由を記載します。
And write NSLocationAlwaysUsage key to info.plist and write reason of accessing to current place information.

これにより現在地情報にアクセスする時に次のようなメッセージがユーザーに表示されます。(画像は言語の設定が英語の場合です。)
And display below message when an application access to current place information.

ユーザーから現在地情報にアクセスする許可を得られたらCLLocationManagerのstartUpdateLocationメソッドで現在地を取得します。
Execute startUpdateLocation of CLLocationManager for getting current place after getting user's permission to access to current place information.

if CLLocationManager.locationServicesEnabled(){
      locationManager!.startUpdatingLocation()

}


現在地が取得できたら、CLLocationManagerのdidUpdateLocationsイベントが呼び出されますので、MKMapKitに位置情報を設定します。
この時、地図のズームを少し拡大するといいでしょう。
And if an application can get current place,didUpdateLocations of CLLocationManager is called.
And set current place to MKMapKit.
It is good to scale up on MKMapKit at this time.

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        //Get Details of Current Place
        let location = locations[0]
        let latitude = location.coordinate.latitude
        let longitude = location.coordinate.longitude
        let newlocation = CLLocationCoordinate2DMake(latitude,longitude)
        let span = MKCoordinateSpan(latitudeDelta: 0.005,longitudeDelta: 0.005)
        let region = MKCoordinateRegion(center: newlocation,span: span)
        
        //Show Current Place on Map
        mkMapView.setRegion(region, animated: true)
        locationManager!.stopUpdatingLocation()
        locationManager = nil

        mkMapView.showsUserLocation = false
}

あと現在地の取得が終わったらCLLocationManagerのstopUpdatingLocationメソッドを呼び出して、現在地を取得する処理を止めるようにしましょう。止め忘れると恐ろしい勢いでメモリ使用量が増えてしまいます。
You must call stopUpdatingLocation of CLLocationManager for stopping to get current place information.If you forget to call stopUpdatingLocation, memory size of an application is increasing quickly.


ではコード全文を見てみましょう。
Let's see the full text of code.

ViewController.swift
import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController,CLLocationManagerDelegate {

    let mkMapView:MKMapView = MKMapView()
    let buttonCurrentPlace:UIButton = UIButton()
    var locationManager: CLLocationManager?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        mkMapView.frame = CGRect(x:10,y:50,width:350,height:500)
        self.view.addSubview(mkMapView)
        
        buttonCurrentPlace.frame = CGRect(x:10,y:600,width:350,height:50)
        buttonCurrentPlace.setTitle("Show Current Place", for: .normal)
        buttonCurrentPlace.setTitleColor(UIColor.blue, for: .normal)
        buttonCurrentPlace.titleLabel?.adjustsFontSizeToFitWidth = true
        buttonCurrentPlace.addTarget(self, action: #selector(self.touchUpButtonCurrentPlace), for: .touchUpInside)
        self.view.addSubview(buttonCurrentPlace)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    //Tap Show Current Place Button
    func touchUpButtonCurrentPlace(){
        locationManager = CLLocationManager()
        locationManager!.requestAlwaysAuthorization()
        locationManager!.delegate = self
        
        if CLLocationManager.locationServicesEnabled(){
            locationManager!.startUpdatingLocation()
        }
    }
    
    //Get Current Place
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        //Get Details of Current Place
        let location = locations[0]
        let latitude = location.coordinate.latitude
        let longitude = location.coordinate.longitude
        let newlocation = CLLocationCoordinate2DMake(latitude,longitude)
        let span = MKCoordinateSpan(latitudeDelta: 0.005,longitudeDelta: 0.005)
        let region = MKCoordinateRegion(center: newlocation,span: span)
        
        //Show Current Place on Map
        mkMapView.setRegion(region, animated: true)
        locationManager!.stopUpdatingLocation()
        locationManager = nil
        mkMapView.showsUserLocation = false
    }

}


[関連記事(Articles)]

にほんブログ村 ライフスタイルブログ クリエイティブライフへ
にほんブログ村

クリエイティブライフ ブログランキングへ