效果图
D6F43000-961E-456F-803C-F025F4E7690F.png
#import "UCGridVC.h"
#import "UCGriddAnnotation.h"
#import "ZTBezierPathHelper.h"//画曲线
#import "SYMapHelper.h"
@interface UCGridVC ()<MKMapViewDelegate>
@property(nonatomic,strong)MKMapView *mapView;//地图
@end
@implementation UCGridVC
- (void)dealloc
{
_mapView = nil;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self createUI];
[self addAnnotations];
// Do any additional setup after loading the view.
}
#pragma mark UI
- (void)createUI
{
[self.view addSubview:self.mapView];
}
#pragma mark 地图
//地图
- (MKMapView *)mapView
{
if (_mapView == nil) {
_mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
_mapView.delegate=self;//设置代理
_mapView.mapType=MKMapTypeStandard;//设置地图类型
_mapView.showsBuildings=NO;
_mapView.showsUserLocation=NO;//在地图上显示用户当前位置
_mapView.showsCompass = NO;//指南针隐藏
}
return _mapView;
}
#pragma mark 添加网点大头针
//添加大头针
- (void)addAnnotations
{
//清除大头针和线
[self.mapView removeAnnotations:self.mapView.annotations];
[self.mapView removeOverlays:self.mapView.overlays];
//设置中心点
// MKCoordinateRegion region;
// region.span = MKCoordinateSpanMake(0.5, 0.5);
// region.center = CLLocationCoordinate2DMake(31.165456, 121.401279);
// [self.mapView setRegion:region animated:YES];
NSMutableArray *coor = [NSMutableArray array];
[coor addObject:@{@"lat":@(31.163982907147894),@"lng":@(121.30678802929651)}];
[coor addObject:@{@"lat":@(32.163982907147894),@"lng":@(121.30678802929651)}];
[coor addObject:@{@"lat":@(33.163982907147894),@"lng":@(121.30678802929651)}];
[coor addObject:@{@"lat":@(34.163982907147894),@"lng":@(121.30678802929651)}];
[coor addObject:@{@"lat":@(35.163982907147894),@"lng":@(121.30678802929651)}];
[coor addObject:@{@"lat":@(36.163982907147894),@"lng":@(121.30678802929651)}];
CLLocationCoordinate2D coordinates[(6)];
coordinates[0] = CLLocationCoordinate2DMake(31.163982907147894, 121.30678802929651);
coordinates[1] = CLLocationCoordinate2DMake(32.163982907147894, 121.30678802929651);
coordinates[2] = CLLocationCoordinate2DMake(33.163982907147894, 121.30678802929651);
coordinates[3] = CLLocationCoordinate2DMake(34.163982907147894, 121.30678802929651);
coordinates[4] = CLLocationCoordinate2DMake(35.163982907147894, 121.30678802929651);
coordinates[5] = CLLocationCoordinate2DMake(36.163982907147894, 121.30678802929651);
MKCoordinateRegion region=[SYMapHelper calculate:coordinates count:5 latitudeDeltaAdd:0.1f longitudeDeltaAdd:0.1f];
NSLog(@"%f %f %f %f",region.center.latitude,region.center.longitude,region.span.latitudeDelta,region.span.longitudeDelta);
if (region.span.latitudeDelta < 0.035) {
region.span.latitudeDelta = 0.035;
}
if (region.span.longitudeDelta < 0.04) {
region.span.longitudeDelta = 0.04;
}
region = [_mapView regionThatFits:region];
NSLog(@"%f %f %f %f",region.center.latitude,region.center.longitude,region.span.latitudeDelta,region.span.longitudeDelta);
if (isnan(region.span.latitudeDelta) || isnan(region.span.longitudeDelta)) {
//如果在这里操作,就会崩溃,抛出异常
}else{
// [self.mapView setRegion:region animated:NO];
[self.mapView setRegion:region];
}
CLLocationDistance kilometers = 0.0;
for (int i = 0; i < coor.count; i++) {
NSDictionary *dic = coor[I];
double lat = [dic[@"lat"] doubleValue];
double lng = [dic[@"lng"] doubleValue];
CLLocation *orig=[[CLLocation alloc] initWithLatitude:31.165456 longitude:121.401279];
CLLocation* dist=[[CLLocation alloc] initWithLatitude:lat longitude:lng];
if (kilometers != 0) {
if (kilometers > [orig distanceFromLocation:dist]) {
kilometers=[orig distanceFromLocation:dist];
}
}else{
kilometers=[orig distanceFromLocation:dist];
}
NSLog(@"距离: = %f",kilometers);
[self drawCurveLat:lat lng:lng];
}
//构造圆
MKCircle *circle = [MKCircle circleWithCenterCoordinate:CLLocationCoordinate2DMake(31.165456, 121.401279) radius:kilometers];
circle.title = @"A";
//在地图上添加圆
[_mapView addOverlay: circle];
}
//画线和点
- (void)drawCurveLat:(double)lat lng:(double)lng
{
//大头针
CLLocationCoordinate2D location1= CLLocationCoordinate2DMake(lat,lng);
UCGriddAnnotation *annotation1= [[UCGriddAnnotation alloc] init];//配套大仓
annotation1.coordinate = location1;
[self.mapView addAnnotation:annotation1];
//画曲线
CLLocationCoordinate2D startLocation = CLLocationCoordinate2DMake(31.165456, 121.401279);
CLLocationCoordinate2D endLocation= CLLocationCoordinate2DMake(lat, lng);
NSMutableArray *bezierPaths=[ZTBezierPathHelper bezierPath:startLocation targetPoint:endLocation clockwise:YES];
CLLocationCoordinate2D pointsToUse[bezierPaths.count];
for (int i = 0; i < bezierPaths.count; i++) {
pointsToUse[i] = ((CLLocation *)[bezierPaths objectAtIndex:i]).coordinate;
}
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:pointsToUse count:bezierPaths.count];
[self.mapView addOverlay:polyline];
}
//这样就在地图上面增加了一个圆形覆盖。但是就这样的画我们是看不到的。需要实现代理方法,去设置背景色,线宽什么的。
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKCircle class]])
{
MKCircleRenderer *circleRenderer = [[MKCircleRenderer alloc] initWithCircle:overlay];
circleRenderer.lineWidth = 1.0f;
circleRenderer.strokeColor =[UIColor colorWithHex:(0x04A504)];
return circleRenderer;
}else if ([overlay isKindOfClass:MKPolyline.class]) {
MKPolylineRenderer *lineView = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
lineView.strokeColor = [UIColor greenColor];
lineView.lineWidth=1.0f;
return lineView;
}
return nil;
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *key1=@"current";
MKAnnotationView *annotationView= (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:key1];
//如果缓存池中不存在则新建
if (annotationView == nil) {
annotationView=[[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:key1];
}
annotationView.image=[UIImage imageNamed:@"bigGlodOneIcon"];//设置大头针视图的图片
return annotationView;
}
// 选中大头针
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
NSLog(@"选中大头针");
}
// 取消选中大头针
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view{
// self.hintView.hidden=YES;
NSLog(@"取消选中大头针");
}
//自定义大头针不能使用系统的MKPinAnnotationView来添加从天儿降的效果,只能自己添加动画
#pragma mark MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
}
//计算曲线的点.h文件
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface ZTBezierPathHelper : NSObject
+(NSMutableArray *)bezierPath:(CLLocationCoordinate2D)p1 targetPoint:(CLLocationCoordinate2D)p2 clockwise:(BOOL)isClockWise;
@end
//计算曲线的点.m文件
#import "ZTBezierPathHelper.h"
//angle of the auxiliaty point between start point and end point
#define ANGEL_OF_AUXILIARY_POINT 30
@implementation ZTBezierPathHelper
/**
* p1 -> 起始点 CLLocationCoordinate2D
*
* p2 -> 结束点 CLLocationCoordinate2D
*
* isClockWise -> 是否顺时针方向 YES NO
*/
+(NSMutableArray *)bezierPath:(CLLocationCoordinate2D)p1 targetPoint:(CLLocationCoordinate2D)p2 clockwise:(BOOL)isClockWise{
//get the auxiliary point
CLLocationCoordinate2D auxiliaryPoint = [self fetchThirdPointByLocations:p1 withEndLocation:p2 withAngle:ANGEL_OF_AUXILIARY_POINT clockwise:isClockWise];
float bezier1x;
float bezier1y;
float bezier2x;
float bezier2y;
NSMutableArray *targetPoints=[NSMutableArray arrayWithCapacity:3];
float bezier_x,bezier_y;
float t = 0;
//t between 0.01 and 1
while ( [targetPoints count]<=100 ) {
//get the start point of a Bezier curve
bezier1x = p1.longitude + ( auxiliaryPoint.longitude - p1.longitude ) * t;
bezier1y = p1.latitude + ( auxiliaryPoint.latitude - p1.latitude ) * t;
//get the end point of a Bezier curve
bezier2x = auxiliaryPoint.longitude + ( p2.longitude - auxiliaryPoint.longitude ) * t;
bezier2y = auxiliaryPoint.latitude + ( p2.latitude - auxiliaryPoint.latitude ) * t;
//get the point of quadratic Bezier curve
bezier_x = bezier1x + ( bezier2x - bezier1x ) * t;
bezier_y = bezier1y + ( bezier2y - bezier1y ) * t;
CLLocation *bezierPoint=[[CLLocation alloc] initWithLatitude:bezier_y longitude:bezier_x];
[targetPoints addObject:bezierPoint];
t += 0.01f;
}
return targetPoints;
}
+(CLLocationCoordinate2D)fetchThirdPointByLocations:(CLLocationCoordinate2D)startLoc withEndLocation:(CLLocationCoordinate2D)endLoc withAngle:(float)angle clockwise:(BOOL)isClockWise{
CLLocationCoordinate2D target;
//angle between the two points
double btpAngle=0.0;
btpAngle=atan2(fabs(startLoc.latitude-endLoc.latitude) , fabs(startLoc.longitude-endLoc.longitude))*180/M_PI;
//center point
CLLocationCoordinate2D center=CLLocationCoordinate2DMake((startLoc.latitude+endLoc.latitude)/2.0, (startLoc.longitude+endLoc.longitude)/2.0);
//distance between the two points
double distance=sqrtf((startLoc.latitude-endLoc.latitude)*(startLoc.latitude-endLoc.latitude)+(startLoc.longitude-endLoc.longitude)*(startLoc.longitude-endLoc.longitude));
//distance taget point between and center point
double adis=(distance/2.0)*tan(angle*M_PI/180);
//target distance longt and lat
double longt=adis*cosf((90-btpAngle)*M_PI/180);
double lat=adis*sinf((90-btpAngle)*M_PI/180);
if (startLoc.longitude>endLoc.longitude) {
isClockWise=!isClockWise;
}
//to get the right side of target
if (isClockWise) {
target.latitude=center.latitude+lat;
target.longitude=center.longitude+longt;
}else{
target.latitude=center.latitude-lat;
target.longitude=center.longitude-longt;
}
//avoid the target out of the map
if (target.latitude>90) {
target.latitude=90.0f;
}else if (target.latitude<-90){
target.latitude=-90.0f;
}
if (target.longitude>180) {
target.longitude=target.longitude-360.0;
}else if (target.longitude<-180){
target.longitude=360.0f+target.longitude;
}
return target;
}
@end
动态计算缩放级别和中心点.h文件
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#import <MAMapKit/MAMapKit.h>
@interface SYMapHelper : NSObject
+(MKCoordinateRegion )calculate:(CLLocationCoordinate2D [])coordinates count:(NSInteger)count latitudeDeltaAdd:(double)latitudeDeltaAdd longitudeDeltaAdd:(double)longitudeDeltaAdd;
@end
动态计算缩放级别和中心点.m文件
#import "SYMapHelper.h"
@implementation SYMapHelper
+(MKCoordinateRegion )calculate:(CLLocationCoordinate2D [])coordinates count:(NSInteger)count latitudeDeltaAdd:(double)latitudeDeltaAdd longitudeDeltaAdd:(double)longitudeDeltaAdd{
CLLocationDegrees minLat = 0.0;
CLLocationDegrees maxLat=0.0;
CLLocationDegrees minLon=0.0;
CLLocationDegrees maxLon=0.0;
for (int i=0; i<count; i++) {
CLLocationCoordinate2D coordinate=coordinates[I];
if (i==0) {
minLat =coordinate.latitude;
maxLat = coordinate.latitude;
minLon = coordinate.longitude;
maxLon = coordinate.longitude;
}else{
//对比筛选出最小纬度,最大纬度;最小经度,最大经度
minLat = MIN(minLat, coordinate.latitude);
maxLat = MAX(maxLat, coordinate.latitude);
minLon = MIN(minLon, coordinate.longitude);
maxLon = MAX(maxLon, coordinate.longitude);
}
}
CLLocationCoordinate2D centCoor;
centCoor.latitude = (CLLocationDegrees)((maxLat+minLat) * 0.5f);
centCoor.longitude = (CLLocationDegrees)((maxLon+minLon) * 0.5f);
MKCoordinateSpan span;
span.latitudeDelta = (maxLat - minLat) * 2;
span.longitudeDelta = (maxLon - minLon) * 2;
// span.latitudeDelta = maxLat - minLat+latitudeDeltaAdd;// 边缘坐标 不被边界覆盖
// span.longitudeDelta = maxLon - minLon+longitudeDeltaAdd;
//得出数据的坐标区域
MKCoordinateRegion center_region = MKCoordinateRegionMake(centCoor, span);
return center_region ;
}
@end
网友评论