index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<script type="text/javascript" src="//maps.google.com/maps/api/js?sensor=true"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="https://raw.github.com/jasondavies/conrec.js/master/conrec.js"></script>
<script src="https://raw.github.com/d3/d3-plugins/master/geom/contour/contour.js"></script>
<style type="text/css">
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#map {
width: 100%;
height: 100%;
}
.stations, .stations svg, .contour {
position: absolute;
}
.stations svg {
width: 60px;
height: 20px;
padding-right: 100px;
font: 8px sans-serif;
}
.stations circle {
fill: brown;
stroke: black;
stroke-width: 0.2px;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
var map = new google.maps.Map(d3.select("#map").node(), {
zoom : 3,
center : new google.maps.LatLng(30.0, 10.0),
mapTypeId : google.maps.MapTypeId.TERRAIN
});
d3.json("aaa.json", function (data) {
var overlay = new google.maps.OverlayView();
overlay.onAdd = function () {
var layer = d3.select(this.getPanes().overlayLayer).append("div")
.attr("class", "stations");
var cont_layer = d3.select(this.getPanes().overlayLayer).append("div")
.attr("class","contour").append("svg:svg");
var cont_group = cont_layer.append("g").attr("opacity",0.3);
overlay.draw = function () {
var projection = this.getProjection(),
padding = 10;
var marker = layer.selectAll("svg")
.data(d3.entries(data))
.each(transform)
.enter().append("svg:svg")
.each(transform)
.attr("class", "marker");
marker.append("svg:circle")
.attr("r", 1.5)
.attr("cx", padding)
.attr("cy", padding);
marker.append("svg:text")
.attr("x", padding - 6)
.attr("y", padding + 6)
.attr("dy", ".31em")
.text(function (d) {
return (d.value[2].toFixed(2));
});
var maxY = data[0][0];
var minY = data[0][0];
var maxX = data[0][1];
var minX = data[0][1];
var spacingX = 2.5;
var spacingY = 2.5;
data.forEach(function(val){
maxX=maxX>val[1]?maxX:val[1];
minX=minX<val[1]?minX:val[1];
maxY=maxY>val[0]?maxY:val[0];
minY=minY<val[0]?minY:val[0];
});
console.log("Mx = "+maxX+" mx = "+minX+" My = "+maxY+" my = "+minY + " => " +(maxX-minX)/spacingX+":"+(maxY-minY)/spacingY);
var grid=new Array((maxX-minX)/spacingX+1);
for (var i=0;i<grid.length;i++)
grid[i] = Array((maxY-minY)/spacingY+1);
data.forEach(function(val){grid[(val[1]-minX)/spacingX][(val[0]-minY)/spacingY]=val[2];});
var cliff = -100;
grid.push(d3.range(grid[0].length).map(function() { return cliff; }));
grid.unshift(d3.range(grid[0].length).map(function() { return cliff; }));
grid.forEach(function(nd) {
nd.push(cliff);
nd.unshift(cliff);
});
var c2 = projection.fromLatLngToDivPixel(new google.maps.LatLng(minY, maxX));
var c1 = projection.fromLatLngToDivPixel(new google.maps.LatLng(maxY, minX));
var svgHeight = 8000;
var svgWidth = 8000;
var padX = -4000;
var padY = -4000;
console.log(svgHeight,svgWidth);
cont_layer
.attr("width",svgWidth)
.attr("height",svgHeight)
.style("position","absolute")
.style("top",padX)
.style("left",padY);
var latpy = new Array();
var lonpx = new Array();
for (var i = 0; i < grid[0].length; i++)
latpy[i] = minY + 2.5 * (i-1);
for (var i = grid.length-1; i>=0; i--)
lonpx[i] = minX + 2.5 * (i-1);
var colours = ['#000099','#0000FF','#3399FF','#00CCFF','#00CC00','#66FF00','#FFFF00','#CC0000','#FF6633'],
zs = [-0.1, 20.0, 50.0, 75.0, 90.0, 95.0, 98.0, 99.0, 99.9, 100.1];
var c = new Conrec();
c.contour(grid, 0, lonpx.length-1, 0, latpy.length-1, lonpx, latpy, zs.length, zs);
var cont = cont_group.selectAll("path").data(c.contourList())
.style("fill",function(d) {
return colours[zs.indexOf(d.level)-1];
})
.style("stroke","black")
.attr("d",d3.svg.line()
.x(function(d) { return (projection.fromLatLngToDivPixel(new google.maps.LatLng(d.y, d.x))).x - padX; })
.y(function(d) { return (projection.fromLatLngToDivPixel(new google.maps.LatLng(d.y, d.x))).y - padY; })
)
.enter().append("svg:path")
.style("fill",function(d) {
return colours[zs.indexOf(d.level)-1];
})
.style("stroke","black")
.attr("d",d3.svg.line()
.x(function(d) { return (projection.fromLatLngToDivPixel(new google.maps.LatLng(d.y, d.x))).x - padX; })
.y(function(d) { return (projection.fromLatLngToDivPixel(new google.maps.LatLng(d.y, d.x))).y - padY; })
);
function transform(d) {
d = new google.maps.LatLng(d.value[0], d.value[1]);
d = projection.fromLatLngToDivPixel(d);
return d3.select(this)
.style("left", (d.x - padding) + "px")
.style("top", (d.y - padding) + "px");
}
};
};
overlay.setMap(map);
});
</script>
</body>
</html>