kosmtik / kosmtik

Make maps with OpenStreetMap and Mapnik

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Data Inspector hangs

sandman7920 opened this issue · comments

kosmtik hangs when Data Inspector is feed with empty data.

When DataSource returns empty data for an x-ray tile, the XRayTile class doesn't execute the callback, this leads to a full hang.

    render(project, map, cb) {
        var styleMap = this.styleMap(project),
            vtile = new mapnik.VectorTile(this.z, this.x, this.y);
        if (this.data.length){
            vtile.setData(this.data, function(err) {
                if(err) {
                    console.log(err.message);
                    return cb(err);
                }
                vtile.render(styleMap, new mapnik.Image(256, 256), cb);  
            });
        } // ELSE CALLBACK IS NEVER EXECUTED
    };

One possible workaround is to add a transparent GeoJSON layer that wraps the whole world.

My current fix is ProjectServer.js to return HTTP 204 code for the missing data

diff --git a/src/back/ProjectServer.js b/src/back/ProjectServer.js
index 006ce81..4ba8293 100644
--- a/src/back/ProjectServer.js
+++ b/src/back/ProjectServer.js
@@ -152,6 +152,12 @@ class ProjectServer {
             var tile = new tileClass(z, x, y, {metatile: 1, buffer_size: 1});
             return tile.renderToVector(self.project, map, function (err, t) {
                 if (err) return self.raise(err.message, res, release);
+                if (t.getData().length == 0) {
+                    res.writeHead(204, {'Content-Type': 'image/png', 'Content-Length': 0});
+                    res.end();
+                    release();
+                    return;
+                }
                 var xtile = new XRayTile(z, x, y, t.getData(), {layer: query.layer, background: query.background});
                 xtile.render(self.project, map, function (err, im) {
                     if (err) return self.raise(err.message, res, release);

Another possible fix is XRayTile.js to render empty tile with the selected style or to render the tile with specially crafted tile data

diff --git a/src/back/XRayTile.js b/src/back/XRayTile.js
index 9f9162b..cfe50a0 100644
--- a/src/back/XRayTile.js
+++ b/src/back/XRayTile.js
@@ -24,6 +24,8 @@ class XRayTile {
                 }
                 vtile.render(styleMap, new mapnik.Image(256, 256), cb);
             });
+        } else {
+            vtile.render(styleMap, new mapnik.Image(256, 256), cb);
         }
     };

Both options sounds good, but I'd go with option 1. Can you provide a PR ?