Skip to content

Instantly share code, notes, and snippets.

@pnavarrc
Last active September 21, 2015 19:20
Show Gist options
  • Select an option

  • Save pnavarrc/5bb1a7c2b4c5b624bb83 to your computer and use it in GitHub Desktop.

Select an option

Save pnavarrc/5bb1a7c2b4c5b624bb83 to your computer and use it in GitHub Desktop.
Inverse Projection
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Inverse Projection</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script>
</head>
<body>
<style>
body {
margin: 0;
}
svg {
background-color: #4B4B55;
cursor: crosshair;
}
.sphere {
fill: none;
stroke: #d6ff9f;
}
.coords {
stroke: none;
fill: #8DBD0C;
font-family: 'Helvetica Neue', Helvetica, sans-serif;
}
.land {
fill: #8DBD0C;
fill-opacity: 0.25;
stroke: #8DBD0C;
stroke-width: 1;
}
</style>
<div id="map-container"></div>
<script>
// Set the dimensions of the map
var width = 960,
height = 480;
// Create a selection for the container div and append the svg element
var div = d3.select('#map-container'),
svg = div.append('svg');
// Set the size of the SVG element
svg.attr('width', width).attr('height', height);
// Create a text element to write the coordinates
var label = svg.append('text')
.classed('coords', true)
.attr('x', 20)
.attr('y', 30);
// Create and configure a geographic projection
var projection = d3.geo.equirectangular()
.translate([width / 2, height / 2]);
// Create and configure a path generator
var pathGenerator = d3.geo.path()
.projection(projection);
// Create and configure the graticule generator (one line every 20 degrees)
var graticule = d3.geo.graticule()
.step([20, 20]);
// Retrieve the geographic data asynchronously
d3.json('land.topojson', function(err, data) {
// Throw errors on getting or parsing the file
if (err) { throw err; }
// Convert the TopoJSON features to GeoJSON
var features = topojson.feature(data, data.objects.land);
// Sphere
var sphere = svg.selectAll('path.sphere').data([{type: 'Sphere'}]);
sphere.enter().append('path').classed('sphere', true);
sphere.attr('d', pathGenerator);
sphere.exit().remove();
// Land
var land = svg.selectAll('path.land').data([features]);
land.enter().append('path').classed('land', true);
land.attr('d', pathGenerator);
land.exit().remove();
});
// Attach a listener for the mousemove event
svg.on('mousemove', function(ev) {
// Get the (x, y) position of the mouse (relative to the SVG element)
var pos = d3.mouse(svg.node()),
px = pos[0],
py = pos[1];
// Compute the corresponding geographic coordinates using the inverse projection
var coords = projection.invert([px, py]);
// Format the coordinates to have at most 4 decimal places
var lon = coords[0].toFixed(4),
lat = coords[1].toFixed(4);
// Set the content of the label
label.text([lat, lon].join(', '));
});
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
# Download and Transform the 1:50m Country Shapefiles from Natural Earth
# http://www.naturalearthdata.com/downloads/110m-physical-vectors/
URL = http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/110m/physical/ne_110m_land.zip
# Download the zip file from the Natural Earth server
ne_110m_land.zip:
curl -LO $(URL)
# Unzip the shapefiles
ne_110m_land.shp: ne_110m_land.zip
unzip ne_110m_land.zip
touch ne_110m_land.shp
# Convert the shapefiles to GeoJSON
land.geojson: ne_110m_land.shp
ogr2ogr -f GeoJSON land.geojson ne_110m_land.shp
# Convert the GeoJSON file to TopoJSON
land.topojson: land.geojson
topojson -p -o land.topojson land.geojson
# Remove source and temporary files
clean:
rm ne_110m_land*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment