gpt4 book ai didi

iphone - 仅在叠加层内显示注释

转载 作者:行者123 更新时间:2023-11-29 13:44:11 26 4
gpt4 key购买 nike

在我的 map 中,我必须通过 URL 显示来自 kml 文件的注释。我还需要仅显示多边形或圆形区域内的注释(如果用户绘制了两个叠加层,则同时显示两者)。

我已经看到问题How to determine if an annotation is inside of MKPolygonView (iOS) , 但我有两个困惑:

  1. 关于注解坐标,我应该使用addAnnotation方法中的注解坐标吗?
  2. 在提到的问题中创建了一个新的叠加层,但我在其他地方创建了两个不同的叠加层。所以我的问题是:什么地方最适合放置这段代码(或类似的东西)?

编辑:我创建了一些代码:

-(IBAction)showKmlData:(id)sender
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"KMLGenerator" ofType:@"kml"];

kml = [[KMLParser parseKMLAtPath:path] retain];

NSArray *annotationsImmut = [kml points];
//[mapview addAnnotations:annotations]; not anymore
NSMutableArray *annotations = [annotationsImmut mutableCopy];
[self filterAnnotations:annotations];

MKMapRect flyTo = MKMapRectNull;

for (id <MKAnnotation> annotation in annotations) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
if (MKMapRectIsNull(flyTo)) {
flyTo = pointRect;
} else {
flyTo = MKMapRectUnion(flyTo, pointRect);
}
}

mapview.visibleMapRect = flyTo;
}


-(void)filterAnnotations:(NSMutableArray *)annotationsToFilter {

for (int i=0; i<[annotationsToFilter count]; i++) {

CLLocationCoordinate2D mapCoordinate = [[annotationsToFilter objectAtIndex:i] coordinate];

MKMapPoint mapPoint = MKMapPointForCoordinate(mapCoordinate);

MKPolygonView *polygonView =
(MKPolygonView *)[mapView viewForOverlay:polygonOverlay];

MKCircleView *circleView =
(MKCircleView *)[mapView viewForOverlay:circleOverlay];

CGPoint polygonViewPoint = [polygonView pointForMapPoint:mapPoint];
CGPoint circleViewPoint = [circleView pointForMapPoint:mapPoint];

BOOL mapCoordinateIsInPolygon =
CGPathContainsPoint(polygonView.path, NULL, polygonViewPoint, NO);

BOOL mapCoordinateIsInCircle =
CGPathContainsPoint(circleView.path, NULL, circleViewPoint, NO);

if( mapCoordinateIsInPolygon || mapCoordinateIsInCircle )
[annotationsToFilter removeObjectAtIndex:i];
}
[mapView addAnnotations:annotationsToFilter];
}

EDIT Nr.2 这是我对 viewForOverlay 委托(delegate)方法的实现。我看到了我创建的覆盖图、圆形和多边形。我看到了所有注释。所有这些,覆盖图内部和外部的注释...

