124 lines
4.0 KiB
JavaScript
124 lines
4.0 KiB
JavaScript
import assert from "node:assert/strict"
|
|
import test from "node:test"
|
|
|
|
import {Supercluster} from "@maplibre/geojson-vt"
|
|
import {
|
|
clusterCountLabel,
|
|
clusterExpansionTarget,
|
|
clusterSizeClass,
|
|
pointFeatureCollection
|
|
} from "./map_cluster_features.mjs"
|
|
|
|
const buildIndex = points => {
|
|
const index = new Supercluster({
|
|
radius: 64,
|
|
maxZoom: 21,
|
|
minPoints: 2,
|
|
map: properties => ({
|
|
total_count: properties.weight,
|
|
urgent_count: properties.urgent_weight
|
|
}),
|
|
reduce: (accumulated, properties) => {
|
|
accumulated.total_count += properties.total_count
|
|
accumulated.urgent_count += properties.urgent_count
|
|
}
|
|
})
|
|
|
|
index.load(pointFeatureCollection(points).features)
|
|
return index
|
|
}
|
|
|
|
test("weighted server nodes preserve the represented record total", () => {
|
|
const index = buildIndex([
|
|
{id: "request:4:1:1", type: "cluster", longitude: 30.50, latitude: 50.45, count: 700},
|
|
{
|
|
id: "request:4:1:2",
|
|
type: "cluster",
|
|
longitude: 30.51,
|
|
latitude: 50.46,
|
|
count: 300,
|
|
urgent_count: 10
|
|
},
|
|
{id: "one", type: "request", longitude: -74.0, latitude: 40.7}
|
|
])
|
|
|
|
const world = index.getClusters([-180, -85, 180, 85], 0)
|
|
const represented = world.reduce(
|
|
(sum, feature) => sum + (feature.properties.total_count || feature.properties.weight),
|
|
0
|
|
)
|
|
const urgent = world.reduce(
|
|
(sum, feature) => sum + (feature.properties.urgent_count || feature.properties.urgent_weight),
|
|
0
|
|
)
|
|
|
|
assert.equal(represented, 1_001)
|
|
assert.equal(urgent, 10)
|
|
})
|
|
|
|
test("server hierarchy metadata survives GeoJSON conversion without becoming a native cluster", () => {
|
|
const feature = pointFeatureCollection([
|
|
{
|
|
id: "request:11:1197:1378",
|
|
type: "cluster",
|
|
cluster_id: "request:11:1197:1378",
|
|
parent_cluster_id: "request:10:598:689",
|
|
hierarchy_level: 11,
|
|
expansion_zoom: 13,
|
|
longitude: 30.52,
|
|
latitude: 50.45,
|
|
count: 27
|
|
}
|
|
]).features[0]
|
|
|
|
assert.equal(feature.properties.server_cluster_id, "request:11:1197:1378")
|
|
assert.equal(feature.properties.parent_cluster_id, "request:10:598:689")
|
|
assert.equal(feature.properties.hierarchy_level, 11)
|
|
assert.equal(feature.properties.expansion_zoom, 13)
|
|
assert.equal(feature.properties.weight, 27)
|
|
assert.equal("point_count" in feature.properties, false)
|
|
})
|
|
|
|
test("native clusters expose an expansion zoom and eventually split unique coordinates", () => {
|
|
const index = buildIndex([
|
|
{id: "a", longitude: 30.52340, latitude: 50.45010},
|
|
{id: "b", longitude: 30.52341, latitude: 50.45011},
|
|
{id: "c", longitude: 30.60, latitude: 50.50}
|
|
])
|
|
|
|
const world = index.getClusters([-180, -85, 180, 85], 0)
|
|
const cluster = world.find(feature => feature.properties.cluster)
|
|
|
|
assert.ok(cluster)
|
|
assert.ok(index.getClusterExpansionZoom(cluster.properties.cluster_id) > 0)
|
|
assert.equal(
|
|
index.getClusters([30.5, 50.4, 30.7, 50.6], 22)
|
|
.filter(feature => !feature.properties.cluster)
|
|
.length,
|
|
3
|
|
)
|
|
})
|
|
|
|
test("cluster size classes remain stable for accessible count buttons", () => {
|
|
assert.equal(clusterSizeClass(999), "is-md")
|
|
assert.equal(clusterSizeClass(1_000), "is-lg")
|
|
assert.equal(clusterSizeClass(10_000), "is-xl")
|
|
assert.equal(clusterSizeClass(100_000), "is-xxl")
|
|
})
|
|
|
|
test("large visual counts are compact while exact values remain available to accessibility text", () => {
|
|
assert.equal(clusterCountLabel(999, "en"), "999")
|
|
assert.equal(clusterCountLabel(1_250, "en"), "1.3K")
|
|
assert.equal(clusterCountLabel(48_533, "en"), "49K")
|
|
assert.equal(clusterCountLabel(1_000_000, "en"), "1M")
|
|
})
|
|
|
|
test("cluster expansion always advances at least one integer zoom level", () => {
|
|
assert.equal(clusterExpansionTarget(9, 9), 10)
|
|
assert.equal(clusterExpansionTarget(8.999_999_096_835_52, 9), 10)
|
|
assert.equal(clusterExpansionTarget(10.999_994_193_019_71, 11), 12)
|
|
assert.equal(clusterExpansionTarget(9.6, 10), 10)
|
|
assert.equal(clusterExpansionTarget(9.6, 13), 13)
|
|
assert.equal(clusterExpansionTarget(21.9, 24), 22)
|
|
})
|