Skip to content
This repository has been archived by the owner on Apr 4, 2019. It is now read-only.

Commit

Permalink
Add mbtiles preview for exports.
Browse files Browse the repository at this point in the history
  • Loading branch information
Young Hahn committed Jul 29, 2011
1 parent 2c6c28e commit e2a7727
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 15 deletions.
20 changes: 20 additions & 0 deletions assets/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,7 @@ li:hover .icon { display:block; }
.icon.tooltip { background-position:-580px -180px; }
.icon.star { background-position:-600px -180px; }
.icon.cloud { background-position:-620px -180px; }
.icon.eye { background-position:-640px -180px; }

.reverse.edit { background-position:0px -200px; }
.reverse.inspect { background-position:-20px -200px; }
Expand Down Expand Up @@ -863,6 +864,7 @@ li:hover .icon { display:block; }
.reverse.tooltip { background-position:-580px -200px; }
.reverse.star { background-position:-600px -200px; }
.reverse.cloud { background-position:-620px -200px; }
.reverse.eye { background-position:-640px -200px; }

/* Dock-icon specific reverse styles */
.dock .active > .icon.legend { background-position:-280px -200px; }
Expand Down Expand Up @@ -1356,6 +1358,24 @@ div.fonts { padding-top:30px; }
width:120px;
}

/* Exports preview */
#preview {
background-position:50% 50%;
background-repeat:no-repeat;
background-color:#eee;
border:1px solid #ccc;
position:absolute !important;
left:20px !important;
right:20px !important;
top:80px !important;
bottom:20px !important;
width:auto !important;
height:auto !important;
box-shadow:inset #ddd 0px 0px 5px;
-moz-box-shadow:inset #ddd 0px 0px 5px;
-webkit-box-shadow:inset #ddd 0px 0px 5px;
}

/* Error page */
.empty {
text-align:center;
Expand Down
Binary file modified assets/images/sprite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 12 additions & 3 deletions assets/images/sprite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 2 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#!/usr/bin/env node
process.title = 'tilemill';


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

require('bones').load(__dirname);
!module.parent && require('bones').start();
3 changes: 3 additions & 0 deletions models/Preview.bones
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Preview of an mbtiles export.
model = Backbone.Model.extend({});
model.prototype.url = function() { return '/api/Preview/' + this.id; };
17 changes: 17 additions & 0 deletions models/Preview.server.bones
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
var path = require('path');
var tilelive = require('tilelive');
var settings = Bones.plugin.config;

models.Preview.prototype.sync = function(method, model, success, error) {
if (method !== 'read') return error(new Error('Method not supported.'));
var filepath = path.join(settings.files, 'export', model.id);
tilelive.load('mbtiles://' + filepath, function(err, source) {
if (err) return error(err);
source.getInfo(function(err, info) {
if (err) return error(err);
info.tiles = ['/1.0.0/' + model.id + '/{z}/{x}/{y}.png'];
success(_(info).extend({id: model.id }));
});
});
};

25 changes: 23 additions & 2 deletions servers/Tile.bones
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ var path = require('path'),
server = Bones.Server.extend({});

server.prototype.initialize = function() {
_.bindAll(this, 'load', 'grid', 'getArtifact');
_.bindAll(this, 'load', 'grid', 'getArtifact', 'mbtiles');
this.get('/1.0.0/:id.mbtiles/:z/:x/:y.:format(png8|png|jpeg[\\d]+|jpeg)', this.mbtiles);
this.get('/1.0.0/:id.mbtiles/:z/:x/:y.:format(grid.json)', this.mbtiles);
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);
};
Expand Down Expand Up @@ -50,7 +52,7 @@ server.prototype.getArtifact = function(req, res, next) {
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;
if (headers) headers['max-age'] = 3600;
res.send(tile, headers);
});
});
Expand All @@ -70,3 +72,22 @@ server.prototype.grid = function(req, res, next) {
next();
};

