mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
Fix zoomPanning
for simplicity, use raw mercator like context.projection()
This commit is contained in:
@@ -37,14 +37,12 @@ export function Map(context) {
|
||||
mouse,
|
||||
mousemove;
|
||||
|
||||
var initialTransform = d3.zoomIdentity
|
||||
.translate(projection.translate())
|
||||
.scale(projection.scale() * 2 * Math.PI),
|
||||
zoom = d3.zoom()
|
||||
.scaleExtent([1024, 256 * Math.pow(2, 24)])
|
||||
var zoom = d3.zoom()
|
||||
.scaleExtent([ztok(2), ztok(24)])
|
||||
.on('zoom', zoomPan);
|
||||
|
||||
var _selection;
|
||||
var _selection = d3.select(null);
|
||||
|
||||
|
||||
function map(selection) {
|
||||
|
||||
@@ -66,7 +64,10 @@ export function Map(context) {
|
||||
|
||||
selection
|
||||
.on('dblclick.map', dblClick)
|
||||
.call(zoom, initialTransform);
|
||||
.call(zoom, d3.zoomIdentity
|
||||
.translate(projection.translate())
|
||||
.scale(projection.scale())
|
||||
);
|
||||
|
||||
supersurface = selection.append('div')
|
||||
.attr('id', 'supersurface')
|
||||
@@ -132,10 +133,20 @@ export function Map(context) {
|
||||
drawLabels.supersurface(supersurface);
|
||||
}
|
||||
|
||||
|
||||
function ztok(z) {
|
||||
return 256 * Math.pow(2, z);
|
||||
}
|
||||
|
||||
function ktoz(k) {
|
||||
return Math.max(Math.log(k) / Math.LN2 - 8, 0);
|
||||
}
|
||||
|
||||
function pxCenter() {
|
||||
return [dimensions[0] / 2, dimensions[1] / 2];
|
||||
}
|
||||
|
||||
|
||||
function drawVector(difference, extent) {
|
||||
var graph = context.graph(),
|
||||
features = context.features(),
|
||||
@@ -179,12 +190,14 @@ export function Map(context) {
|
||||
dispatch.call('drawn', this, {full: true});
|
||||
}
|
||||
|
||||
|
||||
function editOff() {
|
||||
context.features().resetStats();
|
||||
surface.selectAll('.layer-osm *').remove();
|
||||
dispatch.call('drawn', this, {full: true});
|
||||
}
|
||||
|
||||
|
||||
function dblClick() {
|
||||
if (!dblclickEnabled) {
|
||||
d3.event.preventDefault();
|
||||
@@ -192,10 +205,11 @@ export function Map(context) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function zoomPan(manualEvent) {
|
||||
var eventTransform = (manualEvent || d3.event).transform;
|
||||
|
||||
if (Math.log(eventTransform.k) / Math.LN2 - 8 < minzoom) {
|
||||
if (ktoz(eventTransform.k * 2 * Math.PI) < minzoom) {
|
||||
surface.interrupt();
|
||||
flash(context.container())
|
||||
.select('.content')
|
||||
@@ -206,9 +220,16 @@ export function Map(context) {
|
||||
return;
|
||||
}
|
||||
|
||||
var t = projection.translate(),
|
||||
k = projection.scale();
|
||||
|
||||
if (t[0] === eventTransform.x && t[1] === eventTransform.y && k === eventTransform.k) {
|
||||
return; // no change
|
||||
}
|
||||
|
||||
projection
|
||||
.translate([eventTransform.x, eventTransform.y])
|
||||
.scale(eventTransform.k / (2 * Math.PI));
|
||||
.scale(eventTransform.k);
|
||||
|
||||
var scale = eventTransform.k / transformStart.k,
|
||||
tX = (eventTransform.x / scale - transformStart.x) * scale,
|
||||
@@ -221,6 +242,7 @@ export function Map(context) {
|
||||
dispatch.call('move', this, map);
|
||||
}
|
||||
|
||||
|
||||
function resetTransform() {
|
||||
if (!transformed) return false;
|
||||
|
||||
@@ -230,6 +252,7 @@ export function Map(context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function redraw(difference, extent) {
|
||||
if (!surface || !redrawEnabled) return;
|
||||
|
||||
@@ -264,7 +287,7 @@ export function Map(context) {
|
||||
.call(drawLayers);
|
||||
|
||||
transformStart = {
|
||||
k: projection.scale() * 2 * Math.PI,
|
||||
k: projection.scale(),
|
||||
x: projection.translate()[0],
|
||||
y: projection.translate()[1]
|
||||
};
|
||||
@@ -272,115 +295,130 @@ export function Map(context) {
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
var timeoutId;
|
||||
function queueRedraw() {
|
||||
timeoutId = setTimeout(function() { redraw(); }, 750);
|
||||
}
|
||||
|
||||
|
||||
function pointLocation(p) {
|
||||
var translate = projection.translate(),
|
||||
scale = projection.scale() * 2 * Math.PI;
|
||||
return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
|
||||
}
|
||||
|
||||
|
||||
function locationPoint(l) {
|
||||
var translate = projection.translate(),
|
||||
scale = projection.scale() * 2 * Math.PI;
|
||||
return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
|
||||
}
|
||||
|
||||
|
||||
map.mouse = function() {
|
||||
var e = mousemove || d3.event, s;
|
||||
while ((s = e.sourceEvent)) e = s;
|
||||
return mouse(e);
|
||||
};
|
||||
|
||||
|
||||
map.mouseCoordinates = function() {
|
||||
return projection.invert(map.mouse());
|
||||
};
|
||||
|
||||
|
||||
map.dblclickEnable = function(_) {
|
||||
if (!arguments.length) return dblclickEnabled;
|
||||
dblclickEnabled = _;
|
||||
return map;
|
||||
};
|
||||
|
||||
|
||||
map.redrawEnable = function(_) {
|
||||
if (!arguments.length) return redrawEnabled;
|
||||
redrawEnabled = _;
|
||||
return map;
|
||||
};
|
||||
|
||||
|
||||
function interpolateZoom(_) {
|
||||
var k = projection.scale(),
|
||||
t = projection.translate();
|
||||
// TODO
|
||||
setZoom(_, true);
|
||||
// var k = projection.scale(),
|
||||
// t = projection.translate();
|
||||
|
||||
surface.node().__chart__ = {
|
||||
x: t[0],
|
||||
y: t[1],
|
||||
k: k * 2 * Math.PI
|
||||
};
|
||||
// surface.node().__chart__ = {
|
||||
// x: t[0],
|
||||
// y: t[1],
|
||||
// k: k * 2 * Math.PI
|
||||
// };
|
||||
|
||||
setZoom(_);
|
||||
projection.scale(k).translate(t); // undo setZoom projection changes
|
||||
// setZoom(_);
|
||||
// projection.scale(k).translate(t); // undo setZoom projection changes
|
||||
|
||||
zoom.event(surface.transition());
|
||||
// zoom.event(surface.transition());
|
||||
}
|
||||
|
||||
|
||||
function setZoom(_, force) {
|
||||
if (_ === map.zoom() && !force)
|
||||
return false;
|
||||
var scale = 256 * Math.pow(2, _),
|
||||
|
||||
var k = Math.max(ztok(2), Math.min(ztok(24), ztok(_))) / (2 * Math.PI),
|
||||
center = pxCenter(),
|
||||
l = pointLocation(center);
|
||||
scale = Math.max(1024, Math.min(256 * Math.pow(2, 24), scale));
|
||||
projection.scale(scale / (2 * Math.PI));
|
||||
if (_selection) {
|
||||
_selection.call(zoom.transform, d3.zoomTransform(_selection).scale(scale));
|
||||
}
|
||||
|
||||
projection.scale(k);
|
||||
|
||||
var t = projection.translate();
|
||||
l = locationPoint(l);
|
||||
t[0] += center[0] - l[0];
|
||||
t[1] += center[1] - l[1];
|
||||
projection.translate(t);
|
||||
// TODO zoom.translate(projection.translate());
|
||||
|
||||
transformStart = { k: k, x: t[0], y: t[1] };
|
||||
_selection.call(zoom.transform, d3.zoomIdentity.translate(t[0], t[1]).scale(k));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function setCenter(_) {
|
||||
var c = map.center();
|
||||
if (_[0] === c[0] && _[1] === c[1])
|
||||
return false;
|
||||
|
||||
var t = projection.translate(),
|
||||
k = projection.scale(),
|
||||
pxC = pxCenter(),
|
||||
ll = projection(_);
|
||||
projection.translate([
|
||||
t[0] - ll[0] + pxC[0],
|
||||
t[1] - ll[1] + pxC[1]]);
|
||||
if (_selection) {
|
||||
_selection.call(zoom.transform, d3.zoomTransform(_selection).translate(
|
||||
projection.translate()[0],
|
||||
projection.translate()[1]
|
||||
));
|
||||
}
|
||||
|
||||
t[0] = t[0] - ll[0] + pxC[0];
|
||||
t[1] = t[1] - ll[1] + pxC[1];
|
||||
projection.translate(t);
|
||||
|
||||
transformStart = { k: k, x: t[0], y: t[1] };
|
||||
_selection.call(zoom.transform, d3.zoomIdentity.translate(t[0], t[1]).scale(k));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
map.pan = function(d) {
|
||||
var t = projection.translate();
|
||||
var t = projection.translate(),
|
||||
k = projection.scale();
|
||||
|
||||
t[0] += d[0];
|
||||
t[1] += d[1];
|
||||
projection.translate(t);
|
||||
if (_selection) {
|
||||
_selection.call(zoom.transform, d3.zoomTransform(_selection).translate(
|
||||
projection.translate()[0],
|
||||
projection.translate()[1]
|
||||
));
|
||||
}
|
||||
|
||||
transformStart = { k: k, x: t[0], y: t[1] };
|
||||
_selection.call(zoom.transform, d3.zoomIdentity.translate(t[0], t[1]).scale(k));
|
||||
|
||||
dispatch.call('move', this, map);
|
||||
return redraw();
|
||||
};
|
||||
|
||||
|
||||
map.dimensions = function(_) {
|
||||
if (!arguments.length) return dimensions;
|
||||
var center = map.center();
|
||||
@@ -393,20 +431,24 @@ export function Map(context) {
|
||||
return redraw();
|
||||
};
|
||||
|
||||
|
||||
function zoomIn(integer) {
|
||||
interpolateZoom(~~map.zoom() + integer);
|
||||
interpolateZoom(~~map.zoom() + integer);
|
||||
}
|
||||
|
||||
|
||||
function zoomOut(integer) {
|
||||
interpolateZoom(~~map.zoom() - integer);
|
||||
interpolateZoom(~~map.zoom() - integer);
|
||||
}
|
||||
|
||||
|
||||
map.zoomIn = function() { zoomIn(1); };
|
||||
map.zoomInFurther = function() { zoomIn(4); };
|
||||
|
||||
map.zoomOut = function() { zoomOut(1); };
|
||||
map.zoomOutFurther = function() { zoomOut(4); };
|
||||
|
||||
|
||||
map.center = function(loc) {
|
||||
if (!arguments.length) {
|
||||
return projection.invert(pxCenter());
|
||||
@@ -419,9 +461,10 @@ export function Map(context) {
|
||||
return redraw();
|
||||
};
|
||||
|
||||
|
||||
map.zoom = function(z) {
|
||||
if (!arguments.length) {
|
||||
return Math.max(Math.log(projection.scale() * 2 * Math.PI) / Math.LN2 - 8, 0);
|
||||
return Math.max(ktoz(projection.scale() * 2 * Math.PI), 0);
|
||||
}
|
||||
|
||||
if (z < minzoom) {
|
||||
@@ -439,6 +482,7 @@ export function Map(context) {
|
||||
return redraw();
|
||||
};
|
||||
|
||||
|
||||
map.zoomTo = function(entity, zoomLimits) {
|
||||
var extent = entity.extent(context.graph());
|
||||
if (!isFinite(extent.area())) return;
|
||||
@@ -448,6 +492,7 @@ export function Map(context) {
|
||||
map.centerZoom(extent.center(), Math.min(Math.max(zoom, zoomLimits[0]), zoomLimits[1]));
|
||||
};
|
||||
|
||||
|
||||
map.centerZoom = function(loc, z) {
|
||||
var centered = setCenter(loc),
|
||||
zoomed = setZoom(z);
|
||||
@@ -459,6 +504,7 @@ export function Map(context) {
|
||||
return redraw();
|
||||
};
|
||||
|
||||
|
||||
map.centerEase = function(loc2, duration) {
|
||||
duration = duration || 250;
|
||||
|
||||
@@ -488,24 +534,20 @@ export function Map(context) {
|
||||
|
||||
var locNow = interp(loc1, loc2, ease((tNow - t1) / duration));
|
||||
setCenter(locNow);
|
||||
|
||||
// TODO: fix
|
||||
|
||||
zoomPan({
|
||||
transform: d3.zoomTransform(_selection)
|
||||
});
|
||||
return !easing;
|
||||
});
|
||||
|
||||
return map;
|
||||
};
|
||||
|
||||
|
||||
map.cancelEase = function() {
|
||||
easing = false;
|
||||
d3.timerFlush();
|
||||
return map;
|
||||
};
|
||||
|
||||
|
||||
map.extent = function(_) {
|
||||
if (!arguments.length) {
|
||||
return new Extent(projection.invert([0, dimensions[1]]),
|
||||
@@ -516,6 +558,7 @@ export function Map(context) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
map.trimmedExtent = function(_) {
|
||||
if (!arguments.length) {
|
||||
var headerY = 60, footerY = 30, pad = 10;
|
||||
@@ -527,6 +570,7 @@ export function Map(context) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function calcZoom(extent, dim) {
|
||||
var tl = projection([extent[0][0], extent[1][1]]),
|
||||
br = projection([extent[1][0], extent[0][1]]);
|
||||
@@ -541,26 +585,31 @@ export function Map(context) {
|
||||
return newZoom;
|
||||
}
|
||||
|
||||
|
||||
map.extentZoom = function(_) {
|
||||
return calcZoom(Extent(_), dimensions);
|
||||
};
|
||||
|
||||
|
||||
map.trimmedExtentZoom = function(_) {
|
||||
var trimY = 120, trimX = 40,
|
||||
trimmed = [dimensions[0] - trimX, dimensions[1] - trimY];
|
||||
return calcZoom(Extent(_), trimmed);
|
||||
};
|
||||
|
||||
|
||||
map.editable = function() {
|
||||
return map.zoom() >= context.minEditableZoom();
|
||||
};
|
||||
|
||||
|
||||
map.minzoom = function(_) {
|
||||
if (!arguments.length) return minzoom;
|
||||
minzoom = _;
|
||||
return map;
|
||||
};
|
||||
|
||||
|
||||
map.layers = drawLayers;
|
||||
|
||||
return rebind(map, dispatch, 'on');
|
||||
|
||||
Reference in New Issue
Block a user