mirror of
https://github.com/mapillary/mapillary-js.git
synced 2026-01-18 13:56:53 +00:00
304 lines
12 KiB
TypeScript
304 lines
12 KiB
TypeScript
import { S2 } from "s2-geometry";
|
|
|
|
import GeoCoords from "../../src/geo/GeoCoords";
|
|
import MapillaryError from "../../src/error/MapillaryError";
|
|
import S2GeometryProvider from "../../src/api/S2GeometryProvider";
|
|
|
|
describe("S2GeometryProvider.ctor", () => {
|
|
it("should be defined", () => {
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider();
|
|
|
|
expect(geometry).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe("GS2GeometryProvider.latLonToCellId", () => {
|
|
it("should call geometry correctly", () => {
|
|
const keySpy: jasmine.Spy = spyOn(S2, "latLngToKey");
|
|
const idSpy: jasmine.Spy = spyOn(S2, "keyToId");
|
|
keySpy.and.returnValue("0/0");
|
|
idSpy.and.returnValue("0.0");
|
|
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider();
|
|
|
|
const lat: number = -1;
|
|
const lon: number = 1;
|
|
|
|
geometry.latLonToCellId({ lat: -1, lon: 1 });
|
|
|
|
expect(keySpy.calls.count()).toBe(1);
|
|
expect(keySpy.calls.first().args[0]).toBe(lat);
|
|
expect(keySpy.calls.first().args[1]).toBe(lon);
|
|
|
|
expect(idSpy.calls.count()).toBe(1);
|
|
expect(idSpy.calls.first().args[0]).toBe("0/0");
|
|
});
|
|
});
|
|
|
|
describe("S2GeometryProvider.latLonToCellIds", () => {
|
|
const setupSpies: (geoCoords: GeoCoords, tileSize: number) => void =
|
|
(geoCoords: GeoCoords, tileSize: number): void => {
|
|
spyOn(S2, "latLngToKey").and.callFake(
|
|
(lat: number, lng: number): string => {
|
|
return `${Math.round(lat)}/${Math.round(lng)}`;
|
|
});
|
|
|
|
spyOn(S2, "keyToId").and.callFake(
|
|
(key: string): string => {
|
|
const [k0, k1]: string[] = key.split("/");
|
|
return `${k0}.${k1}`;
|
|
});
|
|
|
|
spyOn(S2, "idToKey").and.callFake(
|
|
(id: string): string => {
|
|
const [i0, i1]: string[] = id.split(".");
|
|
return `${i0}/${i1}`;
|
|
});
|
|
|
|
spyOn(S2, "keyToLatLng").and.callFake(
|
|
(key: string): S2.ILatLng => {
|
|
const [k0, k1]: string[] = key.split("/");
|
|
const lat: number = Number.parseInt(k0, 10);
|
|
const lng: number = Number.parseInt(k1, 10);
|
|
|
|
return { lat: lat, lng: lng };
|
|
});
|
|
|
|
spyOn(S2.S2Cell, "FromHilbertQuadKey").and.callFake(
|
|
(key: string): S2.S2Cell => {
|
|
const [k0, k1]: string[] = key.split("/");
|
|
const lat: number = Number.parseInt(k0, 10);
|
|
const lng: number = Number.parseInt(k1, 10);
|
|
|
|
const s2Cell: S2.S2Cell = new S2.S2Cell();
|
|
spyOn(s2Cell, "getCornerLatLngs").and.returnValue([
|
|
{ lat: lat + 0.5, lng: lng - 0.5 },
|
|
{ lat: lat + 0.5, lng: lng + 0.5 },
|
|
{ lat: lat - 0.5, lng: lng + 0.5 },
|
|
{ lat: lat - 0.5, lng: lng - 0.5 },
|
|
]);
|
|
|
|
return s2Cell;
|
|
});
|
|
|
|
spyOn(S2, "latLngToNeighborKeys").and.callFake(
|
|
(lat: number, lng: number): string[] => {
|
|
return [
|
|
`${lat}/${lng - 1}`,
|
|
`${lat + 1}/${lng}`,
|
|
`${lat}/${lng + 1}`,
|
|
`${lat - 1}/${lng}`,
|
|
];
|
|
});
|
|
|
|
spyOn(geoCoords, "geodeticToEnu").and.callFake(
|
|
(lat: number, lon: number, _: number, refLat: number, refLon: number): number[] => {
|
|
return [
|
|
tileSize * (lon - refLon),
|
|
tileSize * (lat - refLat),
|
|
0];
|
|
});
|
|
};
|
|
|
|
it("should return cell id of position only", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
const threshold: number = 20;
|
|
const tileSize: number = 2 * (threshold + 1);
|
|
|
|
setupSpies(geoCoords, tileSize);
|
|
|
|
const cellIds: string[] = geometry.latLonToCellIds({ lat: 0, lon: 0 }, threshold);
|
|
|
|
expect(cellIds.length).toBe(1);
|
|
expect(cellIds[0]).toBe("0.0");
|
|
});
|
|
|
|
it("should return cell id of position and north neighbour", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
const threshold: number = 20;
|
|
const tileSize: number = 2 * (threshold + 1);
|
|
|
|
setupSpies(geoCoords, tileSize);
|
|
|
|
const cellIds: string[] = geometry.latLonToCellIds({ lat: 0.4, lon: 0 }, threshold);
|
|
|
|
expect(cellIds.length).toBe(2);
|
|
expect(cellIds.indexOf("0.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("1.0")).not.toBe(-1);
|
|
});
|
|
|
|
it("should return cell id of position and east neighbour", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
const threshold: number = 20;
|
|
const tileSize: number = 2 * (threshold + 1);
|
|
|
|
setupSpies(geoCoords, tileSize);
|
|
|
|
const cellIds: string[] = geometry.latLonToCellIds({ lat: 0, lon: 0.4 }, threshold);
|
|
|
|
expect(cellIds.length).toBe(2);
|
|
expect(cellIds.indexOf("0.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("0.1")).not.toBe(-1);
|
|
});
|
|
|
|
it("should return cell id of position and south neighbour", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
const threshold: number = 20;
|
|
const tileSize: number = 2 * (threshold + 1);
|
|
|
|
setupSpies(geoCoords, tileSize);
|
|
|
|
const cellIds: string[] = geometry.latLonToCellIds({ lat: -0.4, lon: 0 }, threshold);
|
|
|
|
expect(cellIds.length).toBe(2);
|
|
expect(cellIds.indexOf("0.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("-1.0")).not.toBe(-1);
|
|
});
|
|
|
|
it("should return cell id of position and west neighbour", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
const threshold: number = 20;
|
|
const tileSize: number = 2 * (threshold + 1);
|
|
|
|
setupSpies(geoCoords, tileSize);
|
|
|
|
const cellIds: string[] = geometry.latLonToCellIds({ lat: 0, lon: -0.4 }, threshold);
|
|
|
|
expect(cellIds.length).toBe(2);
|
|
expect(cellIds.indexOf("0.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("0.-1")).not.toBe(-1);
|
|
});
|
|
|
|
it("should return cell id of position and north east neighbours", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
const threshold: number = 20;
|
|
const tileSize: number = 2 * (threshold + 1);
|
|
|
|
setupSpies(geoCoords, tileSize);
|
|
|
|
const cellIds: string[] = geometry.latLonToCellIds({ lat: 0.4, lon: 0.4 }, threshold);
|
|
|
|
expect(cellIds.length).toBe(4);
|
|
expect(cellIds.indexOf("0.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("1.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("1.1")).not.toBe(-1);
|
|
expect(cellIds.indexOf("0.1")).not.toBe(-1);
|
|
});
|
|
|
|
it("should return cell id of position and south east neighbours", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
const threshold: number = 20;
|
|
const tileSize: number = 2 * (threshold + 1);
|
|
|
|
setupSpies(geoCoords, tileSize);
|
|
|
|
const cellIds: string[] = geometry.latLonToCellIds({ lat: -0.4, lon: 0.4 }, threshold);
|
|
|
|
expect(cellIds.length).toBe(4);
|
|
expect(cellIds.indexOf("0.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("-1.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("-1.1")).not.toBe(-1);
|
|
expect(cellIds.indexOf("0.1")).not.toBe(-1);
|
|
});
|
|
|
|
it("should return cell id of position and south west neighbours", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
const threshold: number = 20;
|
|
const tileSize: number = 2 * (threshold + 1);
|
|
|
|
setupSpies(geoCoords, tileSize);
|
|
|
|
const cellIds: string[] = geometry.latLonToCellIds({ lat: -0.4, lon: -0.4 }, threshold);
|
|
|
|
expect(cellIds.length).toBe(4);
|
|
expect(cellIds.indexOf("0.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("-1.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("-1.-1")).not.toBe(-1);
|
|
expect(cellIds.indexOf("0.-1")).not.toBe(-1);
|
|
});
|
|
|
|
it("should return cell id of position and north west neighbours", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
const threshold: number = 20;
|
|
const tileSize: number = 2 * (threshold + 1);
|
|
|
|
setupSpies(geoCoords, tileSize);
|
|
|
|
const cellIds: string[] = geometry.latLonToCellIds({ lat: 0.4, lon: -0.4 }, threshold);
|
|
|
|
expect(cellIds.length).toBe(4);
|
|
expect(cellIds.indexOf("0.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("1.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("1.-1")).not.toBe(-1);
|
|
expect(cellIds.indexOf("0.-1")).not.toBe(-1);
|
|
});
|
|
|
|
it("should return cell id of position and all neighbours", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
const threshold: number = 20;
|
|
const tileSize: number = 2 * (threshold - 1);
|
|
|
|
setupSpies(geoCoords, tileSize);
|
|
|
|
const cellIds: string[] = geometry.latLonToCellIds({ lat: 0, lon: 0 }, threshold);
|
|
|
|
expect(cellIds.length).toBe(9);
|
|
expect(cellIds.indexOf("0.0")).not.toBe(-1);
|
|
expect(cellIds.indexOf("0.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("0.-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);
|
|
});
|
|
});
|
|
|
|
describe("S2GeometryProvider.bboxToCellIds", () => {
|
|
it("should throw if north east is not larger than south west", () => {
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider();
|
|
|
|
expect(() => { geometry.bboxToCellIds({ lat: 0, lon: 0 }, { lat: -1, lon: 1 }); })
|
|
.toThrowError(MapillaryError);
|
|
expect(() => { geometry.bboxToCellIds({ lat: 0, lon: 0 }, { lat: 1, lon: -1 }); })
|
|
.toThrowError(MapillaryError);
|
|
expect(() => { geometry.bboxToCellIds({ lat: 0, lon: 0 }, { lat: -1, lon: -1 }); })
|
|
.toThrowError(MapillaryError);
|
|
});
|
|
|
|
it("should call latLonToCellIds with center and correct threshold", () => {
|
|
const geoCoords: GeoCoords = new GeoCoords();
|
|
const geometry: S2GeometryProvider = new S2GeometryProvider(geoCoords);
|
|
|
|
spyOn(geoCoords, "geodeticToEnu").and.returnValue([10, 20, 0]);
|
|
const encodeHsSpy: jasmine.Spy = spyOn(geometry, "latLonToCellIds").and.stub();
|
|
|
|
geometry.bboxToCellIds({ lat: 0, lon: 0 }, { lat: 1, lon: 3 });
|
|
|
|
expect(encodeHsSpy.calls.count()).toBe(1);
|
|
expect(encodeHsSpy.calls.argsFor(0)[0].lat).toBe(0.5);
|
|
expect(encodeHsSpy.calls.argsFor(0)[0].lon).toBe(1.5);
|
|
});
|
|
});
|