]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.server/server/tileserver-mapnik/server.js
Adding pkg-precompiled tileserver-mapnik to avoid npm install
[simantics/district.git] / org.simantics.maps.server / server / tileserver-mapnik / server.js
1 #!/usr/bin/env node
2 "use strict";
3
4 // increase the libuv threadpool size to 1.5x the number of logical CPUs.
5 process.env.UV_THREADPOOL_SIZE = process.env.UV_THREADPOOL_SIZE || Math.ceil(Math.max(4, require('os').cpus().length * 1.5));
6
7 var fs = require("fs"),
8     path = require("path");
9
10 var async = require("async"),
11     cors = require("cors"),
12     debug = require("debug"),
13     express = require("express"),
14     morgan = require("morgan"),
15     responseTime = require("response-time");
16
17 var serve = require("./lib/app"),
18     tessera = require("./lib/index");
19
20 debug = debug("tessera");
21
22 var tmstyle = require('tilelive-tmstyle');
23 var tilelivevector = require('tilelive-vector');
24 var mbtiles = require('mbtiles');
25
26 module.exports = function(opts, callback) {
27   var app = express().disable("x-powered-by"),
28       tilelive = require("tilelive-cache")(require("tilelive"), {
29         size: process.env.CACHE_SIZE || opts.cacheSize,
30         sources: process.env.SOURCE_CACHE_SIZE || opts.sourceCacheSize
31       });
32
33   app.enable('trust proxy');
34
35   callback = callback || function() {};
36
37   // load and register tilelive modules
38   require("tilelive-modules/loader")(tilelive, opts);
39   console.log('tilelive : ' + tilelive.protocols);
40   // test by jani
41   var testOpts = {
42     require: ['tilelive-vector', 'tilelive-tmstyle', 'mbtiles']
43   };
44   require("tilelive-modules/loader")(tilelive, testOpts);
45   console.log('tilelive2 : ' + tilelive.protocols);
46   if (process.env.NODE_ENV !== "production") {
47     // TODO configurable logging per-style
48     app.use(morgan("dev"));
49   }
50
51   if (opts.uri) {
52     app.use(responseTime());
53     app.use(cors());
54     app.use(express.static(path.join(__dirname, "public")));
55     //app.use(express.static(path.join(__dirname, "bower_components")));
56     app.use(serve(tilelive, opts.uri));
57
58     tilelive.load(opts.uri, function(err, src) {
59       if (err) {
60         throw err;
61       }
62
63       return tessera.getInfo(src, function(err, info) {
64         if (err) {
65           debug(err.stack);
66           return;
67         }
68
69         if (info.format === "pbf") {
70           app.use("/_", serve(tilelive, "xray+" + opts.uri));
71           app.use("/_", express.static(path.join(__dirname, "public")));
72           //app.use("/_", express.static(path.join(__dirname, "bower_components")));
73         }
74       });
75     });
76   }
77
78   if (opts.config) {
79     var configPath = path.resolve(opts.config),
80         stats = fs.statSync(configPath),
81         config = {};
82
83     if (stats.isFile()) {
84       config = require(configPath);
85     } else if (stats.isDirectory()) {
86       config = fs.readdirSync(configPath)
87         .filter(function(filename) {
88           return path.extname(filename) === ".json";
89         })
90         .reduce(function(config, filename) {
91           var localConfig = require(path.join(configPath, filename));
92
93           return Object.keys(localConfig).reduce(function(config, k) {
94             config[k] = localConfig[k];
95
96             return config;
97           }, config);
98         }, config);
99     }
100
101     Object.keys(config).forEach(function(prefix) {
102       if (config[prefix].timing !== false) {
103         app.use(prefix, responseTime());
104       }
105
106       if (config[prefix].cors !== false) {
107         app.use(prefix, cors());
108       }
109
110       //app.use(prefix, express.static(path.join(__dirname, "public")));
111       //app.use(prefix, express.static(path.join(__dirname, "bower_components")));
112       app.use(prefix, serve(tilelive, config[prefix]));
113     });
114
115     // serve index.html even on the root
116     app.use("/", express.static(path.join(__dirname, "public")));
117     //app.use("/", express.static(path.join(__dirname, "bower_components")));
118
119     // aggregate index.json on root for multiple sources
120     app.get("/index.json", function(req, res, next) {
121       var queue = [];
122       Object.keys(config).forEach(function(prefix) {
123         queue.push(function(callback) {
124           var url = config[prefix].source || config[prefix];
125           tilelive.load(url, function(err, source) {
126             if (err) {
127               throw err;
128             }
129
130             tessera.getInfo(source, function(err, info) {
131               if (err) {
132                 throw err;
133               }
134
135               var domains = [],
136                   tilePath = config[prefix].tilePath || "/{z}/{x}/{y}.{format}";
137
138               if (config[prefix].domains && config[prefix].domains.length > 0) {
139                 domains = config[prefix].domains.split(',');
140               }
141
142               if (prefix.length > 1) {
143                 info.basename = prefix.substr(1);
144               }
145
146               info.tiles = serve.getTileUrls(domains, req.headers.host, prefix,
147                                              tilePath, info.format,
148                                              req.query.key, req.protocol);
149               info.tilejson = "2.0.0";
150
151               callback(null, info);
152             });
153           });
154         });
155       });
156       return async.parallel(queue, function(err, results) {
157         return res.send(results);
158       });
159     });
160   }
161
162   app.listen(process.env.PORT || opts.port, function() {
163     console.log("Listening at http://%s:%d/", this.address().address, this.address().port);
164
165     return callback();
166   });
167 };