博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS地图开发及定位
阅读量:5960 次
发布时间:2019-06-19

本文共 14022 字,大约阅读时间需要 46 分钟。

  hot3.png

定位服务编程

(一)、地理信息反编码(需要框架CoreLocation,主要使用类 CLLocationManagerDelegate/CLLocationManager/CLLocation/CLPlacemark)其中 CLPlacemark 地标类属性有国家信息,指定城市信息,街道级别信息等

//给定坐标定位地名 CLGeocoder  reverseGeocodeLocation:方法

//  ViewController.swift

//  ServiceAndMap

//

//  Created by sus001 on 16/6/7.

//  Copyright © 2016年 njsus. All rights reserved.

//

 

import UIKit

import CoreLocation

import Contacts

import ContactsUI

class ViewController: UIViewController,CLLocationManagerDelegate,UIAlertViewDelegate {

    

    @IBOutlet weak var textView: UITextView!

    @IBOutlet weak var txtLng: UITextField!// 经度

    @IBOutlet weak var txtLat: UITextField!//纬度

    @IBOutlet weak var txtAlt: UITextField!//高度

    var locationManager: CLLocationManager!

    var _location: CLLocation!

    override func viewDidLoad() {

        super.viewDidLoad()

        

        if CLLocationManager.locationServicesEnabled(){

            locationManager = CLLocationManager()

            locationManager.delegate = self //设置委托

            locationManager.desiredAccuracy = kCLLocationAccuracyBest //所需精度

            locationManager.distanceFilter = 1000 //距离过滤器

        }

        //在iOS 8.0下要授权

        if NSString(string: UIDevice.currentDevice().systemVersion).floatValue >= 8.0 {

//            NSLocationWhenInUseUsageDescription  =  yes info.plist文件中输入

            self.locationManager.requestWhenInUseAuthorization() //调用了这句,就会弹出允许框了

//            NSLocationAlwaysUsageDescription   =  yes

            self.locationManager.requestAlwaysAuthorization()// 前后台同时定位

        }

        // Do any additional setup after loading the view, typically from a nib.

      

    }

//    地理信息反编码

    @IBAction func clickButton(sender: UIButton) {

        let geocoder = CLGeocoder() //实例化 CLGeocoder地理反编码对象

//        调用地理反编码对象的reverseGeocodeLocation

        geocoder.reverseGeocodeLocation(_location!) { (placemarks:[CLPlacemark]?, error:NSError?) in

            if placemarks?.count > 0 {

//               地标类 里面包含了国际信息,指定城市信息等

                let placemark = placemarks![0]

                

                let dd = placemark.addressDictionary

                print(dd!["State"]!)

                 print(dd!["Country"]!)

                var address = placemark.thoroughfare

               

                address = address == nil ? "" : address

                

                var state = placemark.country

                state = state == nil ? "" : state

                

                var city = placemark.locality

                city = city == nil ? "" : city

               

                self.textView.text = NSString(format: "\(state!) \n\(address!)  \n\(city!)", locale: nil) as String

                

            }

            if error != nil {

                print(error?.localizedDescription)

            }

        }

    }

    override func viewWillAppear(animated: Bool) {

        super.viewWillAppear(animated)

        if CLLocationManager.locationServicesEnabled() && CLAuthorizationStatus.Denied == CLLocationManager.authorizationStatus(){

            print("定位服务没有打开")

            let status = CLLocationManager.authorizationStatus()

            print(status)

            if status == CLAuthorizationStatus.Denied || status == CLAuthorizationStatus.Restricted || status == CLAuthorizationStatus.NotDetermined {

                let alert = UIAlertController(title:  "提示", message: "ServiceAndMap\n 要适应您当前的位置?", preferredStyle: UIAlertControllerStyle.Alert)

                

                let cancel = UIAlertAction(title: "取消", style: .Cancel, handler: { (alertAction:UIAlertAction) in

                    print("cancel")

                })

                

                let ok = UIAlertAction(title: "OK", style: .Default, handler: { (alertAction:UIAlertAction) in

                    print("ok")

                })

                

                alert.addAction(cancel)

                alert.addAction(ok)

                presentViewController(alert, animated: true, completion: nil)

            }

 

        }else{

            print("定位服务打开")

            locationManager.startUpdatingLocation() //开启定位服务

        }

       

        //定位服务进入后台后,下面这个方法可以延迟更新位置信息

//        locationManager.allowDeferredLocationUpdatesUntilTraveled(<#T##distance: CLLocationDistance##CLLocationDistance#>, timeout: <#T##NSTimeInterval#>)

    }

//    通过didChangeAuthorizationStatus代理方法,可以监听用户授权的改动

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {

        if status == .NotDetermined || status == .Denied{

            //允许使用定位服务

            //开始启动定位更新服务

            locationManager.startUpdatingLocation()

            print("开始定位")

        }

    }

