From 3d90801e63b0bbf756f1287971917b0fc2ed2ec3 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 22 Jan 2013 10:22:00 -0500 Subject: [PATCH] Add willselect to hash, works with non-line features. --- js/id/id.js | 2 +- js/id/modes/select.js | 24 +++++++++++++----------- js/id/renderer/hash.js | 31 +++++++++++++++++++++++++++++++ js/id/renderer/map.js | 42 +++++++++++++++++++++--------------------- 4 files changed, 66 insertions(+), 33 deletions(-) diff --git a/js/id/id.js b/js/id/id.js index 4d3948107..3d9004bfb 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -202,7 +202,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); diff --git a/js/id/modes/select.js b/js/id/modes/select.js index 505aff07a..3b9667de3 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -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 = [ @@ -58,16 +58,18 @@ iD.modes.Select = function (entity) { .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 diff --git a/js/id/renderer/hash.js b/js/id/renderer/hash.js index 652e64f20..81da12d90 100644 --- a/js/id/renderer/hash.js +++ b/js/id/renderer/hash.js @@ -2,6 +2,7 @@ iD.Hash = function() { var hash = { hadHash: false }, s0 = null, // cached location.hash lat = 90 - 1e-8, // allowable latitude range + controller, map; var parser = function(map, s) { @@ -40,6 +41,32 @@ iD.Hash = function() { } } + // 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) { @@ -51,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; } diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index 3f55f7271..c2de92855 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -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; };