引入头文件:
import MapKit
import CoreLocation
添加代理CLLocationManagerDelegate
===========定位(一次定位、持续定位、使用期间定位、后台定位)=======
func mapLocation(){
locationManager=CLLocationManager.init()
//在使用期间发定位请求
if (locationManager?.responds(to: #selector(CLLocationManager.requestWhenInUseAuthorization)))!{
locationManager?.requestWhenInUseAuthorization()
// locationManager?.requestAlwaysAuthorization()//永久定位
}
/* iOS9新特性: 临时获取后台定位
当使用了使用期间授权时,可以在需要后台定位的地方,添加allowsBackgroundLocationUpdates属性,并设置为true.同时还需要打开后台定位模式 -->点击项目-->Capabilitys-->Background Modes-->勾选Location update
不用设置永久定位,此时就可以进行临时获取后台定位信息,但是屏幕上会有蓝条信息显示
*/
locationManager?.allowsBackgroundLocationUpdates=true//允许后台定位
locationManager?.delegate=self
//距离筛选器
locationManager?.distanceFilter=10//位置移动10米以上才待用位置更新的代理方法
locationManager?.desiredAccuracy=kCLLocationAccuracyKilometer//金准度
// 比较2个位置之间的距离比较的是直线距离
let l1:CLLocation=CLLocation.init(latitude: 40.06, longitude: 116.39)
let l2:CLLocation=CLLocation.init(latitude: 30.06, longitude: 116.39)
let distance:CLLocationDistance=l1.distance(from: l2);//l1距离l2的距离
locationManager?.startUpdatingLocation()//开始定位
}
//完成定位---// 当完成位置更新的时候调用
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// locations: 位置信息数据
print("\(locations)")
// 停止定位( 如果不 停止定为就是持续定位)
locationManager?.stopUpdatingHeading()
}
==============地理编码和反地理编码===========
引入import CoreLocation
*****
//地理编码:把地名转换成经纬度,可能会出现一对多的情况;
func geocoderClick(){
//创建地理编码对象
let geo:CLGeocoder=CLGeocoder.init()
//placemarks: 地标对象
// //CLPlacemark中有CLLocation(可以获得经纬度),region,街道名称,城市,州很多信息。
geo.geocodeAddressString("这里写入地址") { (placemarks, error) in
for placemark:CLPlacemark in placemarks!{
if (placemarks?.count==0)||(error != nil){
print("解析出错")
}
//获取经纬度等信息
print(placemark.location?.coordinate.latitude as Any)
//详细地址
print(placemark.name as Any)
//城市
print(placemark.locality as Any)
//行政区域
print(placemark.administrativeArea as Any)
}
}
}
//反地理编码---经纬度变成地址
func reverceGeocoderClick(){
//创建地理编码对象
let geo:CLGeocoder=CLGeocoder.init()
//创建位置
let l1:CLLocation=CLLocation.init(latitude: 40.06, longitude: 116.39)
geo.reverseGeocodeLocation(l1) { (placemarks, error) in
// 解析数据反地理编码,只会对应一个唯一的地址,所以不需要for循环
if (placemarks?.count==0)||(error != nil){
print("解析出错")
}
let placemark:CLPlacemark=(placemarks?.last)!
//详细地址
print(placemark.name as Any)
//城市
print(placemark.locality as Any)
//行政区域
print(placemark.administrativeArea as Any)
}
}
=============地图的基本使用===========
引入
MKMapViewDelegate
/**
// 需求:
// 1. 显示用户位置
// 2. 点击大头针,显示详情信息 -->反地理编码
// 3. 切换地图类型
// 4. 返回用户当前位置
// 5. 放大和缩小(了解)
// */
let mapview:MKMapView=MKMapView.init(frame:CGRect.init(x: 0, y: 0, width: 300, height: 300))
var locationManager:CLLocationManager?//位置管理器
func anotate(){
self.view.addSubview(mapview)
if (locationManager?.responds(to: #selector(CLLocationManager.requestWhenInUseAuthorization)))!{
locationManager?.requestWhenInUseAuthorization()
// locationManager?.requestAlwaysAuthorization()//永久定位
}
mapview.userTrackingMode=MKUserTrackingMode.follow//追踪模式
mapview.delegate=self
mapview.showsTraffic=true//显示交通状况
mapview.showsScale=true//显示比例尺
mapview.showsCompass=true//显示罗盘
mapview.showsBuildings=true//显示建筑物
mapview.mapType=MKMapType.standard//地图的显示模式,有号几个选项
mapview.delegate=self
}
// 获取用户的位置
func getUserLocation(){
//设置地图的中心经纬度---无动画
mapview.centerCoordinate=(mapview.userLocation.location?.coordinate)!
//设置地图的中心点经纬度 ---有动画
mapview.setCenter((mapview.userLocation.location?.coordinate)!, animated: true)
//获取地图的中心点坐标
let center:CLLocationCoordinate2D=(mapview.userLocation.location?.coordinate)!
//显示跨度,1°约等于111KM
let span:MKCoordinateSpan=MKCoordinateSpan.init(latitudeDelta: 0.01, longitudeDelta: 0.01)
//设置region---就是设置地图缩放
mapview.setRegion(MKCoordinateRegion.init(center: center, span: span), animated: true)
// 将当前的显示跨度缩小一倍(*0.5)放大一倍(*2)
let la=mapview.region.span.latitudeDelta*0.5
let lo=mapview.region.span.longitudeDelta*0.5
mapview.setRegion(MKCoordinateRegion.init(center: mapview.region.center, span: MKCoordinateSpan.init(latitudeDelta: la, longitudeDelta: lo)), animated: true)
}
//完成用户位置更新时调用的代理方法
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
// userLocation是系统的大头针
// 获取经纬度度
print(userLocation.location?.coordinate.latitude)
//设置标题和子标题
userLocation.title="合肥"
userLocation.subtitle="高新"
}
//地图显示区域发生改变的时候调用
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
//获取当前显示的跨度(缩放比例)
print(mapview.region.span.latitudeDelta)
}
============添加大头针=========
import UIKit
import MapKit
import CoreLocation
class RecordManager : LYBBaseVC,MKMapViewDelegate{
var mapview:MKMapView?
override func viewDidLoad() {
super.viewDidLoad()
mapview=MKMapView.init(frame: CGRect.init(x: 0, y: 0, width: WIDTH, height: HEIGHT))
mapview?.delegate=self
view.addSubview(mapview)
}
func adAnotation() {
//添加自定义的大头针模型,系统的大头针是MKPointAnnotation
let annotation:MyAnnotation=MyAnnotation.init()
annotation.coordinate=coordinate
annotation.title="合肥1"
annotation.subtitle="高新1"
mapview?.addAnnotation(annotation)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1. 获取点击的点
let point:CGPoint=touches.first?.location(in:mapview)
//2. 将点转换成经纬度
let coordinate:CLLocationCoordinate2D=mapview?.convert(point, toCoordinateFrom: mapview)
//添加大头针模型
let annotation:MyAnnotation=MyAnnotation.init()
annotation.coordinate=coordinate
annotation.title="合肥"
annotation.subtitle="高新"
mapview?.addAnnotation(annotation)
}
}
extension RecordManager:MKMapViewDelegate{
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// 如果返回nil,代表着用户没有自定义大头针的需求.所有的大头针显示由系统控制
// //MKUserLocation --> 系统显示用户位置的大头针类
// // 如果不是自己的大头针模型类,返回nil
if !(annotation is MyAnnotation){
return nil
}
var IDS:String="anoview"//重用标识
// //MKAnnotationView: 里面有一个image属性,默认没有值,需要设置一张图
// //MKPinAnnotationView: 默认有图像
// //如果要更改颜色,设置掉落效果只能找子类 MKPinAnnotationView
let anoview:MKPinAnnotationView=mapview?.dequeueReusableAnnotationView(withIdentifier: IDS)
if anoview==nil{
anoview=MKPinAnnotationView.init(annotation: annotation, reuseIdentifier: IDS)
// //如果大头针自定义了,标题和子标题默认不会实现;
// //设置大头针可以点击,显示标题和子标题
anoview.canShowCallout=true
// //设置大头针左右附属视图
anoview.leftCalloutAccessoryView=UISwitch.init()
anoview.rightCalloutAccessoryView=UISwitch.init()
// //设置大头针头像
anoview.image=UIImage.init(named: "")
// //1. 更改颜色
anoview.pinTintColor=UIColor.red
anoview.backgroundColor=UIColor.red
anoview.tintColor=UIColor.yellow
// //2. 动画掉落
anoview.animatesDrop=true
}
return annoView;
}
}
//自定义大头针
class MyAnnotation:MKAnnotation{
var coordinate:CLLocationCoordinate2D?
var title:String?
var subtitle:String?
}
=====================导航============import UIKit
import MapKit
import CoreLocation
class RecordManager : LYBBaseVC,MKMapViewDelegate{
var mapview:MKMapView?
override func viewDidLoad() {
super.viewDidLoad()
mapview=MKMapView.init(frame: CGRect.init(x: 0, y: 0, width: WIDTH, height: HEIGHT))
mapview?.delegate=self
view.addSubview(mapview)
}
func guide(){
// //1. 创建CLGeocoder对象
let geocoder:CLGeocoder=CLGeocoder.init()
// //2. 调用地理编码方法
geocoder.geocodeAddressString("地址名") { (placemarks, error) in
//3.1 防错处理
if placemarks?.count==0||error==nil{
return
}
//3.2 获取CLPlacemar对象 -->地理编码
// // 正向会有多个结果,咱们暂时取出一个
let pm:CLPlacemark=placemarks?.last
//3.3 创建一个MKPlacemark对象
let mkpm:MKPlacemark=MKPlacemark.init(placemark: pm)
//3.4 终点位置
let destinationItem:MKMapItem=MKMapItem.init(placemark: mkpm)
// //3.5 当前位置
let sourceItem:MKMapItem=MKMapItem.forCurrentLocation()
//实现导航关键点:在于一个MKMapItem的open方法
// //MKMapItem: 地图上的点
// //需要起点和终点
// //3.6 调用系统地图进行导航
let maptems=[sourceItem,destinationItem]
// // 导航模式. 地图类型.交通状态
let options=[MKLaunchOptionsDirectionsModeKey :MKLaunchOptionsDirectionsModeTransit,MKLaunchOptionsMapTypeKey :MKMapTypeHybrid]
MKMapItem.openMaps(with: maptems, launchOptions: options)
}
}
}
================导航划线==============
import UIKit
import MapKit
import CoreLocation
class RecordManager : LYBBaseVC,MKMapViewDelegate{
var mapview:MKMapView?
override func viewDidLoad() {
super.viewDidLoad()
mapview=MKMapView.init(frame: CGRect.init(x: 0, y: 0, width: WIDTH, height: HEIGHT))
mapview?.delegate=self
view.addSubview(mapview)
}
func guide(){
// //1. 创建CLGeocoder对象
let geocoder:CLGeocoder=CLGeocoder.init()
// //2. 调用地理编码方法
geocoder.geocodeAddressString("地址名") { (placemarks, error) in
//3.1 防错处理
if placemarks?.count==0||error==nil{
return
}
//3.2 获取CLPlacemar对象 -->地理编码
// // 正向会有多个结果,咱们暂时取出一个
let pm:CLPlacemark=placemarks?.last
//3.3 创建一个MKPlacemark对象
let mkpm:MKPlacemark=MKPlacemark.init(placemark: pm)
//3.4 终点位置
let destinationItem:MKMapItem=MKMapItem.init(placemark: mkpm)
// //3.5 当前位置
let sourceItem:MKMapItem=MKMapItem.forCurrentLocation()
//实现导航关键点:在于一个MKMapItem的open方法
// //MKMapItem: 地图上的点
// //需要起点和终点
// //3.6 调用系统地图进行导航
let maptems=[sourceItem,destinationItem]
// // 导航模式. 地图类型.交通状态
//3.6 计算路线
//1. 创建一个方向请求对象 --> 拼接URL地址的参数
let request:MKDirectionsRequest=MKDirectionsRequest.init()
request.source = sourceItem;
request.destination = destinationItem;
//2. 创建方向对象
let directions:MKDirections=MKDirections.init(request: request)
//3. 调用方法计算路线
directions.calculate(completionHandler: { (reponse, error) in
if placemarks?.count==0||error==nil{
return
}
//3.2 获取路线信息polyline
for route:MKRoute in reponse?.routes{
// 获取折线 多段线 polyline
let polyline:MKPolyline=route.polyline
//3.3 添加地图遮盖物
//Overlay: 遮盖物
mapview?.addOverlays(polyline)
}
})
}
}
}
extension RecordManager:MKMapViewDelegate{
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
//1. 创建一个渲染物对象 MKPolylineRenderer-->MKOverlayRenderer子类
let polyline:MKPolylineRenderer=MKPolylineRenderer.init(overlay: overlay)
// //2. 设置线条颜色 --> 默认无色
polyline.fillColor=UIColor.red
return polyline;
}
}