+ var geojsonRewind = rewind;
+
+ function rewind(gj, outer) {
+ var type = gj && gj.type,
+ i;
+
+ if (type === 'FeatureCollection') {
+ for (i = 0; i < gj.features.length; i++) {
+ rewind(gj.features[i], outer);
+ }
+ } else if (type === 'GeometryCollection') {
+ for (i = 0; i < gj.geometries.length; i++) {
+ rewind(gj.geometries[i], outer);
+ }
+ } else if (type === 'Feature') {
+ rewind(gj.geometry, outer);
+ } else if (type === 'Polygon') {
+ rewindRings(gj.coordinates, outer);
+ } else if (type === 'MultiPolygon') {
+ for (i = 0; i < gj.coordinates.length; i++) {
+ rewindRings(gj.coordinates[i], outer);
+ }
+ }
+
+ return gj;
+ }
+
+ function rewindRings(rings, outer) {
+ if (rings.length === 0) return;
+ rewindRing(rings[0], outer);
+
+ for (var i = 1; i < rings.length; i++) {
+ rewindRing(rings[i], !outer);
+ }
+ }
+
+ function rewindRing(ring, dir) {
+ var area = 0;
+
+ for (var i = 0, len = ring.length, j = len - 1; i < len; j = i++) {
+ area += (ring[i][0] - ring[j][0]) * (ring[j][1] + ring[i][1]);
+ }
+
+ if (area >= 0 !== !!dir) ring.reverse();
+ }
+