From d90f8d64a91d1c29bf5247b00a6bb76e0ae35b18 Mon Sep 17 00:00:00 2001 From: Oscar Lorentzon Date: Wed, 20 Apr 2016 11:06:35 +0200 Subject: [PATCH] Make node properties readonly. Remove duplicated key param from constructor. Adjust unit tests. --- spec/geo/Transform.spec.ts | 56 ++-- spec/graph/Node.spec.ts | 32 +-- .../edge/EdgeCalculator.Sequence.spec.ts | 2 +- spec/graph/edge/EdgeCalculator.spec.ts | 4 +- spec/helper/EdgeCalculatorHelper.spec.ts | 2 +- src/graph/Graph.ts | 13 +- src/graph/Node.ts | 264 +++++++++++------- 7 files changed, 211 insertions(+), 162 deletions(-) diff --git a/spec/geo/Transform.spec.ts b/spec/geo/Transform.spec.ts index 0a8afcf6..dbad6610 100644 --- a/spec/geo/Transform.spec.ts +++ b/spec/geo/Transform.spec.ts @@ -15,7 +15,7 @@ describe("Transform.rt", () => { let r: number[] = [0, 0, 0]; let t: number[] = [0, 0, 0]; - let node: Node = new Node("", 0, null, true, null, { key: "", rotation: r }, []); + let node: Node = new Node(0, null, true, null, { key: "", rotation: r }, []); let transform: Transform = new Transform(node, t); let Rt: THREE.Matrix4 = transform.rt; @@ -45,7 +45,7 @@ describe("Transform.rt", () => { let r: number[] = [0, 0, Math.PI]; let t: number[] = [0, 0, 0]; - let node: Node = new Node("key", 0, null, true, null, { key: "key", rotation: r }, []); + let node: Node = new Node(0, null, true, null, { key: "key", rotation: r }, []); let transform: Transform = new Transform(node, t); let Rt: THREE.Matrix4 = transform.rt; @@ -75,7 +75,7 @@ describe("Transform.rt", () => { let r: number[] = [Math.PI / 2, 0, 0]; let t: number[] = [0, 0, 0]; - let node: Node = new Node("key", 0, null, true, null, { key: "key", rotation: r }, []); + let node: Node = new Node(0, null, true, null, { key: "key", rotation: r }, []); let transform: Transform = new Transform(node, t); let Rt: THREE.Matrix4 = transform.rt; @@ -105,7 +105,7 @@ describe("Transform.rt", () => { let r: number[] = [0, 0, 0]; let t: number[] = [10, 20, 30]; - let node: Node = new Node("key", 0, null, true, null, { key: "key", rotation: r }, []); + let node: Node = new Node(0, null, true, null, { key: "key", rotation: r }, []); let transform: Transform = new Transform(node, t); let Rt: THREE.Matrix4 = transform.rt; @@ -139,7 +139,7 @@ describe("Transform.srt", () => { let r: number[] = [0, 0, 0]; let t: number[] = [0, 0, 0]; - let node: Node = new Node("", 0, null, true, null, { key: "", rotation: r, atomic_scale: 1 }, []); + let node: Node = new Node(0, null, true, null, { key: "", rotation: r, atomic_scale: 1 }, []); let transform: Transform = new Transform(node, t); let sRt: THREE.Matrix4 = transform.srt; @@ -169,7 +169,7 @@ describe("Transform.srt", () => { let r: number[] = [0, Math.PI / 2, 0]; let t: number[] = [0, 0, 0]; - let node: Node = new Node("", 0, null, true, null, { key: "", rotation: r, atomic_scale: 3 }, []); + let node: Node = new Node(0, null, true, null, { key: "", rotation: r, atomic_scale: 3 }, []); let transform: Transform = new Transform(node, t); let sRt: THREE.Matrix4 = transform.srt; @@ -199,7 +199,7 @@ describe("Transform.srt", () => { let r: number[] = [0, 0, 0]; let t: number[] = [-10, 20, -30]; - let node: Node = new Node("", 0, null, true, null, { key: "", rotation: r, atomic_scale: 0.5 }, []); + let node: Node = new Node(0, null, true, null, { key: "", rotation: r, atomic_scale: 0.5 }, []); let transform: Transform = new Transform(node, t); let sRt: THREE.Matrix4 = transform.srt; @@ -230,7 +230,7 @@ describe("Transform.width", () => { it("should have fallback width", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0, 0, 0] }, []); @@ -244,7 +244,7 @@ describe("Transform.width", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { width: width, key: "", rotation: [0, 0, 0] }, []); @@ -258,7 +258,7 @@ describe("Transform.height", () => { it("should have fallback height", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { height: -1, key: "", rotation: [0, 0, 0] }, []); @@ -272,7 +272,7 @@ describe("Transform.height", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { height: height, key: "", rotation: [0, 0, 0] }, []); @@ -286,7 +286,7 @@ describe("Transform.focal", () => { it("should have fallback focal", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0, 0, 0] }, []); @@ -300,7 +300,7 @@ describe("Transform.focal", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { cfocal: focal, key: "", rotation: [0, 0, 0] }, []); @@ -314,7 +314,7 @@ describe("Transform.orientation", () => { it("should have fallback orientation", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0, 0, 0] }, []); @@ -328,7 +328,7 @@ describe("Transform.orientation", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { orientation: orientation, key: "", rotation: [0, 0, 0] }, []); @@ -342,7 +342,7 @@ describe("Transform.scale", () => { it("should have fallback scale", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0, 0, 0] }, []); @@ -356,7 +356,7 @@ describe("Transform.scale", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { atomic_scale: scale, key: "", rotation: [0, 0, 0] }, []); @@ -370,7 +370,7 @@ describe("Transform.gpano", () => { it("should not have gpano set", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0, 0, 0] }, []); @@ -391,7 +391,7 @@ describe("Transform.gpano", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { gpano: gpano, key: "", rotation: [0, 0, 0] }, []); @@ -413,7 +413,7 @@ describe("Transform.pixelToVertex", () => { it("should return vertex at origin", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0, 0, 0] }, []); @@ -429,7 +429,7 @@ describe("Transform.pixelToVertex", () => { it("should return vertex at inverted translation", () => { let t: number[] = [10, -20, 30]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0, 0, 0] }, []); @@ -448,7 +448,7 @@ describe("Transform.pixelToVertex", () => { let t: number[] = geoHelper.getTranslation(r, C); let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: r }, []); @@ -464,7 +464,7 @@ describe("Transform.pixelToVertex", () => { it("should return vertex 10 units front of origin in camera direction", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0, 0, 0] }, []); @@ -484,7 +484,7 @@ describe("Transform.pixelToVertex", () => { let t: number[] = geoHelper.getTranslation(r, C); let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: r }, []); @@ -505,7 +505,7 @@ describe("Transform.projectBasic", () => { it("should project to the image center", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0, 0, 0] }, []); @@ -520,7 +520,7 @@ describe("Transform.projectBasic", () => { it("should project to the first quadrant", () => { let t: number[] = [0, 0, 0]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0, 0, 0] }, []); @@ -539,7 +539,7 @@ describe("Transform.unprojectBasic", () => { it("should back-project to the same pixel", () => { let t: number[] = [10, 20, 30]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { key: "", rotation: [0.1, 0.2, 0.3] }, []); @@ -558,7 +558,7 @@ describe("Transform.unprojectBasic", () => { it("should back-project to the same pixel for full pano", () => { let t: number[] = [5, 15, 2]; let node: Node = new Node( - "", 0, null, true, null, + 0, null, true, null, { gpano: { CroppedAreaLeftPixels: 0, diff --git a/spec/graph/Node.spec.ts b/spec/graph/Node.spec.ts index a77842e8..d9c55ca9 100644 --- a/spec/graph/Node.spec.ts +++ b/spec/graph/Node.spec.ts @@ -1,13 +1,13 @@ /// -import {IAPINavImIm} from "../../src/API"; +import {IAPINavImIm, IAPINavImS} from "../../src/API"; import {Node, Sequence} from "../../src/Graph"; describe("Node", () => { var sequence: Sequence; beforeEach(() => { - let response: any = { + let response: IAPINavImS = { key: 'A', keys: ['B','C','D','E'], path: {} @@ -16,53 +16,53 @@ describe("Node", () => { }); it("should create a node", () => { - let node: Node = new Node("C", 0, {lat: 1, lon: 1}, true, sequence, null, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "C" }, null); expect(node).toBeDefined(); }); it("should find next node key in nodes sequence", () => { - let node: Node = new Node("C", 0, {lat: 1, lon: 1}, true, sequence, null, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "C" }, null); expect(node.findNextKeyInSequence()).toEqual('D') }); it("should find prev node key in nodes sequence", () => { - let node: Node = new Node("C", 0, {lat: 1, lon: 1}, true, sequence, null, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "C" }, null); expect(node.findPrevKeyInSequence()).toEqual('B') }); it("should return null if no next key", () => { - let node: Node = new Node("E", 0, {lat: 1, lon: 1}, true, sequence, null, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "E" }, null); expect(node.findNextKeyInSequence()).toBe(null) }); it("should return null if no prev key", () => { - let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, null, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "B" }, null); expect(node.findPrevKeyInSequence()).toBe(null) }); it("should not be merged", () => { - let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, null, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, { key: "B" }, null); expect(node.merged).toBe(false) }); it("should not be merged because merge version is zero", () => { let apiNavImIm: IAPINavImIm = { key: "B", merge_version: 0} - let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); expect(node.merged).toBe(false) }); it("should be merged because merge version present and larger than zero", () => { let apiNavImIm: IAPINavImIm = { key: "B", merge_version: 4} - let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); expect(node.merged).toBe(true) }); it("should not be full pano when gpano is null", () => { let apiNavImIm: IAPINavImIm = { key: "B", gpano: null } - let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); expect(node.fullPano).toBe(false) }); @@ -79,7 +79,7 @@ describe("Node", () => { } }; - let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); expect(node.fullPano).toBe(false) }); @@ -96,7 +96,7 @@ describe("Node", () => { } }; - let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); expect(node.fullPano).toBe(false) }); @@ -113,7 +113,7 @@ describe("Node", () => { } }; - let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); expect(node.fullPano).toBe(false) }); @@ -130,7 +130,7 @@ describe("Node", () => { } }; - let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); expect(node.fullPano).toBe(false) }); @@ -147,7 +147,7 @@ describe("Node", () => { } }; - let node: Node = new Node("B", 0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); + let node: Node = new Node(0, {lat: 1, lon: 1}, true, sequence, apiNavImIm, null); expect(node.fullPano).toBe(true) }); }); \ No newline at end of file diff --git a/spec/graph/edge/EdgeCalculator.Sequence.spec.ts b/spec/graph/edge/EdgeCalculator.Sequence.spec.ts index 905df4d4..0c1701e1 100644 --- a/spec/graph/edge/EdgeCalculator.Sequence.spec.ts +++ b/spec/graph/edge/EdgeCalculator.Sequence.spec.ts @@ -21,7 +21,7 @@ describe("EdgeCalculator.computeSequenceEdges", () => { let apiNavImIm: IAPINavImIm = { key: key }; - let node: Node = new Node(key, 0, {lat: 0, lon: 0}, true, sequence, apiNavImIm, []); + let node: Node = new Node(0, {lat: 0, lon: 0}, true, sequence, apiNavImIm, []); return node; } diff --git a/spec/graph/edge/EdgeCalculator.spec.ts b/spec/graph/edge/EdgeCalculator.spec.ts index ea31f7d8..53ba6819 100644 --- a/spec/graph/edge/EdgeCalculator.spec.ts +++ b/spec/graph/edge/EdgeCalculator.spec.ts @@ -57,7 +57,7 @@ describe("EdgeCalculator.getPotentialEdges", () => { } : apiNavImIm; - return new Node(key, 0, latLonAlt, true, sequence, apiNavImIm, []); + return new Node(0, latLonAlt, true, sequence, apiNavImIm, []); }; let createRotationVector = (azimuth: number, norm: number = Math.PI / 2): number[] => { @@ -80,7 +80,7 @@ describe("EdgeCalculator.getPotentialEdges", () => { }); it("should return empty array when node is not worthy", () => { - let node: Node = new Node("key", 0, null, false, null, null, null); + let node: Node = new Node(0, null, false, null, { key: "" }, null); let result: IPotentialEdge[] = edgeCalculator.getPotentialEdges(node, null, []); diff --git a/spec/helper/EdgeCalculatorHelper.spec.ts b/spec/helper/EdgeCalculatorHelper.spec.ts index 284b0f79..45dfc4e7 100644 --- a/spec/helper/EdgeCalculatorHelper.spec.ts +++ b/spec/helper/EdgeCalculatorHelper.spec.ts @@ -38,7 +38,7 @@ export class EdgeCalculatorHelper { } } - let node: Node = new Node(key, 0, {lat: 0, lon: 0}, true, sequence, apiNavImIm, []); + let node: Node = new Node(0, {lat: 0, lon: 0}, true, sequence, apiNavImIm, []); return node; } diff --git a/src/graph/Graph.ts b/src/graph/Graph.ts index d8dfcce0..99e0ca1e 100644 --- a/src/graph/Graph.ts +++ b/src/graph/Graph.ts @@ -135,18 +135,7 @@ export class Graph { } } - let node: Node = new Node( - im.key, - ca, - latLon, - false, - sequence, - im, - hs - ); - - node.user = im.user; - node.capturedAt = im.captured_at; + let node: Node = new Node(ca, latLon, false, sequence, im, hs); this._unWorthyNodes[im.key] = true; diff --git a/src/graph/Node.ts b/src/graph/Node.ts index da2e55e9..fbc6d949 100644 --- a/src/graph/Node.ts +++ b/src/graph/Node.ts @@ -14,143 +14,109 @@ interface ILoadStatusObject { } export class Node { - public key: string; - public user: string; - public capturedAt: number; - public ca: number; - public latLon: ILatLon; public worthy: boolean; - public sequence: Sequence; - public apiNavImIm: IAPINavImIm; public cached: boolean; + public lastCacheEvict: number; public lastUsed: number; - public image: any; - public mesh: IMesh; - public edges: IEdge[]; + private _apiNavImIm: IAPINavImIm; + private _key: string; + private _ca: number; + private _latLon: ILatLon; + private _sequence: Sequence; - public hs: string[]; + private _hs: string[]; - public loadStatus: ILoadStatus; + private _image: HTMLImageElement; + private _mesh: IMesh; + private _edges: IEdge[]; + + private _loadStatus: ILoadStatus; constructor ( - key: string, ca: number, latLon: ILatLon, worthy: boolean, sequence: Sequence, apiNavImIm: IAPINavImIm, hs: string[]) { - this.key = key; - this.ca = ca; - this.latLon = latLon; + + this._apiNavImIm = apiNavImIm; + this._key = apiNavImIm.key; + this._ca = ca; + this._latLon = latLon; + this._sequence = sequence; + + this._hs = hs; + + this._image = null; + this._mesh = null; + this._edges = null; + this.worthy = worthy; - this.sequence = sequence; - this.apiNavImIm = apiNavImIm; this.cached = false; + this.lastCacheEvict = 0; this.lastUsed = new Date().getTime(); - this.hs = hs; - - this.loadStatus = {loaded: 0, total: 100}; + this._loadStatus = { loaded: 0, total: 100 }; } - public cacheAssets(): rx.Observable { - return this.cacheImage().combineLatest(this.cacheMesh(), (image: ILoadStatusObject, mesh: ILoadStatusObject): Node => { - this.loadStatus.loaded = 0; - this.loadStatus.total = 0; - - if (mesh) { - this.mesh = mesh.object; - this.loadStatus.loaded += mesh.loaded.loaded; - this.loadStatus.total += mesh.loaded.total; - } - if (image) { - this.image = image.object; - this.loadStatus.loaded += image.loaded.loaded; - this.loadStatus.total += image.loaded.total; - } - return this; - }); + public get apiNavImIm(): IAPINavImIm { + return this._apiNavImIm; } - public cacheImage(): rx.Observable { - return rx.Observable.create((observer: rx.Observer): void => { - let img: HTMLImageElement = new Image(); - img.crossOrigin = "Anonymous"; - - if (process.env.MAPENV === "development") { - observer.onNext({loaded: {loaded: 1, total: 1}, object: this.image}); - observer.onCompleted(); - return; - } - - let xmlHTTP: XMLHttpRequest = new XMLHttpRequest(); - xmlHTTP.open("GET", Urls.image(this.key, Settings.baseImageSize), true); - xmlHTTP.responseType = "arraybuffer"; - xmlHTTP.onload = (e: any) => { - img.onload = () => { - observer.onNext({loaded: {loaded: e.loaded, total: e.total}, object: img}); - observer.onCompleted(); - }; - - img.onerror = (err: Event) => { - observer.onError(err); - }; - - let blob: Blob = new Blob([xmlHTTP.response]); - img.src = window.URL.createObjectURL(blob); - }; - xmlHTTP.onprogress = (e: any) => { - observer.onNext({loaded: {loaded: e.loaded, total: e.total}, object: null}); - }; - xmlHTTP.send(); - }); + public get user(): string { + return this._apiNavImIm.user; } - public cacheMesh(): rx.Observable { - return rx.Observable.create((observer: rx.Observer): void => { - if (process.env.MAPENV === "development") { - observer.onNext({loaded: {loaded: 1, total: 1}, object: { faces: [[-1]], vertices: [[-1]] }}); - observer.onCompleted(); - return; - } + public get capturedAt(): number { + return this._apiNavImIm.captured_at; + } - if (!this.merged) { - let mesh: IMesh = { faces: [], vertices: [] }; - observer.onNext({ loaded: { loaded: 0, total: 0 }, object: mesh }); - observer.onCompleted(); + public get key(): string { + return this._key; + } - return; - } + public get ca(): number { + return this._ca; + } - let xmlHTTP: XMLHttpRequest = new XMLHttpRequest(); - xmlHTTP.open("GET", Urls.proto_mesh(this.key), true); - xmlHTTP.responseType = "arraybuffer"; - xmlHTTP.onload = (e: any) => { - let mesh: IMesh; - if (xmlHTTP.status === 200) { - mesh = MeshReader.read(new Buffer(xmlHTTP.response)); - } else { - mesh = { faces: [], vertices: [] }; - } + public get latLon(): ILatLon { + return this._latLon; + } - observer.onNext({ loaded: {loaded: e.loaded, total: e.total }, object: mesh }); - observer.onCompleted(); - }; + public get sequence(): Sequence { + return this._sequence; + } - xmlHTTP.onprogress = (e: any) => { - observer.onNext({ loaded: { loaded: e.loaded, total: e.total }, object: null}); - }; + public get hs(): string[] { + return this._hs; + } - xmlHTTP.send(null); - }); + public get image(): HTMLImageElement { + return this._image; + } + + public get mesh(): IMesh { + return this._mesh; + } + + public get edges(): IEdge[] { + return this._edges; + } + + public set edges(value: IEdge[]) { + this._edges = value; + } + + public get loadStatus(): ILoadStatus { + return this._loadStatus; } public get loaded(): boolean { - return this.cached && this.image != null; + return this.cached && this._image != null; } public get merged(): boolean { @@ -185,6 +151,100 @@ export class Node { } return this.sequence.findPrevKey(this.key); } + + public cacheAssets(): rx.Observable { + return this.cacheImage().combineLatest(this.cacheMesh(), (image: ILoadStatusObject, mesh: ILoadStatusObject): Node => { + this._loadStatus.loaded = 0; + this._loadStatus.total = 0; + + if (mesh) { + this._mesh = mesh.object; + this._loadStatus.loaded += mesh.loaded.loaded; + this._loadStatus.total += mesh.loaded.total; + } + + if (image) { + this._image = image.object; + this._loadStatus.loaded += image.loaded.loaded; + this._loadStatus.total += image.loaded.total; + } + + return this; + }); + } + + public cacheImage(): rx.Observable { + return rx.Observable.create((observer: rx.Observer): void => { + let img: HTMLImageElement = new Image(); + img.crossOrigin = "Anonymous"; + + if (process.env.MAPENV === "development") { + observer.onNext({ loaded: {loaded: 1, total: 1}, object: this._image }); + observer.onCompleted(); + return; + } + + let xmlHTTP: XMLHttpRequest = new XMLHttpRequest(); + xmlHTTP.open("GET", Urls.image(this.key, Settings.baseImageSize), true); + xmlHTTP.responseType = "arraybuffer"; + xmlHTTP.onload = (e: any) => { + img.onload = () => { + observer.onNext({ loaded: { loaded: e.loaded, total: e.total }, object: img }); + observer.onCompleted(); + }; + + img.onerror = (err: Event) => { + observer.onError(err); + }; + + let blob: Blob = new Blob([xmlHTTP.response]); + img.src = window.URL.createObjectURL(blob); + }; + xmlHTTP.onprogress = (e: any) => { + observer.onNext({loaded: { loaded: e.loaded, total: e.total}, object: null }); + }; + xmlHTTP.send(); + }); + } + + public cacheMesh(): rx.Observable { + return rx.Observable.create((observer: rx.Observer): void => { + if (process.env.MAPENV === "development") { + observer.onNext({loaded: { loaded: 1, total: 1}, object: { faces: [[-1]], vertices: [[-1]] } }); + observer.onCompleted(); + return; + } + + if (!this.merged) { + let mesh: IMesh = { faces: [], vertices: [] }; + observer.onNext({ loaded: { loaded: 0, total: 0 }, object: mesh }); + observer.onCompleted(); + + return; + } + + let xmlHTTP: XMLHttpRequest = new XMLHttpRequest(); + xmlHTTP.open("GET", Urls.proto_mesh(this.key), true); + xmlHTTP.responseType = "arraybuffer"; + xmlHTTP.onload = (e: any) => { + let mesh: IMesh; + if (xmlHTTP.status === 200) { + mesh = MeshReader.read(new Buffer(xmlHTTP.response)); + } else { + mesh = { faces: [], vertices: [] }; + } + + observer.onNext({ loaded: { loaded: e.loaded, total: e.total }, object: mesh }); + observer.onCompleted(); + }; + + xmlHTTP.onprogress = (e: any) => { + observer.onNext({ loaded: { loaded: e.loaded, total: e.total }, object: null }); + }; + + xmlHTTP.send(null); + }); + } } export default Node;