فهرست منبع

Merge branch 'georeport' of fzadrazil/rural-attractivness-service into master

František Zadražil 5 سال پیش
والد
کامیت
d64a83d647
8فایلهای تغییر یافته به همراه637 افزوده شده و 3 حذف شده
  1. 25 0
      helpers.js
  2. 52 0
      index.js
  3. 411 3
      package-lock.json
  4. 2 0
      package.json
  5. 79 0
      static/NUTS3_4326.json
  6. 27 0
      static/map.css
  7. 11 0
      static/map.js
  8. 30 0
      views/nuts.pug

+ 25 - 0
helpers.js

@@ -1,6 +1,7 @@
 /*
     Helper methods for use in the other modules.
 */
+const fs = require('fs');
 
 module.exports.formatResponse = function (obj, req, res) {
     res.header("Content-Type", 'application/json');
@@ -9,4 +10,28 @@ module.exports.formatResponse = function (obj, req, res) {
         res.send(JSON.stringify(obj, null, 4));
     else
         res.send(obj);
+}
+
+module.exports.loadJSON = function (filename) {
+  let rawdata = fs.readFileSync(filename);
+  let jsondata = JSON.parse(rawdata);
+
+  return jsondata;
+}
+
+module.exports.getCentroid = function (geometry) {
+  let firstPoint = geometry.coordinates[0][0]
+  let xmin = firstPoint[0]
+  let xmax = firstPoint[0]
+  let ymin = firstPoint[1]
+  let ymax = firstPoint[1]
+
+  geometry.coordinates[0].forEach(pt => {
+    if (pt[0] < xmin) xmin = pt[0];
+    if (pt[0] > xmax) xmax = pt[0];
+    if (pt[1] < ymin) ymin = pt[1];
+    if (pt[1] > ymax) ymax = pt[1];
+  });
+
+  return [(ymin + ymax) / 2.0, (xmin + xmax) / 2.0];
 }

+ 52 - 0
index.js

@@ -3,6 +3,7 @@ const helpers = require('./helpers.js');
 const nutsData = require('./nuts-data.js');
 const cors = require('cors');
 const R = require('r-script');
+var where = require("lodash.where");
 
 const app = express();
 
@@ -18,6 +19,10 @@ var _ruralData = undefined;
 app.use(express.json());
 // handle CORS
 app.use(cors())
+// serve static files from the /static directory
+app.use(express.static('static'))
+// set PUG as default rendering engine
+app.set('view engine', 'pug')
 
 /* Dummy web service call without the method specified */
 app.get('/', (req, res) => {
@@ -188,10 +193,57 @@ app.post('/clusters', async (req, res, next) => {
     }
 });
 
+app.get('/georeport/:nuts', (req, res, next) => {
+  if (_ruralData) {
+    renderPugReport(req.params.nuts, req, res);
+  }
+  else {
+    if (_datasets) { // datasets must be loaded prior to data loading
+      nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
+        _ruralData = rd;
+        renderPugReport(req.params.nuts, req, res);
+      });
+    }
+    else {
+      nutsData.loadDatasets(_datasetsFilePath, function (ds) {
+        _datasets = ds;
+
+        nutsData.loadRuralData(_dataFilePath, _datasets, function (rd) {
+          _ruralData = rd;
+          renderPugReport(req.params.nuts, req, res);
+        });
+      });
+    }
+  }
+});
+
 // start the service on the port xxxx
 app.listen(3000, () => console.log('Rural attractivity WS listening on port 3000...'));
 
 
+function renderPugReport(nuts, req, res) {
+  var found = false;
+
+  _ruralData.forEach(region => {
+    if (region.nuts == nuts) {
+
+      let nutsGeoJson = helpers.loadJSON('static/NUTS3_4326.json');
+      let filterednutsGeoJson = where(nutsGeoJson.features, { "properties": { "NUTS_ID": nuts } });
+      region.metadata = {
+        name: filterednutsGeoJson[0].properties.NUTS_NAME,
+        code: nuts,
+        centroid: helpers.getCentroid(filterednutsGeoJson[0].geometry)
+      };
+
+      res.render('nuts', { region: region, datasets: _datasets });
+      found = true;
+    }
+  });
+
+  if (!found)
+    res.render('err', {  });
+}
+
 function returnAllScores(req, res) {
     var resData = [];
     _ruralData.forEach(region => {

+ 411 - 3
package-lock.json

@@ -4,6 +4,38 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
+    "@babel/helper-validator-identifier": {
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+      "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw=="
+    },
+    "@babel/parser": {
+      "version": "7.12.5",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz",
+      "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ=="
+    },
+    "@babel/types": {
+      "version": "7.12.6",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.6.tgz",
+      "integrity": "sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA==",
+      "requires": {
+        "@babel/helper-validator-identifier": "^7.10.4",
+        "lodash": "^4.17.19",
+        "to-fast-properties": "^2.0.0"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.20",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+          "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+        },
+        "to-fast-properties": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+          "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
+        }
+      }
+    },
     "abbrev": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -19,6 +51,11 @@
         "negotiator": "0.6.2"
       }
     },
