热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

IOS开发学习笔记(十六)——使用地理位置及地图(上篇)

使用地图iOS系统自带地图(主要是iPhone),为了使用地图,需要做如下步骤:添加MapKit.framework;添加MapView到对应界面;设置MapView属性,例如:Type、Beha

使用地图

iOS系统自带地图(主要是iPhone),为了使用地图,需要做如下步骤:

  1. 添加MapKit.framework;
  2. 添加Map View到对应界面;
  3. 设置Map View属性,例如:Type、Behavior等;
  4. 也可以在代码中进行设置,如:
    - (void)viewDidLoad
    {
    [super viewDidLoad];

    MKMapView *mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    [mapView setMapType: MKMapTypeHybrid];
    [mapView setZoomEnabled:YES];
    [mapView setScrollEnabled:YES];
    [mapView setShowsUserLocation:YES];

    [self.view addSubview:mapView];
    }


  5. ok,可以看到地图展示的效果了。


GIS(Geographic Information System)介绍

我们需要了解几个方面的知识。

  1. GIS系统将地球分割为一个表格系统(这里的表格不是每个单元一样大的,甚至严格来说每个表格都不是一个矩形);
  2. 纬度的计算方式是从赤道到极点,北半球为正,南半球为负;
  3. 经度从格林尼治天文台分割,以东为正,以西为负;
  4. 坐标被标示为°,赤道上是360°,极点是0°;
  5. 一个map view是一个被平坦化的球面标识,一个地图上的点使用x和y来标识;


聚焦

下面使用一个小例子来看如何使用聚焦到某个地点的功能。我们在下面的步骤中都将采用拖拽方式生成界面的形式而不是手动编写界面生成代码。

  1. 工程添加framework;
  2. ViewController.h头文件中添加import
  3. 生成Map View的outlet变量;
  4. 接下来是将某个具体位置聚焦到地图中间的代码:
    #import "ViewController.h"
    #import

    // ShangHai
    #define SH_LATITUDE 31.14
    #define SH_LONGITUDE 121.29

    // BeiJing
    #define BJ_LATITUDE 39.55
    #define BJ_LONGITUDE 116.24

    // Span
    #define SPAN_VALUE 0.20f

    @interface ViewController ()

    @end

    @implementation ViewController

    @synthesize mapView;

    - (void)viewDidLoad
    {
    [super viewDidLoad];

    // region property: center, span
    MKCoordinateRegion region;
    CLLocationCoordinate2D center;
    center.latitude = BJ_LATITUDE;
    center.lOngitude= BJ_LONGITUDE;
    MKCoordinateSpan span;
    span.latitudeDelta = SPAN_VALUE;
    span.lOngitudeDelta= SPAN_VALUE;
    region.span = span;
    region.center = center;
    // assign region to map
    [mapView setRegion:region animated:YES];
    }

    代码中的span指的是在经度/纬度方面显示几个区域。换句话说,代表了一种比例尺的概念。span越大,越能显示更多的区域。
  5. 如果需要支持用户的位置,那么需要做的更多一些。首先需要做的是实现MKMapViewDelegate代理,ViewController.h头文件中需要设置:
    #import 
    #import

    @interface ViewController : UIViewController
    @property (strong, nonatomic) IBOutlet MKMapView *mapView;
    @end

  6. 查看帮助,编写代理实现方法,这里主要在更新用户坐标时刷新,最终代码如下:
    #import "ViewController.h"
    #import


    @interface ViewController ()

    @end

    @implementation ViewController

    @synthesize mapView;

    - (void)viewDidLoad
    {
    [super viewDidLoad];

    [mapView setDelegate:self];
    [mapView setShowsUserLocation:YES];

    }

    - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    CLLocationCoordinate2D loc = [userLocation coordinate];
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 500, 500);
    [self.mapView setRegion:region animated:YES];
    }

  7. 运行在真机上即可查看结果。

添加注解

