Rather than re-drawing paths for the shapes every single time, we apply transformations to the whole shape group when interacting with polymaps, for speed.
-
-
Save radiodario/4500717 to your computer and use it in GitHub Desktop.
Complex geoJson shape transformation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<style type="text/css"> | |
@import url("http://polymaps.org/style.css"); | |
html, body { | |
height: 100%; | |
background: #E6E6E6; | |
margin: 0; | |
font: 10px sans-serif; | |
} | |
svg { | |
display: block; | |
} | |
circle { | |
stroke: black; | |
fill: brown; | |
fill-opacity: .5; | |
} | |
#map { | |
width: 960px; | |
height: 500px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="map"></div> | |
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> | |
<script type="text/javascript" src="http://polymaps.org/polymaps.min.js"></script> | |
<script type="text/javascript"> | |
var po = org.polymaps; | |
var initialZoom = 5; | |
// Create the map object, add it to #map… | |
var map = po.map() | |
.container(d3.select("#map").append("svg:svg").node()) | |
.zoom(initialZoom) | |
.center({lat:55, lon:-3}) | |
.add(po.interact()); | |
// Add the CloudMade image tiles as a base layer… | |
map.add(po.image() | |
.url(po.url("http://{S}tile.cloudmade.com" | |
+ "/677444bfa43f4b1a99a366b991353d2d" // http://cloudmade.com/register | |
+ "/998/256/{Z}/{X}/{Y}.png") | |
.hosts(["a.", "b.", "c.", ""]))); | |
// Add the compass control on top. | |
map.add(po.compass() | |
.pan("none")); | |
// sync up the d3 projection with the polymaps coords system | |
var pt = map.locationPoint({lat: 0, lon: 0}); | |
var projection = d3.geo.mercator() | |
.translate([pt.x, pt.y]) | |
.scale(Math.pow(2, map.zoom()) * 256) | |
var path = d3.geo.path() | |
.projection(projection) | |
/////////////// | |
// map.add(po.geoJson() | |
// .url("http://localhost:8888/projects/ukMap/uk_lads.json") | |
// .id("lad")); | |
/////////////// | |
// scaffolding for the map | |
var ladsLayer = d3.select('#map svg') | |
.insert("svg:g", ".compass") | |
.attr('class', 'lads') | |
var mapBounds = []; | |
var prevBounds = []; | |
var shapesBounds = []; | |
function findMapBounds(bounds) { | |
var topleft = map.locationPoint({lat:bounds[1][1], lon: bounds[0][0]}) | |
var bottomright = map.locationPoint({lat:bounds[0][1], lon: bounds[1][0]}) | |
var w = bottomright.x - topleft.x; | |
var h = bottomright.y - topleft.y; | |
return { | |
topleft: topleft, | |
bottomright: bottomright, | |
width : w, | |
height : h | |
}; | |
} | |
d3.json('uk_lads.json', function(data) { | |
shapesBounds = d3.geo.bounds(data); | |
mapBounds = findMapBounds(shapesBounds); | |
var lads = ladsLayer.selectAll('path').data(data.features); | |
lads.enter() | |
.append('path') | |
.attr('class', 'district') | |
.attr('d', path) | |
.attr('id', function(d) { | |
return d.properties.LAD11CD; | |
}) | |
}) | |
/* | |
<path d="...", transform="translate(x, y) scale(y)"/> | |
*/ | |
function transform(d, i) { | |
var newBounds = findMapBounds(shapesBounds); | |
var scale = newBounds.width/mapBounds.width; | |
var tranx = newBounds.topleft.x - (mapBounds.topleft.x * scale); | |
var trany = newBounds.topleft.y - (mapBounds.topleft.y * scale); | |
var translate = 'translate(' + tranx + ',' + trany + ')'; | |
scale = 'scale(' + scale + ')'; | |
var transformstring = translate + ' ' + scale; | |
//console.log(transformstring); | |
return transformstring | |
} | |
function update() { | |
// update the projection | |
// console.log('updating projection') | |
// 1 get the center from polymaps | |
var pt = map.locationPoint({lat: 0, lon: 0}); | |
// projection | |
// .translate([pt.x, pt.y]) | |
// .scale(Math.pow(2, map.zoom()) * 256) | |
if (shapesBounds.length > 0) { | |
ladsLayer.attr('transform', transform) | |
} | |
// .attr('height', newBounds.height) | |
// .attr('width', newBounds.width) | |
// .attr('x', newBounds.topleft.x) | |
// .attr('y', newBounds.topleft.y) | |
// path.projection(projection) | |
// ladsLayer. | |
// ladsLayer.selectAll('path.district') | |
// .attr('d', path) | |
mapBounds.prevZoom = map.zoom(); | |
} | |
map.on('resize', update); | |
map.on('move', update); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment