SwingerDinger
SwingerDinger

Reputation: 276

How to do an action if location hits custom area

I need some help combining zipcode or current location values with an responding action for an custom area. Thought it was called a Polygon Class. Correct me if I am wrong.

For example: I have these following locations. If the users input falls in the following locations. There must be an action.

(52.38434879837112, 4.882092475891113)(52.38036714957116, 4.888787269592285)(52.37964674712061, 4.890203475952148)(52.37891323436772, 4.893829822540283)(52.38018377551705, 4.895482063293457)(52.38163764888611, 4.891576766967773)(52.38241040893942, 4.889967441558838)(52.38284262476619, 4.890375137329102)(52.384977446937405, 4.890353679656982)(52.38694191601119, 4.890375137329102)(52.38828425293476, 4.890316128730774)(52.38823841771291, 4.889897704124451)(52.388035432586925, 4.886292815208435)(52.38811400758514, 4.885584712028503)(52.38819585639288, 4.884763956069946)(52.3877014872842, 4.884393811225891)(52.386264184057815, 4.88343358039856)(52.386120123751006, 4.883519411087036)(52.38551768464715, 4.883063435554504)(52.38496107599452, 4.882376790046692)(52.3845125097973, 4.882033467292786)

Wat are the possibilities for this in xcode? Or do I need the do this in other coding languages? Might be useful to do this in HTML and implement this in the UIWebView?

Update 1:

I've got the Polygon Map working. Only thing is, I don't know how to make a proper annotation and let it check the Polygon area. I get a samantic issue with MKMapPoint *mapPoint = MKMapPointForCoordinate(CLLocationCoordinate2DMake(52.366243, 4.891097)); which says it's a incompatible type of 'MKMapPoint'.

What I do wrong?

This is btw, 1 of the polygons in the map. How does the CGPathContainsPoint code check multiple polygons?

    CLLocationCoordinate2D roodPoly2[8];

    roodPoly2[0] = CLLocationCoordinate2DMake(52.36715572007325, 4.889763593673706);
    roodPoly2[1] = CLLocationCoordinate2DMake(52.367037801571975, 4.889838695526123);
    roodPoly2[2] = CLLocationCoordinate2DMake(52.36681506576634, 4.891244173049927);
    roodPoly2[3] = CLLocationCoordinate2DMake(52.3667561061004, 4.893143177032471);
    roodPoly2[4] = CLLocationCoordinate2DMake(52.365314845350156, 4.892692565917969);
    roodPoly2[5] = CLLocationCoordinate2DMake(52.36555724249258, 4.890578985214233);
    roodPoly2[6] = CLLocationCoordinate2DMake(52.366729901779145, 4.888583421707153);
    roodPoly2[7] = CLLocationCoordinate2DMake(52.36707710777403, 4.889581203460693);

    MKPolygon *roodpoly2 = [MKPolygon polygonWithCoordinates:roodPoly2 count:8];
    roodpoly2.title = @"Dinsdag & Vrijdag";
    [myMapView addOverlay:roodpoly2];

    MKMapPoint *mapPoint = MKMapPointForCoordinate(CLLocationCoordinate2DMake(52.366243, 4.891097));

    CGMutablePathRef mpr = CGPathCreateMutable();

    MKMapPoint *polygonPoints = roodpoly2.points;
    //myPolygon is the MKPolygon

    for (int p=0; p < roodpoly2.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);

}

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
    if ([overlay isKindOfClass:[MKPolygon class]])
    {
        MKPolygonView* aView = [[MKPolygonView alloc] initWithPolygon:       (MKPolygon*)overlay];

        aView.fillColor = [[UIColor greenColor] colorWithAlphaComponent:0.2];
        aView.strokeColor = [[UIColor greenColor] colorWithAlphaComponent:0.7];
        aView.lineWidth = 3;

        return aView;
    }
    return nil;
}

Upvotes: 1

Views: 428

Answers (2)

user467105
user467105

Reputation:

First, the compiler error "incompatible type MKMapPoint" on this line:

MKMapPoint *mapPoint = MKMapPointForCoordinate(...);

is because MKMapPointForCoordinate returns a plain MKMapPoint struct but you've declared mapPoint as a pointer to an MKMapPoint struct so it's "incompatible".

Don't declare mapPoint as a pointer (remove the asterisk). So change that line to:

MKMapPoint mapPoint = MKMapPointForCoordinate(...);



Next, your other question was "How does the CGPathContainsPoint code check multiple polygons?"

One way is to store all the CGMutablePathRef paths for all the polygons in a C array just like you're storing the individual polygon coordinates in a C array.

Then, you can loop through the paths array and call CGPathContainsPoint with each one.


Following is an example to test multiple polygon overlays that have been added to the map. This example assumes you've already added MKPolygon overlays to the map using addOverlay or addOverlays.

Wherever you want to test whether some coordinate is in any of the polygons added to the map, put this:

CLLocationCoordinate2D coordinateToTest = 
    CLLocationCoordinate2DMake(52.366243, 4.891097);

MKMapPoint mapPointToTest = MKMapPointForCoordinate(coordinateToTest);

//Loop through MKPolygon overlays...
for (id<MKOverlay> overlay in myMapView.overlays)
{
    if ([overlay isKindOfClass:[MKPolygon class]])
    {
        MKPolygon *polygon = (MKPolygon *)overlay;


        CGMutablePathRef mpr = CGPathCreateMutable();

        MKMapPoint *polygonPoints = polygon.points;

        for (int p=0; p < polygon.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(mapPointToTest.x, mapPointToTest.y);

        BOOL pointIsInPolygon = CGPathContainsPoint(mpr, NULL, mapPointAsCGP, FALSE);
        NSLog(@"Coordinate %f,%f is in polygon %@: %@",
              coordinateToTest.latitude, coordinateToTest.longitude,
              polygon.title,
              (pointIsInPolygon ? @"Yes" : @"No"));

        CGPathRelease(mpr);
    }
}

Upvotes: 2

Sergey Grishchev
Sergey Grishchev

Reputation: 12051

What system framework are you talking about? MKMapView maybe? Dig into the CLLocationCoordinate and how to compare them:

memcmp(&first_cllc2d, &second_cllc2d, sizeof(CLLocationCoordinate2D)) 

(fabs(first_cllc2d.latitude - second_cllc2d.latitude) <= epsilon && 
 fabs(first_cllc2d.longitude - second_cllc2d.longitude) <= epsilon)

Upvotes: 0

Related Questions