// index.ts
import { distance } from "@turf/distance";
import { feature, featureCollection } from "@turf/helpers";
import { featureEach } from "@turf/meta";
import { tin } from "@turf/tin";

// lib/turf-dissolve.ts
import { clone as clone3 } from "@turf/clone";
import { isObject as isObject2 } from "@turf/helpers";
import { getType as getType3 } from "@turf/invariant";
import { flattenEach as flattenEach2 } from "@turf/meta";

// lib/turf-line-dissolve.ts
import { clone } from "@turf/clone";
import { isObject, lineString, multiLineString } from "@turf/helpers";
import { getType } from "@turf/invariant";
import { lineReduce } from "@turf/meta";
function lineDissolve(geojson, options = {}) {
  options = options || {};
  if (!isObject(options)) {
    throw new Error("options is invalid");
  }
  const mutate = options.mutate;
  if (getType(geojson) !== "FeatureCollection") {
    throw new Error("geojson must be a FeatureCollection");
  }
  if (!geojson.features.length) {
    throw new Error("geojson is empty");
  }
  if (mutate === false || mutate === void 0) {
    geojson = clone(geojson);
  }
  const result = [];
  const lastLine = lineReduce(
    geojson,
    (previousLine, currentLine) => {
      const merged = mergeLineStrings(previousLine, currentLine);
      if (merged) {
        return merged;
      } else {
        result.push(previousLine);
        return currentLine;
      }
    }
  );
  if (lastLine) {
    result.push(lastLine);
  }
  if (!result.length) {
    return null;
  } else if (result.length === 1) {
    return result[0];
  } else {
    return multiLineString(
      result.map((line) => {
        return line.coordinates;
      })
    );
  }
}
function coordId(coord) {
  return coord[0].toString() + "," + coord[1].toString();
}
function mergeLineStrings(a, b) {
  const coords1 = a.geometry.coordinates;
  const coords2 = b.geometry.coordinates;
  const s1 = coordId(coords1[0]);
  const e1 = coordId(coords1[coords1.length - 1]);
  const s2 = coordId(coords2[0]);
  const e2 = coordId(coords2[coords2.length - 1]);
  let coords;
  if (s1 === e2) {
    coords = coords2.concat(coords1.slice(1));
  } else if (s2 === e1) {
    coords = coords1.concat(coords2.slice(1));
  } else if (s1 === s2) {
    coords = coords1.slice(1).reverse().concat(coords2);
  } else if (e1 === e2) {
    coords = coords1.concat(coords2.reverse().slice(1));
  } else {
    return null;
  }
  return lineString(coords);
}

// lib/turf-polygon-dissolve.ts
import { clone as clone2 } from "@turf/clone";
import { geometryCollection } from "@turf/helpers";
import { getType as getType2 } from "@turf/invariant";
import { flattenEach } from "@turf/meta";
import { merge } from "topojson-client";
import { topology } from "topojson-server";
function polygonDissolve(geojson, options = {}) {
  if (getType2(geojson) !== "FeatureCollection") {
    throw new Error("geojson must be a FeatureCollection");
  }
  if (!geojson.features.length) {
    throw new Error("geojson is empty");
  }
  if (options.mutate === false || options.mutate === void 0) {
    geojson = clone2(geojson);
  }
  const geoms = [];
  flattenEach(geojson, (feature2) => {
    geoms.push(feature2.geometry);
  });
  const topo = topology({ geoms: geometryCollection(geoms).geometry });
  const merged = merge(topo, topo.objects.geoms.geometries);
  return merged;
}

// lib/turf-dissolve.ts
function dissolve(geojson, options = {}) {
  options = options || {};
  if (!isObject2(options)) {
    throw new Error("options is invalid");
  }
  const mutate = options.mutate;
  if (getType3(geojson) !== "FeatureCollection") {
    throw new Error("geojson must be a FeatureCollection");
  }
  if (!geojson.features.length) {
    throw new Error("geojson is empty");
  }
  if (mutate === false || mutate === void 0) {
    geojson = clone3(geojson);
  }
  const type = getHomogenousType(geojson);
  if (!type) {
    throw new Error("geojson must be homogenous");
  }
  const data = geojson;
  switch (type) {
    case "LineString":
      return lineDissolve(data, options);
    case "Polygon":
      return polygonDissolve(data, options);
    default:
      throw new Error(type + " is not supported");
  }
}
function getHomogenousType(geojson) {
  const types = {};
  flattenEach2(geojson, (feature2) => {
    types[feature2.geometry.type] = true;
  });
  const keys = Object.keys(types);
  if (keys.length === 1) {
    return keys[0];
  }
  return null;
}

// index.ts
function concave(points, options = {}) {
  const maxEdge = options.maxEdge || Infinity;
  const cleaned = removeDuplicates(points);
  const tinPolys = tin(cleaned);
  tinPolys.features = tinPolys.features.filter((triangle) => {
    const pt1 = triangle.geometry.coordinates[0][0];
    const pt2 = triangle.geometry.coordinates[0][1];
    const pt3 = triangle.geometry.coordinates[0][2];
    const dist1 = distance(pt1, pt2, options);
    const dist2 = distance(pt2, pt3, options);
    const dist3 = distance(pt1, pt3, options);
    return dist1 <= maxEdge && dist2 <= maxEdge && dist3 <= maxEdge;
  });
  if (tinPolys.features.length < 1) {
    return null;
  }
  const dissolved = dissolve(tinPolys);
  if (dissolved.coordinates.length === 1) {
    dissolved.coordinates = dissolved.coordinates[0];
    dissolved.type = "Polygon";
  }
  return feature(dissolved);
}
function removeDuplicates(points) {
  const cleaned = [];
  const existing = {};
  featureEach(points, (pt) => {
    if (!pt.geometry) {
      return;
    }
    const key = pt.geometry.coordinates.join("-");
    if (!Object.prototype.hasOwnProperty.call(existing, key)) {
      cleaned.push(pt);
      existing[key] = true;
    }
  });
  return featureCollection(cleaned);
}
var turf_concave_default = concave;
export {
  concave,
  turf_concave_default as default
};
//# sourceMappingURL=index.js.map