iOS上地图画线,画线区域内的经纬度坐标点添加大头针

转载 2013年12月02日 16:50:16

实现在Google地图上用手指可以画线的功能,同时地图上的一点(经纬度坐标点)如果在画线的区域内,会在这个点落下大头针的功能,类似大众点评的画线圈商铺的效果

在做了前两篇博客的工作以后,对手指移动画线的方法有了了解,所以思路是一样的,先在根视图上加一个MapView,然后在MapView上面加画图的View,也就是说地图是地图,画线是画线,互不干扰,但是这样做的话怎么能实现范围内经纬度点的识别呢?这里就要用到地图坐标和画图坐标的转换,后面会讲。

所以解决方法是在画布View上画图,然后通过坐标转换获得这一圈儿的经纬度坐标点,然后在经纬度值的范围内的坐标点找出来,然后在这个坐标点上加大头针。

但是在实际操作中发现就算我获得了这一圈儿的经纬度值,存在一个数组里,我也不知道如何判断某个经纬度是不是在这个范围之内。

所以反着来想,之前的解决思路是View上的坐标转化成地图的经纬度坐标,当然也可以把地图上经纬度坐标转化成View上的坐标,因为在View上CGPath范围内的点是可以找出来的(后面会讲),所以后来决定按这个思路做,会更顺利些。

 

 

下面是具体代码,首先创建一个SingleView项目,引入必要的两个库文件CoreLocation.framewrok和MapKit.framework,地图的展示和定位都要用到,然后ViewController.h头文件添加如下代码:

#import <UIKit/UIKit.h>

#import “MapKit/MapKit.h”

@interface ViewController : UIViewController<CLLocationManagerDelegate,MKMapViewDelegate>

{

MKMapView *innerMap;//地图层

UIImageView *imageView;//绘画层

CLLocationManager *locationManager;//定位实例

NSMutableArray *array;//存储经纬度坐标的数组,这里用不着

CGMutablePathRef pathRef;//手指画线的Path

CLLocationCoordinate2D testLocation;//测试的位置(经纬度)

CGPoint locationConverToImage;//存储转换测试位置的CGPoint

}

@end

之后是终点ViewController.m的代码,视图中两个按钮就不说了,通过IB拖拽的,功能函数下面会说,功能如其名,首先是ViewDidLoad方法:

- (void)viewDidLoad

{

[super viewDidLoad];

//添加地图层

innerMap=[[MKMapView alloc] initWithFrame:CGRectMake(0, 50, 320, 430)];

[self.view addSubview:innerMap];

//[innerMap setShowsUserLocation:YES];//不显示定位小蓝点儿

[innerMap setDelegate:self];

//添加定位信息,为了设置地图显示的Region范围

locationManager = [[CLLocationManager alloc] init];

locationManager.delegate=self;

locationManager.desiredAccuracy=kCLLocationAccuracyBest;

locationManager.distanceFilter=1000.0f;

[locationManager startUpdatingLocation];

MKCoordinateSpan theSpan;

theSpan.latitudeDelta=0.03;

theSpan.longitudeDelta=0.03;

MKCoordinateRegion theRegion={ {0.0, 0.0 }, { 0.0, 0.0 } };

theRegion.center=locationManager.location.coordinate;

theRegion.span=theSpan;

[innerMap setRegion:theRegion animated:YES];

//用当前经纬度来设置测试经纬度点,便于查看

// NSLog(@”latitude !!! %f”,locationManager.location.coordinate.latitude);

//  NSLog(@”longtitude !!! %f”,locationManager.location.coordinate.longitude);

//初始化数组为以后存储数据使用

array=[NSMutableArray array];

}

 上面的代码加载了按钮和地图,并让地图显示区域调整到当前位置为中心的一个范围内,准备工作做好了,下面是draw按钮的代码,事件如下:

