mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-25 23:13:42 +00:00
@@ -186,15 +186,18 @@ window.iD = function(container) {
|
||||
|
||||
map.keybinding()
|
||||
.on('a', function(evt, mods) {
|
||||
if (mods) return;
|
||||
controller.enter(iD.modes.AddArea());
|
||||
})
|
||||
.on('⌫.prevent_navigation', function(evt, mods) {
|
||||
evt.preventDefault();
|
||||
})
|
||||
.on('p', function(evt, mods) {
|
||||
if (mods) return;
|
||||
controller.enter(iD.modes.AddPoint());
|
||||
})
|
||||
.on('l', function(evt, mods) {
|
||||
if (mods) return;
|
||||
controller.enter(iD.modes.AddLine());
|
||||
})
|
||||
.on('z', function(evt, mods) {
|
||||
@@ -202,7 +205,7 @@ window.iD = function(container) {
|
||||
if (mods === '⌘' || mods === '⌃') history.undo();
|
||||
});
|
||||
|
||||
var hash = iD.Hash().map(map);
|
||||
var hash = iD.Hash().controller(controller).map(map);
|
||||
|
||||
if (!hash.hadHash) {
|
||||
map.centerZoom([-77.02271, 38.90085], 20);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
iD.modes.Select = function (entity) {
|
||||
iD.modes.Select = function(entity) {
|
||||
var mode = {
|
||||
id: 'select',
|
||||
button: 'browse',
|
||||
@@ -34,7 +34,7 @@ iD.modes.Select = function (entity) {
|
||||
}
|
||||
}
|
||||
|
||||
mode.enter = function () {
|
||||
mode.enter = function() {
|
||||
var surface = mode.map.surface;
|
||||
|
||||
behaviors = [
|
||||
@@ -47,22 +47,29 @@ iD.modes.Select = function (entity) {
|
||||
behavior(surface);
|
||||
});
|
||||
|
||||
var q = iD.util.stringQs(location.hash.substring(1));
|
||||
location.hash = '#' + iD.util.qsString(_.assign(q, {
|
||||
id: entity.id
|
||||
}), true);
|
||||
|
||||
d3.select('.inspector-wrap')
|
||||
.style('display', 'block')
|
||||
.style('opacity', 1)
|
||||
.datum(entity)
|
||||
.call(inspector);
|
||||
|
||||
// Pan the map if the clicked feature intersects with the position
|
||||
// of the inspector
|
||||
var inspector_size = d3.select('.inspector-wrap').size(),
|
||||
map_size = mode.map.size(),
|
||||
offset = 50,
|
||||
shift_left = d3.event.x - map_size[0] + inspector_size[0] + offset,
|
||||
center = (map_size[0] / 2) + shift_left + offset;
|
||||
if (d3.event) {
|
||||
// Pan the map if the clicked feature intersects with the position
|
||||
// of the inspector
|
||||
var inspector_size = d3.select('.inspector-wrap').size(),
|
||||
map_size = mode.map.size(),
|
||||
offset = 50,
|
||||
shift_left = d3.event.x - map_size[0] + inspector_size[0] + offset,
|
||||
center = (map_size[0] / 2) + shift_left + offset;
|
||||
|
||||
if (shift_left > 0 && inspector_size[1] > d3.event.y) {
|
||||
mode.map.centerEase(mode.map.projection.invert([center, map_size[1]/2]));
|
||||
if (shift_left > 0 && inspector_size[1] > d3.event.y) {
|
||||
mode.map.centerEase(mode.map.projection.invert([center, map_size[1]/2]));
|
||||
}
|
||||
}
|
||||
|
||||
inspector
|
||||
@@ -131,14 +138,18 @@ iD.modes.Select = function (entity) {
|
||||
});
|
||||
|
||||
surface.selectAll("*")
|
||||
.filter(function (d) { return d === entity; })
|
||||
.filter(function (d) {
|
||||
return d && entity && d.id === entity.id;
|
||||
})
|
||||
.classed('selected', true);
|
||||
};
|
||||
|
||||
mode.exit = function () {
|
||||
var surface = mode.map.surface;
|
||||
|
||||
entity && changeTags(entity, inspector.tags());
|
||||
if (entity) {
|
||||
changeTags(entity, inspector.tags());
|
||||
}
|
||||
d3.select('.inspector-wrap')
|
||||
.style('display', 'none')
|
||||
.html('');
|
||||
@@ -147,6 +158,9 @@ iD.modes.Select = function (entity) {
|
||||
behavior.off(surface);
|
||||
});
|
||||
|
||||
var q = iD.util.stringQs(location.hash.substring(1));
|
||||
location.hash = '#' + iD.util.qsString(_.omit(q, 'id'), true);
|
||||
|
||||
surface.on("click.select", null);
|
||||
mode.map.keybinding().on('⌫.select', null);
|
||||
mode.history.on('change.entity-undone', null);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
iD.Hash = function() {
|
||||
var hash = { hadHash: false },
|
||||
s0, // cached location.hash
|
||||
s0 = null, // cached location.hash
|
||||
lat = 90 - 1e-8, // allowable latitude range
|
||||
controller,
|
||||
map;
|
||||
|
||||
var parser = function(map, s) {
|
||||
@@ -20,9 +21,12 @@ iD.Hash = function() {
|
||||
var center = map.center(),
|
||||
zoom = map.zoom(),
|
||||
precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
|
||||
return '#?map=' + zoom.toFixed(2) +
|
||||
'/' + center[1].toFixed(precision) +
|
||||
'/' + center[0].toFixed(precision);
|
||||
var q = iD.util.stringQs(location.hash.substring(1));
|
||||
return '#' + iD.util.qsString(_.assign(q, {
|
||||
map: zoom.toFixed(2) +
|
||||
'/' + center[1].toFixed(precision) +
|
||||
'/' + center[0].toFixed(precision)
|
||||
}), true);
|
||||
};
|
||||
|
||||
var move = _.throttle(function() {
|
||||
@@ -32,11 +36,37 @@ iD.Hash = function() {
|
||||
|
||||
function hashchange() {
|
||||
if (location.hash === s0) return; // ignore spurious hashchange events
|
||||
if (parser(map, (s0 = location.hash).substring(2))) {
|
||||
if (parser(map, (s0 = location.hash).substring(1))) {
|
||||
move(); // replace bogus hash
|
||||
}
|
||||
}
|
||||
|
||||
// the hash can declare that the map should select a feature, but it can
|
||||
// do so before any features are loaded. thus wait for the feature to
|
||||
// be loaded and then select
|
||||
function willselect(id) {
|
||||
map.on('drawn.after-draw-select', function() {
|
||||
var entity = map.history().graph().entity(id);
|
||||
if (entity === undefined) return;
|
||||
else selectoff();
|
||||
controller.enter(iD.modes.Select(entity));
|
||||
map.on('drawn.after-draw-select', null);
|
||||
});
|
||||
controller.on('enter', function() {
|
||||
if (controller.mode.id !== 'browse') selectoff();
|
||||
});
|
||||
}
|
||||
|
||||
function selectoff() {
|
||||
map.on('drawn.after-draw-select', null);
|
||||
}
|
||||
|
||||
hash.controller = function(_) {
|
||||
if (!arguments.length) return controller;
|
||||
controller = _;
|
||||
return hash;
|
||||
};
|
||||
|
||||
hash.map = function(x) {
|
||||
if (!arguments.length) return map;
|
||||
if (map) {
|
||||
@@ -48,6 +78,10 @@ iD.Hash = function() {
|
||||
map.on("move", move);
|
||||
window.addEventListener("hashchange", hashchange, false);
|
||||
if (location.hash) {
|
||||
var q = iD.util.stringQs(location.hash.substring(1));
|
||||
if (q.id) {
|
||||
willselect(q.id);
|
||||
}
|
||||
hashchange();
|
||||
hash.hadHash = true;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
iD.Map = function() {
|
||||
var connection, history,
|
||||
dimensions = [],
|
||||
dispatch = d3.dispatch('move'),
|
||||
dispatch = d3.dispatch('move', 'drawn'),
|
||||
translateStart,
|
||||
keybinding = d3.keybinding(),
|
||||
projection = d3.geo.mercator().scale(1024),
|
||||
@@ -65,22 +65,22 @@ iD.Map = function() {
|
||||
extent = map.extent(),
|
||||
graph = history.graph();
|
||||
|
||||
function addParents(parents) {
|
||||
for (var i = 0; i < parents.length; i++) {
|
||||
var parent = parents[i];
|
||||
if (only[parent.id] === undefined) {
|
||||
only[parent.id] = graph.fetch(parent.id);
|
||||
addParents(graph.parentRelations(parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!difference) {
|
||||
all = graph.intersects(extent);
|
||||
filter = d3.functor(true);
|
||||
} else {
|
||||
var only = {};
|
||||
|
||||
function addParents(parents) {
|
||||
for (var i = 0; i < parents.length; i++) {
|
||||
var parent = parents[i];
|
||||
if (only[parent.id] === undefined) {
|
||||
only[parent.id] = graph.fetch(parent.id);
|
||||
addParents(graph.parentRelations(parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < difference.length; j++) {
|
||||
var id = difference[j],
|
||||
entity = graph.fetch(id);
|
||||
@@ -101,16 +101,16 @@ iD.Map = function() {
|
||||
|
||||
if (all.length > 100000) {
|
||||
editOff();
|
||||
return;
|
||||
} else {
|
||||
surface
|
||||
.call(points, graph, all, filter)
|
||||
.call(vertices, graph, all, filter)
|
||||
.call(lines, graph, all, filter)
|
||||
.call(areas, graph, all, filter)
|
||||
.call(multipolygons, graph, all, filter)
|
||||
.call(midpoints, graph, all, filter);
|
||||
}
|
||||
|
||||
surface
|
||||
.call(points, graph, all, filter)
|
||||
.call(vertices, graph, all, filter)
|
||||
.call(lines, graph, all, filter)
|
||||
.call(areas, graph, all, filter)
|
||||
.call(multipolygons, graph, all, filter)
|
||||
.call(midpoints, graph, all, filter);
|
||||
dispatch.drawn(map);
|
||||
}
|
||||
|
||||
function editOff() {
|
||||
@@ -302,7 +302,7 @@ iD.Map = function() {
|
||||
map.connection = function(_) {
|
||||
if (!arguments.length) return connection;
|
||||
connection = _;
|
||||
connection.on('load', connectionLoad);
|
||||
connection.on('load.tile', connectionLoad);
|
||||
return map;
|
||||
};
|
||||
|
||||
|
||||
@@ -30,9 +30,10 @@ iD.util.stringQs = function(str) {
|
||||
}, {});
|
||||
};
|
||||
|
||||
iD.util.qsString = function(obj) {
|
||||
iD.util.qsString = function(obj, noencode) {
|
||||
return Object.keys(obj).sort().map(function(key) {
|
||||
return encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]);
|
||||
return encodeURIComponent(key) + '=' + (
|
||||
noencode ? obj[key] : encodeURIComponent(obj[key]));
|
||||
}).join('&');
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
describe("hash", function () {
|
||||
var hash, map;
|
||||
var hash, map, controller;
|
||||
|
||||
beforeEach(function () {
|
||||
hash = iD.Hash();
|
||||
@@ -7,8 +7,12 @@ describe("hash", function () {
|
||||
on: function () { return map; },
|
||||
off: function () { return map; },
|
||||
zoom: function () { return arguments.length ? map : 0; },
|
||||
center: function () { return arguments.length ? map : [0, 0] },
|
||||
centerZoom: function () { return arguments.length ? map : [0, 0] }
|
||||
center: function () { return arguments.length ? map : [0, 0]; },
|
||||
centerZoom: function () { return arguments.length ? map : [0, 0]; }
|
||||
};
|
||||
controller = {
|
||||
on: function () { return controller; },
|
||||
off: function () { return controller; }
|
||||
};
|
||||
});
|
||||
|
||||
@@ -19,18 +23,18 @@ describe("hash", function () {
|
||||
|
||||
describe("#map()", function () {
|
||||
it("gets and sets map", function () {
|
||||
expect(hash.map(map)).to.equal(hash);
|
||||
expect(hash.controller(controller).map(map)).to.equal(hash);
|
||||
expect(hash.map()).to.equal(map);
|
||||
});
|
||||
|
||||
it("sets hadHash if location.hash is present", function () {
|
||||
location.hash = "?map=20.00/38.87952/-77.02405";
|
||||
location.hash = "map=20.00/38.87952/-77.02405";
|
||||
hash.map(map);
|
||||
expect(hash.hadHash).to.be.true;
|
||||
});
|
||||
|
||||
it("centerZooms map to requested level", function () {
|
||||
location.hash = "?map=20.00/38.87952/-77.02405";
|
||||
location.hash = "map=20.00/38.87952/-77.02405";
|
||||
sinon.spy(map, 'centerZoom');
|
||||
hash.map(map);
|
||||
expect(map.centerZoom).to.have.been.calledWith([-77.02405,38.87952], 20.0);
|
||||
@@ -67,7 +71,7 @@ describe("hash", function () {
|
||||
});
|
||||
|
||||
sinon.spy(map, 'centerZoom');
|
||||
location.hash = "#?map=20.00/38.87952/-77.02405";
|
||||
location.hash = "#map=20.00/38.87952/-77.02405";
|
||||
});
|
||||
});
|
||||
|
||||
@@ -75,7 +79,7 @@ describe("hash", function () {
|
||||
it("stores the current zoom and coordinates in location.hash", function () {
|
||||
sinon.stub(map, 'on').yields();
|
||||
hash.map(map);
|
||||
expect(location.hash).to.equal("#?map=0.00/0/0");
|
||||
expect(location.hash).to.equal("#map=0.00/0/0");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user