地图与位置服务有哪些应用?
1. 显示地图(MapKit)
导入MapKit.framework框架
头文件:
#import <MapKit/MapKit.h>
self . map = [[ MKMapView alloc ] initWithFrame : CGRectMake ( 0 , 0 , 320 , 480 )];
self . map . mapType = MKMapTypeStandard ; // 设置地图样式(3种类型)
[ self . view addSubview : self . map ];
坐标coordinate=(纬度latitude,经度longitude)
区域region=(范围span,中心点center)
导入CoreLocation.framework框架
头文件:
#import <CoreLocation/CoreLocation.h>
// 指定中心坐标(经纬度)
CLLocationCoordinate2D location = CLLocationCoordinate2DMake ( 24.27 , 118.06 );
// 根据当前标注决定是否居中
MKCoordinateSpan span = MKCoordinateSpanMake ( 0.003 , 0.003 );
// 设置地图显示
MKCoordinateRegion region = MKCoordinateRegionMake (location, span);
2. 增加标注(MapKit)
标注annotation与地理位置相关,带有文字描述信息的数据
包含:坐标、文字描述信息(名称、地址等)
标注视图annotationview标注信息在用户界面中的显示类,类似UIImage和UIImageView的关系
-( void )showAnnotation
{
// 显示地图标注
MKPointAnnotation *annotation = [[ MKPointAnnotation alloc ] init ];
annotation. coordinate = CLLocationCoordinate2DMake ( 37.7858 ,- 122.4064 );
annotation. title = @" 厦门 " ;
annotation. subtitle = @" 走神 ing" ;
// 将标注加到地图上
//[self.map addAnnotation:annotation];
// 选中标注,即大头针呼出( call out )效果
[ self . map selectAnnotation :annotation animated : YES ];
}
大头针添加下落动画的效果:
在.h中遵守协议 < MKMapViewDelegate >
在.m中设置代理委托
// 提供委托
self . map . delegate = self ;
// 标注视图创建和重用过程
-( MKAnnotationView *)mapView:( MKMapView *)mapView viewForAnnotation:( id < MKAnnotation >)annotation
{
// 标识符
static NSString *identifier = @"antationView" ;
// 重用 MKPinAnnotationView 标注视图
MKPinAnnotationView *antationView = ( MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier :identifier];
if (!antationView) {
// 创建标注视图
antationView = [[ MKPinAnnotationView alloc ] initWithAnnotation :annotation reuseIdentifier :identifier];
}
// 设置标注视图对应的标注
antationView. annotation = annotation;
// 设置标注视图的属性
annotationView. animatesDrop = YES ;
antationView. canShowCallout = YES ;
return antationView;
}
创建自定义的图片标注取代大头针
新建类继承 MKPointAnnotation:
在.h中
@interface Student : MKPointAnnotation @property ( nonatomic , retain ) UIImage *studentImage;
//判断annotion是否属于[Student class]类,
if ([annotation isKindOfClass :[ Student class ]])
{
// 标注是 Student 类或子类的实例
// 标识符
static NSString *identifier = @"Student View" ;
// 尝试重用标注视图
MKAnnotationView *annotationView = ( MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier :identifier];
if (!annotationView)
{
// 创建标注视图
annotationView = [[[ MKAnnotationView alloc ] initWithAnnotation :annotation reuseIdentifier :identifier] autorelease ];
}
// 设置标注视图对应的标注
annotationView. annotation = annotation;
// 设置标注视图的其他属性
Student *student = ( Student *)annotation;
annotationView. image = student. studentImage ;
annotationView. canShowCallout = YES ;
return annotationView;
}
3. 获得用户位置(CoreLocation)
// 显示用户当前的位置,由于模拟器不具有导航功能,所以经纬度要手动设置,模拟器--调试--位置--自定义位置
//显示用户当前得位置
self . map . showsUserLocation = YES ;
//通过map View获得用户位置并显示
// 自定义标注视图, MKUserLocation 用户的定位,用户定位的大头针是用 点 来表示
if ([annotation isKindOfClass :[ MKUserLocation class ]])
{
return nil ;
}
// 通过 map View 的回调方法获得用户位置
-( void )mapView:( MKMapView *)mapView didUpdateUserLocation:( MKUserLocation *)userLocation
{
// 获取到的用户位置
NSLog ( @"MKUserLocation: %.4f, %.4f" , userLocation. coordinate . latitude , userLocation. coordinate . longitude );
// 移动显示区域
[ self . mapView setRegion : MKCoordinateRegionMake (userLocation. coordinate , MKCoordinateSpanMake ( 0.003 , 0.003 )) animated : YES ];
// 对用户位置标注视图
[mapView selectAnnotation :userLocation animated : YES ];
}
在.h中遵行 < CLLocationManagerDelegate >
@property ( nonatomic , retain ) CLLocationManager *locationManager;
在.m中
// 通过 Core Location 获得用户位置
CLLocationManager *manager = [[ CLLocationManager alloc ] init ];
manager. delegate = self ;
self . locationManager = manager;
[manager startUpdatingLocation ];
// Core Location 定位回调
-( void )locationManager:( CLLocationManager *)manager didUpdateLocations:( NSArray *)locations
{
if (locations)
{
CLLocation *location = [locations lastObject ];
NSLog ( @"Core Location: %.4f, %.4f" , location. coordinate . latitude , location. coordinate . longitude );
// 保存用户位置
// 设置地图视图显示用户位置
self . mapView . showsUserLocation = YES ;
}
[manager stopUpdatingLocation ];
}
定位权限
// 判断设备整体的定位功能开关
if ([ CLLocationManager locationServicesEnabled ]){}
4. 坐标和地址双向查询(CoreLocation)
正向查询(地址找坐标)
// 创建geocoder 对象
CLGeocoder *geocoder = [[ CLGeocoder alloc ] init ];
// 正向 geocoding
[geocoder geocodeAddressString : @" 北京市石景山区石景山路 42 号 " completionHandler:^( NSArray *placemarks, NSError *error) {
if (error)
{
NSLog ( @"Error: %@" , [error localizedDescription ]);
}
else
{
for ( CLPlacemark *placemark in placemarks)
{
CLLocationCoordinate2D coordinate = placemark. location . coordinate ;
NSLog ( @"%.4f, %.4f" , coordinate. latitude , coordinate. longitude );
// 创建标注
MKPointAnnotation *annotation = [[ MKPointAnnotation alloc ] init ];
annotation. coordinate = coordinate;
annotation. title = placemark. name ;
annotation. subtitle = [placemark. addressDictionary objectForKey : @"Name" ];
[ self . mapView addAnnotation :annotation];
[ self . mapView selectAnnotation :annotation animated : NO ];
[annotation release ];
// 指定显示区域
[ self . mapView setRegion : MKCoordinateRegionMake (coordinate, MKCoordinateSpanMake ( 0.003 , 0.003 )) animated : NO ];
}
}
}];
反向查询(坐标找地址)
// 反向 geocoding
CLLocationCoordinate2D coordinateToBeFound = CLLocationCoordinate2DMake ( 39.9265 , 116.4785 );
CLLocation *location = [[ CLLocation alloc ] initWithLatitude : 39.9265 longitude : 116.4785 ];
[geocoder reverseGeocodeLocation :location completionHandler :^( NSArray *placemarks, NSError *error) {
if (error)
{
NSLog ( @"Error: %@" , [error localizedDescription ]);
}
else
{
for ( CLPlacemark *placemark in placemarks)
{
CLLocationCoordinate2D coordinate = coordinateToBeFound;
NSLog ( @"%.4f, %.4f" , coordinate. latitude , coordinate. longitude );
// 创建标注
MKPointAnnotation *annotation = [[ MKPointAnnotation alloc ] init ];
annotation. coordinate = coordinate;
annotation. title = placemark. name ;
annotation. subtitle = [placemark. addressDictionary objectForKey : @"Name" ];
[ self . mapView addAnnotation :annotation];
[ self . mapView selectAnnotation :annotation animated : NO ];
[annotation release ];
// 指定显示区域
[ self . mapView setRegion : MKCoordinateRegionMake (coordinate, MKCoordinateSpanMake ( 0.003 , 0.003 )) animated : NO ];
}
}
}];
5. 查询附近商户(MapKit,第三方SDK)
// 本地商户查询
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake ( 39.9265 , 116.4785 );
MKCoordinateSpan span = MKCoordinateSpanMake ( 0.005 , 0.005 );
MKLocalSearchRequest *request = [[ MKLocalSearchRequest alloc ] init ];
request. naturalLanguageQuery = @" 银行 " ;
request. region = MKCoordinateRegionMake (coordinate, span);
MKLocalSearch *search = [[ MKLocalSearch alloc ] initWithRequest :request];
[search startWithCompletionHandler :^( MKLocalSearchResponse *response, NSError *error) {
if (error)
{
NSLog ( @"Error: %@" , [error localizedDescription ]);
}
else
{
for ( MKMapItem *item in response. mapItems )
{
CLPlacemark *placemark = item. placemark ;
CLLocationCoordinate2D coordinateP = placemark. location . coordinate ;
NSLog ( @"%.4f, %.4f" , coordinateP. latitude , coordinateP. longitude );
CLLocationDegrees lat = coordinateP. latitude - coordinate. latitude ;
CLLocationDegrees lon = coordinateP. longitude - coordinate. longitude ;
if ( fabs (lat) <= 0.01 && fabs (lon) <= 0.01 )
{
// 创建标注
MKPointAnnotation *annotation = [[ MKPointAnnotation alloc ] init ];
annotation. coordinate = coordinateP;
annotation. title = item. name ;
annotation. subtitle = [placemark. addressDictionary objectForKey : @"Street" ];
[ self . mapView addAnnotation :annotation];
[annotation release ];
}
// 3 秒后跳转到行车路线
[self performSelector:@selector(showRoute:) withObject:[NSValue valueWithMKCoordinate:coordinateP] afterDelay:3.0];
}
// 指定显示区域
[ self . mapView setRegion : MKCoordinateRegionMake (coordinate, MKCoordinateSpanMake ( 0.01 , 0.01 )) animated : NO ];
}
}];
6. 查询驾车路线(MapKit)
-( void )showRoute:( NSValue *)coordinateValue
{
// 通过 map item 来实现驾车路线查询
CLLocationCoordinate2D coordinate = [coordinateValue MKCoordinateValue ];
MKPlacemark *placemark = [[ MKPlacemark alloc ] initWithCoordinate : CLLocationCoordinate2DMake (coordinate. latitude , coordinate. longitude ) addressDictionary :[ NSDictionary dictionaryWithObjectsAndKeys : @" 测试地址 " , @"Street" , @" 测试名称 " , @"Name" , nil ]];
MKMapItem *mapItem = [[ MKMapItem alloc ] initWithPlacemark :placemark];
mapItem. name = @" 银行 " ;
[ MKMapItem openMapsWithItems :[ NSArray arrayWithObject :mapItem] launchOptions :[ NSDictionary dictionaryWithObjectsAndKeys : MKLaunchOptionsDirectionsModeDriving , MKLaunchOptionsDirectionsModeKey , nil ]];
[mapItem release ];
[placemark release ];
}
1. 显示地图(MapKit)
导入MapKit.framework框架
头文件:
#import <MapKit/MapKit.h>
self . map = [[ MKMapView alloc ] initWithFrame : CGRectMake ( 0 , 0 , 320 , 480 )];
self . map . mapType = MKMapTypeStandard ; // 设置地图样式(3种类型)
[ self . view addSubview : self . map ];
坐标coordinate=(纬度latitude,经度longitude)
区域region=(范围span,中心点center)
导入CoreLocation.framework框架
头文件:
#import <CoreLocation/CoreLocation.h>
// 指定中心坐标(经纬度)
CLLocationCoordinate2D location = CLLocationCoordinate2DMake ( 24.27 , 118.06 );
// 根据当前标注决定是否居中
id<MKAnnotation> annotation = [self.annotations lastObject];
location = annotation.coordinate;
// 指定显示范围MKCoordinateSpan span = MKCoordinateSpanMake ( 0.003 , 0.003 );
// 设置地图显示
MKCoordinateRegion region = MKCoordinateRegionMake (location, span);
self.map.region = region;
//动画显示指定区域,效果由大到小
[self.map setRegion:region animated:YES];
2. 增加标注(MapKit)
标注annotation与地理位置相关,带有文字描述信息的数据
包含:坐标、文字描述信息(名称、地址等)
标注视图annotationview标注信息在用户界面中的显示类,类似UIImage和UIImageView的关系
//添加标注操作,设置延后2.0效果
[self performSelector:@selector(showAnnotation) withObject:nil afterDelay:2.0f];
-( void )showAnnotation
{
// 显示地图标注
MKPointAnnotation *annotation = [[ MKPointAnnotation alloc ] init ];
annotation. coordinate = CLLocationCoordinate2DMake ( 37.7858 ,- 122.4064 );
annotation. title = @" 厦门 " ;
annotation. subtitle = @" 走神 ing" ;
// 将标注加到地图上
//[self.map addAnnotation:annotation];
// 选中标注,即大头针呼出( call out )效果
[ self . map selectAnnotation :annotation animated : YES ];
}
大头针添加下落动画的效果:
在.h中遵守协议 < MKMapViewDelegate >
在.m中设置代理委托
// 提供委托
self . map . delegate = self ;
// 标注视图创建和重用过程
-( MKAnnotationView *)mapView:( MKMapView *)mapView viewForAnnotation:( id < MKAnnotation >)annotation
{
// 标识符
static NSString *identifier = @"antationView" ;
// 重用 MKPinAnnotationView 标注视图
MKPinAnnotationView *antationView = ( MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier :identifier];
if (!antationView) {
// 创建标注视图
antationView = [[ MKPinAnnotationView alloc ] initWithAnnotation :annotation reuseIdentifier :identifier];
}
// 设置标注视图对应的标注
antationView. annotation = annotation;
// 设置标注视图的属性
annotationView. animatesDrop = YES ;
antationView. canShowCallout = YES ;
return antationView;
}
创建自定义的图片标注取代大头针
新建类继承 MKPointAnnotation:
在.h中
@interface Student : MKPointAnnotation @property ( nonatomic , retain ) UIImage *studentImage;
//判断annotion是否属于[Student class]类,
if ([annotation isKindOfClass :[ Student class ]])
{
// 标注是 Student 类或子类的实例
// 标识符
static NSString *identifier = @"Student View" ;
// 尝试重用标注视图
MKAnnotationView *annotationView = ( MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier :identifier];
if (!annotationView)
{
// 创建标注视图
annotationView = [[[ MKAnnotationView alloc ] initWithAnnotation :annotation reuseIdentifier :identifier] autorelease ];
}
// 设置标注视图对应的标注
annotationView. annotation = annotation;
// 设置标注视图的其他属性
Student *student = ( Student *)annotation;
annotationView. image = student. studentImage ;
annotationView. canShowCallout = YES ;
return annotationView;
}
3. 获得用户位置(CoreLocation)
// 显示用户当前的位置,由于模拟器不具有导航功能,所以经纬度要手动设置,模拟器--调试--位置--自定义位置
//显示用户当前得位置
self . map . showsUserLocation = YES ;
//通过map View获得用户位置并显示
// 自定义标注视图, MKUserLocation 用户的定位,用户定位的大头针是用 点 来表示
if ([annotation isKindOfClass :[ MKUserLocation class ]])
{
return nil ;
}
// 通过 map View 的回调方法获得用户位置
-( void )mapView:( MKMapView *)mapView didUpdateUserLocation:( MKUserLocation *)userLocation
{
// 获取到的用户位置
NSLog ( @"MKUserLocation: %.4f, %.4f" , userLocation. coordinate . latitude , userLocation. coordinate . longitude );
// 移动显示区域
[ self . mapView setRegion : MKCoordinateRegionMake (userLocation. coordinate , MKCoordinateSpanMake ( 0.003 , 0.003 )) animated : YES ];
// 对用户位置标注视图
[mapView selectAnnotation :userLocation animated : YES ];
}
在.h中遵行 < CLLocationManagerDelegate >
@property ( nonatomic , retain ) CLLocationManager *locationManager;
在.m中
// 通过 Core Location 获得用户位置
CLLocationManager *manager = [[ CLLocationManager alloc ] init ];
manager. delegate = self ;
self . locationManager = manager;
[manager startUpdatingLocation ];
// Core Location 定位回调
-( void )locationManager:( CLLocationManager *)manager didUpdateLocations:( NSArray *)locations
{
if (locations)
{
CLLocation *location = [locations lastObject ];
NSLog ( @"Core Location: %.4f, %.4f" , location. coordinate . latitude , location. coordinate . longitude );
// 保存用户位置
// 设置地图视图显示用户位置
self . mapView . showsUserLocation = YES ;
}
[manager stopUpdatingLocation ];
}
定位权限
// 判断设备整体的定位功能开关
if ([ CLLocationManager locationServicesEnabled ]){}
4. 坐标和地址双向查询(CoreLocation)
正向查询(地址找坐标)
// 创建geocoder 对象
CLGeocoder *geocoder = [[ CLGeocoder alloc ] init ];
// 正向 geocoding
[geocoder geocodeAddressString : @" 北京市石景山区石景山路 42 号 " completionHandler:^( NSArray *placemarks, NSError *error) {
if (error)
{
NSLog ( @"Error: %@" , [error localizedDescription ]);
}
else
{
for ( CLPlacemark *placemark in placemarks)
{
CLLocationCoordinate2D coordinate = placemark. location . coordinate ;
NSLog ( @"%.4f, %.4f" , coordinate. latitude , coordinate. longitude );
// 创建标注
MKPointAnnotation *annotation = [[ MKPointAnnotation alloc ] init ];
annotation. coordinate = coordinate;
annotation. title = placemark. name ;
annotation. subtitle = [placemark. addressDictionary objectForKey : @"Name" ];
[ self . mapView addAnnotation :annotation];
[ self . mapView selectAnnotation :annotation animated : NO ];
[annotation release ];
// 指定显示区域
[ self . mapView setRegion : MKCoordinateRegionMake (coordinate, MKCoordinateSpanMake ( 0.003 , 0.003 )) animated : NO ];
}
}
}];
反向查询(坐标找地址)
// 反向 geocoding
CLLocationCoordinate2D coordinateToBeFound = CLLocationCoordinate2DMake ( 39.9265 , 116.4785 );
CLLocation *location = [[ CLLocation alloc ] initWithLatitude : 39.9265 longitude : 116.4785 ];
[geocoder reverseGeocodeLocation :location completionHandler :^( NSArray *placemarks, NSError *error) {
if (error)
{
NSLog ( @"Error: %@" , [error localizedDescription ]);
}
else
{
for ( CLPlacemark *placemark in placemarks)
{
CLLocationCoordinate2D coordinate = coordinateToBeFound;
NSLog ( @"%.4f, %.4f" , coordinate. latitude , coordinate. longitude );
// 创建标注
MKPointAnnotation *annotation = [[ MKPointAnnotation alloc ] init ];
annotation. coordinate = coordinate;
annotation. title = placemark. name ;
annotation. subtitle = [placemark. addressDictionary objectForKey : @"Name" ];
[ self . mapView addAnnotation :annotation];
[ self . mapView selectAnnotation :annotation animated : NO ];
[annotation release ];
// 指定显示区域
[ self . mapView setRegion : MKCoordinateRegionMake (coordinate, MKCoordinateSpanMake ( 0.003 , 0.003 )) animated : NO ];
}
}
}];
5. 查询附近商户(MapKit,第三方SDK)
// 本地商户查询
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake ( 39.9265 , 116.4785 );
MKCoordinateSpan span = MKCoordinateSpanMake ( 0.005 , 0.005 );
MKLocalSearchRequest *request = [[ MKLocalSearchRequest alloc ] init ];
request. naturalLanguageQuery = @" 银行 " ;
request. region = MKCoordinateRegionMake (coordinate, span);
MKLocalSearch *search = [[ MKLocalSearch alloc ] initWithRequest :request];
[search startWithCompletionHandler :^( MKLocalSearchResponse *response, NSError *error) {
if (error)
{
NSLog ( @"Error: %@" , [error localizedDescription ]);
}
else
{
for ( MKMapItem *item in response. mapItems )
{
CLPlacemark *placemark = item. placemark ;
CLLocationCoordinate2D coordinateP = placemark. location . coordinate ;
NSLog ( @"%.4f, %.4f" , coordinateP. latitude , coordinateP. longitude );
CLLocationDegrees lat = coordinateP. latitude - coordinate. latitude ;
CLLocationDegrees lon = coordinateP. longitude - coordinate. longitude ;
if ( fabs (lat) <= 0.01 && fabs (lon) <= 0.01 )
{
// 创建标注
MKPointAnnotation *annotation = [[ MKPointAnnotation alloc ] init ];
annotation. coordinate = coordinateP;
annotation. title = item. name ;
annotation. subtitle = [placemark. addressDictionary objectForKey : @"Street" ];
[ self . mapView addAnnotation :annotation];
[annotation release ];
}
// 3 秒后跳转到行车路线
[self performSelector:@selector(showRoute:) withObject:[NSValue valueWithMKCoordinate:coordinateP] afterDelay:3.0];
}
// 指定显示区域
[ self . mapView setRegion : MKCoordinateRegionMake (coordinate, MKCoordinateSpanMake ( 0.01 , 0.01 )) animated : NO ];
}
}];
6. 查询驾车路线(MapKit)
-( void )showRoute:( NSValue *)coordinateValue
{
// 通过 map item 来实现驾车路线查询
CLLocationCoordinate2D coordinate = [coordinateValue MKCoordinateValue ];
MKPlacemark *placemark = [[ MKPlacemark alloc ] initWithCoordinate : CLLocationCoordinate2DMake (coordinate. latitude , coordinate. longitude ) addressDictionary :[ NSDictionary dictionaryWithObjectsAndKeys : @" 测试地址 " , @"Street" , @" 测试名称 " , @"Name" , nil ]];
MKMapItem *mapItem = [[ MKMapItem alloc ] initWithPlacemark :placemark];
mapItem. name = @" 银行 " ;
[ MKMapItem openMapsWithItems :[ NSArray arrayWithObject :mapItem] launchOptions :[ NSDictionary dictionaryWithObjectsAndKeys : MKLaunchOptionsDirectionsModeDriving , MKLaunchOptionsDirectionsModeKey , nil ]];
[mapItem release ];
[placemark release ];
}