This is actually quite simple. There are several ways to do it, but the following way is probably one of the simplest. It doesn't use Canvas at all, just pure SVG.
I am going to assume that when you say the "pin" is another file, that is not really a strict requirement. Ie. that there is no reason you couldn't include the pin picture in your map SVG file.
Here's a sample SVG map file. I will assume for now that it is embedded in the HTML file, but an external file should work as well.
<html>
<body>
<svg id="map" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="500" height="400" viewBox="0 0 500 400">
<defs>
<!-- Define our map "pin". Just a circle in this case.
The circle is centred on (0,0) to make positioning at the destination point simpler. -->
<g id="pin">
<circle cx="0" cy="0" r="7" fill="white" stroke="green" stroke-width="2"/>
</g>
</defs>
<!-- A simple floorplan map -->
<g id="floor" fill="#ddd" stroke="black" stroke-width="3">
<rect x="50" y="50" width="200" height="150" />
<rect x="100" y="200" width="150" height="150" />
<rect x="250" y="100" width="200" height="225" />
</g>
<!-- A group to hold the created pin refernces. Not necessary, but keeps things tidy. -->
<g id="markers">
</g>
</svg>
</body>
</html>
The group "floor" is our floor plan, and the pin image has been included in the <defs>
section. Stuff defined in the <defs>
section is not rendered itself. It has to be referenced elsewhere in the file.
From here all you need is a simple Javascript loop which uses the DOM to add one <use>
element for each pin.
var markerPositions = [[225,175], [75,75], [150,225], [400,125], [300,300]];
var svgNS = "http://www.w3.org/2000/svg";
var xlinkNS = "http://www.w3.org/1999/xlink";
for (var i=0; i<markerPositions.length; i++) {
// Create an SVG <use> element
var use = document.createElementNS(svgNS, "use");
// Point it at our pin marker (the circle)
use.setAttributeNS(xlinkNS, "href", "#pin");
// Set it's x and y
use.setAttribute("x", markerPositions[i][0]);
use.setAttribute("y", markerPositions[i][1]);
// Add it to the "markers" group
document.getElementById("markers").appendChild(use);
}
The <use>
allows us to make a reference to another element in the SVG file. So we create a <use>
element for each pin we want to place. Each <use>
references our predefined pin symbol.
Here is a demo: http://jsfiddle.net/6cFfU/3/
Update:
To use an external "pin" file, referencing it from an image should work.
<g id="pin">
<image xlink:href="pin.svg"/>
</g>
Demo here: http://jsfiddle.net/6cFfU/4/
If you are not even allowed to reference the pin file from your map file. Then you just need to insert this marker definition using a bit of DOM manipulation. Something like:
var grp = document.createElementNS(svgNS, "g");
grp.id = "pin";
var img = document.createElementNS(svgNS, "image");
img.setAttributeNS(xlinkNS, "href", "pin.pvg");
grp.appendChild(img);
document.getElementsByTagName("defs")[0].appendChild(grp);
Demo here: http://jsfiddle.net/7Mysc/1/
That's assuming you want to go the pure SVG route. There are other ways. For instance you could do a similar thing using HTML. Wrap your PIN file in a <div>
and use jQuery to clone the div, then use absolute positioning to position them them in the correct place. However you then have to worry about adjusting for the map scale etc.