Skip to content

Instantly share code, notes, and snippets.

@RandomEtc
Created August 23, 2011 06:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RandomEtc/1164509 to your computer and use it in GitHub Desktop.
Save RandomEtc/1164509 to your computer and use it in GitHub Desktop.
Node.js server for composing map tiles using modestmaps.js
var MM = require('modestmaps'),
Canvas = require('canvas'),
Image = Canvas.Image;
get = require('get'),
express = require('express');
function renderStaticMap(provider, dimensions, zoom, location, callback) {
var canvas = new Canvas(dimensions.x, dimensions.y),
ctx = canvas.getContext('2d');
var centerCoordinate = provider.locationCoordinate(location).zoomTo(zoom);
function pointCoordinate(point) {
// new point coordinate reflecting distance from map center, in tile widths
var coord = centerCoordinate.copy();
coord.column += (point.x - dimensions.x/2) / provider.tileWidth;
coord.row += (point.y - dimensions.y/2) / provider.tileHeight;
return coord;
};
function coordinatePoint(coord) {
// Return an x, y point on the map image for a given coordinate.
if (coord.zoom != zoom) {
coord = coord.zoomTo(zoom);
}
var point = new MM.Point(dimensions.x/2, dimensions.y/2);
point.x += provider.tileWidth * (coord.column - centerCoordinate.column);
point.y += provider.tileHeight * (coord.row - centerCoordinate.row);
return point;
}
var startCoord = pointCoordinate(new MM.Point(0,0)).container(),
endCoord = pointCoordinate(dimensions).container();
var numRequests = 0,
completeRequests = 0;
function checkDone() {
if (completeRequests == numRequests) {
callback(null, canvas);
}
}
function getTile(url, p) {
new get(url).asBuffer(function(error,data) {
if (error) {
callback(url + ' error: ' + error);
}
else {
var img = new Image();
img.src = data;
ctx.drawImage(img, p.x, p.y, provider.tileWidth, provider.tileHeight);
completeRequests++;
checkDone();
}
});
}
for (var column = startCoord.column; column <= endCoord.column; column++) {
for (var row = startCoord.row; row <= endCoord.row; row++) {
var c = new MM.Coordinate(row, column, zoom),
url = provider.getTileUrl(c),
p = coordinatePoint(c);
getTile(url, p);
numRequests++;
}
}
}
// just one for now...
var providers = {
osm: new MM.TemplatedMapProvider("http://tile.openstreetmap.org/{Z}/{X}/{Y}.png")
}
var app = express.createServer();
app.get('/map', function(req,res) {
var provider = providers[req.param("provider") || "osm"], // default osm
width = req.param("width") || 800,
height = req.param("height") || 600,
dimensions = new MM.Point(width, height),
zoom = parseInt(req.param("zoom") || 1),
lat = parseFloat(req.param("lat") || 0.0),
lon = parseFloat(req.param("lon") || 0.0),
location = new MM.Location(lat, lon);
renderStaticMap(provider, dimensions, zoom, location, function(err,canvas) {
if (err) {
res.send(new Error(err));
} else {
res.header('Content-Type', 'image/png');
res.send(canvas.toBuffer());
}
});
});
app.listen(3000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment