I have an old project which involves using Unfolding Maps and Processing to draw, well...maps haha. The project works fine, but I was checking something out to help a colleague and encountered something I don't quite understand.

My question is as follows: if I call Unfolding Map's draw() method (map.draw()) in Processing's draw() method, everything works fine, everything gets redrawn continuously and I can properly interact with the app and whatnot. However, if I do map.draw() in Processing's setup() method and then avoid Processing's draw() method from ever running, shouldn't the map get drawn once and then everything get shut down?

Instead, when I run map.draw() in setup() and then force everything to stop, it doesn't draw anything, not even once.

Also, I've tried running Processing's draw() method just once and calling map.draw() just once in Processing's draw() method, by using noLoop() at the end of setup(). My project is really long, so I'll just post a bit of code only meant to test this small question of mine.

private static final boolean offline = false;
public static String mbTilesString = "/Users/roy/IdeaProjects/UnfoldingMaps/data/blankLight-1-3.mbtiles"
private UnfoldingMap map;

public void setup() {
    size(900, 700, OPENGL);

    if (offline) {
        this.map = new UnfoldingMap(this, 200, 50, 650, 600, new MBTilesMapProvider(mbTilesString));
    } else {
        this.map = new UnfoldingMap(this, 200, 50, 650, 600, new Microsoft.RoadProvider());
    }

    MapUtils.createDefaultEventDispatcher(this, this.map);

    noLoop(); // draw() gets called only once
}

public void draw() {
    this.map.draw();
}

I expect the map to be drawn once and then everything to stop. Instead I get the following:

blank window

1

There are 1 answers

2
Kevin Workman On BEST ANSWER

Everything you've said makes sense, and your expectations are valid. You can confirm the behavior by drawing a rectangle instead of a map.

My best guess is that Unfolding Maps is not compatible with the noLoop() function. I would assume that Unfolding Maps has some internal logic that relies on the draw loop: loading map tiles asynchronously, responding to user input, etc.

You can explore the behavior by doing something like this in your setup() function:

noLoop();

for(int i = 0; i < 100; i++){
  draw();
}

This is a hack meant to explore the behavior. I'm not recommending this is a fix. If I do this, I see that the map gets partially loaded:

partially loaded map

This tells me that Unfolding Maps somehow relies on draw() being called multiple times to handle the loading. This makes sense, as the loading is asynchronous and happens in the background over time. It probably has something to do with needing to draw on Processing's main thread after the images are loaded. If you want to be sure, you could look at the source of Unfolding Maps to understand its internal behaviors.

If you really really need to use noLoop() with Unfolding Maps, you might use a hack with the delay() function. Or you could look at the documentation for Unfolding Maps; maybe there's a useful function that we've missed. Or you could modify the source to get the behavior your want. Or maybe you could put something together using a PGraphics or something.

But mostly, I think you should avoid using noLoop() with Unfolding Maps.