mapillary-js/test/api/GeohashGeometryProvider.test.ts
2021-03-29 10:35:45 +02:00

182 lines
6.4 KiB
TypeScript

import * as geohash from "latlon-geohash";
import { GeohashGeometryProvider } from "../../src/api/GeohashGeometryProvider";
import { LngLat } from "../../src/api/interfaces/LngLat";
import { MapillaryError } from "../../src/error/MapillaryError";
import * as GeoCoords from "../../src/geo/GeoCoords";
describe("GeohashGeometryProvider.ctor", () => {
test("should be defined", () => {
const geometry = new GeohashGeometryProvider();
expect(geometry).toBeDefined();
});
});
describe("GeohashGeometryProvider.lngLatToCellId", () => {
test("should call encoder correctly", () => {
const mockEncode = spyOn(geohash, "encode").and.returnValue("0/0");
const level = 22;
const geometry = new GeohashGeometryProvider(level);
const lat = -1;
const lon = 1;
geometry.lngLatToCellId({ lat, lng: lon });
expect(mockEncode).toHaveBeenCalledTimes(1);
expect(mockEncode).toHaveBeenCalledWith(lat, lon, level);
});
});
describe("GeohashGeometryProvider.bboxToCellIds", () => {
const setupSpies: (tileSize: number) => void =
(tileSize: number): void => {
spyOn(geohash, "encode").and.callFake(
(lat: number, lng: number): string => {
return `${Math.round(lat)}/${Math.round(lng)}`;
});
spyOn(geohash, "decode").and.callFake(
(cellId: string): geohash.Point => {
const [lat, lng] = cellId.split("/");
return {
lat: parseInt(lat, 10),
lon: parseInt(lng, 10),
};
});
spyOn(geohash, "bounds").and.callFake(
(lat: number, lng: number): geohash.Bounds => {
return {
ne: { lat: lat + 0.5, lon: lng + 0.5 },
sw: { lat: lat - 0.5, lon: lng - 0.5 },
}
});
spyOn(geohash, "neighbours").and.callFake(
(cellId: string): geohash.Neighbours => {
const ll = geohash.decode(cellId);
const lat = ll.lat;
const lng = ll.lon;
return {
w: `${lat}/${lng - 1}`,
n: `${lat + 1}/${lng}`,
e: `${lat}/${lng + 1}`,
s: `${lat - 1}/${lng}`,
nw: `${lat + 1}/${lng - 1}`,
ne: `${lat + 1}/${lng + 1}`,
sw: `${lat - 1}/${lng - 1}`,
se: `${lat - 1}/${lng + 1}`,
};
});
spyOn(GeoCoords, "geodeticToEnu").and.callFake(
(
lat: number,
lon: number,
_: number,
refLat: number,
refLon: number)
: number[] => {
return [
tileSize * (lat - refLat),
tileSize * (lon - refLon),
0];
});
spyOn(GeoCoords, "enuToGeodetic").and.callFake(
(x: number, y: number, _: number, refLat: number, refLon: number): number[] => {
return [
refLat + y / tileSize,
refLon + x / tileSize,
0];
});
};
test("should return cell", () => {
const geometry = new GeohashGeometryProvider();
const tileSize = 1;
setupSpies(tileSize);
const sw: LngLat = { lat: -0.1, lng: -0.1 };
const ne: LngLat = { lat: 0.1, lng: 0.1 };
const cellIds = geometry.bboxToCellIds(sw, ne);
expect(cellIds.length).toBe(1);
expect(cellIds[0]).toBe("0/0");
});
test("should return cell and adjacent", () => {
const geometry = new GeohashGeometryProvider();
const tileSize = 1;
setupSpies(tileSize);
const sw: LngLat = { lat: -0.6, lng: -0.6 };
const ne: LngLat = { lat: 0.6, lng: 0.6 };
const cellIds = geometry.bboxToCellIds(sw, ne);
expect(cellIds.length).toBe(9);
expect(cellIds.indexOf("0/0")).not.toBe(-1);
expect(cellIds.indexOf("0/1")).not.toBe(-1);
expect(cellIds.indexOf("0/-1")).not.toBe(-1);
expect(cellIds.indexOf("1/0")).not.toBe(-1);
expect(cellIds.indexOf("1/-1")).not.toBe(-1);
expect(cellIds.indexOf("1/1")).not.toBe(-1);
expect(cellIds.indexOf("-1/0")).not.toBe(-1);
expect(cellIds.indexOf("-1/-1")).not.toBe(-1);
expect(cellIds.indexOf("-1/1")).not.toBe(-1);
});
});
describe("GeohashGeometryProvider.bboxToCellIds", () => {
test("should throw if north east is not larger than south west", () => {
const geometry = new GeohashGeometryProvider();
expect(() => {
geometry
.bboxToCellIds(
{ lat: 0, lng: 0 },
{ lat: -1, lng: 1 });
}).toThrowError(MapillaryError);
expect(() => {
geometry
.bboxToCellIds(
{ lat: 0, lng: 0 },
{ lat: 1, lng: -1 });
}).toThrowError(MapillaryError);
expect(() => {
geometry
.bboxToCellIds(
{ lat: 0, lng: 0 },
{ lat: -1, lng: -1 });
}).toThrowError(MapillaryError);
});
describe("GeohashGeometryProvider.getAdjacent", () => {
it("should always be 8", () => {
const geometry = new GeohashGeometryProvider();
const lngLats: LngLat[] = [
{ lat: 45, lng: 0 },
{ lat: 0, lng: 45 },
{ lat: -45, lng: 0 },
{ lat: 0, lng: -45 },
{ lat: 45, lng: 45 },
{ lat: -45, lng: -45 },
{ lat: 45, lng: -45 },
{ lat: -45, lng: 45 },
{ lat: -45, lng: 135 },
{ lat: -45, lng: 180 },
{ lat: 0, lng: 180 },
{ lat: 45, lng: 180 },
];
for (let lngLat of lngLats) {
const cellId = geometry.lngLatToCellId(lngLat);
const adjacent = geometry.getAdjacent(cellId);
expect(adjacent.length).toBe(8);
}
});
});
});