Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tiles from mapnik with nodejs #60

Closed
KlemenSpruk opened this issue Jan 11, 2016 · 6 comments
Closed

Tiles from mapnik with nodejs #60

KlemenSpruk opened this issue Jan 11, 2016 · 6 comments

Comments

@KlemenSpruk
Copy link

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
Copy link
Member

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
Copy link
Author

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

@springmeyer
Copy link
Member

Make sure you are running the latest node-mapnik version so that you are not getting hit by mapnik/mapnik#2725

@KlemenSpruk
Copy link
Author

Hello!

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

@dozzes
Copy link

dozzes commented Jan 15, 2020

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
Copy link

dozzes commented Jan 16, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants