地图效果图
卡片上画出来的效果
需求说明:最新项目要做到像华为运动app的,运动记录显示轨迹效果。 思路:第一个点为所有点的中心点,算出连个点之间的距离。转换经纬度,得到两个点之间的x,y坐标,然后就可以连线。目前还没达到太好的效果,本文只是个抛砖引玉的作用。欢迎交流学习:QQ/微信308806988.
1、计算两个经纬度之间距离
#define PI 3.14159265358979323
-(**double**) CalculationDistanceOther_Lon1:(**double**)lon1 Other_Lat1:(**double**)lat1 self_Lon2:(**double**)lon2 self_Lat2:(**double**)lat2{
**double** er = 6371229; // 6378700.0f;
//ave. radius = 6371.315 (someone said more accurate is 6366.707)
//equatorial radius = 6378.388
//nautical mile = 1.15078
**double** radlat1 = PI*lat1/180.0f;
**double** radlat2 = PI*lat2/180.0f;
//now long.
**double** radlong1 = PI*lon1/180.0f;
**double** radlong2 = PI*lon2/180.0f;
**if**( radlat1 < 0 ) radlat1 = PI/2 + fabs(radlat1);// south
**if**( radlat1 > 0 ) radlat1 = PI/2 - fabs(radlat1);// north
**if**( radlong1 < 0 ) radlong1 = PI*2 - fabs(radlong1);//west
**if**( radlat2 < 0 ) radlat2 = PI/2 + fabs(radlat2);// south
**if**( radlat2 > 0 ) radlat2 = PI/2 - fabs(radlat2);// north
**if**( radlong2 < 0 ) radlong2 = PI*2 - fabs(radlong2);// west
//spherical coordinates x=r*cos(ag)sin(at), y=r*sin(ag)*sin(at), z=r*cos(at)
//zero ag is up so reverse lat
**double** x1 = er * cos(radlong1) * sin(radlat1);
**double** y1 = er * sin(radlong1) * sin(radlat1);
**double** z1 = er * cos(radlat1);
**double** x2 = er * cos(radlong2) * sin(radlat2);
**double** y2 = er * sin(radlong2) * sin(radlat2);
**double** z2 = er * cos(radlat2);
**double** d = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
//side, side, side, law of cosines and arccos
**double** theta = acos((er*er+er*er-d*d)/(2*er*er));
**double** dist = theta*er;
**return** dist;
}
2、经纬度值转成view的x、y值
NSMutableArray *pointAry = [NSMutableArray array];
MapLaAndLoModel *fMode = _last_ary.firstObject;//经纬度数据
NSArray *lon_lat_ary = [**self** transformLongitueAndLatitude:fMode];
**double** first_lon = [lon_lat_ary.firstObject doubleValue];
**double** first_lat = [lon_lat_ary.lastObject doubleValue];
**double** max_lon = 0.00;
**double** min_lon = 180.00;
**double** max_lat = 0.00;
**double** min_lat = 90.00;
CGFloat oldLngLineDistance = 0;
CGFloat oldLatLineDistance = 0;
**for** (NSInteger i = 1; i < _last_ary.count; i++) {
MapLaAndLoModel *lalonModel = [_last_ary objectAtIndex:i];
NSArray *lon_lat_ary_1 = [**self** transformLongitueAndLatitude:lalonModel];
**double** lon = [lon_lat_ary_1.firstObject doubleValue];
**double** lat = [lon_lat_ary_1.lastObject doubleValue];
//longitude取第一个点的经度,同一个经度计算纬度,两点之间距离,则就是y值
**double** new_lat = [**self** CalculationDistanceOther_Lon1:first_lon Other_Lat1:first_lat self_Lon2:first_lon self_Lat2:lat];
//latitude取第一个点的纬度,同一个纬度计算经度,两点之间距离,则就是x值
**double** new_lon = [**self** CalculationDistanceOther_Lon1:first_lon Other_Lat1:first_lat self_Lon2:lon self_Lat2:first_lat];
**if**(lon > max_lon){
max_lon = lon;
}
**if**(min_lon > lon){
min_lon = lon;
}
**if**(lat > max_lat){
max_lat = lat;
}
**if**(lat < min_lat){
min_lat = lat;
}
//第一次经度如果小于后面的经度, 证明是往西走. 反之往东走
**if** (first_lon > lon) {
new_lon = oldLngLineDistance - new_lon;//往西走, x取负值
}
//第一次纬度如果小于后面的纬度, 证明是往北走. 反之往南走
**if** (first_lat < lat) {
new_lat = oldLatLineDistance - new_lat;//往北走, y取负值
}
PointModel *mode = [PointModel new];
mode.x = new_lon;
mode.y = new_lat;
[pointAry addObject:mode];
}
3、计算缩放比例
//计算同一最大、最小经度两点之间到距离
**double** max_lon_distance = [**self** CalculationDistanceOther_Lon1:min_lon Other_Lat1:first_lat self_Lon2:max_lon self_Lat2:first_lat];
//计算同一最大、最小纬度两点之间到距离
**double** max_lat_distance = [**self** CalculationDistanceOther_Lon1:max_lon Other_Lat1:min_lat self_Lon2:max_lon self_Lat2:max_lat];
CGFloat b_height = 35;
CGFloat line_height = **self**.height - b_height - 15;
//画布
UIView *bgView = [[UIView alloc]initWithFrame:CGRectMake(0,0,**self**.width, line_height)];
bgView.backgroundColor = UIColor.clearColor;
CAShapeLayer *layer = [CAShapeLayer layer];
layer.strokeColor = UIColor.greenColor.CGColor;
layer.fillColor = UIColor.clearColor.CGColor;
layer.lineWidth = 2;
UIBezierPath *path = [UIBezierPath bezierPath];
CGPoint firstPoint = CGPointZero;
CGPoint endPoint = CGPointZero;
CGFloat scale_y = bgView.height / max_lat_distance;
CGFloat scale_x = bgView.width / max_lon_distance;
CGFloat zoomScale = scale_y;
**if**(scale_y < 1 && scale_x < 1){
**if**(scale_y > scale_x){
zoomScale = scale_x;
}
}**else** **if** (scale_y < 1){
zoomScale = scale_y;
}**else** **if** (scale_x < 1){
zoomScale = scale_x;
}
zoomScale *= 0.781;
4、调整位置,居中显示
NSMutableArray *point_array = [NSMutableArray arrayWithCapacity:pointAry.count];
CGFloat offset_x = 0;
CGFloat offset_y = 0;
CGFloat max_line_x = 0;
CGFloat min_line_x = bgView.width;
CGFloat max_line_y = 0;
CGFloat min_line_y = bgView.height;
**for** (NSInteger j = 0; j < pointAry.count; j++) {
PointModel *xyModel = [pointAry objectAtIndex:j];
CGFloat y = xyModel.y * zoomScale;
CGFloat x = xyModel.x * zoomScale;
**if**(max_line_x < x){
max_line_x = x;
}
**if**(min_line_x > x){
min_line_x = x;
}
**if**(max_line_y < y){
max_line_y = y;
}
**if**(min_line_y > y){
min_line_y = y;
}
CGPoint point = CGPointMake(x, y);
[point_array addObject:[NSValue valueWithCGPoint:point]];
}
**if**(max_line_x < 0 || min_line_x < 0){//在中心点左边
CGFloat all_x_distance = fabs(max_line_x) + fabs(min_line_x);
offset_x = (bgView.width - all_x_distance) * 0.5 + fabs(min_line_x);
}**else**{//在中心点右边
CGFloat all_x_distance = fabs(max_line_x) - fabs(min_line_x);
offset_x = -(max_line_x - all_x_distance * 0.5 - bgView.width * 0.5);
}
**if**(max_line_y < 0 || min_line_y < 0){
CGFloat all_y_distance = fabs(max_line_y) + fabs(min_line_y);
offset_y = (bgView.height - all_y_distance) * 0.5 + fabs(min_line_y);
}**else**{
CGFloat all_y_distance = fabs(max_line_y) - fabs(min_line_y);
offset_y = -(max_line_y - all_y_distance * 0.5 - bgView.height * 0.5);
}
5、在画布view上显示
**for** (NSInteger i = 0; i < point_array.count; i++) {
CGPoint point = [[point_array objectAtIndex:i] CGPointValue];
CGPoint n_point = CGPointMake(point.x + offset_x, point.y + offset_y);
**if** (i == 0) {
[path moveToPoint:n_point];
firstPoint = n_point;
}**else**{
[path addLineToPoint:n_point];
}
**if**(i == point_array.count - 1){
endPoint = n_point;
}
}
layer.path = path.CGPath;
[bgView.layer addSublayer:layer];
//结束圆环
UIColor *r_cl = [UIColor.redColor colorWithAlphaComponent:0.8];
CAShapeLayer *cirlLayer = [**self** addCirlViewColor:r_cl point:endPoint];
[bgView.layer addSublayer:cirlLayer];
//开始圆环
CAShapeLayer *cirlLayer2 = [**self** addCirlViewColor:RGB(117, 84, 60) point:firstPoint];
[bgView.layer addSublayer:cirlLayer2];
[**self** addSubview:bgView];
结束语:该做法尚有不足之处,请不吝指教。