My problem:
In my react app, I have some functionality that allows for getting an image from an API. If the image is added while the user is above a certain zoomlevel (differs depending on area, ~7.4 in UK and 6.82 in northern Germany for me) the image will not load unless the user zooms out. Once the user has zoomed out past a specific point (I checked, it's literally always the same zoom level in the same rough area, even when I reload the app, but it differs over long distances roughly country-length) the imageLoadFunction will start the request to the API and it works fine after that. I get no error messages, and if I try to load multiple areas while zoomed in, it's like they are all queued until I zoom out and they start downloading.
I have had another person test the app on their PC, and the zoom levels are not exactly the same (for which it works / doesn't work), but they are again consistent in the same general area.
What I expect is that the imageLoadFunction should be executed regardless of the user's zoom level, which is not happening.
If it matters, my implementation of openlayers also utilizes ol-kit (https://github.com/Bayer-Group/ol-kit/)
This image is added using the following functionality
addImageToMap(<params>) {
const url = `<url>`;
const imgSource = new OlImageStatic({
url: url,
imageExtent: [
-37441.9223544409, 6708299.891274841, 48375.87197907233,
6787434.524407205,
],
imageLoadFunction: this.imageLoadFunction,
});
const imageLayer = new OlImageLayer({
title: `UTM${Zone} ${XPosition}-${YPosition} on ${date.slice(0, 10)}`,
zIndex: 1,
source: imgSource,
});
this.state.map.addLayer(imageLayer);
}
I have created a custom imageLoadFunction:
imageLoadFunction(image, src) {
const requestOptions = {
method: "GET",
mode: "cors",
};
let loadingText = `downloading preview`;
let successText = `Finished downloading preview`;
const requestQueryParameters = new URL(src).searchParams.entries();
const dateParameter = Array.from(requestQueryParameters).filter(
(e) => e[0] === "date"
);
if (dateParameter.length) {
const formattedDate = dateParameter[0][1].slice(0, 10);
loadingText = `Downloading preview of ${formattedDate} in the background`;
successText = `Finished downloading preview of ${formattedDate}`;
}
this.state.setInfoMessage(loadingText);
try {
fetch(src, requestOptions).then(
(res) => {
res
.blob()
.then(
(blob) => {
const file = window.URL.createObjectURL(blob);
const extentValues = res.headers
.get("X-IMAGE-EXTENT")
.replace("[", "")
.replace("]", "")
.split(",")
.map((n) => +n);
image.getImage().src = file;
image.extent = extentValues;
},
(error) => this.state.setErrorMessage(error)
)
.then(() => this.state.setSuccessMessage(successText));
},
(error) => this.state.setErrorMessage(error)
);
} catch (error) {
this.state.setErrorMessage(error);
}
}
I have tried:
Any help that can point me towards stuff to research (or even fixing the problem outright) is greatly appreciated.
In the meanwhile, I fixed the issue by always animating the view to zoom out to a level that I believe will always enable the imageLoadFunction to execute, and so far it works wonders (except for terrible UX).
Setting image.extent
is not the same as specifying imageExtent
. If you obtain the extent when you load the source url create the layer then asynchronously create and set the source.
const imageLayer = new OlImageLayer({
title: `UTM${Zone} ${XPosition}-${YPosition} on ${date.slice(0, 10)}`,
zIndex: 1,
});
fetch(src, requestOptions).then(
(res) => {
res
.blob()
.then(
(blob) => {
const file = window.URL.createObjectURL(blob);
const extentValues = res.headers
.get("X-IMAGE-EXTENT")
.replace("[", "")
.replace("]", "")
.split(",")
.map((n) => +n);
const imgSource = new OlImageStatic({
url: file,
imageExtent: extentValues,
});
imageLayer.setSource(imgSource);
},