Getting Started
Interior Point computes a representative point guaranteed to lie inside a geometry. It is a faithful port of the JTS (Java Topology Suite) InteriorPoint algorithm, available as both a TypeScript library and a Rust crate.
Installation
npm install interior-pointcargo add interior-point
cargo add geo-typesOr pin the versions in your manifest:
// package.json
{
"dependencies": {
"interior-point": "^1.0.0"
}
}# Cargo.toml
[dependencies]
interior-point = "1.0"
geo-types = "0.7"Usage
Compute an interior point
import { interiorPoint } from "interior-point";
const polygon = {
type: "Polygon",
coordinates: [
[
[0, 0],
[6, 0],
[6, 2],
[2, 2],
[2, 8],
[0, 8],
[0, 0],
],
],
};
const point = interiorPoint(polygon);
console.log(point);
// => [1, 5]use geo_types::{Geometry, LineString, Polygon};
use interior_point::interior_point;
let poly = Polygon::new(
LineString::from(vec![
(0.0, 0.0),
(6.0, 0.0),
(6.0, 2.0),
(2.0, 2.0),
(2.0, 8.0),
(0.0, 8.0),
(0.0, 0.0),
]),
vec![],
);
let geometry: Geometry<f64> = poly.into();
let result = interior_point(&geometry);
// => Some(Coord { x: 1.0, y: 5.0 })Verify the result
Check that result against the geometry it came from, through a point-in-polygon locator that shares no code with the algorithm above. Each tab goes on using the bindings its own snippet introduced.
import { verifyInteriorPoint, Verification } from "interior-point";
console.log(verifyInteriorPoint(point, polygon) === Verification.Interior);
// => trueuse interior_point::{verify_interior_point, Verification};
assert_eq!(verify_interior_point(result, Some(&geometry)), Verification::Interior);This verifies the library's own output. It is not an OGC geometry validity check: an invalid geometry can still yield a point that verifies. See the API reference (TypeScript | Rust) for the four outcomes it distinguishes, and the CLI page for the same check as a flag.
Prefer the centroid
Or ask for the centroid instead, falling back to the algorithm above only when the centroid is not strictly inside:
import { centroidFirstInteriorPoint } from "interior-point";
// This polygon's centroid [2, 3] sits exactly on an edge, so it is rejected.
console.log(centroidFirstInteriorPoint(polygon));
// => [1, 5]use interior_point::centroid_first_interior_point;
// This polygon's centroid (2, 3) sits exactly on an edge, so it is rejected.
let point = centroid_first_interior_point(&geometry);
// => Some(Coord { x: 1.0, y: 5.0 })