Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add polygon area calculation #21

Merged
merged 15 commits into from
Jan 8, 2018
Merged
6 changes: 6 additions & 0 deletions Turf.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
052521D81FC47A1300DD266A /* dc-polygon.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 052521D71FC47A0300DD266A /* dc-polygon.geojson */; };
052521D91FC47A1900DD266A /* dc-polygon.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 052521D71FC47A0300DD266A /* dc-polygon.geojson */; };
353E9B101F3E093A007CFA23 /* Turf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 353E9B071F3E093A007CFA23 /* Turf.framework */; };
353E9B1E1F3E09D3007CFA23 /* CoreLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 356D24531F17948C003BBB9D /* CoreLocation.swift */; };
353E9B1F1F3E09D8007CFA23 /* Turf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35650B0A1F150DDB00B5C158 /* Turf.swift */; };
Expand Down Expand Up @@ -41,6 +43,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
052521D71FC47A0300DD266A /* dc-polygon.geojson */ = {isa = PBXFileReference; lastKnownFileType = text; path = "dc-polygon.geojson"; sourceTree = "<group>"; };
353E9B071F3E093A007CFA23 /* Turf.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Turf.framework; sourceTree = BUILT_PRODUCTS_DIR; };
353E9B0F1F3E093A007CFA23 /* TurfMacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TurfMacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
35650AF01F150DC500B5C158 /* Turf.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Turf.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -135,6 +138,7 @@
isa = PBXGroup;
children = (
356D24581F179B72003BBB9D /* dc-line.geojson */,
052521D71FC47A0300DD266A /* dc-polygon.geojson */,
);
path = Fixtures;
sourceTree = "<group>";
Expand Down Expand Up @@ -291,6 +295,7 @@
buildActionMask = 2147483647;
files = (
35CB7F6F1F798A51008A18C8 /* dc-line.geojson in Resources */,
052521D91FC47A1900DD266A /* dc-polygon.geojson in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -306,6 +311,7 @@
buildActionMask = 2147483647;
files = (
356D24591F179B72003BBB9D /* dc-line.geojson in Resources */,
052521D81FC47A1300DD266A /* dc-polygon.geojson in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
59 changes: 59 additions & 0 deletions Turf/Turf.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public typealias RadianDistance = Double
public typealias RadianDirection = Double

let metersPerRadian = 6_373_000.0
let equitorialRadius:Double = 6378137

/**
A `RadianCoordinate2D` is a coordinate represented in radians as opposed to
Expand Down Expand Up @@ -285,3 +286,61 @@ public struct Polyline {
return closestCoordinate
}
}

public struct Polygon {
var coordinates: [CLLocationCoordinate2D]
Copy link
Contributor

@frederoni frederoni Nov 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capturing from chat: The coordinates property on a GeoJSON Polygon should be represented as a [[CLLocationCoordate2D]]

Even better now encapsulated in a Ring.


var polygonArea: Double {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This property already lives inside a struct named Polygon, so the word “polygon” here is redundant.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment with a permalink to the specific commit of the Turf package you’re porting this code from, in case we need to track down a discrepancy in the future.

return 0;
}

/**
* Calculate the approximate area of the polygon were it projected onto the earth.
* Note that this area will be positive if ring is oriented clockwise, otherwise it will be negative.
*
* Reference:
* Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
* Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409
*
*/

var ringArea: Double {
var p1:CLLocationCoordinate2D
var p2:CLLocationCoordinate2D
var p3:CLLocationCoordinate2D
var lowerIndex:Int
var middleIndex:Int
var upperIndex:Int
var i:Int
var area:Double = 0
var coordsLength:Int = coordinates.count

if (coordsLength > 2) {
for(index, coordinate) in coordinates.enumerated() {
if (index == coordsLength - 2) {
lowerIndex = coordsLength - 2
middleIndex = coordsLength - 1
upperIndex = 0
} else if(index == coordsLength - 1) {
lowerIndex = coordsLength - 1;
middleIndex = 0;
upperIndex = 1;
} else {
lowerIndex = index
middleIndex = index + 1
upperIndex = index + 2
}

p1 = coordinates[lowerIndex]
p2 = coordinates[middleIndex]
p3 = coordinates[upperIndex]
area += (p3.longitude.toRadians() - p1.longitude.toRadians()) * sin(p2.latitude.toRadians())
}

area = area * equitorialRadius * equitorialRadius / 2;

}

return area
}
}
25 changes: 25 additions & 0 deletions TurfTests/Fixtures/dc-polygon.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
-77.0416259765625,
39.06611426153784
],
[
-77.32177734375,
38.843986129756615
],
[
-76.7669677734375,
38.831149809348744
],
[
-77.0416259765625,
39.06611426153784
]
]
}
}
8 changes: 8 additions & 0 deletions TurfTests/TurfTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -286,4 +286,12 @@ class TurfTests: XCTestCase {
let b = radian.toDegrees()
XCTAssertEqual(b, 229, accuracy: 1)
}

func testPolygonArea() {
let json = Fixture.JSONFromFileNamed(name: "dc-polygon")
let coordinates = ((json["geometry"] as! [String: Any])["coordinates"] as! [[Double]]).map { CLLocationCoordinate2D(latitude: $0[0], longitude: $0[1]) }
let polygon = Polygon(coordinates: coordinates)

XCTAssertEqual(polygon.ringArea, 611152631.86)
}
}