{"version":3,"file":"rewind.es.mjs","sources":["../lib/index.ts"],"sourcesContent":["import {\n  Feature as IFeature,\n  Geometry,\n  FeatureCollection,\n  Position,\n} from 'geojson';\n\ntype Feature = IFeature<Geometry | null>;\n\n/**\n * Winding order. By default, this uses the RFC7946 order,\n * which is what is in the GeoJSON standard.\n *\n * You can also choose to wind in the d3 order.\n */\nexport type Winding = 'RFC7946' | 'd3';\n\nexport function rewindGeometry(geometry: Geometry, outer = false): Geometry {\n  switch (geometry.type) {\n    case 'Polygon': {\n      if (!geometry.coordinates) return geometry;\n      return {\n        ...geometry,\n        coordinates: rewindRings(geometry.coordinates, outer),\n      };\n    }\n    case 'MultiPolygon': {\n      if (!geometry.coordinates) return geometry;\n      return {\n        ...geometry,\n        coordinates: geometry.coordinates.map((polygon) =>\n          rewindRings(polygon, outer)\n        ),\n      };\n    }\n    case 'GeometryCollection': {\n      return {\n        ...geometry,\n        geometries: geometry.geometries.map((geometry) => {\n          return rewindGeometry(geometry, outer);\n        }),\n      };\n    }\n    default: {\n      return geometry;\n    }\n  }\n}\n\nfunction rewindRings(rings: Position[][], outer: boolean): Position[][] {\n  if (rings.length === 0) return rings;\n\n  const rewound: Position[][] = [];\n\n  for (let i = 0; i < rings.length; i++) {\n    rewound.push(rewindRing(rings[i], i === 0 ? outer : !outer));\n  }\n\n  return rewound;\n}\n\n/**\n * Compute the area of a ring to decide whether to wind it\n * clockwise or not.\n */\nfunction rewindRing(ring: Position[], dir: boolean): Position[] {\n  let area = 0;\n  let err = 0;\n  for (let i = 0, len = ring.length, j = len - 1; i < len; j = i++) {\n    const k = (ring[i][0] - ring[j][0]) * (ring[j][1] + ring[i][1]);\n    const m = area + k;\n    err += Math.abs(area) >= Math.abs(k) ? area - m + k : k - m + area;\n    area = m;\n  }\n  if (area + err >= 0 !== !!dir) return ring.slice().reverse();\n  return ring;\n}\n\n/**\n * # Wind the rings of polygons and multipolygons.\n *\n * This creates a copy of the input.\n *\n * - outer as false is the default, which is the GeoJSON RFC way.\n * - outer as true is for d3-geo.\n */\nexport function rewindFeature(\n  feature: Feature,\n  winding: Winding = 'RFC7946'\n): Feature {\n  const geometry = feature.geometry;\n  if (!geometry) return feature;\n  const geometryRewound = rewindGeometry(geometry, winding === 'd3');\n  if (geometryRewound === geometry) {\n    return feature;\n  }\n\n  return {\n    ...feature,\n    geometry: geometryRewound,\n  };\n}\n\nexport function rewindFeatureCollection(\n  featureCollection: FeatureCollection,\n  outer: Winding = 'RFC7946'\n) {\n  return {\n    ...featureCollection,\n    features: featureCollection.features.map((feature) =>\n      rewindFeature(feature, outer)\n    ),\n  };\n}\n"],"names":[],"mappings":"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"}