detect if a point is inside a MKPolygon overlay
I created this MKPolygon category in case anyone wants to use it. Seems to work well. You have to account for the interior polygons (i.e. holes in the polygon):
@interface MKPolygon (PointInPolygon)
-(BOOL) pointInPolygon:(CLLocationCoordinate2D) point mapView: (MKMapView*) mapView;
@end
@implementation MKPolygon (PointInPolygon)
-(BOOL) pointInPolygon:(CLLocationCoordinate2D) point mapView: (MKMapView*) mapView {
MKMapPoint mapPoint = MKMapPointForCoordinate(point);
MKPolygonView * polygonView = (MKPolygonView*)[mapView viewForOverlay:self];
CGPoint polygonViewPoint = [polygonView pointForMapPoint:mapPoint];
return CGPathContainsPoint(polygonView.path, NULL, polygonViewPoint, NO) &&
![self pointInInteriorPolygons:point mapView:mapView];
}
-(BOOL) pointInInteriorPolygons:(CLLocationCoordinate2D) point mapView: (MKMapView*) mapView {
return [self pointInInteriorPolygonIndex:0 point:point mapView:mapView];
}
-(BOOL) pointInInteriorPolygonIndex:(int) index point:(CLLocationCoordinate2D) point mapView: (MKMapView*) mapView {
if(index >= [self.interiorPolygons count])
return NO;
return [[self.interiorPolygons objectAtIndex:index] pointInPolygon:point mapView:mapView] || [self pointInInteriorPolygonIndex:(index+1) point:point mapView:mapView];
}
@end
SwiftUI - how to know if the user location is in a MKPolygon?
I don't see any code that is actually handling the location updates?
Assuming you have implemented that in your LocationManager
along the lines of:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let loc = locations.first {
self.location = loc
}
}
Your problematic line would change from:
self.isInArea = MKPolygon(coordinates: model.zona40, count: model.zona40.count).isCoordinateInsidePolyon(coordinate: locationManager)
to:
guard let c2D = self.locationManager.location?.coordinate else {
return
}
self.isInArea = MKPolygon(coordinates: model.zona40, count: model.zona40.count).isCoordinateInsidePolyon(coordinate: c2D)
If you have not already implemented the didUpdateLocations
delegate func, take a read through a Core Location tutorial or two.
How to determine if an annotation is inside of MKPolygonView (iOS)
The following converts the coordinate to a CGPoint in the polygon view and uses CGPathContainsPoint to test if that point is in the path (which may be non-rectangular):
CLLocationCoordinate2D mapCoordinate = ...; //user location or annot coord
MKMapPoint mapPoint = MKMapPointForCoordinate(mapCoordinate);
MKPolygonView *polygonView =
(MKPolygonView *)[mapView viewForOverlay:polygonOverlay];
CGPoint polygonViewPoint = [polygonView pointForMapPoint:mapPoint];
BOOL mapCoordinateIsInPolygon =
CGPathContainsPoint(polygonView.path, NULL, polygonViewPoint, NO);
This should work with any overlay view that is a subclass of MKOverlayPathView. You can actually replace MKPolygonView with MKOverlayPathView in the example.
Validate if a latlong is inside a MKPolygon in iOS
The picture shown appears to demonstrate the even-odd fill rule. By specifying FALSE
as the final parameter to CGPathContainsPoint
you've asked it to apply the winding number rule. Try passing TRUE
.
For information on the teo rules see Apple's Quartz documentation, particularly 'Filling a Path' (slightly less than halfway down).
Check if MKPolyline intersects MKPolygon
They both conform to the MKOverlay protocol. You can use the property defined on the protocol called boundingMapRect, and use it on a protocol-defined method called intersectsMapRect. More info here:
http://developer.apple.com/library/ios/#DOCUMENTATION/MapKit/Reference/MKOverlay_protocol/Reference/Reference.html
Check if a point on map lies within an overlay
Well, I figured it out finally. The code above should work as is, except that there is a missing break statement in the loop. The code as is returns only the last checked point of the poly. Inserting a test to mapCoordinateIsInPolygon and then a break statement in the inner loop leaves the loop as soon as the first test is positive, thus giving the correct result. ;-)
Detecting a point in a MKPolygon broke with iOS7 (CGPathContainsPoint)
For some reason (possibly a bug), the path
property returns NULL
in the current release of iOS 7.
A workaround is to construct your own CGPathRef
from the points
of the polygon.
With this method, you don't need a reference to the MKPolygonView
or the MKPolygonRenderer
.
For example:
CGMutablePathRef mpr = CGPathCreateMutable();
MKMapPoint *polygonPoints = myPolygon.points;
//myPolygon is the MKPolygon
for (int p=0; p < myPolygon.pointCount; p++)
{
MKMapPoint mp = polygonPoints[p];
if (p == 0)
CGPathMoveToPoint(mpr, NULL, mp.x, mp.y);
else
CGPathAddLineToPoint(mpr, NULL, mp.x, mp.y);
}
CGPoint mapPointAsCGP = CGPointMake(mapPoint.x, mapPoint.y);
//mapPoint above is the MKMapPoint of the coordinate we are testing.
//Putting it in a CGPoint because that's what CGPathContainsPoint wants.
BOOL pointIsInPolygon = CGPathContainsPoint(mpr, NULL, mapPointAsCGP, FALSE);
CGPathRelease(mpr);
This should work on iOS 6 as well.
However, you may want to do this manual construction only if the overlay view's path
property returns NULL
.
Related Topics
iOS Tesseract Ocr Image Preperation
Xcode 8, iOS 10 - "Starting Webfilter Logging for Process"
Bringing a Subview to Be in Front of All Other Views
Uiscrollview in Storyboard Not Working with iOS 8 Size Classes and Autolayout
Wait for Async Task to Finish Completion Block Before Returning in App Delegate
Watchkit Appicon - the App Icon Set Named "Appicon" Did Not Have Any Applicable Content
Where Are iOS Simulator Screenshots Stored
Change Color of Png in Buttons - iOS
How to Change Navigation Bar Color in iOS 7 or 6
Using Convertpoint to Get the Relative Position Inside a Parent Uiview
Invalid Update: Invalid Number of Items on Uicollectionview
Align Text Using Drawinrect:Withattributes:
How to Add Live Camera Preview to Uiview
iOS Avplayer Trigger Streaming Is Out of Buffer
Can't Set Titleview in the Center of Navigation Bar Because Back Button
Clean Architecture - Robert Martin - How to Connect Use Cases