Skip to content

Commit

Permalink
feat(ol-map-adapter): abort image adapter request on map move
Browse files Browse the repository at this point in the history
  • Loading branch information
rendrom committed Apr 17, 2024
1 parent a3fa11c commit 976dadc
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 76 deletions.
217 changes: 142 additions & 75 deletions packages/ol-map-adapter/src/layer-adapters/ImageAdapter.ts
Expand Up @@ -11,8 +11,53 @@ import { BaseAdapter } from './BaseAdapter';
import type { ImageAdapterOptions, MainLayerAdapter } from '@nextgis/webmap';
import type Map from 'ol/Map';
import type { Extent } from 'ol/extent';
import type { Options as BaseImageOptions } from 'ol/layer/BaseImage';
import type { Options as ImageWMSOptions } from 'ol/source/ImageWMS';

class ImageLayerExtended extends ImageLayer<ImageWMS> {
constructor(
options: BaseImageOptions<ImageWMS>,
private ratio: number,
) {
super(options);
}
createRenderer() {
return new CanvasILRendererExtended(this, this.ratio);
}
}

class ImageWMSExtended extends ImageWMS {
constructor(
options: ImageWMSOptions,
private ratio: number,
) {
super(options);
}

getImageInternal(
extent: Extent,
resolution: number,
_pixelRatio: number,
projection: any,
) {
return super.getImageInternal(extent, resolution, this.ratio, projection);
}
}

class CanvasILRendererExtended extends CanvasImageLayerRenderer {
constructor(
layer: any,
private ratio: number,
) {
super(layer);
}

renderFrame(frameState: any, target: any) {
frameState.pixelRatio = this.ratio;
return super.renderFrame(frameState, target);
}
}

export class ImageAdapter extends BaseAdapter implements MainLayerAdapter {
layer: any;

Expand All @@ -33,90 +78,112 @@ export class ImageAdapter extends BaseAdapter implements MainLayerAdapter {
...options.params,
},
projection: undefined,
imageLoadFunction: this.constructImageLoadFunction(options),
};
const updateWmsParams = options.updateWmsParams;

imageOptions.imageLoadFunction = (image, src) => {
const url = src.split('?')[0];
const query = src.split('?')[1];
const { resource, BBOX, WIDTH, HEIGHT, ...params } =
queryToObject(query);

const queryParams = {
resource,
bbox: BBOX,
width: WIDTH,
height: HEIGHT,
...params,
};
const queryString = objectToQuery(
updateWmsParams ? updateWmsParams(queryParams) : params,
);
const headers = options.headers;

const _src = url + '?' + queryString;
// const updateWmsParams = options.updateWmsParams;
// imageOptions.imageLoadFunction = (image, src) => {
// const url = src.split('?')[0];
// const query = src.split('?')[1];
// const { resource, BBOX, WIDTH, HEIGHT, ...params } =
// queryToObject(query);

if (headers) {
setTileLoadFunction(image, _src, headers);
} else {
// @ts-ignore
image.getImage().src = _src;
}
// const im = image.getImage();
// im.addEventListener('load', () => {
// console.log(im);
// return true;
// });
// const queryParams = {
// resource,
// bbox: BBOX,
// width: WIDTH,
// height: HEIGHT,
// ...params,
// };
// const queryString = objectToQuery(
// updateWmsParams ? updateWmsParams(queryParams) : params,
// );
// const headers = options.headers;

// const _src = url + '?' + queryString;

// if (headers) {
// setTileLoadFunction(image, _src, headers);
// } else {
// // @ts-ignore
// image.getImage().src = _src;
// }
// };

const layerOptions: BaseImageOptions<ImageWMS> = {
opacity: options.opacity,
...resolutionOptions(this.map, options),
...options.nativeOptions,
};

let ImLayer = ImageLayer;
let ImWms = ImageWMS;
if (ratio > 1) {
imageOptions.ratio = ratio;
imageOptions.serverType = 'mapserver';
class CanvasILRendererExtended extends CanvasImageLayerRenderer {
renderFrame(frameState: any, target: any) {
frameState.pixelRatio = ratio;
// @ts-ignore
return super.renderFrame(frameState, target);
}
}
class ImageLayerExtended extends ImageLayer<ImageWMS> {
// @ts-ignore
createRenderer() {
return new CanvasILRendererExtended(this);
}
}
// @ts-ignore
ImLayer = ImageLayerExtended;

class ImageWmsExtended extends ImageWMS {
getImageInternal(
extent: Extent,
resolution: number,
pixelRatio: number,
projection: any,
) {
return super.getImageInternal(
extent,
resolution,
ratio,
projection,
);
}
}
ImWms = ImageWmsExtended;
}

const source = new ImWms(imageOptions);
const layer = new ImLayer({
source,
opacity: options.opacity,
...resolutionOptions(this.map, options),
...options.nativeOptions,
});
this.layer = layer;
return layer;
const source = new ImageWMSExtended(imageOptions, ratio);
const layer = new ImageLayerExtended(
{
source,
...layerOptions,
},
ratio,
);
this.layer = layer;
} else {
const source = new ImageWMS(imageOptions);
const layer = new ImageLayer({
source,
...layerOptions,
});
this.layer = layer;
}
return this.layer;
}
}

private constructImageLoadFunction(
options: ImageAdapterOptions,
): ImageWMSOptions['imageLoadFunction'] {
const updateWmsParams = options.updateWmsParams;
let _abortFunc: (() => void) | undefined = undefined;

const abort = () => {
if (_abortFunc) {
_abortFunc();
_abortFunc = undefined;
}
};

return (image, src) => {
abort();
const url = src.split('?')[0];
const query = src.split('?')[1];
const { resource, BBOX, WIDTH, HEIGHT, ...params } = queryToObject(query);

const queryParams = {
resource,
bbox: BBOX,
width: WIDTH,
height: HEIGHT,
...params,
};
const queryString = objectToQuery(
updateWmsParams ? updateWmsParams(queryParams) : params,
);
const headers = options.headers;

const _src = url + '?' + queryString;

if (headers) {
_abortFunc = setTileLoadFunction(image, _src, headers);
} else {
// @ts-ignore
image.getImage().src = _src;
_abortFunc = () => {
// @ts-ignore
image.getImage().src = '';
};
}
};
}
}
4 changes: 3 additions & 1 deletion packages/ol-map-adapter/src/utils/setTileLoadFunction.ts
Expand Up @@ -5,7 +5,7 @@ export function setTileLoadFunction(
tile: Tile | ImageWrapper,
src: string,
headers: Record<string, any>,
): void {
): () => void {
const xhr = new XMLHttpRequest();
xhr.open('GET', src);
xhr.responseType = 'arraybuffer';
Expand All @@ -23,4 +23,6 @@ export function setTileLoadFunction(
tile.getImage().src = imageUrl;
};
xhr.send();

return () => xhr.abort();
}

0 comments on commit 976dadc

Please sign in to comment.