我们经常需要将某个地点标注到地图上,我们需要增加Annotation功能,实际就是一个标注。

  1. 我们创建一个MapAnnotation类,实现Annotation;
    头文件:
    #import 
    #import

    @interface MapAnnotation : NSObject

    @property (nonatomic, assign) CLLocationCoordinate2D coordinate;
    @property (nonatomic, copy) NSString *title;
    @property (nonatomic, copy) NSString *subTitle;

    - initWithPosition:(CLLocationCoordinate2D) coords;

    @end

    .m文件:
    #import "MapAnnotation.h"

    @implementation MapAnnotation
    @synthesize coordinate;
    @synthesize title;
    @synthesize subTitle;


    - initWithPosition:(CLLocationCoordinate2D) coords {
    if (self = [super init]) {
    self.coordinate = coords;
    }

    return self;
    }

    @end

  2. 然后使用上面创建的Annotation:
    // ShangHai
    #define SH_LATITUDE 31.14
    #define SH_LONGITUDE 121.29
    // BeiJing
    #define BJ_LATITUDE 39.55
    #define BJ_LONGITUDE 116.24
    // Span
    #define SPAN_VALUE 0.20f

    @interface ViewController ()

    @end

    @implementation ViewController

    @synthesize mapView;

    - (void)viewDidLoad
    {
    [super viewDidLoad];


    // region property: center, span
    MKCoordinateRegion region;
    CLLocationCoordinate2D center;
    center.latitude = BJ_LATITUDE;
    center.lOngitude= BJ_LONGITUDE;
    MKCoordinateSpan span;
    span.latitudeDelta = SPAN_VALUE;
    span.lOngitudeDelta= SPAN_VALUE;
    region.span = span;
    region.center = center;
    // assign region to map
    [mapView setRegion:region animated:YES];


    CLLocationCoordinate2D location;
    location.latitude = SH_LATITUDE;
    location.lOngitude= SH_LONGITUDE;

    MapAnnotation *anno = [[MapAnnotation alloc] initWithPosition: location];
    [anno setTitle: @"Shanghai"];
    [anno setSubTitle: @"Shanghai center"];
    [mapView addAnnotation: anno];
    }

  3. 完成,查看效果。

自定义注解

默认的注解是一个图钉一样的图标,点击后弹出文字。我们可以修改注解为我们期望的效果。

  1. 首先我们设置ViewController为MKMapViewDelegate代理;
  2. 在.m文件中设置代理为自身:
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    [mapView setDelegate: self];

    // region property: center, span
    MKCoordinateRegion region;
    CLLocationCoordinate2D center;
    center.latitude = SZ_LATITUDE;
    center.lOngitude= SZ_LONGITUDE;
    MKCoordinateSpan span;
    span.latitudeDelta = SPAN_VALUE;
    span.lOngitudeDelta= SPAN_VALUE;
    region.span = span;
    region.center = center;
    // assign region to map
    [mapView setRegion:region animated:YES];


    CLLocationCoordinate2D location;
    location.latitude = SH_LATITUDE;
    location.lOngitude= SH_LONGITUDE;

    MapAnnotation *anno = [[MapAnnotation alloc] initWithPosition: location];
    [anno setTitle: @"Shanghai"];
    [anno setSubTitle: @"Shanghai center"];
    [mapView addAnnotation: anno];
    }

  3. 添加代理方法:
    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation {
    // view
    MKPinAnnotationView * view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"];
    // pin color
    [view setPinColor:MKPinAnnotationColorPurple];
    // enabled animated
    [view setEnabled: YES];
    [view setAnimatesDrop: YES];
    [view setCanShowCallout: YES];
    // image button
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"customanno.png"]];
    [view setLeftCalloutAccessoryView:imageView];
    [view setRightCalloutAccessoryView: [UIButton buttonWithType: UIButtonTypeDetailDisclosure]];

    return view;
    }

  4. 完成,查看效果。

增加AccessoryView点击效果

我们点击大头针会弹出自定义的AccessoryView,显示一个图文标题加上一个向右箭头,但是这些都是无法点击的,现在我们加上向右箭头点击效果。

我们添加一个代理方法:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation {
// view
MKPinAnnotationView * view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"];
// pin color
[view setPinColor:MKPinAnnotationColorPurple];
// enabled animated
[view setEnabled: YES];
[view setAnimatesDrop: YES];
[view setCanShowCallout: YES];
// image button
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"customanno.png"]];
[view setLeftCalloutAccessoryView:imageView];
[view setRightCalloutAccessoryView: [UIButton buttonWithType: UIButtonTypeDetailDisclosure]];

