// Ported from topojson-client v3.1.0 src/feature.js, ISC.
///|
fn Topology::line(
self : Topology,
refs : Json,
minimum : Int,
) -> Array[Array[Double]] raise TopoError {
let points : Array[Array[Double]] = []
for arc_ref in array(refs) {
if !points.is_empty() {
ignore(points.pop())
}
for p in self.arc(number(arc_ref).to_int()) {
points.push(p)
}
}
if !points.is_empty() {
while points.length() < minimum {
points.push(points[0].copy())
}
}
points
}
///|
fn Topology::geometry(self : Topology, g : Json) -> Json raise TopoError {
let type_ = kind(g)
let refs = field(g, "arcs")
let coords : Json = match type_ {
"Point" => self.point(field(g, "coordinates")).to_json()
"MultiPoint" =>
array(field(g, "coordinates")).map(p => self.point(p)).to_json()
"LineString" => self.line(refs, 2).to_json()
"MultiLineString" => array(refs).map(r => self.line(r, 2)).to_json()
"Polygon" => array(refs).map(r => self.line(r, 4)).to_json()
"MultiPolygon" =>
array(refs).map(poly => array(poly).map(r => self.line(r, 4))).to_json()
"GeometryCollection" =>
return {
"type": "GeometryCollection",
"geometries": array(field(g, "geometries"))
.map(c => self.geometry(c))
.to_json(),
}
_ => return Json::null()
}
{ "type": type_.to_json(), "coordinates": coords }
}
///|
fn Topology::single_feature(self : Topology, g : Json) -> Json raise TopoError {
let properties = field(g, "properties")
let out : Map[String, Json] = Map([
("type", "Feature".to_json()),
("geometry", self.geometry(g)),
(
"properties",
if properties == Json::null() {
Json::empty_object()
} else {
properties
},
),
])
for k in ["id", "bbox"] {
let v = field(g, k)
if v != Json::null() {
out[k] = v
}
}
Json::object(out)
}
///|
/// Convert a named object into a GeoJSON Feature or FeatureCollection.
pub fn Topology::feature(
self : Topology,
name : String,
) -> Json raise TopoError {
let g = self.object(name)
if kind(g) == "GeometryCollection" {
{
"type": "FeatureCollection",
"features": array(field(g, "geometries"))
.map(c => self.single_feature(c))
.to_json(),
}
} else {
self.single_feature(g)
}
}