// index.ts
import { bbox as calcBbox } from "@turf/bbox";
import { booleanPointInPolygon } from "@turf/boolean-point-in-polygon";
import { booleanPointOnLine as isPointOnLine } from "@turf/boolean-point-on-line";
import { getGeom } from "@turf/invariant";
function booleanContains(feature1, feature2) {
  const geom1 = getGeom(feature1);
  const geom2 = getGeom(feature2);
  const type1 = geom1.type;
  const type2 = geom2.type;
  const coords1 = geom1.coordinates;
  const coords2 = geom2.coordinates;
  switch (type1) {
    case "Point":
      switch (type2) {
        case "Point":
          return compareCoords(coords1, coords2);
        default:
          throw new Error("feature2 " + type2 + " geometry not supported");
      }
    case "MultiPoint":
      switch (type2) {
        case "Point":
          return isPointInMultiPoint(geom1, geom2);
        case "MultiPoint":
          return isMultiPointInMultiPoint(geom1, geom2);
        default:
          throw new Error("feature2 " + type2 + " geometry not supported");
      }
    case "LineString":
      switch (type2) {
        case "Point":
          return isPointOnLine(geom2, geom1, { ignoreEndVertices: true });
        case "LineString":
          return isLineOnLine(geom1, geom2);
        case "MultiPoint":
          return isMultiPointOnLine(geom1, geom2);
        default:
          throw new Error("feature2 " + type2 + " geometry not supported");
      }
    case "Polygon":
      switch (type2) {
        case "Point":
          return booleanPointInPolygon(geom2, geom1, { ignoreBoundary: true });
        case "LineString":
          return isLineInPoly(geom1, geom2);
        case "Polygon":
          return isPolyInPoly(geom1, geom2);
        case "MultiPoint":
          return isMultiPointInPoly(geom1, geom2);
        default:
          throw new Error("feature2 " + type2 + " geometry not supported");
      }
    case "MultiPolygon":
      switch (type2) {
        case "Polygon":
          return isPolygonInMultiPolygon(geom1, geom2);
        default:
          throw new Error("feature2 " + type2 + " geometry not supported");
      }
    default:
      throw new Error("feature1 " + type1 + " geometry not supported");
  }
}
function isPolygonInMultiPolygon(multiPolygon, polygon) {
  return multiPolygon.coordinates.some(
    (coords) => isPolyInPoly({ type: "Polygon", coordinates: coords }, polygon)
  );
}
function isPointInMultiPoint(multiPoint, pt) {
  let i;
  let output = false;
  for (i = 0; i < multiPoint.coordinates.length; i++) {
    if (compareCoords(multiPoint.coordinates[i], pt.coordinates)) {
      output = true;
      break;
    }
  }
  return output;
}
function isMultiPointInMultiPoint(multiPoint1, multiPoint2) {
  for (const coord2 of multiPoint2.coordinates) {
    let matchFound = false;
    for (const coord1 of multiPoint1.coordinates) {
      if (compareCoords(coord2, coord1)) {
        matchFound = true;
        break;
      }
    }
    if (!matchFound) {
      return false;
    }
  }
  return true;
}
function isMultiPointOnLine(lineString, multiPoint) {
  let haveFoundInteriorPoint = false;
  for (const coord of multiPoint.coordinates) {
    if (isPointOnLine(coord, lineString, { ignoreEndVertices: true })) {
      haveFoundInteriorPoint = true;
    }
    if (!isPointOnLine(coord, lineString)) {
      return false;
    }
  }
  if (haveFoundInteriorPoint) {
    return true;
  }
  return false;
}
function isMultiPointInPoly(polygon, multiPoint) {
  for (const coord of multiPoint.coordinates) {
    if (!booleanPointInPolygon(coord, polygon, { ignoreBoundary: true })) {
      return false;
    }
  }
  return true;
}
function isLineOnLine(lineString1, lineString2) {
  let haveFoundInteriorPoint = false;
  for (const coords of lineString2.coordinates) {
    if (isPointOnLine({ type: "Point", coordinates: coords }, lineString1, {
      ignoreEndVertices: true
    })) {
      haveFoundInteriorPoint = true;
    }
    if (!isPointOnLine({ type: "Point", coordinates: coords }, lineString1, {
      ignoreEndVertices: false
    })) {
      return false;
    }
  }
  return haveFoundInteriorPoint;
}
function isLineInPoly(polygon, linestring) {
  let output = false;
  let i = 0;
  const polyBbox = calcBbox(polygon);
  const lineBbox = calcBbox(linestring);
  if (!doBBoxOverlap(polyBbox, lineBbox)) {
    return false;
  }
  for (i; i < linestring.coordinates.length - 1; i++) {
    const midPoint = getMidpoint(
      linestring.coordinates[i],
      linestring.coordinates[i + 1]
    );
    if (booleanPointInPolygon({ type: "Point", coordinates: midPoint }, polygon, {
      ignoreBoundary: true
    })) {
      output = true;
      break;
    }
  }
  return output;
}
function isPolyInPoly(feature1, feature2) {
  if (feature1.type === "Feature" && feature1.geometry === null) {
    return false;
  }
  if (feature2.type === "Feature" && feature2.geometry === null) {
    return false;
  }
  const poly1Bbox = calcBbox(feature1);
  const poly2Bbox = calcBbox(feature2);
  if (!doBBoxOverlap(poly1Bbox, poly2Bbox)) {
    return false;
  }
  const coords = getGeom(feature2).coordinates;
  for (const ring of coords) {
    for (const coord of ring) {
      if (!booleanPointInPolygon(coord, feature1)) {
        return false;
      }
    }
  }
  return true;
}
function doBBoxOverlap(bbox1, bbox2) {
  if (bbox1[0] > bbox2[0]) {
    return false;
  }
  if (bbox1[2] < bbox2[2]) {
    return false;
  }
  if (bbox1[1] > bbox2[1]) {
    return false;
  }
  if (bbox1[3] < bbox2[3]) {
    return false;
  }
  return true;
}
function compareCoords(pair1, pair2) {
  return pair1[0] === pair2[0] && pair1[1] === pair2[1];
}
function getMidpoint(pair1, pair2) {
  return [(pair1[0] + pair2[0]) / 2, (pair1[1] + pair2[1]) / 2];
}
var turf_boolean_contains_default = booleanContains;
export {
  booleanContains,
  compareCoords,
  turf_boolean_contains_default as default,
  doBBoxOverlap,
  getMidpoint,
  isLineInPoly,
  isLineOnLine,
  isMultiPointInMultiPoint,
  isMultiPointInPoly,
  isMultiPointOnLine,
  isPointInMultiPoint,
  isPolyInPoly,
  isPolygonInMultiPolygon
};
//# sourceMappingURL=index.js.map