From 56388aee93b072e1a7f33a9736106ada90331470 Mon Sep 17 00:00:00 2001 From: Johan Gyllenspetz Date: Wed, 11 Nov 2015 21:47:45 -0800 Subject: [PATCH] Add movDir to Viewer --- spec/Viewer.spec.ts | 13 ++++++- src/Graph.ts | 1 + src/graph/EdgeCalculator.ts | 6 +-- src/graph/Graph.ts | 69 +++++++++++++++++++++++++--------- src/viewer/Viewer.ts | 45 +++++++++++++++++----- typings/graphlib/graphlib.d.ts | 1 + 6 files changed, 101 insertions(+), 34 deletions(-) diff --git a/spec/Viewer.spec.ts b/spec/Viewer.spec.ts index f612bda2..19758364 100644 --- a/spec/Viewer.spec.ts +++ b/spec/Viewer.spec.ts @@ -17,8 +17,17 @@ describe("Viewer.moveToKey", () => { }); it("should move to a key", (done) => { - viewer.moveToKey("h_tzkTklF6DZfU5plCA9Cw", (data: any) => { - done(); + var response: any = viewer.moveToKey("XkK3qsRg9j9UY5jTg8BKGQ"); + + response.then((node: any) => { + // fixme depends on real API data + expect(node.key).toBe("XkK3qsRg9j9UY5jTg8BKGQ"); + response = viewer.moveDir(Mapillary.GraphConstants.DirEnum.NEXT); + + response.then((node: any) => { + expect(node.key).toBe("EUTk0zsxzVgIyE6XeO-yWQ"); + done(); + }); }); }); }); diff --git a/src/Graph.ts b/src/Graph.ts index e976170d..ae9092c4 100644 --- a/src/Graph.ts +++ b/src/Graph.ts @@ -3,3 +3,4 @@ export {Graph} from "./graph/Graph"; export {GraphConstants} from "./graph/GraphConstants"; export {Node} from "./graph/Node"; export {Sequence} from "./graph/Sequence"; +export * from "./graph/interfaces/interfaces"; diff --git a/src/graph/EdgeCalculator.ts b/src/graph/EdgeCalculator.ts index 34f6fdb9..abacd104 100644 --- a/src/graph/EdgeCalculator.ts +++ b/src/graph/EdgeCalculator.ts @@ -1,8 +1,4 @@ -import {GraphConstants, Node} from "../Graph"; - -export interface ICalculatedEdges { - [key: string]: string[]; -} +import {ICalculatedEdges, GraphConstants, Node} from "../Graph"; export class EdgeCalculator { public calculateEdges(node: Node): ICalculatedEdges { diff --git a/src/graph/Graph.ts b/src/graph/Graph.ts index e7fcfc6a..82bfeab5 100644 --- a/src/graph/Graph.ts +++ b/src/graph/Graph.ts @@ -4,8 +4,7 @@ import * as graphlib from "graphlib"; import * as rbush from "rbush"; -import {GraphConstants} from "../Graph"; -import {ICalculatedEdges, EdgeCalculator} from "../Graph"; +import {GraphConstants, ICalculatedEdges, EdgeCalculator} from "../Graph"; import {IAPINavIm, IAPINavImIm} from "../API"; import {ILatLon} from "../Viewer"; import {Node} from "./Node"; @@ -31,7 +30,7 @@ export class Graph { this.mapImageSequences = {}; this.sequences = {}; this.spatial = rbush(20000, [".lon", ".lat", ".lon", ".lat"]); - this.graph = new graphlib.Graph(); + this.graph = new graphlib.Graph({multigraph: true}); this.edgeCalculator = new EdgeCalculator(); this.traversedCache = {}; @@ -83,6 +82,36 @@ export class Graph { } } + public keyIsWorthy(key: string): boolean { + let node: Node = this.node(key); + + if (node == null) { + return false; + } + + return node.worthy; + } + + public nextNode(node: Node, dir: GraphConstants.DirEnum): Node { + let outEdges: any[] = this.graph.outEdges(node.key); + + for (var i in outEdges) { + if (outEdges.hasOwnProperty(i)) { + let e: any = outEdges[i]; + if (this.graph.edge(e.v, e.w) === dir) { + return this.node(e.w); + } + } + } + + return null; + } + + public node(key: string): Node { + let node: any = this.graph.node(key); + return node; + } + public updateGraphForKey(key: string): void { this.traversedCache = {}; this.traversedDir = {}; @@ -103,23 +132,27 @@ export class Graph { this.traverseAndGenerateDir(node, GraphConstants.DirEnum.PANO, 1); } - public keyIsWorthy(key: string): boolean { - let node: Node = this.node(key); + private addCalculatedEdgesToNode(node: Node, edges: ICalculatedEdges): void { + let outEdges: any[] = this.graph.outEdges(node.key); - if (node == null) { - return false; + for (var i in outEdges) { + if (outEdges.hasOwnProperty(i)) { + let e: any = outEdges[i]; + this.graph.removeEdge(e); + } } - return node.worthy; - } - - public node (key: string): Node { - let node: any = this.graph.node(key); - return node; - } - - private addCalculatedEdgesToNode(node: Node: edges: CalculatedEdges): void { - console.log(node); + for (var k in edges) { + if (edges.hasOwnProperty(k)) { + let es: any = edges[k]; + for (var l in es) { + if (es.hasOwnProperty(l)) { + let e: any = es[l]; + this.graph.setEdge(node.key, e, parseInt(k, 10)); + } + } + } + } } private traverseAndGenerateDir(node: Node, dir: GraphConstants.DirEnum, depth: number): void { @@ -133,7 +166,7 @@ export class Graph { return; } if (!(node.key in this.traversedKeys)) { - let edges: CalculatedEdges = this.edgeCalculator.calculateEdges(node); + let edges: ICalculatedEdges = this.edgeCalculator.calculateEdges(node); this.addCalculatedEdgesToNode(node, edges); } diff --git a/src/viewer/Viewer.ts b/src/viewer/Viewer.ts index 53e24303..df60bace 100644 --- a/src/viewer/Viewer.ts +++ b/src/viewer/Viewer.ts @@ -2,8 +2,7 @@ import * as when from "when"; -import {Debug} from "../Utils"; -import {Graph} from "../Graph"; +import {GraphConstants, Graph, Node} from "../Graph"; import {IAPINavIm} from "../API"; import {ILatLon, IViewerOptions} from "../Viewer"; import {OptionsParser} from "./OptionsParser"; @@ -11,6 +10,14 @@ import {ParameterMapillaryError} from "../Error"; import {Prefetcher} from "./Prefetcher"; export class Viewer { + /** + * The node that the viewer is currently looking at + * @member Mapillary.Viewer#currentNode + * @public + * @type {Node} + */ + public currentNode: Node; + /** * true if Viewer is loading internally, false if not. * @member Mapillary.Viewer#loading @@ -68,28 +75,48 @@ export class Viewer { * @param {string} key Mapillary image key to move to * @throws {ParamaterMapillaryError} If no key is provided */ - public moveToKey(key: string, cb?: (data: IAPINavIm) => void): boolean { + public moveToKey(key: string): when.Promise<{}> { if (key == null) { throw new ParameterMapillaryError(); } if (this.loading) { - return false; + return when.reject("Viewer is Loading"); } if (this.graph.keyIsWorthy(key)) { - Debug.log("MOVE ON"); + return when(this.graph.node(key)); } else { let response: when.Promise = this.prefetcher.loadFromKey(key); - response.then((data: IAPINavIm) => { + return response.then((data: IAPINavIm) => { this.graph.insertNodes(data); this.graph.updateGraphForKey(key); - if (cb != null) { - cb(data); - } + this.currentNode = this.graph.node(key); + return this.currentNode; }); } } + /** + * Move in a direction + * @method Mapillary.Viewer#moveToLngLat + * @param {LatLng} latLng FIXME + */ + public moveDir(dir: GraphConstants.DirEnum): when.Promise<{}> { + if (dir < 0 || dir >= 13) { + throw new ParameterMapillaryError(); + } + if (this.loading) { + return when.reject("Viewer is Loading"); + } + + let nextNode: Node = this.graph.nextNode(this.currentNode, dir); + if (nextNode == null) { + return when.reject("There are no node in direction: " + dir); + } + + return this.moveToKey(nextNode.key); + } + /** * Move to a latitude longitude * @method Mapillary.Viewer#moveToLngLat diff --git a/typings/graphlib/graphlib.d.ts b/typings/graphlib/graphlib.d.ts index d638e5e0..913cfa72 100644 --- a/typings/graphlib/graphlib.d.ts +++ b/typings/graphlib/graphlib.d.ts @@ -4,6 +4,7 @@ declare module "graphlib" { module graphlib { export class Graph { constructor(); + constructor(params: any); hasNode(key: string): any; node(key: string): any; setNode(key: string, node: any): any;