// Ported from topojson-client v3.1.0 src/bbox.js, ISC.
///|
fn extend_box(box : Array[Double], p : Array[Double]) -> Unit {
box[0] = box[0].min(p[0])
box[1] = box[1].min(p[1])
box[2] = box[2].max(p[0])
box[3] = box[3].max(p[1])
}
///|
fn Topology::point_bounds(
self : Topology,
g : Json,
box : Array[Double],
) -> Unit {
match kind(g) {
"Point" => extend_box(box, self.point(field(g, "coordinates")))
"MultiPoint" =>
for p in array(field(g, "coordinates")) {
extend_box(box, self.point(p))
}
"GeometryCollection" =>
for c in array(field(g, "geometries")) {
self.point_bounds(c, box)
}
_ => ()
}
}
///|
/// Bounds include all stored arcs, including unreferenced arcs, as in the upstream client.
/// None denotes a completely empty topology.
pub fn Topology::bbox(self : Topology) -> Array[Double]? raise TopoError {
let box = [1.0 / 0.0, 1.0 / 0.0, -1.0 / 0.0, -1.0 / 0.0]
for i = 0; i < array(field(self.data, "arcs")).length(); i = i + 1 {
for p in self.arc(i) {
extend_box(box, p)
}
}
for name in self.names() {
self.point_bounds(self.lookup(name), box)
}
if box[0].is_inf() {
None
} else {
Some(box)
}
}