+    "acorn": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
+    },
     "ansi-align": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
@@ -87,6 +124,16 @@
       "dev": true,
       "optional": true
     },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+    },
+    "assert-never": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz",
+      "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw=="
+    },
     "assign-symbols": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
@@ -757,6 +804,14 @@
         "to-fast-properties": "^1.0.3"
       }
     },
+    "babel-walk": {
+      "version": "3.0.0-canary-5",
+      "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz",
+      "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==",
+      "requires": {
+        "@babel/types": "^7.9.6"
+      }
+    },
     "babylon": {
       "version": "6.18.0",
       "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
@@ -1018,6 +1073,14 @@
         "supports-color": "^2.0.0"
       }
     },
+    "character-parser": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
+      "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=",
+      "requires": {
+        "is-regex": "^1.0.3"
+      }
+    },
     "chokidar": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
@@ -1139,6 +1202,15 @@
         "xdg-basedir": "^3.0.0"
       }
     },
+    "constantinople": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
+      "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==",
+      "requires": {
+        "@babel/parser": "^7.6.0",
+        "@babel/types": "^7.6.1"
+      }
+    },
     "content-disposition": {
       "version": "0.5.3",
       "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
@@ -1335,6 +1407,11 @@
         "repeating": "^2.0.0"
       }
     },
+    "doctypes": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
+      "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
+    },
     "dot-prop": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
@@ -2135,6 +2212,11 @@
         }
       }
     },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+    },
     "get-stream": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
@@ -2223,6 +2305,14 @@
       "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
       "dev": true
     },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
     "has-ansi": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
@@ -2238,6 +2328,11 @@
       "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
       "dev": true
     },
+    "has-symbols": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
+    },
     "has-value": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
@@ -2423,6 +2518,14 @@
         "ci-info": "^1.5.0"
       }
     },
+    "is-core-module": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.0.0.tgz",
+      "integrity": "sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw==",
+      "requires": {
+        "has": "^1.0.3"
+      }
+    },
     "is-data-descriptor": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
@@ -2471,6 +2574,15 @@
         "is-primitive": "^2.0.0"
       }
     },
+    "is-expression": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz",
+      "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==",
+      "requires": {
+        "acorn": "^7.1.1",
+        "object-assign": "^4.1.1"
+      }
+    },
     "is-extendable": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
@@ -2581,12 +2693,25 @@
       "dev": true,
       "optional": true
     },
+    "is-promise": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+      "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
+    },
     "is-redirect": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
       "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
       "dev": true
     },
+    "is-regex": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
+      "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
+      "requires": {
+        "has-symbols": "^1.0.1"
+      }
+    },
     "is-retry-allowed": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
@@ -2629,6 +2754,11 @@
         "isarray": "1.0.0"
       }
     },
+    "js-stringify": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
+      "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds="
+    },
     "js-tokens": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
@@ -2647,6 +2777,15 @@
       "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
       "dev": true
     },
+    "jstransformer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
+      "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=",
+      "requires": {
+        "is-promise": "^2.0.0",
+        "promise": "^7.0.1"
+      }
+    },
     "kind-of": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
@@ -2667,11 +2806,125 @@
       }
     },
     "lodash": {
-      "version": "4.17.15",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+      "version": "4.17.20",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+      "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
       "dev": true
     },
