Do pyramid loading in both directions, use transforms for tile sizing.

Fixes #190
This commit is contained in:
Tom MacWright
2012-12-06 15:07:37 -05:00
parent b8a06aa215
commit f9455270f1
3 changed files with 89 additions and 15 deletions
+14
View File
@@ -451,3 +451,17 @@ a.selected {
border-bottom-color: #000000;
border-width: 0 5px 5px;
}
img.tile {
position:absolute;
transform-origin:0 0;
-ms-transform-origin:0 0;
-webkit-transform-origin:0 0;
-moz-transform-origin:0 0;
-o-transform-origin:0 0;
}
#tile-g {
position:absolute;
top:0;
}
+64 -10
View File
@@ -2,8 +2,33 @@ iD.Background = function() {
var tile = d3.geo.tile(),
scaleExtent = [0, 20],
projection,
cache = {},
transformProp = iD.util.prefixProperty('Transform'),
source = d3.functor('');
function atZoom(t, distance) {
var power = Math.pow(2, distance);
var az = [
Math.floor(t[0] * power),
Math.floor(t[1] * power),
t[2] + distance];
az.push(source(az));
return az;
}
function upZoom(t, distance) {
var az = atZoom(t, distance),
tiles = [];
for (var x = 0; x < 2; x++) {
for (var y = 0; y < 2; y++) {
var up = [az[0] + x, az[1] + y, az[2]];
up.push(source(up));
tiles.push(up);
}
}
return tiles;
}
// derive the tiles onscreen, remove those offscreen and position tiles
// correctly for the currentstate of `projection`
function background() {
@@ -17,23 +42,52 @@ iD.Background = function() {
projection.scale() / 2 - projection.translate()[0],
projection.scale() / 2 - projection.translate()[1]];
tiles.forEach(function(t) { t.push(source(t)); });
var ups = {};
tiles.forEach(function(d) {
d.push(source(d));
// this tile has not been loaded yet
if (!cache[d] &&
cache[atZoom(d, -1)] &&
!ups[atZoom(d, -1)]) {
ups[atZoom(d, -1)] = true;
tiles.push(atZoom(d, -1));
} else if (!cache[d]) {
upZoom(d, 1).forEach(function(u) {
if (cache[u] && !ups[u]) {
ups[u] = true;
tiles.push(u);
}
});
}
});
var image = this
.selectAll("image")
.selectAll('img')
.data(tiles, function(d) { return d; });
image.exit().remove();
image.enter().append("image")
.attr("xlink:href", function(d) { return d[3]; });
image.enter().append('img')
.attr('class', 'tile')
.attr('src', function(d) { return d[3]; })
.on('load', function(d) {
cache[d] = true;
});
image.attr('transform', function(d) {
function tileSize(d) {
return Math.ceil(256 * Math.pow(2, z - d[2])) / 256;
}
image.style(transformProp, function(d) {
var _ts = 256 * Math.pow(2, z - d[2]);
var scale = tileSize(d);
return 'translate(' +
Math.round((d[0] * ts) - tile_origin[0]) + ',' +
Math.round((d[1] * ts) - tile_origin[1]) + ')';
})
.attr("width", Math.ceil(ts))
.attr("height", Math.ceil(ts));
Math.round((d[0] * _ts) - tile_origin[0]) + 'px,' +
Math.round((d[1] * _ts) - tile_origin[1]) + 'px) scale(' + scale + ',' + scale + ')';
});
if (Object.keys(cache).length > 100) cache = {};
}
background.projection = function(_) {
+11 -5
View File
@@ -66,7 +66,12 @@ iD.Map = function() {
supersurface, surface, defs, tilegroup, r, g, alength;
function map() {
supersurface = this.append('div').call(zoom);
tilegroup = this.append('div')
.attr('id', 'tile-g');
supersurface = this.append('div')
.style('position', 'absolute')
.call(zoom);
surface = supersurface.append('svg')
.on('mouseup', resetTransform)
@@ -79,10 +84,6 @@ iD.Map = function() {
.attr('id', 'clip-rect')
.attr({ x: 0, y: 0 });
tilegroup = surface.append('g')
.attr('id', 'tile-g')
.attr('clip-path', 'url(#clip)');
r = surface.append('g')
.on('mouseover', hoverIn)
.on('mouseout', hoverOut)
@@ -306,9 +307,13 @@ iD.Map = function() {
var a = d3.event.translate,
b = translateStart;
if (support3d) {
tilegroup.style(transformProp,
'translate3d(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px, 0px)');
surface.style(transformProp,
'translate3d(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px, 0px)');
} else {
tilegroup.style(transformProp,
'translate(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px)');
surface.style(transformProp,
'translate(' + ~~(a[0] - b[0]) + 'px,' + ~~(a[1] - b[1]) + 'px)');
}
@@ -322,6 +327,7 @@ iD.Map = function() {
if (!surface.style(transformProp)) return;
translateStart = null;
surface.style(transformProp, '');
tilegroup.style(transformProp, '');
redraw();
}