mapnik / mapnik-support

Use the issues queue here to ask questions and offer help on using Mapnik (maybe if this works well we can retire the mailing list at http://mapnik.org/contact/?)
6 stars 6 forks source link

Tiles from mapnik with nodejs #60

Closed KlemenSpruk closed 8 years ago

KlemenSpruk commented 8 years ago

I' m running a script to get tiles from mapnik with nodejs server. I get tiles rendered on at a time. But we i request tiles from browser eg. on map page reload, the server reports a POSTGIS extension error. This probably happens when too many concurrent requests happens.

Does anyone have any experience with mapnik and nodejs how to handle many concurrent requests on nodejs server with mapnik bindings???

Thanks!

My script:

//set framework and dependencies
var express = require('express');
var app = express();
var url = require('url');

//mapnik and dependecies
var mapnik = require('mapnik');
var fs = require('fs');

var mapProjection = '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs';
var map = new mapnik.Map(512, 512, mapProjection);

//mapnik
mapnik.register_default_fonts();
mapnik.register_default_input_plugins();

//mapnik pool
var mapnikPool = require('mapnik-pool')(mapnik);
var pool = mapnikPool.fromString(fs.readFileSync('./styles/style_pg.xml', 'utf8'), {
    'size': 512,
    'height': 512,
    'width': 512,
}, {});

//postgis
var settings = require('./settings');
var postgis = new mapnik.Datasource(settings.postgis);

app.get('/geoserver/fmp_eles/gwc/service/wms', function (req, res) {
    console.log('request' + "\n");

    pool.acquire(function (err, map) {
        //console.log(map);

        var query = req.url.split('&');
        //console.log(query);

        var bbox = query[13].replace('BBOX=', '').split('%2C').map(function (item) {
            return parseFloat(item);
        });
        //get layer
        var layerName = query[5].replace('LAYERS=', '').split('%3A')[1];

        //set style, datasource
        var layer = new mapnik.Layer(layerName, mapProjection);
        layer.datasource = postgis;
        layer.styles = ['style_pg'];

        map.add_layer(layer);
        map.extent = bbox;
        //map.zoomAll(bbox);

        //console.log(map);

        var im = new mapnik.Image(512, 512);
        map.render(im, function (err, im) {
            if (err) throw err;
            im.encode('png', function (err, buffer) {
                if (err) throw err;
                fs.writeFile('./tiles/map' + Math.round(Math.random() * 10000) + '.png', buffer, function (err) {
                    if (err) throw err;

                    //send file must be here because async functions
                    res.setHeader('Content-Length', buffer.length);
                    res.setHeader('Content-Type', 'image/png');
                    /*res.sendFile('map' + Math.round(Math.random() * 10000) + '.png', {
                        'root': '/var/www/fmp/etc/nodejs/'
                    });*/
                    res.send(buffer);
                    //console.log('saved map image to map.png');
                });
            });
        });
        //});
    });
});

var server = app.listen(3000, function () {
    var host = '127.0.0.1';
    var port = '3000';

    console.log('Mapnik app listening at http://%s:%s', host, port);
});

*****************************settings.js
settings.js: 

var path = require('path');

module.exports.styles = path.join(__dirname, 'styles');

module.exports.postgis = {
    'dbname' : 'fmp_data_eles',
    'table': 'powerlinesnew',
    'geometry_field' : 'geom',
    'srid' : 3857,
    'user' : 'postgres',
    'password': 'postgres',
    'max_size' : 1,
    'type' : 'postgis',
    'port': '5432',
    'host': 'localhost',
    'extent' : '-20005048.4188,-9039211.13765,19907487.2779,17096598.5401'  //set for epsg: 3857
};
springmeyer commented 8 years ago

reports a POSTGIS extension error

What is the error exactly?

Does anyone have any experience with mapnik and nodejs how to handle many concurrent requests on nodejs server with mapnik bindings???

The developers of https://github.com/cartodb/Windshaft might be able to help you. In general my first advise would be to increase the # of concurrent connections allowed by your database. I think Postgres defaults to 100.

'max_size' : 1,

The higher that number the better performance. I would increase to at least max_size = Number of CPUS.

KlemenSpruk commented 8 years ago

The exact error is: Error: Postgis Plugin: Null connection

springmeyer commented 8 years ago

Make sure you are running the latest node-mapnik version so that you are not getting hit by https://github.com/mapnik/mapnik/issues/2725

KlemenSpruk commented 8 years ago

Hello!

Thanks for advice. I increased the max_size parameter and number of postgres connections. That solved problems for my test case.

dozzes commented 4 years ago

I use similar code from https://github.com/pocketIlmatto/mapnik_node_tile_server to generate tiles from a shapefile created by gdal_contour. Most of the contour lines are not rendered in the tiles and transparent areas are not created correctly. Here is shapefile drawn in QGIS and generated tiles in CesiumJS respectively.

UPD. The mapnik sample from node-mapnik also creates wrong png. Here is the source shape shapefile.tar.gz file

QGIS screenshot QGIS_shapefile

CesiumJS screenshot Cesiumjs_contours

dozzes commented 4 years ago

The reason was in mapnik style xml, I forgot tor remove this line <PolygonSymbolizer fill="white" />