+    "lodash._arrayfilter": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/lodash._arrayfilter/-/lodash._arrayfilter-3.0.0.tgz",
+      "integrity": "sha1-LevhHuxp5dzG9LhhNxKKSPFSQjc="
+    },
+    "lodash._basecallback": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/lodash._basecallback/-/lodash._basecallback-3.3.1.tgz",
+      "integrity": "sha1-t7K7Q9whYEJKIczybFfkQ3cqjic=",
+      "requires": {
+        "lodash._baseisequal": "^3.0.0",
+        "lodash._bindcallback": "^3.0.0",
+        "lodash.isarray": "^3.0.0",
+        "lodash.pairs": "^3.0.0"
+      }
+    },
+    "lodash._baseeach": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/lodash._baseeach/-/lodash._baseeach-3.0.4.tgz",
+      "integrity": "sha1-z4cGVyyhROjZ11InyZDamC+TKvM=",
+      "requires": {
+        "lodash.keys": "^3.0.0"
+      }
+    },
+    "lodash._basefilter": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/lodash._basefilter/-/lodash._basefilter-3.0.0.tgz",
+      "integrity": "sha1-S3ZAPfDihtA9Xg9yle00QeEB0SE=",
+      "requires": {
+        "lodash._baseeach": "^3.0.0"
+      }
+    },
+    "lodash._baseisequal": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz",
+      "integrity": "sha1-2AJfdjOdKTQnZ9zIh85cuVpbUfE=",
+      "requires": {
+        "lodash.isarray": "^3.0.0",
+        "lodash.istypedarray": "^3.0.0",
+        "lodash.keys": "^3.0.0"
+      }
+    },
+    "lodash._baseismatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/lodash._baseismatch/-/lodash._baseismatch-3.1.3.tgz",
+      "integrity": "sha1-Byj8SO+hFpnT1fLXMEnyqxPED9U=",
+      "requires": {
+        "lodash._baseisequal": "^3.0.0"
+      }
+    },
+    "lodash._basematches": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/lodash._basematches/-/lodash._basematches-3.2.0.tgz",
+      "integrity": "sha1-9H4D8H7CB4SrCWjQy2y1l+IQEVg=",
+      "requires": {
+        "lodash._baseismatch": "^3.0.0",
+        "lodash.pairs": "^3.0.0"
+      }
+    },
+    "lodash._bindcallback": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
+      "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4="
+    },
+    "lodash._getnative": {
+      "version": "3.9.1",
+      "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+      "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U="
+    },
+    "lodash.isarguments": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+      "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo="
+    },
+    "lodash.isarray": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
+      "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U="
+    },
+    "lodash.istypedarray": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz",
+      "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I="
+    },
+    "lodash.keys": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
+      "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
+      "requires": {
+        "lodash._getnative": "^3.0.0",
+        "lodash.isarguments": "^3.0.0",
+        "lodash.isarray": "^3.0.0"
+      }
+    },
+    "lodash.pairs": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.pairs/-/lodash.pairs-3.0.1.tgz",
+      "integrity": "sha1-u+CNV4bu6qCaFckevw3LfSvjJqk=",
+      "requires": {
+        "lodash.keys": "^3.0.0"
+      }
+    },
+    "lodash.where": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/lodash.where/-/lodash.where-3.1.0.tgz",
+      "integrity": "sha1-LnhLnJM2jV11qu4zLOF2Ai8rlVM=",
+      "requires": {
+        "lodash._arrayfilter": "^3.0.0",
+        "lodash._basecallback": "^3.0.0",
+        "lodash._basefilter": "^3.0.0",
+        "lodash._basematches": "^3.0.0",
+        "lodash.isarray": "^3.0.0"
+      }
+    },
     "loose-envify": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -3263,6 +3516,11 @@
       "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
       "dev": true
     },
+    "path-parse": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+    },
     "path-to-regexp": {
       "version": "0.1.7",
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
@@ -3313,6 +3571,14 @@
       "dev": true,
       "optional": true
     },
+    "promise": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+      "requires": {
+        "asap": "~2.0.3"
+      }
+    },
     "proxy-addr": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
@@ -3334,6 +3600,118 @@
       "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==",
       "dev": true
     },
+    "pug": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.0.tgz",
+      "integrity": "sha512-inmsJyFBSHZaiGLaguoFgJGViX0If6AcfcElimvwj9perqjDpUpw79UIEDZbWFmoGVidh08aoE+e8tVkjVJPCw==",
+      "requires": {
+        "pug-code-gen": "^3.0.0",
+        "pug-filters": "^4.0.0",
+        "pug-lexer": "^5.0.0",
+        "pug-linker": "^4.0.0",
+        "pug-load": "^3.0.0",
+        "pug-parser": "^6.0.0",
+        "pug-runtime": "^3.0.0",
+        "pug-strip-comments": "^2.0.0"
+      }
+    },
+    "pug-attrs": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz",
+      "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==",
+      "requires": {
+        "constantinople": "^4.0.1",
+        "js-stringify": "^1.0.2",
+        "pug-runtime": "^3.0.0"
+      }
+    },
+    "pug-code-gen": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.1.tgz",
+      "integrity": "sha512-xJIGvmXTQlkJllq6hqxxjRWcay2F9CU69TuAuiVZgHK0afOhG5txrQOcZyaPHBvSWCU/QQOqEp5XCH94rRZpBQ==",
+      "requires": {
+        "constantinople": "^4.0.1",
+        "doctypes": "^1.1.0",
+        "js-stringify": "^1.0.2",
+        "pug-attrs": "^3.0.0",
+        "pug-error": "^2.0.0",
+        "pug-runtime": "^3.0.0",
+        "void-elements": "^3.1.0",
+        "with": "^7.0.0"
+      }
+    },
+    "pug-error": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz",
+      "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ=="
+    },
+    "pug-filters": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz",
+      "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==",
+      "requires": {
+        "constantinople": "^4.0.1",
+        "jstransformer": "1.0.0",
+        "pug-error": "^2.0.0",
+        "pug-walk": "^2.0.0",
+        "resolve": "^1.15.1"
+      }
+    },
+    "pug-lexer": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.0.tgz",
+      "integrity": "sha512-52xMk8nNpuyQ/M2wjZBN5gXQLIylaGkAoTk5Y1pBhVqaopaoj8Z0iVzpbFZAqitL4RHNVDZRnJDsqEYe99Ti0A==",
+      "requires": {
+        "character-parser": "^2.2.0",
+        "is-expression": "^4.0.0",
+        "pug-error": "^2.0.0"
+      }
+    },
+    "pug-linker": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz",
+      "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==",
+      "requires": {
+        "pug-error": "^2.0.0",
+        "pug-walk": "^2.0.0"
+      }
+    },
+    "pug-load": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz",
+      "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==",
+      "requires": {
+        "object-assign": "^4.1.1",
+        "pug-walk": "^2.0.0"
+      }
+    },
+    "pug-parser": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz",
+      "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==",
+      "requires": {
+        "pug-error": "^2.0.0",
+        "token-stream": "1.0.0"
+      }
+    },
+    "pug-runtime": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.0.tgz",
+      "integrity": "sha512-GoEPcmQNnaTsePEdVA05bDpY+Op5VLHKayg08AQiqJBWU/yIaywEYv7TetC5dEQS3fzBBoyb2InDcZEg3mPTIA=="
+    },
+    "pug-strip-comments": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz",
+      "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==",
+      "requires": {
+        "pug-error": "^2.0.0"
+      }
+    },
+    "pug-walk": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz",
+      "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ=="
+    },
     "qs": {
       "version": "6.7.0",
       "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
@@ -3860,6 +4238,15 @@
         "is-finite": "^1.0.0"
       }
     },