-(IBAction)drawFunction:(id)sender{

imageView=[[UIImageView alloc] initWithFrame:innerMap.frame];

[self.view addSubview:imageView];

imageView.userInteractionEnabled=YES;

UIGraphicsBeginImageContext(imageView.frame.size);

[imageView.image drawInRect:CGRectMake(0, 0, imageView.frame.size.width, imageView.frame.size.height)];

CGContextSetRGBFillColor(UIGraphicsGetCurrentContext(), 50, 79, 133, 1.0);

CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), [UIColor redColor].CGColor);

CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 4);

//地理坐标转换成点

testLocation.latitude=39.995012;//设定测试点的坐标是当前位置

testLocation.longitude=116.411892;

locationConverToImage=[innerMap convertCoordinate:testLocation toPointToView:imageView];

// NSLog(@”111 %f”,locationConverToImage.x);

// NSLog(@”222 %f”,locationConverToImage.y);

}

上面的方法点击后会创建一个imageView,我们会在上面来画图,同时设定了上下文和画线的宽度填充色等元素,最底下
convertCoordinate:toPointToView:
这个方法就是坐标转换的方法了,把一个经纬度坐标转化为CGPoint坐标并存储在locationConverToImage里,这里要说明一下坐标的转化了,坐标转化能做什么呢?
(1)让当前屏幕显示区域的CGPoint点坐标(x,y)值映射到当前地图可视区域同一个位置的CLLocationCoordinate2D(latitude,longitude)值,也就是让绘图层上的一点的xy值对应地图层上一点的经纬度值
(2)反之,让地图上的经纬度点坐标转换成同位置的CGPoint点坐标。
这里我觉得这个方法的功能实现的很奇妙,两个毫不相关的层就这么互通有无了,相信苹果一定利用某种算法计算了当前显示的地图区域的缩放等级并有一个经纬度范围。
总之这个draw按钮的点击创建了绘画层,也定义了一个测试的经纬度坐标点,同时把这个点转换成了imageView上面的CGPoint点
再看下Clear按钮:

-(IBAction)clearFunction:(id)sender{

[imageView removeFromSuperview];//删除绘图层

[array removeAllObjects];

[innerMap removeAnnotations:innerMap.annotations];//删除大头针

UIGraphicsEndImageContext();//删除画布

}

这个就比较简单了,剩下的就是添加touch的三个方法,begin,move,end,在begin和move的时候画图,在end的时候做判断区域的处理并添加大头针

首先是touchbegin:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

UITouch *touch = [touches anyObject];

CGPoint location = [touch locationInView:imageView];

//创建path

pathRef=CGPathCreateMutable();

CGPathMoveToPoint(pathRef, NULL, location.x, location.y);

}

在点击开始的方法里记录了点击的坐标,同时创建了一个CGPath,并设置起点为当前坐标,这个Path在手指移动的时候会跟随着改变,接下来是touchmove方法:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

UITouch *touch = [touches anyObject];

CGPoint location = [touch locationInView:imageView];

CGPoint pastLocation = [touch previousLocationInView:imageView];

//画线

CGContextMoveToPoint(UIGraphicsGetCurrentContext(), pastLocation.x, pastLocation.y);

CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), location.x, location.y);

CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);

imageView.image=UIGraphicsGetImageFromCurrentImageContext();

//更新Path

CGPathAddLineToPoint(pathRef, NULL, location.x, location.y);

}

这里的画线部分和之前的博客一样,值得注意的是每一次touchmove都会让path跟着更新,接下来是touchend方法:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

CGPathCloseSubpath(pathRef);

if (CGPathContainsPoint(pathRef, NULL, locationConverToImage, NO)) {

NSLog(@”point in path!”);

MKPointAnnotation *pointAnnotation = nil;

pointAnnotation = [[MKPointAnnotation alloc] init];

pointAnnotation.coordinate = locationManager.location.coordinate;

pointAnnotation.title = @”大头针”;

[innerMap addAnnotation:pointAnnotation];

}

}