    override func viewWillDisappear(animated: Bool) {

        super.viewWillDisappear(animated)

        locationManager.stopUpdatingHeading() //关闭定位服务

        //locationManager.disallowDeferredLocationUpdates() //关闭延迟更新

        locationManager.pausesLocationUpdatesAutomatically = true //自动暂停为主更新

    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        let currLocation = locations.last

        txtLat.text = NSString(format:"\(currLocation!.coordinate.latitude)") as String

        txtLng.text = NSString(format: "\(currLocation!.coordinate.longitude)") as String

        txtAlt.text = NSString(format: "\(currLocation!.altitude)") as String

        self._location = currLocation

    }

//    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {

//        NSLog("error:\(error.localizedDescription)", nil)

//    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

 

 

}

 

 

 

(二)、地理信息编码 (CoreLocation框架CLLocationManagerDelegate/CLLocationManager/CLLocation/CLGeocoder/CLPacemark)

//给点地名,定位坐标 CLGeocoder geocodeAddressString方法

//  SelWhereViewController.swift

//  ServiceAndMap

//

//  Created by sus001 on 16/6/10.

//  Copyright © 2016年 njsus. All rights reserved.

//

 

import UIKit

import CoreLocation

class SelWhereViewController: UIViewController,CLLocationManagerDelegate{

    var locationManager:CLLocationManager!

    

    @IBOutlet weak var selText: UITextField!

   

    

    @IBOutlet weak var textView: UITextView!

    @IBAction func selClick(sender: AnyObject) {

        //查询地点为空时不执行

        if selText.text == nil || NSString(string: selText.text!).length == 0 {

            return

        }

//        地理信息编码查询,查询的返回结果marks参数是NSArray类型集合

        CLGeocoder().geocodeAddressString(self.selText.text!) { (marks:[CLPlacemark]?, error:NSError?) in

            print("查询纪录数:\(marks)")

            if marks?.count > 0 {

//                取出第一个参数 ,其中CLPlacemark封装了街道,区域等信息

                let placemark = marks![0]

//                获得地标的经纬度信息

                let coordinate = placemark.location?.coordinate

                let strCoordinater = NSString(format: "经度:\(coordinate!.longitude)\n纬度:\(coordinate!.latitude)")

                

                self.textView.text = NSString(format: "\(strCoordinater) \n \(placemark.country!) \n\(placemark.locality!) \n \((placemark.thoroughfare == nil ?  "" : placemark.thoroughfare)!)", locale: nil) as String

                // 关闭键盘,如果想输入中文字 先在模拟器中找到设置,

//                即Settings->General->Keyboard->Keyboards->Add New Keyboard...

//               到了这里大家应该就都明白了,在列表中选择自己需要的输入法,

//                我选择的中文输入法是Chinese-Simplified(PinYin)即简体拼音其它没有试过

                

                self.selText.resignFirstResponder()

            }

        }

    }

    

    override func viewDidLoad() {

        super.viewDidLoad()

 

        // Do any additional setup after loading the view.

    }

 

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

 

    /*

    // MARK: - Navigation

 

    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */

 

}

 

(三)、定位服务测试

Scheme ——> Eidt  Scheme   ——> Options    ——> Defual location

如果地名没有添加gpx文件

工具 www.mygeoposition.com生成gpx文件

