in src/graph/GraphService.ts [195:404]
public cacheImage$(id: string): Observable<Image> {
const firstGraphSubject$: Subject<Graph> = new Subject<Graph>();
this._firstGraphSubjects$.push(firstGraphSubject$);
const firstGraph$: Observable<Graph> = firstGraphSubject$.pipe(
publishReplay(1),
refCount());
const image$: Observable<Image> = firstGraph$.pipe(
map(
(graph: Graph): Image => {
return graph.getNode(id);
}),
mergeMap(
(image: Image): Observable<Image> => {
return image.assetsCached ?
observableOf(image) :
image.cacheAssets$();
}),
publishReplay(1),
refCount());
image$.subscribe(
undefined,
(error: Error): void => {
console.error(`Failed to cache image (${id}).`, error);
});
let initializeCacheSubscription: Subscription;
initializeCacheSubscription = this._graph$.pipe(
first(),
mergeMap(
(graph: Graph): Observable<Graph> => {
if (graph.isCachingFull(id) || !graph.hasNode(id)) {
return graph.cacheFull$(id);
}
if (graph.isCachingFill(id) || !graph.getNode(id).complete) {
return graph.cacheFill$(id);
}
return observableOf<Graph>(graph);
}),
tap(
(graph: Graph): void => {
if (!graph.hasNode(id)) {
throw new GraphMapillaryError(`Failed to cache image (${id})`);
}
if (!graph.hasInitializedCache(id)) {
graph.initializeCache(id);
}
}),
finalize(
(): void => {
if (initializeCacheSubscription == null) {
return;
}
this._removeFromArray(initializeCacheSubscription, this._initializeCacheSubscriptions);
this._removeFromArray(firstGraphSubject$, this._firstGraphSubjects$);
}))
.subscribe(
(graph: Graph): void => {
firstGraphSubject$.next(graph);
firstGraphSubject$.complete();
},
(error: Error): void => {
firstGraphSubject$.error(error);
});
if (!initializeCacheSubscription.closed) {
this._initializeCacheSubscriptions.push(initializeCacheSubscription);
}
const graphSequence$: Observable<Graph> = firstGraph$.pipe(
catchError(
(): Observable<Graph> => {
return observableEmpty();
}),
mergeMap(
(graph: Graph): Observable<Graph> => {
if (graph.isCachingNodeSequence(id) || !graph.hasNodeSequence(id)) {
return graph.cacheNodeSequence$(id);
}
return observableOf<Graph>(graph);
}),
publishReplay(1),
refCount());
let sequenceSubscription: Subscription;
sequenceSubscription = graphSequence$.pipe(
tap(
(graph: Graph): void => {
if (!graph.getNode(id).sequenceEdges.cached) {
graph.cacheSequenceEdges(id);
}
}),
finalize(
(): void => {
if (sequenceSubscription == null) {
return;
}
this._removeFromArray(sequenceSubscription, this._sequenceSubscriptions);
}))
.subscribe(
(): void => { return; },
(error: Error): void => {
console.error(`Failed to cache sequence edges (${id}).`, error);
});
if (!sequenceSubscription.closed) {
this._sequenceSubscriptions.push(sequenceSubscription);
}
if (this._graphMode === GraphMode.Spatial) {
let spatialSubscription: Subscription;
spatialSubscription = firstGraph$.pipe(
catchError(
(): Observable<Graph> => {
return observableEmpty();
}),
expand(
(graph: Graph): Observable<Graph> => {
if (graph.hasTiles(id)) {
return observableEmpty();
}
return observableFrom(graph.cacheTiles$(id)).pipe(
mergeMap(
(graph$: Observable<Graph>): Observable<Graph> => {
return graph$.pipe(
mergeMap(
(g: Graph): Observable<Graph> => {
if (g.isCachingTiles(id)) {
return observableEmpty();
}
return observableOf<Graph>(g);
}),
catchError(
(error: Error): Observable<Graph> => {
console.error(`Failed to cache tile data (${id}).`, error);
return observableEmpty();
}));
}));
}),
takeLast(1),
mergeMap(
(graph: Graph): Observable<Graph> => {
if (graph.hasSpatialArea(id)) {
return observableOf<Graph>(graph);
}
return observableFrom(graph.cacheSpatialArea$(id)).pipe(
mergeMap(
(graph$: Observable<Graph>): Observable<Graph> => {
return graph$.pipe(
catchError(
(error: Error): Observable<Graph> => {
console.error(`Failed to cache spatial images (${id}).`, error);
return observableEmpty();
}));
}));
}),
takeLast(1),
mergeMap(
(graph: Graph): Observable<Graph> => {
return graph.hasNodeSequence(id) ?
observableOf<Graph>(graph) :
graph.cacheNodeSequence$(id);
}),
tap(
(graph: Graph): void => {
if (!graph.getNode(id).spatialEdges.cached) {
graph.cacheSpatialEdges(id);
}
}),
finalize(
(): void => {
if (spatialSubscription == null) {
return;
}
this._removeFromArray(spatialSubscription, this._spatialSubscriptions);
}))
.subscribe(
(): void => { return; },
(error: Error): void => {
const message =
`Failed to cache spatial edges (${id}).`;
console.error(message, error);
});
if (!spatialSubscription.closed) {
this._spatialSubscriptions.push(spatialSubscription);
}
}
return image$.pipe(
first(
(image: Image): boolean => {
return image.assetsCached;
}));
}