/** * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * Project: Groupe Ka / Ka Maps * * bboxOfProperties + pointInPolygon — les briques géométriques de la * synchronisation liste ↔ carte (fitBounds sur les résultats, zone dessinée). */ import { describe, expect, it } from "vitest"; import { bboxOfProperties, pointInPolygon } from "../src/utils/geo.js"; import type { MapProperty } from "../src/types/index.js"; const prop = (lat: number, lng: number): MapProperty => ({ id: `${lat},${lng}`, appSource: "lou-ka", latitude: lat, longitude: lng, kind: "listing", }); describe("bboxOfProperties", () => { it("englobe tous les points", () => { const bbox = bboxOfProperties([prop(46.8, -71.2), prop(45.5, -73.6), prop(46.3, -72.5)]); expect(bbox).toEqual({ west: -73.6, south: 45.5, east: -71.2, north: 46.8 }); }); it("ignore les coordonnées invalides (0,0 sentinelle)", () => { const bbox = bboxOfProperties([prop(0, 0), prop(46.8, -71.2)]); expect(bbox).toEqual({ west: -71.2, south: 46.8, east: -71.2, north: 46.8 }); }); it("null quand rien n'est géolocalisé", () => { expect(bboxOfProperties([prop(0, 0)])).toBeNull(); expect(bboxOfProperties([])).toBeNull(); }); }); describe("pointInPolygon", () => { // triangle autour du Vieux-Québec const ring: [number, number][] = [ [-71.24, 46.80], [-71.20, 46.82], [-71.24, 46.83], ]; it("dedans", () => { expect(pointInPolygon(-71.228, 46.817, ring)).toBe(true); }); it("dehors", () => { expect(pointInPolygon(-71.30, 46.81, ring)).toBe(false); expect(pointInPolygon(-71.21, 46.79, ring)).toBe(false); }); it("polygone concave", () => { const u: [number, number][] = [ [0, 0], [4, 0], [4, 4], [3, 4], [3, 1], [1, 1], [1, 4], [0, 4], ]; expect(pointInPolygon(0.5, 2, u)).toBe(true); // branche gauche du U expect(pointInPolygon(2, 2, u)).toBe(false); // creux du U expect(pointInPolygon(3.5, 2, u)).toBe(true); // branche droite }); });