Created
August 23, 2011 06:52
-
-
Save RandomEtc/1164509 to your computer and use it in GitHub Desktop.
Node.js server for composing map tiles using modestmaps.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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