可以看到抬手的时候判断是否在path区域内的点locationConverToImage就是测试经纬度坐标点转化完以后的点,如果在这个区域里就添加大头针,如果想让大头针有落下的动画或者自定义颜色还要加上这个代理方法:

- (MKAnnotationView*) mapView: (MKMapView*) mapView viewForAnnotation: (id<MKAnnotation>) annotation{

MKPinAnnotationView *pinView = nil;

static NSString *defaultPinID = @”com.invasivecode.pin”;

pinView = (MKPinAnnotationView *)[innerMap dequeueReusableAnnotationViewWithIdentifier:defaultPinID];

if ( pinView == nil ) pinView = [[MKPinAnnotationView alloc]

initWithAnnotation:annotation reuseIdentifier:defaultPinID];

pinView.pinColor = MKPinAnnotationColorPurple;

pinView.animatesDrop = YES;

[innerMap.userLocation setTitle:@"欧陆经典"];

[innerMap.userLocation setSubtitle:@"vsp"];

return pinView;

}

接下来要完成的是填充path颜色,增加多个点等等,有待继续完善

(转自:http://lipengxuan.easymorse.com/?p=588)

相关文章推荐

iOS之使用MapKit通过经纬度坐标画线

在使用iOS sdk自带的mapkit 需要引入mapkit头文件#import 首先定义几个全局的变量,包含map视图、线及线视图,并包含map的委托 @property (retain, non...
  • reylen
  • reylen
  • 2015年11月20日 16:19
  • 2679

ArcEngine 经纬度坐标 画线

项目需要,把Android设备上的手绘数据

在Android里如何判断一个指定的经纬度点是否落在一个多边形区域内

在lbs开发中,可能要碰到这样的问题,如何判断一个指定的经纬度点是否落在一个多边形区域内,比如我在地图上画了一个多边形区域,然后给出一个经纬度点,怎样判断这个点是否在这个多边形范围之内,由于我用的是a...

百度地图经纬度转换+反地址解析+显示可视区域内标注点+地图自动刷新+标注的聚合

一:代码简介 本次主要将百度地图的经纬度转换,反地址解析,显示可视区域内的标注点,Markers聚合等整合到了同一个jsp页面上;旨在实现在经纬度未转换的情况下,页面自动实现百度经纬度转换,添加标注...

解决高德地图锁屏黑屏定位不更新,高德地图绘制定位轨迹,高德定位判断定位停留点,高德地图将所有坐标绘制在可视区域内

本文章主要介绍 高德定位锁屏黑屏定位不更新的问题。 实现流程是:程序开始阶段正常执行定位,注册监听锁屏监听,唤醒cpu监听,当锁屏 广播每2秒发起一起单次定位唤醒。源码如下: package net....

iOS大头针(自定义大头针,定位,画线)

//自定义大头针  #import #import @interface MyAnn : NSObject MKAnnotation> ...

Android:自定义imageview实现两条线裁剪图片,不在区域内显示阴影

MainActivitypackage com.example.customimageview;import java.io.File; import java.io.FileNotFoundExce...
  • hgk324
  • hgk324
  • 2016年09月24日 21:32
  • 404

php结合mongodb判断坐标是否在指定多边形区域内的实例

之前写过一篇《mongodb 判断坐标是否在指定多边形区域内的方法》是基于mongodb实现,所有操作都是在mongodb执行。本文将使用php结合mongodb,使用php判断坐标是否在多边形区域内...
  • fdipzone
  • fdipzone
  • 2016年09月30日 21:41
  • 19124

判断一个指定的经纬坐标是否落在一个多边形区域内?

Python: def IsPtInPoly(aLon, aLat, pointList): ''' :param aLon: double 经度 :param aLat: d...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS上地图画线,画线区域内的经纬度坐标点添加大头针
举报原因:
原因补充:

(最多只允许输入30个字)