(四)、使用苹果地图(MapKit框架,mapview控件

  添加标柱:(第一步:触发添加动作,第二步:实现地图委托方法)

//

//  IOSMapViewController.swift

//  ServiceAndMap

//

//  Created by sus001 on 16/6/10.

//  Copyright © 2016年 njsus. All rights reserved.

//

 

import UIKit

import MapKit

class IOSMapViewController: UIViewController,MKMapViewDelegate{

 

    @IBOutlet weak var mapView: MKMapView!

    @IBOutlet weak var selText: UITextField!

//   添加标柱:(第一步:触发添加动作,第二步:实现地图委托方法)

    @IBAction func selClic(sender: AnyObject) {

        if self.selText.text == nil || NSString(string: self.selText.text!).length == 0 {

            return

        }

        let gecoder = CLGeocoder()

        gecoder.geocodeAddressString(self.selText.text!) { (placemarks:[CLPlacemark]?, error:NSError?) in

            NSLog("查询记录:\(placemarks!.count)")

            if placemarks?.count > 0 {

                self.mapView.removeAnnotations(self.mapView.annotations)

            }

            

            var i = 0

            repeat{

                self.selText.resignFirstResponder() //关闭键盘

                let placemark = placemarks![i]

             //            调整地图位置和缩放比例

//                第一个参数:指定区域的中心点,第二个参数 是南北跨度,第三个参数是东西跨度,这个两个参数会影响地图缩放

                let viewRegion = MKCoordinateRegionMakeWithDistance((placemark.location!.coordinate), 100000, 100000)

//                重新设置地图的显示区域

                self.mapView.setRegion(viewRegion, animated: true)

//                实例化 MKAnnotation子类对象,这个是自定义的类为地图上标注 

//                地图上的标注点是MKPinAnnotationView(大头针标注视图)类型,这个视图要求标注点信息由实现MKAnnotation协议的类提供

                let annotation = MapLocation(coordinate: (placemark.location?.coordinate)!)

                annotation.name = placemark.name

//                 annotation.streetAdress = placemark.subThoroughfare

//                annotation.city = placemark.locality

//                annotation.state = placemark.administrativeArea

//                annotation.zip = placemark.postalCode

//                将标注点对象添加到地图上 ,一旦调用这个方法,地图视图委托方法就会被调用 mapView:viewForAnnotation:                self.mapView.addAnnotation(annotation)

                

              

                

                i = i + 1

            }while(i < placemarks!.count)

//            for var i = 0;i < placemarks!.count;i=(i+1) {

//                self.selText.resignFirstResponder() //关闭键盘

//                let placemark = placemarks![i]

//                //            调整地图位置和缩放比例

//                let viewRegion = MKCoordinateRegionMakeWithDistance((placemark.location!.coordinate), 10000, 10000)

//                self.mapView.setRegion(viewRegion, animated: true)

//                

//                

//                let annotation = MapLocation(coordinate: (placemark.location?.coordinate)!)

//                

//                 annotation.streetAdress = placemark.thoroughfare

//                annotation.city = placemark.locality

//                annotation.state = placemark.administrativeArea

//                annotation.zip = placemark.postalCode

//                self.mapView.addAnnotation(annotation)

//                print("placemarks!.count:\(placemarks!.count)")

//            }

            if error != nil {

                print(error?.localizedDescription)

            }

          

            

        }

    }

//    这个方法在地图视图添加标注时回调  mapView.addAnnotation(annotation)  annotation地图标注对象

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

//         用于获得地图标注对象 MKPinAnnotationView

        var annotationView = self.mapView.dequeueReusableAnnotationViewWithIdentifier("dd") as? MKPinAnnotationView

        if annotationView == nil {

            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "dd")

        }

//        设置大头针标注视图的颜色为紫色(红色/绿色)

        annotationView?.pinTintColor = UIColor.purpleColor()

//        设置标注视图时,是否以动画效果的信息显示在地图上

        annotationView?.animatesDrop = true

//        用于在标注点上显示一些附加信息 (大点的文字保存在Title属性中小的文字保存中subTitle属性中)

        annotationView?.canShowCallout = true

        return annotationView

    }

    override func viewDidLoad() {

        super.viewDidLoad()

       

        // Do any additional setup after loading the view.

        if CLLocationManager.locationServicesEnabled() == true {

            mapView.mapType = MKMapType.Standard

            mapView.delegate = self

//            跟踪用户位置变化

            self.mapView.showsUserLocation = true

            self.mapView.setUserTrackingMode(.Follow, animated: true)

            

        }

    }

 

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

 

    /*

    // MARK: - Navigation

 

    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */

 

}

(五)、使用程序外地图(调用ios苹果地图)

//  MapOutViewController.swift

//  ServiceAndMap

//

//  Created by sus001 on 16/6/11.

//  Copyright © 2016年 njsus. All rights reserved.

//

 

import UIKit

import CoreLocation

import MapKit

class MapOutViewController: UIViewController{

 @IBOutlet weak var selTxt: UITextField!