-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay 
{
MKCircleView* circleView = [[[MKCircleView alloc] initWithOverlay:overlay] autorelease];
circleOverlay = circleView;
circleView.fillColor = [UIColor blueColor];
circleView.strokeColor = [UIColor blueColor];
circleView.lineWidth = 5.0;
circleView.alpha = 0.20;

MKPolygonView *polygonView = [[[MKPolygonView alloc] initWithOverlay:overlay] autorelease];
polygonOverlay = polygonView;
polygonView.fillColor = [UIColor blueColor];
polygonView.strokeColor = [UIColor blueColor];
polygonView.lineWidth = 5.0;
polygonView.alpha = 0.20;


if ([overlay isKindOfClass:[MKCircle class]])
{
return circleView;
}

else
return polygonView;

最佳答案

总的来说,这看起来不错,但是 filterAnnotations 方法中存在一个问题,即如何从 annotationsToFilter 数组中删除注释。

将会发生的是一些注释将被跳过并且永远不会通过检查。

例如:

  • 假设有 5 个注释(0=A、1=B、2=C、3=D、4=E)
  • for 循环从索引 0 开始,“A”满足删除条件
  • “A”从数组中删除,现在其他注释向下移动一个索引,因此删除后数组为:(0=B, 1=C, 2=D, 3=E)
  • 现在 for 循环转到下一个索引 1(所以注释 C 被选中)
  • 所以注释 B 被跳过并且永远不会被检查

解决此问题的一种方法是将要保留的注释收集到另一个数组“annotationsToAdd”中,而不是将它们从原始数组中删除,然后将 annotationsToAdd 传递给 addAnnotations 方法。

以下是建议的修改。我还建议将 viewForOverlay 调用移到 for 循环之外,因为这些引用在循环期间不会更改,因此无需重复调用它们。

-(void)filterAnnotations:(NSMutableArray *)annotationsToFilter 
{
NSMutableArray *annotationsToAdd = [NSMutableArray array];

//Get a reference to the overlay views OUTSIDE the for-loop since
//they will remain constant so there's no need to keep calling
//viewForOverlay repeatedly...
MKPolygonView *polygonView = (MKPolygonView *)[mapView viewForOverlay:polygonOverlay];

MKCircleView *circleView = (MKCircleView *)[mapView viewForOverlay:circleOverlay];

for (int i=0; i < [annotationsToFilter count]; i++)
{
//get a handy reference to the annotation at the current index...
id<MKAnnotation> currentAnnotation = [annotationsToFilter objectAtIndex:i];

CLLocationCoordinate2D mapCoordinate = [currentAnnotation coordinate];

MKMapPoint mapPoint = MKMapPointForCoordinate(mapCoordinate);

CGPoint polygonViewPoint = [polygonView pointForMapPoint:mapPoint];
CGPoint circleViewPoint = [circleView pointForMapPoint:mapPoint];

BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polygonView.path, NULL, polygonViewPoint, NO);

BOOL mapCoordinateIsInCircle = CGPathContainsPoint(circleView.path, NULL, circleViewPoint, NO);

if ( !mapCoordinateIsInPolygon && !mapCoordinateIsInCircle )
//Note the reversed if-condition because now
//we are finding annotations we want to KEEP
{
[annotationsToAdd addObject:currentAnnotation];
}
}

[mapView addAnnotations:annotationsToAdd];
}

此外,我注意到在 showKmlData 方法中您使用的是变量 mapview 但在 filterAnnotations 中它是 mapView(大写 V)。希望编译器会就此向您发出警告。


附加信息:
根据您的评论和您添加到问题中的 viewForOverlay 代码...

首先,您得到的编译器警告 class 'MKPolygonView' does not implement the 'MKOverlay' protocol 暗示变量 polygonOverlaycircleOverlay 被声明为 MKPolygonViewMKCircleView 而不是 MKPolygonMKCircle

其次,viewForOverlay委托(delegate)方法中的代码是错误的。它会尝试为传入的任何 overlay 创建圆形和多边形 View ,然后 检查覆盖层的类别。它似乎也在保存对覆盖层 view 的引用,但其余代码假定我们保留对 overlay 的引用(MKOverlay 对象——不是 MKOverlayView)。

尝试以下更改...

//polygonOverlay and circleOverlay should be declared as MKOverlay objects...
@property (nonatomic, retain) MKPolygon *polygonOverlay;
@property (nonatomic, retain) MKCircle *circleOverlay;

//save a reference to them when you call addOverlay...
self.polygonOverlay = [MKPolygon polygonWithCoordinates:polyCoords count:coordsCount];
[mapView addOverlay:polygonOverlay];
self.circleOverlay = [MKCircle circleWithCenterCoordinate:cirleCenter radius:circleRadius];
[mapView addOverlay:circleOverlay];

//the viewForOverlay delegate method...
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay
{
if ([overlay isKindOfClass:[MKCircle class]])
{
MKCircleView* circleView = [[[MKCircleView alloc] initWithOverlay:overlay] autorelease];
circleView.fillColor = [UIColor blueColor];
circleView.strokeColor = [UIColor blueColor];
circleView.lineWidth = 5.0;
circleView.alpha = 0.20;
return circleView;
}
else
if ([overlay isKindOfClass:[MKPolygon class]])
{
MKPolygonView *polygonView = [[[MKPolygonView alloc] initWithOverlay:overlay] autorelease];
polygonView.fillColor = [UIColor blueColor];
polygonView.strokeColor = [UIColor blueColor];
polygonView.lineWidth = 5.0;
polygonView.alpha = 0.20;
return polygonView;
}

return nil;
}

您还在编辑中提到“我看到了叠加层、圆形和多边形”。听起来您正在创建多个圆圈和/或多边形叠加层。在那种情况下,只有一个 polygonOverlay 和 circleOverlay 变量将不起作用。

如果每种类型确实有多个叠加层,则不要存储对叠加层的引用。相反,在 filterAnnotations 方法中,对于每个 注释,遍历 mapView.overlays 数组并执行 viewForOverlay和嵌套循环中的多边形点测试。

关于iphone - 仅在叠加层内显示注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8138037/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com