return view;
}

添加多个注解

我们可能希望将多个地点注解添加到我们的地图中,那么我们需要以下几步:

  1. 我们需要定义多个经纬度:
    // ShangHai
    #define SH_LATITUDE 31.14
    #define SH_LONGITUDE 121.29
    // SuZhou
    #define SZ_LATITUDE 31.19
    #define SZ_LONGITUDE 120.37
    // ChangZhou
    #define CZ_LATITUDE 31.47
    #define CZ_LONGITUDE 119.58
    // KunShan
    #define KS_LATITUDE 31.23
    #define KS_LONGITUDE 120.57
    // Span
    #define SPAN_VALUE 2.0f

  2. 我们需要一个Annotation数组:
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    [mapView setDelegate: self];

    // region property: center, span
    MKCoordinateRegion region;
    CLLocationCoordinate2D center;
    center.latitude = KS_LATITUDE;
    center.lOngitude= KS_LONGITUDE;
    MKCoordinateSpan span;
    span.latitudeDelta = SPAN_VALUE;
    span.lOngitudeDelta= SPAN_VALUE;
    region.span = span;
    region.center = center;
    // assign region to map
    [mapView setRegion:region animated:YES];

    NSMutableArray *annotatiOns= [[NSMutableArray alloc] init];
    MapAnnotation *anno;
    CLLocationCoordinate2D location;

    anno = [[MapAnnotation alloc] init];
    location.latitude = SH_LATITUDE;
    location.lOngitude= SH_LONGITUDE;
    [anno setCoordinate: location];
    [anno setTitle: @"上海"];
    [annotations addObject:anno];

    anno = [[MapAnnotation alloc] init];
    location.latitude = SZ_LATITUDE;
    location.lOngitude= SZ_LONGITUDE;
    [anno setCoordinate: location];
    [anno setTitle: @"苏州"];
    [annotations addObject:anno];

    anno = [[MapAnnotation alloc] init];
    location.latitude = CZ_LATITUDE;
    location.lOngitude= CZ_LONGITUDE;
    [anno setCoordinate: location];
    [anno setTitle: @"常州"];
    [annotations addObject:anno];

    anno = [[MapAnnotation alloc] init];
    location.latitude = KS_LATITUDE;
    location.lOngitude= KS_LONGITUDE;
    [anno setCoordinate: location];
    [anno setTitle: @"昆山"];
    [annotations addObject:anno];

    [mapView addAnnotations:annotations];
    }

  3. 我们需要修改代理方法,为了能够重用Annotation View,避免不必要的资源消耗,需要在创建view之前请求资源重用:
        MKPinAnnotationView *view = [self.mapView dequeueReusableAnnotationViewWithIdentifier:@"pin"];
    if (view == nil) {
    view = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"];
    }

  4. 查看效果:

添加多个不同的注解

