定位服务编程
(一)、地理信息反编码(需要框架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
// }
}