Skip to content

Commit

Permalink
move to tilelive 4
Browse files Browse the repository at this point in the history
  • Loading branch information
kkaefer committed Jul 21, 2011
1 parent e9d341e commit 14fc288
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 69 deletions.
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#!/usr/bin/env node
process.title = 'tilemill';


var tilelive_mapnik = require('tilelive-mapnik');
tilelive_mapnik.registerProtocols(require('tilelive'));

require('bones').load(__dirname);
!module.parent && require('bones').start();
87 changes: 50 additions & 37 deletions models/Datasource.server.bones
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var path = require('path');
var url = require('url');
var fs = require('fs');
var mapnik = require('tilelive-mapnik/node_modules/mapnik');
var Map = require('tilelive-mapnik').Map;
var tilelive = require('tilelive');
var Step = require('step');

// @TODO this is rather messy atm - it caches the datasource to
Expand All @@ -25,53 +25,66 @@ models.Datasource.prototype.sync = function(method, model, success, error) {
Layer: [{
name: options.id,
Datasource: _({
file: options.url,
file: options.file,
type: options.ds_type
}).extend(options),
srs: SRS
}]
};
var env = {
data_dir: path.join(config.files, 'project', options.project),
local_data_dir: path.join(config.files, 'project', options.project)

// We abuse tilelive-mapnik and use a faked MML object to localize data
// into the project directory.
var id = options.project;
var uri = {
protocol: 'mapnik:',
slashes: true,
pathname: path.join(config.files, 'project', id, id + '.mml'),
query: {
// Note: data_file is only used to force a different cache key.
data_file: options.file,
data_dir: path.join(config.files, 'project', options.project),
local_data_dir: path.join(config.files, 'project', options.project)
},
data: mml
};
var map = new Map(mml, env);
var datasource;

Step(function() {
map.initialize(this);
},
function(err) {
tilelive.load(uri, function(err, source) {
if (err) return error(err);

var ds = map.mapnik.describe_data()[options.id];
datasource = {
id: options.id,
project: options.project,
url: options.url,
fields: ds.fields,
features: options.features ? map.mapnik.features(0, 1000) : [],
type: ds.type,
geometry_type: ds.type === 'raster' ? 'raster' : ds.geometry_type
};
// @TODO: We're accessing the internals of tilelive-mapnik.
// This may or may not be a good idea.
source._pool.acquire(function(err, map) {
if (err) return error(err);

// Process fields and calculate min/max values.
for (var f in datasource.fields) {
datasource.fields[f] = {
type: datasource.fields[f],
max: _(datasource.features).chain().pluck(f)
.max(function(v) {
return _(v).isString() ? v.length : v;
}).value(),
min: _(datasource.features).chain().pluck(f)
.min(function(v) {
return _(v).isString() ? v.length : v;
}).value()
var ds = map.describe_data()[options.id];
var datasource = {
id: options.id,
project: options.project,
url: options.file,
fields: ds.fields,
features: options.features ? map.features(0, 1000) : [],
type: ds.type,
geometry_type: ds.type === 'raster' ? 'raster' : ds.geometry_type
};
}

map.destroy();
success(datasource);
// Process fields and calculate min/max values.
for (var f in datasource.fields) {
datasource.fields[f] = {
type: datasource.fields[f],
max: _(datasource.features).chain().pluck(f)
.max(function(v) {
return _(v).isString() ? v.length : v;
}).value(),
min: _(datasource.features).chain().pluck(f)
.min(function(v) {
return _(v).isString() ? v.length : v;
}).value()
};
}

source._pool.release(map);
success(datasource);
});
});
};

3 changes: 1 addition & 2 deletions models/Project.bones
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,7 @@ model = Backbone.Model.extend({
if (!Bones.server) return options.success(this, null);

var carto = require('carto'),
// var carto = require('tilelive-mapnik/node_modules/carto'),
mapnik = require('tilelive-mapnik/node_modules/mapnik'),
mapnik = require('mapnik'),
stylesheets = this.get('Stylesheet'),
env = {
returnErrors: true,
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@
"bones": "1.3.x",
"chrono": "~1.0.1",
"JSV": "3.5.x",
"mbtiles": "0.0.x",
"mbtiles": "~0.1.1",
"sax": "0.1.x",
"request": "1.9.x",
"step": "0.0.x",
"tilelive": "~ 3.0.3",
"tilelive-mapnik": "~ 0.0.6",
"tilelive": "4.0.x",
"mapnik": "0.4.x",
"tilelive-mapnik": "https://github.com/mapbox/tilelive-mapnik/tarball/tilelive-refactoring",
"underscore": "1.1.x",
"carto": "https://github.com/mapbox/carto/tarball/b84f22830336235aaf6fdaf64fb963a6f6a087b4",
"wax": "https://github.com/mapbox/wax/tarball/abf06066575c63b84f952e658956d49ab8644d2a"
Expand Down
3 changes: 1 addition & 2 deletions servers/App.bones
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
var mapnik = require('tilelive-mapnik/node_modules/mapnik');
var mapnik = require('mapnik');
var path = require('path');
var env = process.env.NODE_ENV || 'development';

var abilities = {
carto: require('carto').tree.Reference.data,
// carto: require('tilelive-mapnik/node_modules/carto').tree.Reference.data,
fonts: mapnik.fonts(),
datasources: mapnik.datasources(),
exports: {
Expand Down
72 changes: 47 additions & 25 deletions servers/Tile.bones
Original file line number Diff line number Diff line change
@@ -1,47 +1,69 @@
var path = require('path'),
tilelive = new (require('tilelive').Server)(require('tilelive-mapnik')),
tilelive = require('tilelive'),
settings = Bones.plugin.config;

server = Bones.Server.extend({});

server.prototype.initialize = function() {
_.bindAll(this, 'load', 'layer', 'tile');
this.get('/1.0.0/:id/:z/:x/:y.:format(png8|png|jpeg[\\d]+|jpeg)', this.tile);
this.get('/1.0.0/:id/:z/:x/:y.:format(grid.json)', this.load, this.tile);
_.bindAll(this, 'load', 'grid', 'layer', 'getArtifact');
this.get('/1.0.0/:id/:z/:x/:y.:format(png8|png|jpeg[\\d]+|jpeg)', this.load, this.getArtifact);
this.get('/1.0.0/:id/:z/:x/:y.:format(grid.json)', this.load, this.grid, this.getArtifact);
this.get('/1.0.0/:id/layer.json', this.load, this.layer);
};

server.prototype.load = function(req, res, next) {
res.project = new models.Project({id: req.param('id')});
res.project.fetch({
success: function(model, resp) { next(); },
error: function(model, resp) { next(resp); }
success: function(model, resp) {
res.projectMML = resp;
next();
},
error: function(model, resp) {
next(resp);
}
});
};

server.prototype.tile = function(req, res, next) {
req.params.datasource = path.join(
settings.files,
'project',
req.param('id'),
req.param('id') + '.mml'
);
if (req.params.format === 'grid.json' && res.project) {
if (!res.project.get('interactivity'))
return next(new Error.HTTP('Not found.', 404));

var interactivity = res.project.get('interactivity');
req.params.layer = interactivity.layer;
req.params.fields = models.Project.fields(interactivity);
req.query.callback = 'grid'; // Force jsonp.
}
tilelive.serve(req.params, function(err, data) {
server.prototype.getArtifact = function(req, res, next) {
// This is the cache key in tilelive-mapnik, so make sure it
// contains the mtime with _updated.
var id = req.params.id;
var uri = {
protocol: 'mapnik:',
slashes: true,
pathname: path.join(settings.files, 'project', id, id + '.mml'),
search: '_updated=' + res.projectMML._updated,
data: res.projectMML
};

tilelive.load(uri, function(err, source) {
if (err) return next(err);
data[1]['max-age'] = 3600;
res.send.apply(res, data);

var z = req.params.z, x = +req.params.x, y = +req.params.y;

// The interface is still TMS.
y = (1 << z) - 1 - y;

var fn = req.params.format === 'grid.json' ? 'getGrid' : 'getTile';
source[fn](z, x, y, function(err, tile, headers) {
if (err) return next(err);
headers['max-age'] = 3600;
res.send(tile, headers);
});
});
};

server.prototype.grid = function(req, res, next) {
// Early exit. tilelive-mapnik would catch that too.
if (!res.project.get('interactivity')) {
return next(new Error.HTTP('Not found.', 404));
}

// Force jsonp.
req.query.callback = 'grid';
next();
};

server.prototype.layer = function(req, res, next) {
if (!res.project.get('formatter') && !res.project.get('legend')) {
next(new Error.HTTP('Not found.', 404));
Expand Down

0 comments on commit 14fc288

Please sign in to comment.