public cacheSequenceNodes$()

in src/graph/Graph.ts [664:753]


    public cacheSequenceNodes$(sequenceKey: string, referenceNodeKey?: string): Observable<Graph> {
        if (!this.hasSequence(sequenceKey)) {
            throw new GraphMapillaryError(
                `Cannot cache sequence nodes of sequence that does not exist in graph (${sequenceKey}).`);
        }

        if (this.hasSequenceNodes(sequenceKey)) {
            throw new GraphMapillaryError(`Sequence nodes already cached (${sequenceKey}).`);
        }

        const sequence: Sequence = this.getSequence(sequenceKey);
        if (sequence.id in this._cachingSequenceNodes$) {
            return this._cachingSequenceNodes$[sequence.id];
        }

        const batches: string[][] = [];
        const keys: string[] = sequence.imageIds.slice();

        const referenceBatchSize: number = 50;
        if (!!referenceNodeKey && keys.length > referenceBatchSize) {
            const referenceIndex: number = keys.indexOf(referenceNodeKey);
            const startIndex: number = Math.max(
                0,
                Math.min(
                    referenceIndex - referenceBatchSize / 2,
                    keys.length - referenceBatchSize));

            batches.push(keys.splice(startIndex, referenceBatchSize));
        }

        const batchSize: number = 200;
        while (keys.length > 0) {
            batches.push(keys.splice(0, batchSize));
        }

        let batchesToCache: number = batches.length;
        const sequenceNodes$: Observable<Graph> = observableFrom(batches).pipe(
            mergeMap(
                (batch: string[]): Observable<Graph> => {
                    return this._api.getImages$(batch).pipe(
                        tap(
                            (items: ImagesContract): void => {
                                for (const item of items) {
                                    if (!item.node) {
                                        console.warn(
                                            `Image empty (${item.node_id})`);
                                        continue;
                                    }
                                    const id = item.node_id;
                                    if (this.hasNode(id)) {
                                        const node = this.getNode(id);
                                        if (!node.complete) {
                                            this._makeFull(node, item.node);
                                        }
                                    } else {
                                        if (item.node.sequence.id == null) {
                                            console.warn(`Sequence missing, discarding node (${item.node_id})`);
                                        }

                                        const node = new Image(item.node);
                                        this._makeFull(node, item.node);

                                        const cellId = this._api.data.geometry
                                            .lngLatToCellId(node.originalLngLat);
                                        this._preStore(cellId, node);
                                        this._setNode(node);
                                    }
                                }

                                batchesToCache--;
                            }),
                        map((): Graph => this));
                },
                6),
            last(),
            finalize(
                (): void => {
                    delete this._cachingSequenceNodes$[sequence.id];

                    if (batchesToCache === 0) {
                        this._cachedSequenceNodes[sequence.id] = true;
                    }
                }),
            publish(),
            refCount());

        this._cachingSequenceNodes$[sequence.id] = sequenceNodes$;

        return sequenceNodes$;
    }