@loaders.gl/tiles
Version:
Common components for different tiles loaders.
102 lines (93 loc) • 3.03 kB
text/typescript
import {FrameState} from '../helpers/frame-state';
import {I3SPendingTilesRegister} from './i3s-pending-tiles-register';
const STATUS = {
REQUESTED: 'REQUESTED',
COMPLETED: 'COMPLETED',
ERROR: 'ERROR'
};
// A helper class to manage tile metadata fetching
export class I3STileManager {
private _statusMap: object;
private pendingTilesRegister = new I3SPendingTilesRegister();
constructor() {
this._statusMap = {};
}
/**
* Add request to map
* @param request - node metadata request
* @param key - unique key
* @param callback - callback after request completed
* @param frameState - frameState data
*/
add(request, key, callback, frameState: FrameState) {
if (!this._statusMap[key]) {
const {
frameNumber,
viewport: {id}
} = frameState;
this._statusMap[key] = {request, callback, key, frameState, status: STATUS.REQUESTED};
// Register pending request for the frameNumber
this.pendingTilesRegister.register(id, frameNumber);
request()
.then((data) => {
this._statusMap[key].status = STATUS.COMPLETED;
const {
frameNumber: actualFrameNumber,
viewport: {id}
} = this._statusMap[key].frameState;
// Deregister pending request for the frameNumber
this.pendingTilesRegister.deregister(id, actualFrameNumber);
this._statusMap[key].callback(data, frameState);
})
.catch((error) => {
this._statusMap[key].status = STATUS.ERROR;
const {
frameNumber: actualFrameNumber,
viewport: {id}
} = this._statusMap[key].frameState;
// Deregister pending request for the frameNumber
this.pendingTilesRegister.deregister(id, actualFrameNumber);
callback(error);
});
}
}
/**
* Update request if it is still actual for the new frameState
* @param key - unique key
* @param frameState - frameState data
*/
update(key, frameState: FrameState) {
if (this._statusMap[key]) {
// Deregister pending request for the old frameNumber
const {
frameNumber,
viewport: {id}
} = this._statusMap[key].frameState;
this.pendingTilesRegister.deregister(id, frameNumber);
// Register pending request for the new frameNumber
const {
frameNumber: newFrameNumber,
viewport: {id: newViewportId}
} = frameState;
this.pendingTilesRegister.register(newViewportId, newFrameNumber);
this._statusMap[key].frameState = frameState;
}
}
/**
* Find request in the map
* @param key - unique key
* @returns
*/
find(key) {
return this._statusMap[key];
}
/**
* Check it there are pending tile headers for the particular frameNumber
* @param viewportId
* @param frameNumber
* @returns
*/
hasPendingTiles(viewportId: string, frameNumber: number): boolean {
return !this.pendingTilesRegister.isZero(viewportId, frameNumber);
}
}