0

こんにちは、setNeedsDisplayInMapRect:関数を介してマップ ビューのオーバーレイを更新するのに問題があります。関連するコードは次のとおりです。

ParkingMapViewController.m:

for (ParkingRegionOverlay *overlay in mapView.overlays) {
    [overlay setNeedsDisplayInMapRect:self.mapView.visibleMapRect];
}

//...
- (MKOverlayView *)mapView:(MKMapView *)mapView 
            viewForOverlay:(id <MKOverlay>)overlay
{   
    NSLog(@"ParkingMapViewController.m mapView:viewForOverlay");
    //...
}
//...

ParkingRegionOverlay.h:

@interface ParkingRegionOverlay : MKOverlayView <MKOverlay> {
    MKPolygon *polygon;
    MKMapRect boundingRect;
    CLLocationCoordinate2D centerCoord;
    //...
}
//...

そして、私が期待しているコンソールへの「ParkingMapViewController.m mapView:viewForOverlay」出力が得られません。デバッガーを調べて、for ループに到達して実行されていることを確認しましたが、mapView:viewForOverlay:何らかの理由で呼び出されていません。私が間違っていることを知っている人はいますか?前もって感謝します!

編集1:

デリゲート、座標、バウンディング rect を適切に設定したと思いますが、見てください...

ParkingMapViewController.h

