1
votes

Working on a new mapping project using Nodejs, leaflet, and PostGIS. At this point I'm able to load and display the map tile layer along with our sales reps zones from Postgis. Now I'm trying to add another layer that will display all US Counties, also stored in Postgresql. Both Postgis queries run and display when used separately but I cannot get both to load and display together. Here's an excerpt from nodejs 'routes/index.js':

router.get('/map', function(req, res) {
var client = new pg.Client(conString); // Setup our Postgres Client
client.connect(); // connect to the client
var query = client.query(zone_query); // Run our Query
query.on("row", function (row, result) {
    result.addRow(row);
});
// Pass the result to the map page
query.on("end", function (result) {
    var data = result.rows[0].row_to_json; // Save the JSON as variable data
    res.render('map', {
        title: "Express API", // Give a title to our page
        zoneData: data // Pass data to the View
    });
});
});

router.get('/map', function(req, res) {
var client = new pg.Client(conString); // Setup our Postgres Client
client.connect(); // connect to the client
var query = client.query(counties_query); // Run our Query
query.on("row", function (row, result) {
    result.addRow(row);
});
// Pass the result to the map page
query.on("end", function (result) {
    var data2 = result.rows[0].row_to_json; // Save the JSON as variable data
    res.render('map', {
        title: "Express API", // Give a title to our page
        countyData: data2 // Pass data to the View
    });
});
});

And from the 'view/map.pug':

    script("text/javascript").
    $(document).ready(function(){
        var myData = !{JSON.stringify(zoneData)};
        var cntyData = !{JSON.stringify(countyData)};
        // Create variable to hold map element, give initial settings to map
        var map = L.map('map',{
            center: [39.7799642, -86.2728367],
            zoom: 6,
            //layers: [zones, counties]
        });

... and then further down:

L.geoJson(myData,{
            style: zoneStyle,

            onEachFeature: function (feature, layer) {
                var ofc = JSON.stringify(feature.properties.office);
                var zn = JSON.stringify(feature.properties.zone);
                layer.bindPopup("office: " + ofc + "<br>" + "zone #" + zn);
               // layer.bindPopup("Zone #"+JSON.stringify(feature.properties.zone));
            }
        }).addTo(map);

        // Add county data to map
        L.geoJson(cntyData,{
            onEachFeature: function (feature, layer) {
                //var desc = JSON.stringify(feature.properties.descriptio);
                layer.bindPopup(desc);
            }
        }).addTo(map);

Any one of these works perfectly by itself but trying to load both layers displays nothing at all. Ultimately what I'm trying to accomplish is to be able to toggle the sales zones and state county boundary layers on and off.

Any insight is appreciated.

1
You're using the variable name query for both PGSQL queries, which might be causing some collisions internally. Use different names, or use closures. - IvanSanchez
On top of that, you're trying to res.render() twice. My node.js is a bit rusty, so make extra sure that doing so makes sense in Express. - IvanSanchez
It's very likely that the first call to res.render() returns all the HTML to the browser, and closes the request-response stream in the express side of things, making one of the res.render() calls to fail silently. - IvanSanchez
Okay, even with my limited experience with nodejs, leaflet, and postgis, that all makes sense. From what I understand I can pass multiple variables in res.render() but I guess I'm still a little confused as to how to get those query results into the res.render() function? - Godfried
Something like one call to res.render('map', {title:"foo", zoneData: z, countyData: c}) - IvanSanchez

1 Answers

1
votes

So I was having the same problem and come up with this solution with the help of some colleagues.

router.get('/', function (req, res) {
var client = new pg.Client(conString); // Setup our Postgres Client
client.connect(); // connect to the client

// creating an empty array for my row_to_json queries
var data = []

var resto_query = client.query(restoPoint_query); //connects to postgres so it can query up my request
resto_query.on("row", function (row, result) {
result.addRow(row);
});
resto_query.on("end", function (result) {
var resto_to_json = result.rows[0].row_to_json; // Save the JSON as variable data
data.push(resto_to_json); // push JSON data to data[]

var barrierQuery = client.query(barrier_query);
barrierQuery.on("row", function (row, result) {
    result.addRow(row);
});
barrierQuery.on("end", function (result) {
    var barrier_to_json = result.rows[0].row_to_json;
    data.push(barrier_to_json);

    res.render('map', {
      title: "Leaflet Test API", // Give a title to our page
      resto_point: data[0], // Pass data to the View
      barrier: data[1]

Probably not the best solution but it works for the time being.