 @IBAction func selClick(sender: AnyObject) {

        if self.selTxt.text == nil || NSString(string: self.selTxt.text!).length == 0 {

            return

        }

//          调用IOS苹果地图

        CLGeocoder().geocodeAddressString(self.selTxt.text!) { (placemarks:[CLPlacemark]?, error:NSError?) in

            print("查询记录数:\(placemarks?.count)")

//            多个点需要标注,起点默认是当前位置,通过定位服务获得

            var arrary = [MKMapItem]()

            var i = 0

            repeat{

//                实例化MKPlacemark对象  CLPlacemark 是地图上的地标类 MKPlacemark 定位是一的地标类

                let place = MKPlacemark(placemark: placemarks![i])

                let mapItem = MKMapItem(placemark: place)

                arrary.append(mapItem)

                i = i + 1

            }while(i < placemarks?.count)

            

            self.selTxt.resignFirstResponder()

            if arrary.count > 0 {

                

                MKMapItem.openMapsWithItems(arrary, launchOptions: nil)

            }

            

            

      /*

            

//            单个点标注

            if placemarks?.count > 0 {

                let mark = placemarks![0]

//                let coordinate = mark.location?.coordinate

//                实例化MKPlacemark对象  CLPlacemark 是地图上的地标类 MKPlacemark 定位是一的地标类

                

//                let place = MKPlacemark(coordinate: (mark.location?.coordinate)!, addressDictionary: mark.addressDictionary as![String : AnyObject]?)

//                let mapItem = MKMapItem(placemark: place)

                 let mkplacemark = MKPlacemark(placemark: mark)

//                实例化MKMapItem对象,封装类地图上一个点的信息类

                 let mapItem = MKMapItem(placemark: mkplacemark)

//                调用ios自动的苹果地图应用

//                openInMapsWithLaunchOptions:是MKMapItem 类的实例方法 ,

//                参数是控制显示地图的初始化信息(设定路线模式/设定地图类型MKLaunchOptionsMapTypeKey/设定丢图中心点/设置地图跨度/设置显示交通状况)

                

                mapItem.openInMapsWithLaunchOptions(nil)

              

               self.selTxt.resignFirstResponder()

            }

 */

        } 

    }

   

    override func viewDidLoad() {

        super.viewDidLoad()

 

        // Do any additional setup after loading the view.

    }

 

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

自定义类

    /*

    // MARK: - Navigation

 

    // In a storyboard-based application, you will often want to do a little preparation before navigation

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // Get the new view controller using segue.destinationViewController.

        // Pass the selected object to the new view controller.

    }

    */

 

}

 

//  MapLocation.swift

//  ServiceAndMap

//

//  Created by sus001 on 16/6/11.

//  Copyright © 2016年 njsus. All rights reserved.

//

 

import Foundation

import MapKit

public class MapLocation:NSObject, MKAnnotation {

     

    public var coordinate:CLLocationCoordinate2D

    var name:String?

//    var streetAdress:String?

//    var city:String?

//    var state:String?

//    var zip:String?

    init(coordinate:CLLocationCoordinate2D) {

        self.coordinate = coordinate

    }

    public var subtitle: String?{

        return name

    }

    public var title: String? { return "您的位置" }

//    public var subtitle: String? {

//        let ret = NSMutableString()

//        if (self.state != nil) {

//            ret.appendString(self.state!)

//        }

//        if (self.city != nil) {

//            ret.appendString(self.city!)

//        }

//        if ((self.city != nil) && (self.state != nil)) {

//            ret.appendString(", ")

//        }

//        if (self.streetAdress != nil) && ((self.state != nil) || (self.city != nil) || (self.zip != nil)){

//            ret.appendString(" . ")

//        }

//        if self.streetAdress != nil {

//            ret.appendString(self.streetAdress!)

//        }

//        if self.zip != nil {

//            ret.appendFormat(" , \(self.zip)")

//        }

//        return ret as String

//    }

}

转载于:https://my.oschina.net/ldm95/blog/689660

你可能感兴趣的文章
Apache uimaFIT 3.0.0 发布,Java 的 UIMA 注解类
查看>>
用js来实现那些数据结构15(图01)
查看>>
web前端学习:React是什么,为什么要使用它?
查看>>
常见排序算法及对应的时间复杂度和空间复杂度
查看>>
业界 | 在德州叫一辆自动驾驶车,Drive.ai安排了7辆无人车展开真实试验
查看>>
实时数据平台设计:解决从OLTP到OLAP实时流转缺失
查看>>
三家公司在SD-WAN方面的新动作
查看>>
C#在PDF中如何以不同颜色高亮文本
查看>>
在同一页面显示多个JavaScript统计图表
查看>>
Mac电脑Tomcat下载及安装(详细)MAC在Eclipse里配置tomcat
查看>>
多线程之-----------定时器
查看>>
C#语法——反射,架构师的入门基础。
查看>>
Beego Models 之 一
查看>>
Python购物车练习
查看>>
StringBuffer 和 StringBiulder的区别
查看>>
自建网页服务器基础
查看>>
浅谈oracle 12C的新特性-CDB和PDB
查看>>
mysql 加密连接SSL
查看>>
mariadb 10.1.xx 自带数据库审计插件,直接上操作过程
查看>>
MySql的安装
查看>>