@interface ParkingMapViewController : UIViewController <MKMapViewDelegate> {
    MKMapView *mapView;
//...

ParkingMapViewController.m:

//...
- (void)viewDidLoad {
    [super viewDidLoad];
    mapView.delegate = self;
//...

ParkingRegionOverlay.m:

//...
//initializes polygon and calculates bounding rect as well as its center coordinate
-(id)initWithPoints:(NSArray *)pointsArray andTitle:(NSString *)overlayTitle{
    MKMapPoint points[[pointsArray count]];
    double maxX = MIN_COORD_VAL;
    double minX = MAX_COORD_VAL;
    double maxY = MIN_COORD_VAL;
    double minY = MAX_COORD_VAL;
    double tempX = 0;
    double tempY = 0;

    if (self = [super init]) {
        int i = 0;
        //determine min/max extrema to help calculate the bounding rect
        for (id coordDict in pointsArray){
            tempX = [[coordDict objectForKey:@"latitude"] doubleValue];
            tempY = [[coordDict objectForKey:@"longitude"] doubleValue];
            maxX = fmax(tempX, maxX);
            minX = fmin(tempX, minX);
            maxY = fmax(tempY, maxY);
            minY = fmin(tempY, minY);

            CLLocationCoordinate2D coord = {tempX,tempY};
            points[i] = MKMapPointForCoordinate(coord);
            i++;
        }//for

        CLLocationCoordinate2D northWestCorner = CLLocationCoordinate2DMake(maxX, minY);
        CLLocationCoordinate2D southEastCorner = CLLocationCoordinate2DMake(minX, maxY);
        MKMapPoint northWestPoint = MKMapPointForCoordinate(northWestCorner);
        MKMapPoint southEastPoint = MKMapPointForCoordinate(southEastCorner);
        boundingRect = MKMapRectMake(northWestPoint.x, northWestPoint.y, 
                                     (southEastPoint.x-northWestPoint.x), 
                                     (southEastPoint.y-northWestPoint.y));

        centerCoord = CLLocationCoordinate2DMake((maxX-minX)/2,(maxY-minY)/2);
        polygon = [MKPolygon polygonWithPoints:points count:[pointsArray count]];
        polygon.title = overlayTitle;

        [self initAcceptedPermitsBasedOnTitle:overlayTitle];
    }//if

    return self;
}
//...

ありがとう。

編集2:

私が試した別の方法は役に立たなかった:

ParkingMapViewController.m

    NSArray *overlayArray = [[NSArray alloc] initWithArray:[mapView overlays]];
    [self.mapView removeOverlays:mapView.overlays];
    [self.mapView addOverlays:overlayArray];

すべてのオーバーレイを削除して再度追加しても、うまくいきません。その 3 行目が実行されると、クラッシュするだけです。何か案は?

編集3:

そのため、以前に投稿したコードを次のように変更しました。

NSArray *overlayArray = [mapView overlays];
[self.mapView removeOverlays:overlayArray];
[self.mapView addOverlays:overlayArray];

そして今、コンソールでこれを見ています:

2011-05-05 14:24:54.145 Parking[68501:207] -[NSCFNumber boundingMapRect]: unrecognized selector sent to instance 0xa9afae0
2011-05-05 14:24:54.147 Parking[68501:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber boundingMapRect]: unrecognized selector sent to instance 0xa9afae0'
4

2 に答える 2

0

座標またはboundingMapRectプロパティをMKOverlay正しく設定していない可能性があります。はMapView、ビューが表示されている可能性があると判断した場合にのみビューを要求します。表示されている四角形が と交差しない場合、ビューは要求されboundMapRectません。

また、delegateformapViewが適切に設定されていることを確認してください。

于 2011-05-05T12:20:23.140 に答える
0

だから私はそれを理解しました。必ずしも最も効率的な方法ではありませんが、私にとってはうまくいきます。これは私がしたことです:

[self.mapView removeOverlays:[mapView overlays]];
[self loadOverlaysAndAnnotations];

そしてここにあるloadOverlaysAndAnnotations

- (void)loadOverlaysAndAnnotations {

    NSError *error;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    CoreDataSingleton *coreDataSingleton = [CoreDataSingleton sharedManager];
    NSEntityDescription *entity = [NSEntityDescription 
                                   entityForName:@"ParkingLot" inManagedObjectContext:[coreDataSingleton managedObjectContext]];
    [fetchRequest setEntity:entity];
    NSArray *fetchedObjects = [[coreDataSingleton managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    for (NSManagedObject *overlayEntity in fetchedObjects) {
        NSArray *pointsArray = [NSArray arrayWithArray:[overlayEntity valueForKey:@"overlayCoordPoints"]];
        ParkingRegionOverlay *regionPolygon = [[ParkingRegionOverlay alloc] initWithPoints:pointsArray andTitle:[overlayEntity valueForKey:@"lotName"]];
        [mapView addOverlay:regionPolygon];
        [regionPolygon release];


        NSSet *annotationsSet = [NSSet setWithSet:[overlayEntity valueForKey:@"parkingAnnotations"]];
        NSArray *allAnnotations = [NSArray arrayWithArray:[annotationsSet allObjects]];
        CLLocationCoordinate2D workingCoordinate;
        for (ParkingAnnotations *annotation in allAnnotations) {
            ParkingAnnotation *parkingAnnot = [[ParkingAnnotation alloc] init];
            workingCoordinate.latitude = [[annotation latitude] doubleValue];
            workingCoordinate.longitude = [[annotation longitude] doubleValue];
            [parkingAnnot setCoordinate:workingCoordinate];
            [parkingAnnot setTitle:[overlayEntity valueForKey:@"lotName"]];
            if ([[overlayEntity valueForKey:@"lotName"] isEqualToString:@"VP 1"]) {
                [parkingAnnot setLot:lot1];
            }

            [mapView addAnnotation:parkingAnnot];
            [parkingAnnot release];
        }
    }        
    [fetchRequest release];
}//loadOverlaysAndAnnotations

つまり、新しい関数を作成する必要はなく、オーバーレイをマップ ビューにロードするために使用した関数を呼び出すだけで、問題なく動作します。これが、同様の状況で立ち往生している他の人に役立つことを願っています。

編集:

注釈とオーバーレイの両方を再読み込みしていることに注意してください。最初に注釈とオーバーレイの両方を削除せずに実行すると、再読み込み関数が何度も呼び出されるとアプリがクラッシュする可能性があります。これは私が現在経験していることです。知っておくべきことだけです。これを修正するために、1 つはオーバーレイ用、もう 1 つは適切に呼び出される注釈用の個別のロード関数を用意します。

于 2011-05-06T04:11:50.657 に答える