server.prototype.mbtiles = function(req, res, next) {
var uri = 'mbtiles://' + path.join(settings.files, 'export', req.param('id') + '.mbtiles');
tilelive.load(uri, function(err, source) {
if (err) return next(err);

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);
if (headers) headers['max-age'] = 3600;
res.send(tile, headers);
});
});
};

5 changes: 5 additions & 0 deletions templates/Exports._
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@
<%= obj.time(m.get('remaining')) %> remaining
<% } %>
<% if (m.get('status') === 'complete') { %>
<div class='joined'>
<% if (m.get('format') === 'mbtiles') { %>
<a class='button preview popup' href='#<%=m.get('filename')%>'><span class='icon reverse labeled eye'></span> Preview</a>
<% } %>
<a class='button' href='/export/download/<%=m.get('filename')%>'><span class='icon reverse labeled export'></span> Download</a>
</div>
<% } %>
<% if (m.get('status') === 'error') { %>
<%=m.get('error')%>
Expand Down
11 changes: 11 additions & 0 deletions templates/Preview._
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<ul class='form fill'>
<li class='text'>
<h2><%= get('id') %></h2>
<p class='prose'>
To host these tiles sign up for <a target='_blank' href='http://mapbox.com/tilestream'>TileStream Hosting</a> or setup <a target='_blank' href='http://github.com/mapbox/tilestream'>TileStream</a> on your own server.
</p>
</li>
</ul>

<div id='preview'></div>

18 changes: 16 additions & 2 deletions views/Exports.bones
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
view = Backbone.View.extend();

view.prototype.events = {
'click a.delete': 'exportDelete'
'click a.delete': 'exportDelete',
'click a.preview': 'exportPreview'
};

view.prototype.initialize = function(options) {
_(this).bindAll('render', 'exportDelete', 'poll');
_(this).bindAll('render', 'exportDelete', 'exportPreview', 'poll');
this.collection.bind('all', this.render);
this.collection.bind('all', this.poll);
this.render(true).poll();
Expand Down Expand Up @@ -47,6 +48,19 @@ view.prototype.exportDelete = function(ev) {
return false;
};

view.prototype.exportPreview = function(ev) {
var id = $(ev.currentTarget).attr('href').split('#').pop();
(new models.Preview({id:id})).fetch({
success: function(model, resp) {
new views.Preview({
el: $('#popup'),
model:model
});
},
error: function(m, e) { new views.Modal(e) }
});
};

// Poll controller.
// - Starts polling if exports are active and drawer shows this view.
// - Stops polling under all other conditions.
Expand Down
27 changes: 27 additions & 0 deletions views/Preview.bones
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
view = Backbone.View.extend();

view.prototype.initialize = function(options) {
_(this).bindAll('render');
this.render();
};

view.prototype.render = function() {
this.$('.content').html(templates.Preview(this.model));

if (!com.modestmaps) throw new Error('ModestMaps not found.');
this.map = new com.modestmaps.Map('preview',
new wax.mm.connector(this.model.attributes));
wax.mm.interaction(this.map, this.model.attributes);
wax.mm.legend(this.map, this.model.attributes);
wax.mm.zoombox(this.map);
wax.mm.zoomer(this.map).appendTo(this.map.parent);

var center = this.model.get('center');
this.map.setCenterZoom(new com.modestmaps.Location(
center[1],
center[0]),
center[2]);

return this;
};

6 changes: 1 addition & 5 deletions views/Project.bones
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,8 @@ view.prototype.render = function(init) {
new wax.mm.connector(this.model.attributes));

// Add references to all controls onto the map object.
// Allows controls to be removed later on. @TODO need
// wax 3.x and updates to controls to return references
// to themselves.
// Allows controls to be removed later on.
this.map.controls = {
// @TODO wax 3.x.
// interaction, legend require TileJSON attributes from the model.
interaction: wax.mm.interaction(this.map, this.model.attributes),
legend: wax.mm.legend(this.map, this.model.attributes),
zoombox: wax.mm.zoombox(this.map),
Expand Down

0 comments on commit e2a7727

Please sign in to comment.