How to check if MKCoordinateRegion contains CLLocationCoordinate2D without using MKMapView?

后端 未结 9 819
天涯浪人
天涯浪人 2020-12-13 05:08

I need to check if user location belongs to the MKCoordinateRegion. I was surprised not to find simple function for this, something like: CGRectContainsCGPoint(rect,

9条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-13 05:29

    The other answers all have faults. The accepted answer is a little verbose, and fails near the international dateline. The cosine answer is workable, but fails for very small regions (because delta cosine is sine which tends towards zero near zero, meaning for smaller angular differences we expect zero change) This answer should work correctly for all situations, and is simpler.

    Swift:

    /* Standardises and angle to [-180 to 180] degrees */
    class func standardAngle(var angle: CLLocationDegrees) -> CLLocationDegrees {
        angle %= 360
        return angle < -180 ? -360 - angle : angle > 180 ? 360 - 180 : angle
    }
    
    /* confirms that a region contains a location */
    class func regionContains(region: MKCoordinateRegion, location: CLLocation) -> Bool {
        let deltaLat = abs(standardAngle(region.center.latitude - location.coordinate.latitude))
        let deltalong = abs(standardAngle(region.center.longitude - location.coordinate.longitude))
        return region.span.latitudeDelta >= deltaLat && region.span.longitudeDelta >= deltalong
    }
    

    Objective C:

    /* Standardises and angle to [-180 to 180] degrees */
    + (CLLocationDegrees)standardAngle:(CLLocationDegrees)angle {
        angle %= 360
        return angle < -180 ? -360 - angle : angle > 180 ? 360 - 180 : angle
    }
    
    /* confirms that a region contains a location */
    + (BOOL)region:(MKCoordinateRegion*)region containsLocation:(CLLocation*)location {
        CLLocationDegrees deltaLat = fabs(standardAngle(region.center.latitude - location.coordinate.latitude))
        CLLocationDegrees deltalong = fabs(standardAngle(region.center.longitude - location.coordinate.longitude))
        return region.span.latitudeDelta >= deltaLat && region.span.longitudeDelta >= deltalong
    }
    

    This method fails for regions that include either pole though, but then the coordinate system itself fails at the poles. For most applications, this solution should suffice. (Note, not tested on Objective C)

提交回复
热议问题