This is a map that uses leaflet.js and d3.js in a way that combines the two so that the d3.js object stays fixed in relation to a geographic point but remains the same size on the screen. It is as used as an example in the book D3 Tips and Tricks.
It is derived from the Pere Roca Ristol example but is simplified somewhat.
<!DOCTYPE html>
<html>
<head>
<title>d3.js with leaflet.js</title>
<link
rel="stylesheet"
href="//cdn.leafletjs.com/leaflet-0.7/leaflet.css"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script
src="//cdn.leafletjs.com/leaflet-0.7/leaflet.js">
</script>
</head>
<body>
<div id="map" style="width: 600px; height: 400px"></div>
<script type="text/javascript">
var map = L.map('map').setView([-41.2858, 174.7868], 13);
mapLink =
'<a href="//openstreetmap.org">OpenStreetMap</a>';
L.tileLayer(
'//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© ' + mapLink + ' Contributors',
maxZoom: 18,
}).addTo(map);
/* Initialize the SVG layer */
map._initPathRoot()
/* We simply pick up the SVG from the map object */
var svg = d3.select("#map").select("svg"),
g = svg.append("g");
d3.json("circles.json", function(collection) {
/* Add a LatLng object to each item in the dataset */
collection.objects.forEach(function(d) {
d.LatLng = new L.LatLng(d.circle.coordinates[0],
d.circle.coordinates[1])
})
var feature = g.selectAll("circle")
.data(collection.objects)
.enter().append("circle")
.style("stroke", "black")
.style("opacity", .6)
.style("fill", "red")
.attr("r", 20);
map.on("viewreset", update);
update();
function update() {
feature.attr("transform",
function(d) {
return "translate("+
map.latLngToLayerPoint(d.LatLng).x +","+
map.latLngToLayerPoint(d.LatLng).y +")";
}
)
}
})
</script>
</body>
</html>
{"objects":[
{"circle":{"coordinates":[-41.28,174.77]}},
{"circle":{"coordinates":[-41.29,174.76]}},
{"circle":{"coordinates":[-41.30,174.79]}},
{"circle":{"coordinates":[-41.27,174.80]}},
{"circle":{"coordinates":[-41.29,174.78]}}
]}