clone

an offline map explorer where each world, from a game map to a city's open data, ships as one .atlas file

archive/golden-reference
atlas / frontend / test / collections.test.mjs
collections.test.mjs 3.2K
1// The highlight filter, run against real OpenLayers polygons but no map: the2// rule is AND across collections and OR within one, with every zone3// answering to the collection id the wire stamped it with.4import assert from "node:assert/strict";5import test from "node:test";67import Polygon from "ol/geom/Polygon.js";89import {10 collectionOf,11 geometryContainsCoordinate,12 groupByCollection,13 passesZoneFilters,14} from "../src/collections.js";1516function square(x, y, size) {17 return new Polygon([[18 [x, y], [x + size, y], [x + size, y + size], [x, y + size], [x, y],19 ]]);20}2122function record(id, geometry, collectionId = 41) {23 return { zone: { id, collectionId }, geometries: [geometry] };24}2526test("a zone answers with the collection id the wire stamped", () => {27 assert.equal(collectionOf({ id: 1, collectionId: 41 }), 41);28 assert.equal(collectionOf({ id: 2 }), undefined, "an unstamped zone claims nothing");29});3031test("groupByCollection buckets records by their real collections", () => {32 const groups = groupByCollection([33 record(1, square(0, 0, 10), 41),34 record(2, square(100, 100, 10), 41),35 record(3, square(0, 0, 40), 42),36 ]);37 assert.equal(groups.size, 2);38 assert.equal(groups.get(41).length, 2);39 assert.equal(groups.get(42).length, 1);40});4142test("one collection, two zones: inside either is enough", () => {43 const groups = groupByCollection([44 record(1, square(0, 0, 10)),45 record(2, square(100, 100, 10)),46 ]);47 assert.equal(groups.size, 1, "one collection, one bucket");48 assert.equal(passesZoneFilters(groups, [5, 5]), true);49 assert.equal(passesZoneFilters(groups, [105, 105]), true);50 assert.equal(passesZoneFilters(groups, [50, 50]), false);51});5253test("two collections: only the overlap survives", () => {54 // Overlapping squares in different collections, so only their shared55 // corner answers both.56 const groups = groupByCollection([57 record(1, square(0, 0, 10), 41),58 record(2, square(5, 5, 10), 42),59 ]);60 assert.equal(passesZoneFilters(groups, [7, 7]), true, "inside both");61 assert.equal(passesZoneFilters(groups, [2, 2]), false, "district only");62 assert.equal(passesZoneFilters(groups, [12, 12]), false, "watershed only");63 assert.equal(passesZoneFilters(groups, [50, 50]), false, "inside neither");64});6566test("two collections, alternatives within one", () => {67 const groups = groupByCollection([68 record(1, square(0, 0, 10), 41),69 record(2, square(20, 0, 10), 41),70 record(3, square(0, 0, 40), 42),71 ]);72 assert.equal(passesZoneFilters(groups, [5, 5]), true, "first district");73 assert.equal(passesZoneFilters(groups, [25, 5]), true, "second district");74 assert.equal(passesZoneFilters(groups, [15, 5]), false,75 "in the watershed but in neither district");76});7778test("no highlights culls nothing", () => {79 assert.equal(passesZoneFilters(groupByCollection([]), [5, 5]), true);80});8182test("containment keeps its pixel of grace at the border", () => {83 const geometry = square(0, 0, 10);84 assert.equal(geometryContainsCoordinate(geometry, [5, 5]), true);85 assert.equal(geometryContainsCoordinate(geometry, [10.9, 5]), true,86 "within a pixel of the edge still counts");87 assert.equal(geometryContainsCoordinate(geometry, [12, 5]), false);88});