diff --git a/NOTES.md b/NOTES.md index d4bd87c74..7f83546ed 100644 --- a/NOTES.md +++ b/NOTES.md @@ -28,6 +28,9 @@ _However_ JOSM also does a little trick where if you have a node selected and then enter draw mode, it'll start either a new way or a continuation of the way, depending on whether it's the start or the end. +Also what happens if you click on a point that happens to be the start or end +of more than one way? + ## Relations and Turn Restrictions http://wiki.openstreetmap.org/wiki/Relation:restriction diff --git a/js/id/actions/modes.js b/js/id/actions/modes.js index 8c0312841..7db9f47b0 100644 --- a/js/id/actions/modes.js +++ b/js/id/actions/modes.js @@ -93,15 +93,28 @@ iD.modes.AddRoad = { }); }); - // http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java#L431 - // https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/Way.as#L215 + // http://bit.ly/SwUwIL + // http://bit.ly/WxqGng function addRoad() { var t = d3.select(d3.event.target), node, + direction = 'forward', + start = true, way = this.way(); // connect a way to an existing way if (t.data() && t.data()[0] && t.data()[0].type === 'node') { + // continue an existing way + var id = t.data()[0].id; + var parents = this.map.history.graph().parents(id); + if (parents.length && parents[0].nodes[0] === id) { + way = parents[0]; + direction = 'backward'; + start = false; + } else if (parents.length && _.last(parents[0].nodes) === id) { + way = parents[0]; + start = false; + } node = t.data()[0]; // snap into an existing way } else if (t.data() && t.data()[0] && t.data()[0].type === 'way') { @@ -116,11 +129,12 @@ iD.modes.AddRoad = { d3.mouse(surface.node()))); } - this.map.perform(iD.actions.startWay(way)); - way.nodes.push(node.id); - this.map.perform(iD.actions.addWayNode(way, node)); - this.map.selectClick(way); - this.controller.enter(iD.modes.DrawRoad(way.id)); + if (start) { + this.map.perform(iD.actions.startWay(way)); + way.nodes.push(node.id); + this.map.perform(iD.actions.addWayNode(way, node)); + } + this.controller.enter(iD.modes.DrawRoad(way.id, direction)); } surface.on('click.addroad', addRoad.bind(this)); @@ -140,9 +154,11 @@ iD.modes.AddRoad = { // user has clicked on the map, started a road, and now needs to click more // nodes to continue it. -iD.modes.DrawRoad = function(way_id) { +iD.modes.DrawRoad = function(way_id, direction) { return { enter: function() { + var push = (direction === 'forward') ? 'push' : 'unshift', + pop = (direction === 'forward') ? 'pop' : 'shift'; this.map.dblclickEnable(false); var surface = this.map.surface, @@ -150,16 +166,15 @@ iD.modes.DrawRoad = function(way_id) { var nextnode_id = nextnode.id; var way = this.map.history.graph().entity(way_id); - var lastnode_id = _.last(way.nodes); - way.nodes.push(nextnode_id); + var lastnode_id = (direction === 'forward') ? _.last(way.nodes) : way.nodes[0]; + way.nodes[push](nextnode_id); this.map.perform(iD.actions.addWayNode(way, nextnode)); surface.on('mousemove.drawroad', function() { var ll = this.map.projection.invert(d3.mouse(surface.node())); var way = this.map.history.graph().entity(way_id); var node = iD.Entity(this.map.history.graph().entity(nextnode_id), { - lon: ll[0], - lat: ll[1] + lon: ll[0], lat: ll[1] }); this.map.history.replace(iD.actions.addWayNode(way, node)); var only = iD.Util.trueObj([way.id].concat(_.pluck(way.nodes, 'id'))); @@ -171,7 +186,7 @@ iD.modes.DrawRoad = function(way_id) { d3.event.stopPropagation(); if (t.data() && t.data()[0] && t.data()[0].type === 'node') { if (t.data()[0].id == lastnode_id) { - var l = this.map.history.graph().entity(way.nodes.pop()); + var l = this.map.history.graph().entity(way.nodes[pop]()); this.map.perform(iD.actions.removeWayNode(way, l)); delete way.tags.elastic; this.map.perform(iD.actions.changeTags(way, way.tags)); @@ -192,12 +207,12 @@ iD.modes.DrawRoad = function(way_id) { node = iD.modes._node(this.map.projection.invert( d3.mouse(surface.node()))); } - var old = this.map.history.graph().entity(way.nodes.pop()); + var old = this.map.history.graph().entity(way.nodes[pop]()); this.map.perform(iD.actions.removeWayNode(way, old)); - way.nodes.push(node.id); + way.nodes[push](node.id); this.map.perform(iD.actions.addWayNode(way, node)); way.nodes = way.nodes.slice(); - this.controller.enter(iD.modes.DrawRoad(way_id)); + this.controller.enter(iD.modes.DrawRoad(way_id, direction)); } surface.on('click.drawroad', drawRoad.bind(this)); diff --git a/js/id/id.js b/js/id/id.js index 0e32ee54d..4e1d0e475 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -145,7 +145,7 @@ var iD = function(container) { }); var hash = iD.Hash().map(map); - if (!hash.hadHash) map.setZoom(19).center([-77.0198, 38.8796]); + if (!hash.hadHash) map.setZoom(18).center([-92.0198, 38.8796]); d3.select('.user').call(iD.userpanel(connection) .on('logout', connection.logout) .on('login', connection.authenticate)); diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index 38df44293..8d2a6f739 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -12,7 +12,7 @@ iD.Map = function(elem, connection) { zoom = d3.behavior.zoom() .translate(projection.translate()) .scale(projection.scale()) - .scaleExtent([256, 134217728]) + .scaleExtent([256, 256 * Math.pow(2, 20)]) .on('zoom', zoomPan), only, dblclickEnabled = true, @@ -116,6 +116,14 @@ iD.Map = function(elem, connection) { var filter = only ? function(d) { return only[d.id]; } : function() { return true; }; + if (all.length > 2000) { + d3.select('.messages').text('Zoom in to edit the map'); + hideVector(); + return; + } else { + d3.select('.messages').text('Zoom in to edit the map'); + } + for (var i = 0; i < all.length; i++) { var a = all[i]; if (a.type === 'way') { @@ -128,9 +136,8 @@ iD.Map = function(elem, connection) { waynodes.push(a); } } - - if (z > 18) { drawHandles(waynodes, filter); } else { hideHandles(); } - if (z > 18) { drawCasings(ways, filter); } else { hideCasings(); } + drawHandles(waynodes, filter); + drawCasings(ways, filter); drawFills(areas, filter); drawStrokes(ways, filter); drawMarkers(points, filter); @@ -142,15 +149,14 @@ iD.Map = function(elem, connection) { .data(waynodes, key); handles.exit().remove(); handles.enter().append('rect') - .attr({ width: 6, height: 6, 'class': 'handle' }) + .attr({ width: 10, height: 10, 'class': 'handle' }) .call(dragbehavior); handles.attr('transform', function(entity) { var p = projection(ll2a(entity)); - return 'translate(' + [~~p[0], ~~p[1]] + ') translate(-3, -3) rotate(45, 2, 2)'; + return 'translate(' + [~~p[0], ~~p[1]] + ') translate(-5, -5) rotate(45, 5, 5)'; }).classed('active', classActive); } - function hideHandles() { g.hit.selectAll('rect.handle').remove(); } function hideVector() { surface.selectAll('.layer-g *').remove(); } @@ -247,8 +253,6 @@ iD.Map = function(elem, connection) { .classed('active', classActive); } - function hideCasings() { g.casing.selectAll('path').remove(); } - function setSize(x) { dimensions = x; var attr = { width: dimensions[0], height: dimensions[1] };