102 lines
3.1 KiB
JavaScript
102 lines
3.1 KiB
JavaScript
import assert from "node:assert/strict"
|
|
import test from "node:test"
|
|
|
|
import {
|
|
clusterDiameterPixels,
|
|
clusterSizeClass,
|
|
mergeNearbyMapClusters,
|
|
mergeNearbyMapPoints
|
|
} from "./map_cluster_points.mjs"
|
|
|
|
const flatMap = scale => ({
|
|
project: ([longitude, latitude]) => ({x: longitude * scale, y: latitude * scale}),
|
|
unproject: ([x, y]) => ({lng: x / scale, lat: y / scale})
|
|
})
|
|
|
|
test("merges visually overlapping clusters and preserves their total", () => {
|
|
const points = [
|
|
{
|
|
id: "a",
|
|
type: "cluster",
|
|
count: 100,
|
|
urgent_count: 2,
|
|
longitude: 0,
|
|
latitude: 0,
|
|
bounds: {west: -5, south: -2, east: 5, north: 2}
|
|
},
|
|
{
|
|
id: "b",
|
|
type: "cluster",
|
|
count: 50,
|
|
urgent_count: 1,
|
|
longitude: 30,
|
|
latitude: 0,
|
|
bounds: {west: 25, south: -3, east: 35, north: 4}
|
|
},
|
|
{id: "c", type: "cluster", count: 7, urgent_count: 0, longitude: 140, latitude: 0}
|
|
]
|
|
|
|
const result = mergeNearbyMapClusters(flatMap(1), points)
|
|
|
|
assert.equal(result.length, 2)
|
|
assert.equal(result.reduce((total, cluster) => total + cluster.count, 0), 157)
|
|
|
|
const merged = result.find(cluster => cluster.count === 150)
|
|
assert.equal(merged.urgent_count, 3)
|
|
assert.equal(merged.longitude, 10)
|
|
assert.equal(merged.latitude, 0)
|
|
assert.deepEqual(merged.bounds, {west: -5, south: -3, east: 35, north: 4})
|
|
})
|
|
|
|
test("splits the same clusters again at a closer zoom", () => {
|
|
const points = [
|
|
{id: "a", type: "cluster", count: 20, longitude: 0, latitude: 0},
|
|
{id: "b", type: "cluster", count: 30, longitude: 30, latitude: 0}
|
|
]
|
|
|
|
assert.equal(mergeNearbyMapClusters(flatMap(1), points).length, 1)
|
|
assert.equal(mergeNearbyMapClusters(flatMap(3), points).length, 2)
|
|
})
|
|
|
|
test("merges a singleton into an overlapping cluster at a distant zoom", () => {
|
|
const points = [
|
|
{id: "cluster", type: "cluster", count: 351, longitude: 0, latitude: 0},
|
|
{id: "request", type: "request", longitude: 28, latitude: 0, exact: true}
|
|
]
|
|
|
|
const result = mergeNearbyMapPoints(flatMap(1), points)
|
|
|
|
assert.equal(result.length, 1)
|
|
assert.equal(result[0].type, "cluster")
|
|
assert.equal(result[0].count, 352)
|
|
assert.deepEqual(result[0].bounds, {west: 0, south: 0, east: 28, north: 0})
|
|
})
|
|
|
|
test("keeps separated singleton points interactive at a closer zoom", () => {
|
|
const points = [
|
|
{id: "left", type: "request", longitude: 0, latitude: 0, exact: true},
|
|
{
|
|
id: "right",
|
|
type: "request",
|
|
longitude: 30,
|
|
latitude: 0,
|
|
radius_meters: 1_000
|
|
}
|
|
]
|
|
|
|
const result = mergeNearbyMapPoints(flatMap(3), points)
|
|
|
|
assert.deepEqual(result, points)
|
|
})
|
|
|
|
test("uses larger non-overlapping markers for larger totals", () => {
|
|
assert.equal(clusterDiameterPixels(999), 44)
|
|
assert.equal(clusterDiameterPixels(1_000), 52)
|
|
assert.equal(clusterDiameterPixels(10_000), 56)
|
|
assert.equal(clusterDiameterPixels(100_000), 60)
|
|
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")
|
|
})
|