From ac5b99a204fda318a14dd679443dd135e2b0b801 Mon Sep 17 00:00:00 2001 From: Oscar Lorentzon Date: Fri, 8 Mar 2024 08:14:12 +0100 Subject: [PATCH] feat: handle spatial edges for graph resets Ensure that the latest graph area request is prioritized. Cancel prior requests. --- doc/src/js/utils/provider.js | 2 +- examples/debug/chunk.html | 6 +++++- src/graph/Graph.ts | 25 +++++++++++++++++-------- src/graph/GraphService.ts | 8 +++++++- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/doc/src/js/utils/provider.js b/doc/src/js/utils/provider.js index 66df10bc..ab8f4309 100644 --- a/doc/src/js/utils/provider.js +++ b/doc/src/js/utils/provider.js @@ -59,7 +59,7 @@ export function generateCluster(options, intervals) { let {idCounter} = options; const {alt, lat, lng} = options.reference; - const distance = 5; + const distance = options.distance ?? 5; const images = []; const thumbUrl = `${cameraType}`; diff --git a/examples/debug/chunk.html b/examples/debug/chunk.html index 676167a0..2f97d17a 100644 --- a/examples/debug/chunk.html +++ b/examples/debug/chunk.html @@ -61,6 +61,7 @@ dataProvider, cameraControls: CameraControls.Earth, component: { + cache: false, cover: false, image: false, spatial: { @@ -73,6 +74,7 @@ imageTiling: false, }; viewer = new Viewer(options); + viewer.setFilter(['!=', 'cameraType', 'invalid']) chunks = []; listen(); @@ -81,13 +83,15 @@ function generateChunk() { const cameraType = CAMERA_TYPE_SPHERICAL; const aspect = cameraTypeToAspect(cameraType); + const distance = 1; const height = 100; const counter = chunks.length; - const shift = counter * 10; + const shift = counter * 1; const mod = 3; const config = { cameraType, color: [1, (counter % mod) / (mod - 1), 0], + distance, east: shift, height, id: counter.toString(), diff --git a/src/graph/Graph.ts b/src/graph/Graph.ts index 9427daf1..7dfb4a11 100644 --- a/src/graph/Graph.ts +++ b/src/graph/Graph.ts @@ -43,6 +43,7 @@ import { SpatialImagesContract } from "../api/contracts/SpatialImagesContract"; import { ImagesContract } from "../api/contracts/ImagesContract"; import { SequenceContract } from "../api/contracts/SequenceContract"; import { CoreImagesContract } from "../api/contracts/CoreImagesContract"; +import { CancelMapillaryError } from "../error/CancelMapillaryError"; type NodeTiles = { cache: string[]; @@ -832,14 +833,20 @@ export class Graph { } let batchesToCache: number = batches.length; - let spatialNodes$: Observable[] = []; + let spatialArea$: Observable[] = []; for (let batch of batches) { let spatialNodeBatch$: Observable = this._api.getSpatialImages$(batch).pipe( tap( (items: SpatialImagesContract): void => { - if (!(key in this._cachingSpatialArea$)) { - return; + const currentSpatialArea = this._requiredSpatialArea[key]; + if (currentSpatialArea == null || spatialArea !== currentSpatialArea) { + throw new CancelMapillaryError('Required spatial area changed.'); + } + + const currentCaching = this._cachingSpatialArea$[key]; + if (currentCaching == null || spatialArea$ !== currentCaching) { + throw new CancelMapillaryError('Spatial area caching changed.'); } for (const item of items) { @@ -876,7 +883,8 @@ export class Graph { } } - if (--batchesToCache === 0) { + const currentCaching = this._cachingSpatialArea$[key]; + if (spatialArea$ === currentCaching) { delete this._cachingSpatialArea$[key]; } @@ -887,16 +895,17 @@ export class Graph { if (Object.keys(spatialArea.cacheNodes).length === 0) { this._changed$.next(this); } + }), publish(), refCount()); - spatialNodes$.push(spatialNodeBatch$); + spatialArea$.push(spatialNodeBatch$); } - this._cachingSpatialArea$[key] = spatialNodes$; + this._cachingSpatialArea$[key] = spatialArea$; - return spatialNodes$; + return spatialArea$; } /** @@ -935,7 +944,7 @@ export class Graph { let spatialNode: Image = allSpatialNodes[spatialNodeKey]; - if (filter(spatialNode)) { + if (spatialNode.complete && filter(spatialNode)) { potentialNodes.push(spatialNode); } } diff --git a/src/graph/GraphService.ts b/src/graph/GraphService.ts index f071bbb4..a13c8fe1 100644 --- a/src/graph/GraphService.ts +++ b/src/graph/GraphService.ts @@ -37,6 +37,7 @@ import { GraphMapillaryError } from "../error/GraphMapillaryError"; import { ProjectionService } from "../viewer/ProjectionService"; import { ICameraFactory } from "../geometry/interfaces/ICameraFactory"; import { ProviderClusterEvent } from "../api/events/ProviderClusterEvent"; +import { CancelMapillaryError } from "../error/CancelMapillaryError"; /** * @class GraphService @@ -386,7 +387,12 @@ export class GraphService { return graph$.pipe( catchError( (error: Error): Observable => { - console.error(`Failed to cache spatial images (${id}).`, error); + if (error instanceof CancelMapillaryError) { + // tslint:disable-next-line:no-console + console.debug(`Failed to cache spatial area (${id}).`, error); + } else { + console.error(`Failed to cache spatial area (${id}).`, error); + } return observableEmpty(); }));