Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm trying to make an area calculation category for MKPolygon. I found some JS code https://github.com/mapbox/geojson-area/blob/master/index.js#L1 with a link to the algorithm: http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409. It says: enter image description here

enter image description here

Here is my code, which gave a wrong result (thousands times more than actual):

#define kEarthRadius 6378137
@implementation MKPolygon (AreaCalculation)
- (double) area {
    double area = 0;
    NSArray *coords = [self coordinates];
    if (coords.count > 2) {
        CLLocationCoordinate2D p1, p2;
        for (int i = 0; i < coords.count - 1; i++) {
            p1 = [coords[i] MKCoordinateValue];
            p2 = [coords[i + 1] MKCoordinateValue];
            area += degreesToRadians(p2.longitude - p1.longitude) * (2 + sinf(degreesToRadians(p1.latitude)) + sinf(degreesToRadians(p2.latitude)));
        }

        area = area * kEarthRadius * kEarthRadius / 2;
    }

    return area;
}
- (NSArray *)coordinates {
    NSMutableArray *points = [NSMutableArray arrayWithCapacity:self.pointCount];
    for (int i = 0; i < self.pointCount; i++) {
        MKMapPoint *point = &self.points[i];
        [points addObject:[NSValue valueWithMKCoordinate:MKCoordinateForMapPoint(* point)]];
    }
    return points.copy;
}

double degreesToRadians(double radius) {
    return radius * M_PI / 180;
}

@end

What did I miss?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
647 views
Welcome To Ask or Share your Answers For Others

1 Answer

The whole algorithm implemented in Swift 3.0 :

import MapKit
let kEarthRadius = 6378137.0

// CLLocationCoordinate2D uses degrees but we need radians
func radians(degrees: Double) -> Double {
    return degrees * M_PI / 180;
}

func regionArea(locations: [CLLocationCoordinate2D]) -> Double {

    guard locations.count > 2 else { return 0 }
    var area = 0.0

    for i in 0..<locations.count {
        let p1 = locations[i > 0 ? i - 1 : locations.count - 1]
        let p2 = locations[i]

        area += radians(degrees: p2.longitude - p1.longitude) * (2 + sin(radians(degrees: p1.latitude)) + sin(radians(degrees: p2.latitude)) )
    }

    area = -(area * kEarthRadius * kEarthRadius / 2);

    return max(area, -area) // In order not to worry about is polygon clockwise or counterclockwise defined.
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...