A common challenge that our users face is a need to render and display huge images like raster logs and GeoTIFF files. Interactions occur in the client’s server architecture, and while these images can be stored in the cloud or on a server, they are usually very large files, making it difficult to move from the server to the client. It is also time-consuming to read data from the cloud and unpack operations for TIFFs.
When trying to open these files, the user may have to wait up to several minutes to start to receive data from the server. This can lead to a poor user experience because the client doesn’t know if a server is working or if it’s already halted the solution that we applied. So we wanted to improve this for our users.
Reducing Calculation Complexity
In order to optimize several areas for the client as well as on the server, we decided to focus on the server data loading from cloud storage and enhance the unpacking of TIFFs. We found a way to minimize the number of requests from client to server and pass more calculations from server to client, reducing the calculation complexity on the server.
So, how did we do it? On the client side, we have a class called tiled shape which requests tiles from the server.
For each tile, the client requests its X and Y position, height, and scaling. In the past, when a user would interact with an image and send a request to the server, requesting new tiles, it would be too much for the server to handle, causing even more delays.
To minimize the impact this request has on the server, we decided to check if the user stops interaction by timer. After any interaction on the client’s side with the image, we start a timer. Before the timer is up, if no requests are sent from the client to the server, this timer finishes quickly and the image loads. This allows us to minimize the number of requests from client to server.
Calculation and Caching
Another feature we optimized is the ability to pass information from the server to plan calculations for the correct tile position and correct tile transformation. By passing the data from server to client, the client calculates the correct position for tile on each side. We also use a cache of tiles on the client side to ensure that we do not request the same tiles. Image cache on a server side is also possible, but after the first request, it is necessary to download the requested image from the cloud, unpack the image, and then start to copy and scale the requested tile to convert this image.
Unpacking the Image
On the server side, we implemented TIFF unpacking on a highly performing native implementation. This is a multithreaded and thread safe solution., which allows us to deal with several requests from clients at the same time. As a result, a large TIFF image file can be stored in the cloud without a problem and an unpacking time of less than four seconds compared to the previous solution’s 60 seconds. We also optimized the cloud access speed on the server side by renting a high-performance AWS instance with high-speed access to AWS cloud storage. This allows us to download the whole TIFF image from the cloud in less than three seconds, making the download speeds about 800 megabytes per second.
As a result, we spend around three seconds to download the image from cloud storage and about four seconds to unpack the image. So it only takes roughly seven seconds to download, unpack the image, deal with client requests, scale the requested tiles, and send them back to the client as opposed to having to wait several minutes to possibly hours for the same process. Overall, this process greatly improves the user experience.
The new raster logs and cloud TIFF rendering are just one of the many new features and improvements from the latest GeoToolkit.JS 2021.1 release.