Well, no there is not a snippet that I would recommend but here's what I did. First I created a "printer" constructor: createPrinter: function ()
{
var transformers = {};
return {
register: function (transformName, transform)
{
transformers[transformName] = transform;
},
print: function (options)
{
var self = this, map, output, features;
map = dojo.byId(options.map);
output = dojo.byId(options.target) || dojo.create("div");
features = dojo.filter(options.features, function (f)
{
return transformers.hasOwnProperty(f);
});
dojo.forEach(features, function (f)
{
self.render(output, transformers(map, options));
});
return output;
},
render: function (div, imagery)
{
var images = imagery.images;
if (images)
{
images = dojo.map(images, function (item)
{
var img = dojo.create("img", {
src: item.src
});
dojo.style(img, {
position: "absolute",
left: item.x + "px",
top: item.y + "px",
opacity: item.opacity || 1,
zIndex: item.zIndex || 99
});
if (item.w)
{
dojo.style(img, {
width: item.w + "px",
height: item.h + "px"
});
}
return img;
});
}
dojo.forEach(images, function (img)
{
div.appendChild(img);
});
if (imagery.polylines)
{
// render vector data
}
}
};
},
Then I instantiate and extend the printer to handle markers and layers: print: function (node)
{
var printer;
printer = createPrinter(acme.gis.mapdrawer.render.createPrinter());
var div = printer.print({
map: agsMap,
features: ["layers", "markers"],
target: node
});
dojo.style(div, {
position: "relative",
overflow: "hidden",
width: $.todo("960px", "move to frame?"),
height: $.todo("600px", "move to frame?")
});
return div;
},
function createPrinter(print)
{
print.register("markers", function (map)
{
var images = [];
dojo.forEach(map.graphicsLayerIds, function (id)
{
var layer = map.getLayer(id);
dojo.forEach(layer.graphics, function (graphic)
{
var geom, symbol, point;
geom = graphic.geometry;
symbol = graphic.symbol;
if (geom.type === "point" && symbol.url)
{
point = map.toScreen(geom);
images.push({
src: symbol.url,
x: point.x,
y: point.y,
zIndex: 10
});
}
});
});
return {
images: images
};
});
print.register("layers", function (map)
{
var images = dojo.query(".layersDiv div img", map.root);
var root = dojo.position(map.root);
images = dojo.map(images, function (img)
{
var pos;
pos = dojo.position(img);
return {
src: img.src,
x: pos.x - root.x,
y: pos.y - root.y,
opacity: dojo.style(img, "opacity"),
zIndex: dojo.style(img, "zIndex")
};
});
return { images: images };
});
return print;
}
And it works well enough for me. Surely you'll need to customize this code a good bit but right-clicking and doing a save-as is not going to work if you have tiled imagery and it's not going to pick up any markers. The only sensible solution I am aware of is something like MapFish Print or another server-side printing solution where the user can download a PDF of the map.