if (frameElement) frameElement.style.height = '1600px'; var degrees = 180 / Math.PI, w_width = 960, w_height = 960, loader = d3.dispatch('world'), id = -1; d3.selectAll('#map') .data([ orthographicProjection(w_width, w_height) .scale(245) .translate([w_width / 2, w_height * .56]) ]) .append('svg') .attr('class', 'world') .attr('width', w_width) .attr('height', w_height) .each(function(projection) { var path = d3.geo.path().projection(projection), svg = d3.select(this).call(drawMap, path, true); svg.selectAll('.foreground') .call(d3.geo.zoom().projection(projection) .scaleExtent([projection.scale() * .7, projection.scale() * 10]) .on('zoom.redraw', function() { if (d3.event.sourceEvent.preventDefault) d3.event.sourceEvent.preventDefault(); svg.selectAll('path').attr('d', path); })); loader.on('world.' + ++id, function() { svg.selectAll('path').attr('d', path); }); }); d3.json('world-110m.json', function(error, world) { d3.selectAll('svg').insert('path', '.foreground') .datum(topojson.feature(world, world.objects.land)) .attr('class', 'land'); d3.selectAll('svg').insert('path', '.foreground') .datum(topojson.mesh(world, world.objects.countries)) .attr('class', 'mesh'); loader.world(); }); function drawMap(svg, path, mousePoint) { var projection = path.projection(); svg.append('path') .datum(d3.geo.graticule()) .attr('class', 'graticule') .attr('d', path); svg.append('path') .datum({ type: 'Sphere' }) .attr('class', 'foreground') .attr('d', path) .on('mousedown.grab', function() { var point; if (mousePoint) point = svg.insert('path', '.foreground') .datum({ type: 'Point', coordinates: projection.invert(d3.mouse(this)) }) .attr('class', 'point') .attr('d', path); var path = d3.select(this).classed('zooming', true), w = d3.select(window).on('mouseup.grab', function() { path.classed('zooming', false); w.on('mouseup.grab', null); if (mousePoint) point.remove(); }); }) .on('mousemove', function logCoords() { var at = toLatLng.apply(this, projection.invert(d3.mouse(this))); if (at) { console.log(at.lat, at.lng); setLocation(at.lat, at.lng); } }); } function toLatLng(lng, lat) { if (isNaN(lng) || isNaN(lat)) return null; while (lng < 360) lng += 360; lng = lng % 360; if (lng > 180) lng -= 360; return { lat: lat, lng: lng }; } function orthographicProjection(width, height) { return d3.geo.orthographic() .precision(.5) .clipAngle(90) .clipExtent([[-1, -1], [width + 1, height + 1]]) .translate([width / 2, height / 2]) .scale(width / 2 - 10) .rotate([0, -30]); }