Resource Constrained Rendering

Hi All

I am hoping to render maps on a small embedded system with very limited resources - the CPU is an ESP32 with 320 total kilobytes of RAM - and perhaps a few MB of PSRAM (additional slower RAM). I plan to use offline maps stored on an SD card. From my initial search, the existing renderers I’ve found seem to be developed for much more capable systems, ie PC/smart phones and the code seems to be quite large/complex. I am wondering as to the feasibility of this - although given that satnav devices have been around on fairly low end devices for decades the answer must be that it is doable? My initial thoughts were that the Garmin IMG format might be a good starting point. I assume a C/C++ based solution would be best but am open to ideas. My fallback would be to use pre-rendered tiles stored on SD but my ultimate goal is to do on device rendering. Any ideas, suggestions or thoughts on how to approach this. What would be the best starting point for me to work from?

Many thanks for any input!


For me, pre-rendered (vector) tiles seems the only way to do it. One of the complex computations is to find out which OSM object is - or should be - visible within a given rectangle. The available OSM formats don’t store data in a spatial index, so you’ll need an effictient format to answer that question, else your program will need a very long time to render a single image.
The older Garmin IMG is not well documented and the newer , partly encrypted (NT) format is still unknown. Some programs understand enough to render tiles, see GpsMapEdit, QLandkarteGT or QMapShack. As a co-author of mkgmap (1) I know quite well how to write the IMG format, but I’ve never cared much about rendering.

Hi Slowzy - coincidentally I also was pondering the same thing as of late, namely map rendering on ESP32/ESP8266/STM32F103.
I would base it either around vector tiles or raster tiles compressed with vector quantization [e.g. codebook of 4096 4x4 entries (0.75 bpp) or 256 2x2 entries (2 bpp)].
I think either way it’s possible to obtain something marginally usable, the most limited resource being the memory.
But it will require hand-crafting or optimizing the whole stack. For instance, with FatFs library, you’d have to use f_lseek which caches cluster ranges in RAM so no seeks to FAT table are made when doing reads. (All of the above uC’s don’t have enough RAM to hold the whole FAT). Data format - create custom one that doesn’t need much seeking and (in case of vector tiles) preferably has pre-computed label placement. And for map rendering algorithms - use fixed point math. Finally for the display - use a frame buffer and DMA, don’t draw pixel by pixel.

So, the Garmin IMG format doesn’t seem to fit. It has a lot of quirks, it’s well compressed, but here you’d probably want to trade-off size for speed.

Thanks for your input - obviously no magic pills but I kind of already suspected that. I have a lot to learn before I get started and may look a bit more at the IMG format and programs GerdP referenced, but suspect I will likely heed your wisdom and go with vector tiles. Even this is going to be a big undertaking for me, especially with the embedded system constraints and slow SD card access but I have to start somewhere. I will update this thread if I make any progress. In the meantime, if anyone has any helpful input on this topic, please add to this thread. Thanks again for your help!