我们期望对不同的注解添加不同的显示效果,则需要添加如下代码:

  1. 对annotation添加属性,以便于能够识别不同属性数据:
    #import 
    #import

    @interface MapAnnotation : NSObject

    @property (nonatomic, assign) CLLocationCoordinate2D coordinate;
    @property (nonatomic, copy) NSString *title;
    @property (nonatomic, copy) NSString *subTitle;
    @property (nonatomic, copy) NSString *province;
    @property (nonatomic, copy) NSString *name;

    - initWithPosition:(CLLocationCoordinate2D) coords;

    @end

  2. 创建新类继承自MKPinAnnotationView,并且重写initWithAnnotation方法:
    - (id)initWithAnnotation:(id)annotation reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];

    // Get a referene to the annotation to get its state value
    MapAnnotation *myAnnotation = (MapAnnotation *)annotation;

    NSString *myImage;
    if ([myAnnotation.province isEqualToString:@"JiangSu"]) {
    myImage = @"jiangsu.png";
    } else if ([myAnnotation.province isEqualToString:@"ShangHai"]) {
    myImage = @"shanghai.png";
    }

    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:myImage]];
    self.leftCalloutAccessoryView = imageView;

    if ([myAnnotation.name isEqualToString:@"ShangHai"]) {
    self.image = [UIImage imageNamed:@"shanghai_anno.png"];
    }
    self.enabled = YES;
    self.canShowCallout = YES;

    return self;
    }

  3. 在ViewController中初始化:
    - (void)viewDidLoad
    {
    [super viewDidLoad];
    [mapView setDelegate: self];

    // region property: center, span
    MKCoordinateRegion region;
    CLLocationCoordinate2D center;
    center.latitude = KS_LATITUDE;
    center.lOngitude= KS_LONGITUDE;
    MKCoordinateSpan span;
    span.latitudeDelta = SPAN_VALUE;
    span.lOngitudeDelta= SPAN_VALUE;
    region.span = span;
    region.center = center;
    // assign region to map
    [mapView setRegion:region animated:YES];

    NSMutableArray *annotatiOns= [[NSMutableArray alloc] init];
    MapAnnotation *anno;
    CLLocationCoordinate2D location;

    anno = [[MapAnnotation alloc] init];
    location.latitude = SH_LATITUDE;
    location.lOngitude= SH_LONGITUDE;
    [anno setCoordinate: location];
    [anno setTitle: @"上海"];
    [anno setName: @"ShangHai"];
    [anno setProvince: @"ShangHai"];
    [annotations addObject:anno];

    anno = [[MapAnnotation alloc] init];
    location.latitude = SZ_LATITUDE;
    location.lOngitude= SZ_LONGITUDE;
    [anno setCoordinate: location];
    [anno setTitle: @"苏州"];
    [anno setName: @"SuZhou"];
    [anno setProvince: @"JiangSu"];
    [annotations addObject:anno];

    anno = [[MapAnnotation alloc] init];
    location.latitude = CZ_LATITUDE;
    location.lOngitude= CZ_LONGITUDE;
    [anno setCoordinate: location];
    [anno setTitle: @"常州"];
    [anno setName: @"ChangZhou"];
    [anno setProvince: @"JiangSu"];
    [annotations addObject:anno];

    anno = [[MapAnnotation alloc] init];
    location.latitude = KS_LATITUDE;
    location.lOngitude= KS_LONGITUDE;
    [anno setCoordinate: location];
    [anno setTitle: @"昆山"];
    [anno setName: @"KunShan"];
    [anno setProvince: @"JiangSu"];
    [annotations addObject:anno];

    [mapView addAnnotations:annotations];
    }

  4. ViewController的viewForAnnotation方法变为:
    - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation {
    // view
    MapAnnotationView *view = (MapAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:@"pin"];
    if (view == nil) {
    view = [[MapAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pin"];
    }

    return view;
    }

  5. 完成,查看效果。





推荐阅读
  • IOS笔记汇总为了方便开发者开发出强大的功能,苹果提供了各种各样的框架IOS属性IOS基础属性导入依赖propertyNSStringNSDictionaryNSAr ... [详细]
  • IOS9之当前位置定位
    2019独角兽企业重金招聘Python工程师标准#import*.h文件中导入以下两个框架*#import ... [详细]
  • IOS开发之百度地图API环境搭建 ... [详细]
  • iOS 系统架构 && 常用 framework
    整理自互联网,感谢原文作者!1.iOS基于UNIX系统,因此从系统的稳定性上来说它要比其他操作系统的产品好很多2.iOS的系统架构分为四层,由上到下一次为:可触摸层(CocoaTo ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了iOS核心笔记—CoreLocation框架-基础相关的知识,希望对你有一定的参考价值。1、 ... [详细]
  • 高德IOS真机调试LMAMapKit出错问题的解决方法(directory not found for option)
    1最近项目到了收尾阶段,所以开始了在真机部署调试,之前的模拟器环境下测试项目,一切都没问题,今天真机调试过程中, ... [详细]
  • MRMapViewController.mCoreLocation&MapKitCreatedbyMr.Roboton201786. ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
  • 在iOS6之后,不再使用谷歌地图了,而是使用苹果自己的地图,但是API编程接口没有太大的变化。开发人员不需要再学习很多新东西就能开发地图应用,这是负责任的做法。因此本节介绍的内容也同样适用于iOS5 ... [详细]
  • 添加#import头文件倒入mapkit.framework库mapkit.framework是属于ui,可以在故事版上添加mkmap ... [详细]
author-avatar
红红的累累vdHRC_958
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有