UNPKG

mapillary-js

Version:

WebGL JavaScript library for displaying street level imagery from mapillary.com

641 lines (485 loc) 23.7 kB
import {empty as observableEmpty, Observable} from "rxjs"; import * as THREE from "three"; import {MockCreator} from "../helper/MockCreator.spec"; import { ImageTileLoader, ImageTileStore, IRegionOfInterest, TextureProvider, } from "../../src/Tiles"; class RendererMock implements THREE.Renderer { public domElement: HTMLCanvasElement = document.createElement("canvas"); public getContext(): void { return; } public render(s: THREE.Scene, c: THREE.Camera, t?: THREE.WebGLRenderTarget): void { return; } public getRenderTarget(): THREE.RenderTarget { return; } public setRenderTarget(t?: THREE.WebGLRenderTarget): void { return; } public setSize(w: number, h: number, updateStyle?: boolean): void { return; } } describe("TextureProvider.ctor", () => { it("should be contructed", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); (<jasmine.Spy>imageTileLoader.getTile).and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let textureProvider: TextureProvider = new TextureProvider( "", 1, 1, 1, new Image(), imageTileLoader, imageTileStore, rendererMock); expect(textureProvider).toBeDefined(); }); }); describe("TextureProvider.setRegionOfInterest", () => { it("should request one tile for the whole image with original size when resolution is the same as the image size", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = tileSize; let height: number = tileSize; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 0, maxY: 0, minX: 0, minY: 0}, pixelHeight: 1 / height, pixelWidth: 1 / width, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(1); let callInfo: jasmine.CallInfo<jasmine.Func> = getTileSpy.calls.first(); expect(callInfo.args.length).toBe(7); expect(callInfo.args[1]).toBe(0); expect(callInfo.args[2]).toBe(0); expect(callInfo.args[3]).toBe(width); expect(callInfo.args[4]).toBe(height); expect(callInfo.args[5]).toBe(width); expect(callInfo.args[6]).toBe(height); }); it("should request one tile for the whole image with original size when resolution higher than image size", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = tileSize; let height: number = tileSize; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 1, maxY: 1, minX: 0, minY: 0}, pixelHeight: 1 / height / 4, pixelWidth: 1 / width / 4, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(1); let callInfo: jasmine.CallInfo<jasmine.Func> = getTileSpy.calls.first(); expect(callInfo.args.length).toBe(7); expect(callInfo.args[1]).toBe(0); expect(callInfo.args[2]).toBe(0); expect(callInfo.args[3]).toBe(width); expect(callInfo.args[4]).toBe(height); expect(callInfo.args[5]).toBe(width); expect(callInfo.args[6]).toBe(height); }); it("should request one tile for the whole image with scaled size when resolution is lower than image size", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = tileSize; let height: number = tileSize; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 1, maxY: 1, minX: 0, minY: 0}, pixelHeight: 2 / height, pixelWidth: 2 / width, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(1); let callInfo: jasmine.CallInfo<jasmine.Func> = getTileSpy.calls.first(); expect(callInfo.args.length).toBe(7); expect(callInfo.args[1]).toBe(0); expect(callInfo.args[2]).toBe(0); expect(callInfo.args[3]).toBe(width); expect(callInfo.args[4]).toBe(height); expect(callInfo.args[5]).toBe(width / 2); expect(callInfo.args[6]).toBe(height / 2); }); it("should request one tile for the whole image with scaled size 1 x 1 when image is contained in one screen pixel", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = tileSize; let height: number = tileSize; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 1, maxY: 1, minX: 0, minY: 0}, pixelHeight: 2, pixelWidth: 2, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(1); let callInfo: jasmine.CallInfo<jasmine.Func> = getTileSpy.calls.first(); expect(callInfo.args.length).toBe(7); expect(callInfo.args[1]).toBe(0); expect(callInfo.args[2]).toBe(0); expect(callInfo.args[3]).toBe(width); expect(callInfo.args[4]).toBe(height); expect(callInfo.args[5]).toBe(1); expect(callInfo.args[6]).toBe(1); }); it("should request one tile with correct size when image width is larger than tile size", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = 512 + 100; let height: number = 512; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 1, maxY: 1, minX: 1, minY: 0}, pixelHeight: 1 / height / 2, pixelWidth: 1 / width / 2, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(1); let callInfo: jasmine.CallInfo<jasmine.Func> = getTileSpy.calls.first(); expect(callInfo.args.length).toBe(7); expect(callInfo.args[1]).toBe(tileSize); expect(callInfo.args[2]).toBe(0); expect(callInfo.args[3]).toBe(width - tileSize); expect(callInfo.args[4]).toBe(height); expect(callInfo.args[5]).toBe(width - tileSize); expect(callInfo.args[6]).toBe(height); }); it("should request one tile with correct size when image width is larger than tile size", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = 512; let height: number = 512 + 200; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 1, maxY: 1, minX: 0, minY: 1}, pixelHeight: 1 / height / 2, pixelWidth: 1 / width / 2, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(1); let callInfo: jasmine.CallInfo<jasmine.Func> = getTileSpy.calls.first(); expect(callInfo.args.length).toBe(7); expect(callInfo.args[1]).toBe(0); expect(callInfo.args[2]).toBe(tileSize); expect(callInfo.args[3]).toBe(width); expect(callInfo.args[4]).toBe(height - tileSize); expect(callInfo.args[5]).toBe(width); expect(callInfo.args[6]).toBe(height - tileSize); }); it("should request one tile with correct size when image width is larger than tile size", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = 512 + 16; let height: number = 512 + 16; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 1, maxY: 1, minX: 1, minY: 1}, pixelHeight: 1 / height / 2, pixelWidth: 1 / width / 2, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(1); let callInfo: jasmine.CallInfo<jasmine.Func> = getTileSpy.calls.first(); expect(callInfo.args.length).toBe(7); expect(callInfo.args[1]).toBe(tileSize); expect(callInfo.args[2]).toBe(tileSize); expect(callInfo.args[3]).toBe(width - tileSize); expect(callInfo.args[4]).toBe(height - tileSize); expect(callInfo.args[5]).toBe(width - tileSize); expect(callInfo.args[6]).toBe(height - tileSize); }); it("should request correct width and height and not scale image when image aspect ratio is not square", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = 488; let height: number = 324; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 1, maxY: 1, minX: 0, minY: 0}, pixelHeight: 1 / tileSize, pixelWidth: 1 / tileSize, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(1); let callInfo: jasmine.CallInfo<jasmine.Func> = getTileSpy.calls.first(); expect(callInfo.args.length).toBe(7); expect(callInfo.args[1]).toBe(0); expect(callInfo.args[2]).toBe(0); expect(callInfo.args[3]).toBe(width); expect(callInfo.args[4]).toBe(height); expect(callInfo.args[5]).toBe(width); expect(callInfo.args[6]).toBe(height); }); it("should request correct width and height and scale image when image aspect ratio is not square", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = 488; let height: number = 324; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 1, maxY: 1, minX: 0, minY: 0}, pixelHeight: 2 / tileSize, pixelWidth: 2 / tileSize, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(1); let callInfo: jasmine.CallInfo<jasmine.Func> = getTileSpy.calls.first(); expect(callInfo.args.length).toBe(7); expect(callInfo.args[1]).toBe(0); expect(callInfo.args[2]).toBe(0); expect(callInfo.args[3]).toBe(width); expect(callInfo.args[4]).toBe(height); expect(callInfo.args[5]).toBe(width / 2); expect(callInfo.args[6]).toBe(height / 2); }); it("should request multiple tiles in x direction", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = 2 * tileSize; let height: number = 2 * tileSize; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 0.75, maxY: 0.25, minX: 0.25, minY: 0}, pixelHeight: 1 / width, pixelWidth: 1 / height, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(2); let args1: any[] = getTileSpy.calls.argsFor(0); expect(args1.length).toBe(7); expect(args1[1]).toBe(0); expect(args1[2]).toBe(0); expect(args1[3]).toBe(tileSize); expect(args1[4]).toBe(tileSize); expect(args1[5]).toBe(tileSize); expect(args1[6]).toBe(tileSize); let args2: any[] = getTileSpy.calls.argsFor(1); expect(args2.length).toBe(7); expect(args2[1]).toBe(tileSize); expect(args2[2]).toBe(0); expect(args2[3]).toBe(tileSize); expect(args2[4]).toBe(tileSize); expect(args2[5]).toBe(tileSize); expect(args2[6]).toBe(tileSize); }); it("should request multiple tiles in y direction", () => { spyOn(console, "warn").and.stub(); let imageTileLoader: ImageTileLoader = new MockCreator().create(ImageTileLoader, "ImageTileLoader"); let getTileSpy: jasmine.Spy = <jasmine.Spy>imageTileLoader.getTile; getTileSpy.and.returnValue([observableEmpty(), (): void => { return; }]); let imageTileStore: ImageTileStore = new MockCreator().create(ImageTileStore, "ImageTileStore"); let rendererMock: THREE.WebGLRenderer = <THREE.WebGLRenderer>new RendererMock(); spyOn(rendererMock, "getContext").and.returnValue( <WebGLRenderingContext><unknown>{ getParameter: () => { return 1024; } }); spyOn(THREE, "WebGLRenderer").and.returnValue(rendererMock); let tileSize: number = 512; let width: number = 2 * tileSize; let height: number = 2 * tileSize; let textureProvider: TextureProvider = new TextureProvider( "", width, height, tileSize, new Image(), imageTileLoader, imageTileStore, rendererMock); let roi: IRegionOfInterest = { bbox: { maxX: 0.25, maxY: 0.75, minX: 0, minY: 0.25 }, pixelHeight: 1 / width, pixelWidth: 1 / height, }; textureProvider.setRegionOfInterest(roi); expect(getTileSpy.calls.count()).toBe(2); let args1: any[] = getTileSpy.calls.argsFor(0); expect(args1.length).toBe(7); expect(args1[1]).toBe(0); expect(args1[2]).toBe(0); expect(args1[3]).toBe(tileSize); expect(args1[4]).toBe(tileSize); expect(args1[5]).toBe(tileSize); expect(args1[6]).toBe(tileSize); let args2: any[] = getTileSpy.calls.argsFor(1); expect(args2.length).toBe(7); expect(args2[1]).toBe(0); expect(args2[2]).toBe(tileSize); expect(args2[3]).toBe(tileSize); expect(args2[4]).toBe(tileSize); expect(args2[5]).toBe(tileSize); expect(args2[6]).toBe(tileSize); }); });