我可以动态放大/缩小在UIMapView上绘制的非对称多边形吗?

时间:2014-04-15 20:18:40

标签: ios iphone objective-c mkmapview

我试图首先在UIMapView上绘制一个非对称多边形,使用MKPolygon动态叠加它。之后,最终用户应该能够放大/缩小该特定区域,而其余的地图区域保持无效。

从最终用户的角度来看,该人应该能够在地图视图上使用他的手指绘制一些区域,然后仅在其他区域不受缩放操作影响的情况下缩放该特定区域。

1 个答案:

答案 0 :(得分:3)

据我所知,没有内置方法可以做到这一点。 此外,官方文件说明:

  

您可以按原样使用此类来显示地图信息并操作应用程序中的地图内容。您可以将地图置于给定坐标的中心,指定要显示的区域的大小,并使用自定义信息注释地图。

所以,要做你想要达到的目标,你需要使用两个MKMapView,一个在另一个之上。

项目链接

我制作了一个简单的项目来向您展示功能,您可以在此处找到它:https://github.com/leonardfactory/mapview-polygon-mask

截图

在这里,您可以看到内部mapView在随机多边形中显示缩放地图。 iPhone screenshot with two MKMapView

解释

开始以编程方式或使用故事板添加两个MKMapView。 在此之后,您可以使用MKMapView屏蔽最顶层的CAShapeLayer,该路径已使用MKPolygon中的点设置。

MKPolygon但是只存储MKMapPoint,所以我们需要在CGPoint中对它们进行转换。我们能做什么?

执行此操作的有用方法由MKMapView本身convertCoordinate:toPointInView:提供,它将CLLocationCoordinate2D点转换为普通CGPoint,例如我们可以编写如下方法:

/**
 *  Convert between MKMapPoint and CGPoint, to be used as masking path point.
 *
 *  @param point The MKMapPoint to be converted
 *
 *  @return The CGPoint, converted in UIView coords from MKMapPoint provided
 */
- (CGPoint) convertPointToMapView:(MKMapPoint) point
{
    return [self.mainMapView convertCoordinate:MKCoordinateForMapPoint(point) toPointToView:self.mainMapView];
}

给定一个多边形,你只需要使用这个辅助方法创建一个CAShapeLayer路径,并将其作为掩码应用到另一个MKMapView,如下所示:

// Create a CAShapeLayer to hold masking path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
CGMutablePathRef mask   = CGPathCreateMutable();

// First point...
CGPoint firstPoint      = [self convertPointToMapView:polygon.points[0]];
CGPathMoveToPoint(mask, NULL, firstPoint.x, firstPoint.y);

// Then with some simple CG functions we can draw all the mask
for(NSUInteger i = 0; i < polygon.pointCount - 1; i++)
{
    CGPoint nextPoint   = [self convertPointToMapView:polygon.points[i+1]];
    CGPathAddLineToPoint(mask, NULL, nextPoint.x, nextPoint.y);
}

// Close path
CGPathCloseSubpath(mask);

maskLayer.path  = mask;
CGPathRelease(mask);

// Mask the second MKMapView
self.backgroundMapView.layer.mask           = maskLayer;

有些注意事项:

  • polygon是MKPolygon。如果你需要从点击中绘制一个,你可以使用MKMapView方法convertPoint:toCoordinateInView:,它与我之前使用的方法converCoordinate:toPointInView完全相反。

  • polygon.pointsMKMapPoint的C数组(因此其类型为MKMapPoint *