-
Notifications
You must be signed in to change notification settings - Fork 0
/
geojson-rewind.js
124 lines (106 loc) · 3.79 KB
/
geojson-rewind.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.geojsonRewind=e():"undefined"!=typeof global?global.geojsonRewind=e():"undefined"!=typeof self&&(self.geojsonRewind=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var geojsonArea = require('geojson-area');
module.exports = rewind;
function rewind(gj, outer) {
switch ((gj && gj.type) || null) {
case 'FeatureCollection':
gj.features = gj.features.map(curryOuter(rewind, outer));
return gj;
case 'Feature':
gj.geometry = rewind(gj.geometry, outer);
return gj;
case 'Polygon':
case 'MultiPolygon':
return correct(gj, outer);
default:
return gj;
}
}
function curryOuter(a, b) {
return function(_) { return a(_, b); };
}
function correct(_, outer) {
if (_.type === 'Polygon') {
_.coordinates = correctRings(_.coordinates, outer);
} else if (_.type === 'MultiPolygon') {
_.coordinates = _.coordinates.map(curryOuter(correctRings, outer));
}
return _;
}
function correctRings(_, outer) {
outer = !!outer;
_[0] = wind(_[0], !outer);
for (var i = 1; i < _.length; i++) {
_[i] = wind(_[i], outer);
}
return _;
}
function wind(_, dir) {
return cw(_) === dir ? _ : _.reverse();
}
function cw(_) {
return geojsonArea.ring(_) >= 0;
}
},{"geojson-area":2}],2:[function(require,module,exports){
var wgs84 = require('wgs84');
module.exports.geometry = geometry;
module.exports.ring = ringArea;
function geometry(_) {
if (_.type === 'Polygon') return polygonArea(_.coordinates);
else if (_.type === 'MultiPolygon') {
var area = 0;
for (var i = 0; i < _.coordinates.length; i++) {
area += polygonArea(_.coordinates[i]);
}
return area;
} else {
return null;
}
}
function polygonArea(coords) {
var area = 0;
if (coords && coords.length > 0) {
area += Math.abs(ringArea(coords[0]));
for (var i = 1; i < coords.length; i++) {
area -= Math.abs(ringArea(coords[i]));
}
}
return area;
}
/**
* 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
*
* Returns:
* {float} The approximate signed geodesic area of the polygon in square
* meters.
*/
function ringArea(coords) {
var area = 0;
if (coords.length > 2) {
var p1, p2;
for (var i = 0; i < coords.length - 1; i++) {
p1 = coords[i];
p2 = coords[i + 1];
area += rad(p2[0] - p1[0]) * (2 + Math.sin(rad(p1[1])) + Math.sin(rad(p2[1])));
}
area = area * wgs84.RADIUS * wgs84.RADIUS / 2;
}
return area;
}
function rad(_) {
return _ * Math.PI / 180;
}
},{"wgs84":3}],3:[function(require,module,exports){
module.exports.RADIUS = 6378137;
module.exports.FLATTENING = 1/298.257223563;
module.exports.POLAR_RADIUS = 6356752.3142;},{}]},{},[1])
(1)
});
;