How do I determine if a coordinate is in the curre

2020-02-09 06:01发布

I have a list of several hundred locations and only want to display an MKPinAnnotation for those locations currently on the screen. The screen starts with the user's current location with a 2 mile radius. Of course, the user can scroll, and zoom on the screen. Right now, I wait for a map update event, and then loop through my location list, and check the coordinates like this:

-(void)mapViewDidFinishLoadingMap:(MKMapView *)mapView {
  CGPoint point;
  CLLocationCoordinate2D coordinate;

  . . .
  /* in location loop */
  coordinate.latitude = [nextLocation getLatitude];
  coordinate.longitude = [nextLocation getLongitude];

  /* Determine if point is in view. Is there a better way then this? */
  point = [mapView convertCoordinate:coordinate toPointToView:nil];
  if( (point.x > 0) && (point.y>0) ) {
    /* Add coordinate to array that is later added to mapView */
  }

So I am asking convertCoordinate where the point would be on the screen(unless I misunderstand this method which is very possible). If the coordinate isn't on the screen, then I never add it to the mapView.

So my question, is this the correct way to determine if a location's lat/long would appear in the current view and should be added to the the mapView? Or should I be doing this in a different way?

3条回答
做个烂人
2楼-- · 2020-02-09 06:12

In your code, you should pass a view for the toPointToView: option. I gave it my mapView. You have to specify an upper bound for the x and y too.

Here's some code which worked for me (told me the currently visible annotations on my map, while looping through the annotation):

for (Shop *shop in self.shops) {
    ShopAnnotation *ann = [ShopAnnotation annotationWithShop:shop];
    [self.mapView addAnnotation:ann];

    CGPoint annPoint = [self.mapView convertCoordinate:ann.coordinate 
            toPointToView:self.mapView];

    if (annPoint.x > 0.0 && annPoint.y > 0.0 && 
            annPoint.x < self.mapView.frame.size.width && 
            annPoint.y < self.mapView.frame.size.height) {
        NSLog(@"%@ Coordinate: %f %f", ann.title, annPoint.x, annPoint.y);
    }
}
查看更多
趁早两清
3楼-- · 2020-02-09 06:13

After a little bit of reading I can't find anything that says this is a bad idea. I've done a bit of testing in my app and I always get correct results. The app loads much quicker when I only add coordinates that will show up in the currently visible map region instead of all the 300+ coordinates at once.

What I was looking for was a method like [mapView isCoordinateInVisibleRegion:myCoordinate], but so far this method is quick and seems accurate.

I've also changed the title to read "in the visible map region" instead of the previous because I think the incorrect title may have confused my meaning.

查看更多
祖国的老花朵
4楼-- · 2020-02-09 06:20

I know this is an old thread, not sure what was available back then... But you should rather do:

// -- Your previous code and CLLocationCoordinate2D init --
MKMapRect visibleRect = [mapView visibleMapRect];
if(MKMapRectContainsPoint(visibleRect, MKMapPointForCoordinate(coordinate))) {

    // Do your stuff

}

No need to convert back to the screen space. Also I am not sure the reason why you are trying to do this, I think this is strange to not add annotations when they are not on the screen... MapKit already optimizes this and only creates (and recycles) annotation views that are visible.

查看更多
登录 后发表回答