+    "resolve": {
+      "version": "1.18.1",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz",
+      "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==",
+      "requires": {
+        "is-core-module": "^2.0.0",
+        "path-parse": "^1.0.6"
+      }
+    },
     "resolve-url": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -4333,6 +4720,11 @@
       "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
       "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
     },
+    "token-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz",
+      "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ="
+    },
     "touch": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
@@ -4559,6 +4951,11 @@
       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
       "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
     },
+    "void-elements": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+      "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk="
+    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -4577,6 +4974,17 @@
         "string-width": "^2.1.1"
       }
     },
+    "with": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz",
+      "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==",
+      "requires": {
+        "@babel/parser": "^7.9.6",
+        "@babel/types": "^7.9.6",
+        "assert-never": "^1.2.1",
+        "babel-walk": "3.0.0-canary-5"
+      }
+    },
     "wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",

+ 2 - 0
package.json

@@ -13,6 +13,8 @@
     "csv-parse": "^4.8.5",
     "csv-stringify": "^5.5.1",
     "express": "^4.17.1",
+    "lodash.where": "^3.1.0",
+    "pug": "^3.0.0",
     "r-script": "0.0.4"
   },
   "devDependencies": {

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 79 - 0
static/NUTS3_4326.json


+ 27 - 0
static/map.css

@@ -0,0 +1,27 @@
+table {
+    border-collapse: collapse;
+}
+
+th {
+    border: 1px solid;
+    padding: 5px;
+}
+
+td {
+    border: 1px solid;
+    padding: 5px;
+}
+
+tr:nth-child(even) {
+    background-color: #dddddd;
+}
+
+#metadata {
+    text-align: center;
+}
+
+#map {
+    height: 200px;
+    width: 400px;
+    margin: 3rem auto;
+}

+ 11 - 0
static/map.js

@@ -0,0 +1,11 @@
+function initMap(location) {
+  var map = L.map('map').setView(location, 3);
+
+  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
+  }).addTo(map);
+
+  L.marker(location).addTo(map);
+    //.bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
+    //.openPopup();
+}

+ 30 - 0
views/nuts.pug

@@ -0,0 +1,30 @@
+html
+  head
+    title= region.nuts
+    link(rel='stylesheet' href='https://unpkg.com/leaflet@1.7.1/dist/leaflet.css' integrity='sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==' crossorigin='')
+    link(rel='stylesheet' href='/map.css')
+    script(src='https://unpkg.com/leaflet@1.7.1/dist/leaflet.js' integrity='sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==' crossorigin='')
+    script(src='/map.js')
+
+    style.
+  body
+    div#metadata
+      h1= region.metadata.name + ' (' + region.metadata.code + ')'
+
+      div#map
+
+    table
+      tr
+        th Dataset
+        th Description
+        th Region score
+
+      each ds in datasets
+        tr
+          td= ds.Name
+          td= ds.Description
+          td= region[ds.Factor][ds.Name]
+    
+    script.
+      let c = !{JSON.stringify(region.metadata.centroid)};
+      initMap(c);

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است