mirror of
https://github.com/mapillary/mapillary-js.git
synced 2026-02-01 14:33:45 +00:00
Add movDir to Viewer
This commit is contained in:
parent
2dd2c75d02
commit
56388aee93
@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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<IAPINavIm> = 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
|
||||
|
||||
1
typings/graphlib/graphlib.d.ts
vendored
1
typings/graphlib/graphlib.d.ts
vendored
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user