diff --git a/Makefile b/Makefile index 3b0f2d1b7..9fd5afb0e 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,9 @@ all: \ js/id/validate.js \ js/id/end.js \ locale/locale.js \ - locale/en.js + locale/en.js \ + data/data.js \ + data/deprecated.js iD.js: Makefile @rm -f $@ diff --git a/css/map.css b/css/map.css index 63950671f..749aeb7b3 100644 --- a/css/map.css +++ b/css/map.css @@ -17,11 +17,11 @@ g.point .shadow { -moz-transition: fill 100ms linear; } .behavior-hover g.point.hover:not(.selected) .shadow { - fill: #E96666; - fill-opacity: 0.3; + fill: #f6634f; + fill-opacity: 0.5; } g.point.selected .shadow { - fill: #E96666; + fill: #f6634f; fill-opacity: 0.7; } @@ -30,8 +30,10 @@ g.point.selected .shadow { g.vertex .fill { fill:white; } + g.vertex .stroke { - stroke:#333; + stroke:black; + stroke-opacity: .5; stroke-width:2; fill:white; } @@ -101,18 +103,18 @@ g.vertex.shared .fill { g.vertex .shadow { fill: none; pointer-events: all; - stroke-width: 10; + stroke-width: 20; -webkit-transition: -webkit-transform 100ms linear; transition: transform 100ms linear; -moz-transition: fill 100ms linear; } .behavior-hover g.vertex.hover:not(.selected) .shadow { - fill: #E96666; + fill: #f6634f; fill-opacity: 0.3; -} +} g.vertex.selected .shadow { - fill: #E96666; - fill-opacity: 0.7; + fill: #f6634f; + fill-opacity: 0.5; } /* midpoints */ @@ -121,16 +123,20 @@ g.vertex.selected .shadow { .mode-draw-line g.midpoint, .mode-add-area g.midpoint, .mode-add-line g.midpoint, -.mode-add-point g.midpoint { +.mode-add-point g.midpoint, +.behavior-drag-node g.midpoint { display: none; } g.midpoint .fill { - fill:#aaa; + fill:#ddd; + stroke:black; + stroke-opacity: .5; + opacity: .5; } .behavior-hover g.midpoint .fill.hover:not(.selected) { - fill:#fff; - stroke:#000; + fill:white; + opacity: .75; } g.midpoint .shadow { @@ -142,7 +148,7 @@ g.midpoint .shadow { -moz-transition: fill 100ms linear; } .behavior-hover g.midpoint .shadow.hover:not(.selected) { - fill:#E96666; + fill:#f6634f; fill-opacity: 0.3; } @@ -154,8 +160,8 @@ path.line { } path.stroke { - stroke: #222; - stroke-width: 2; + stroke: black; + stroke-width: 4; } path.shadow { @@ -165,12 +171,12 @@ path.shadow { } .behavior-hover path.shadow.hover:not(.selected) { - stroke: #E96666; + stroke: #f6634f; stroke-opacity: 0.3; } path.shadow.selected { - stroke: #E96666; + stroke: #f6634f; stroke-opacity: 0.7; } @@ -199,31 +205,31 @@ path.area.stroke.selected { path.area.stroke.tag-natural, path.multipolygon.tag-natural { - stroke: #ADD6A5; + stroke: #b6e199; stroke-width:1; } path.area.fill.tag-natural, path.multipolygon.tag-natural { - fill: #ADD6A5; + fill: #b6e199; } path.area.stroke.tag-natural-water, path.multipolygon.tag-natural-water { - stroke: #6382FF; + stroke: #77d3de; } path.area.fill.tag-natural-water, path.multipolygon.tag-natural-water { - fill: #ADBEFF; + fill: #77d3de; } path.area.stroke.tag-building, path.multipolygon.tag-building { - stroke: #9E176A; + stroke: #e06e5f; stroke-width: 1; } path.area.fill.tag-building, path.multipolygon.tag-building { - fill: #ff6ec7; + fill: #e06e5f; } path.area.stroke.tag-landuse, @@ -236,7 +242,7 @@ path.multipolygon.tag-natural-wood, path.multipolygon.tag-natural-tree, path.multipolygon.tag-natural-grassland, path.multipolygon.tag-leisure-park { - stroke: #006B34; + stroke: #8cd05f; stroke-width: 1; } path.area.fill.tag-landuse, @@ -249,18 +255,18 @@ path.multipolygon.tag-natural-wood, path.multipolygon.tag-natural-tree, path.multipolygon.tag-natural-grassland, path.multipolygon.tag-leisure-park { - fill: #189E59; + fill: #8cd05f; fill-opacity: 0.2; } path.area.stroke.tag-amenity-parking, path.multipolygon.tag-amenity-parking { - stroke: #beb267; + stroke: #aaa; stroke-width: 1; } path.area.fill.tag-amenity-parking, path.multipolygon.tag-amenity-parking { - fill: #edecc0; + fill: #aaa; } path.multipolygon.tag-boundary { @@ -294,56 +300,57 @@ svg[data-zoom="16"] path.stroke.tag-highway { path.stroke.tag-highway-motorway, path.stroke.tag-highway-motorway_link, path.stroke.tag-construction-motorway { - stroke:#809bc0; + stroke:#58a9ed; } + path.casing.tag-highway-motorway, path.casing.tag-highway-motorway_link, path.casing.tag-construction-motorway { - stroke:#506077; + stroke:#2c5476; } path.stroke.tag-highway-trunk, path.stroke.tag-highway-trunk_link, path.stroke.tag-construction-trunk { - stroke:#97d397; + stroke:#8cd05f; } path.casing.tag-highway-trunk, path.casing.tag-highway-trunk_link, path.casing.tag-construction-trunk { - stroke:#477147; + stroke:#46682f; } path.stroke.tag-highway-primary, path.stroke.tag-highway-primary_link, path.stroke.tag-construction-primary { - stroke:#ec989a; + stroke:#e06d5f; } path.casing.tag-highway-primary, path.casing.tag-highway-primary_link, path.casing.tag-construction-primary { - stroke:#8d4346; + stroke:#70372f; } path.stroke.tag-highway-secondary, path.stroke.tag-highway-secondary_link, path.stroke.tag-construction-secondary { - stroke:#fecc8b; + stroke:#eab056; } path.casing.tag-highway-secondary, path.casing.tag-highway-secondary_link, path.casing.tag-construction-secondary { - stroke:#a37b48; + stroke:#75582b; } path.stroke.tag-highway-tertiary, path.stroke.tag-highway-tertiary_link, path.stroke.tag-construction-tertiary { - stroke:#ffffb3; + stroke:#ffff7e; } path.casing.tag-highway-tertiary, path.casing.tag-highway-tertiary_link, path.casing.tag-construction-tertiary { - stroke:#bbb; + stroke:#7f7f3f; } path.stroke.tag-highway-unclassified, @@ -380,7 +387,7 @@ path.stroke.tag-highway-pedestrian { shapeRendering: auto; } path.casing.tag-highway-pedestrian { - stroke:#84C382; + stroke:#8cd05f; stroke-width:6 !important; } @@ -453,17 +460,17 @@ svg[data-zoom="16"] path.casing.tag-highway-bridleway { } path.stroke.tag-highway-footway { - stroke: #996600; + stroke: #ae8681; } path.stroke.tag-highway-cycleway { - stroke: #69f; + stroke: #58a9ed; } path.stroke.tag-highway-bridleway { - stroke: green; + stroke: #e06d5f; } path.stroke.tag-highway-steps { - stroke: #ff6257; + stroke: #81d25c; stroke-width: 4; stroke-linecap: butt; stroke-dasharray: 3, 3; @@ -475,7 +482,7 @@ path.casing.tag-highway-steps { path.casing.tag-bridge-yes { stroke-width: 14; - stroke: #000; + stroke: #333; } path.stroke.tag-highway-construction, @@ -519,12 +526,16 @@ path.casing.tag-railway-subway { /* waterways */ +path.area.fill.tag-waterway { + fill: #77d3de; +} + path.stroke.tag-waterway { - stroke: #10539a; + stroke: #77d3de; stroke-width: 2; } path.casing.tag-waterway { - stroke: #6AA2FF; + stroke: #77d3de; stroke-width: 4; } @@ -543,11 +554,11 @@ svg[data-zoom="16"] path.casing.tag-waterway-river { } path.stroke.tag-waterway-ditch { - stroke: #10539a; + stroke: #6591ff; stroke-width: 1; } path.casing.tag-waterway-ditch { - stroke: #999692; + stroke: #6591ff; stroke-width: 3; } @@ -576,17 +587,22 @@ path.casing.tag-boundary { path.casing.tag-boundary-protected_area, path.casing.tag-boundary-national_park { - stroke: #4D9849; + stroke: #b0e298; } text { font-size:10px; pointer-events: none; + color: #222; + opacity: 1; } .oneway .textpath { pointer-events: none; + font-size: 7px; + baseline-shift: 2px; + opacity: .7; } text.tag-oneway { @@ -614,7 +630,7 @@ text.pathlabel, text.pointlabel { font-size: 12px; font-weight: bold; - fill: black; + fill: #333; text-anchor: middle; pointer-events: none; } @@ -640,7 +656,8 @@ text.pointlabel { text.point { - font-size: 9px; + font-size: 10px; + baseline-shift: 2px; } /* Cursors */ @@ -700,14 +717,16 @@ text.point { .mode-draw-line .behavior-hover .way, .mode-draw-area .behavior-hover .way, .mode-add-line .behavior-hover .way, -.mode-add-area .behavior-hover .way { +.mode-add-area .behavior-hover .way, +.behavior-drag-node.behavior-hover .way { cursor:url(../img/cursor-draw-connect-line.png) 9 9, auto; } .mode-draw-line .behavior-hover .vertex, .mode-draw-area .behavior-hover .vertex, .mode-add-line .behavior-hover .vertex, -.mode-add-area .behavior-hover .vertex { +.mode-add-area .behavior-hover .vertex, +.behavior-drag-node.behavior-hover .vertex { cursor:url(../img/cursor-draw-connect-vertex.png) 9 9, auto; } @@ -718,12 +737,14 @@ text.point { /* Modes */ .mode-draw-line .vertex.active, -.mode-draw-area .vertex.active { +.mode-draw-area .vertex.active, +.behavior-drag-node .vertex.active { display: none; } .mode-draw-line .way.active, -.mode-draw-area .way.active { +.mode-draw-area .way.active, +.behavior-drag-node .active { pointer-events: none; } diff --git a/icons/tree.png b/icons/tree.png index 7575bd63b..d88c945d4 100644 Binary files a/icons/tree.png and b/icons/tree.png differ diff --git a/icons/unknown.png b/icons/unknown.png index 404602aa4..03fff0c0e 100644 Binary files a/icons/unknown.png and b/icons/unknown.png differ diff --git a/img/source/sprite.svg b/img/source/sprite.svg index 29e87e2b8..64f682c3d 100644 --- a/img/source/sprite.svg +++ b/img/source/sprite.svg @@ -39,12 +39,12 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="1" - inkscape:cx="329.64693" - inkscape:cy="58.693021" + inkscape:zoom="0.5" + inkscape:cx="279.87773" + inkscape:cy="136.54467" inkscape:document-units="px" inkscape:current-layer="layer1" - showgrid="false" + showgrid="true" inkscape:window-width="1280" inkscape:window-height="700" inkscape:window-x="48" @@ -186,7 +186,7 @@ image/svg+xml - + @@ -195,11 +195,200 @@ inkscape:groupmode="layer" id="layer1" transform="translate(-25,-62.362183)" - style="display:inline"> + style="display:none"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fix misalignment + + + + + RESET + style="display:inline;fill:#1a1a1a;fill-opacity:1" + transform="translate(505,-653.36218)"> + style="display:inline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;overflow:visible;enable-background:accumulate" /> - - - - - - - - - - - - - + style="opacity:0.50000000000000000;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + style="opacity:0.50000000000000000;fill:#000000;fill-opacity:1;display:inline"> + style="opacity:0.50000000000000000;fill:#000000;fill-opacity:1;display:inline"> @@ -778,9 +932,9 @@ inkscape:connector-curvature="0" id="path58971" d="m 35,44 c 0,1 0,4 0,4 0,0 0,0.5 -0.5,0.5 -0.5,0 -0.429283,-0.27516 -0.5,-0.5 -0.304688,-0.96875 -0.867187,-2.36459 -1,-3 -0.204595,-0.97885 -0.666667,-1 -1,-1 -1,0 -1,1 -1,1 l 1,4 0,3 C 32,52 31.5,51.5 30.5,50.5 29.945312,49.94531 29.257659,49.7508 28.8125,50.00781 28.377049,50.25922 28.150942,50.89541 28.5,51.5 28.853553,52.11237 32,56 32,56 c 1,1 2,1 4,1 2.666667,0 1,0 3,0 2,0 2.288488,-2.86546 3,-5 1,-3 1.5,-5 1.5,-5 0.113427,-0.42332 -0.04289,-0.846 -0.5,-1 -0.880461,-0.29662 -1.36006,0.35278 -1.5,1 -0.25,1.15625 -0.5,2 -0.5,2 -0.09375,0.31383 0.0013,0.5 -0.5,0.5 C 39.99086,49.5 40,49 40,49 c 0,0 0,-2.66667 0,-4 0,-1 -1,-1 -1,-1 0,0 -1,0 -1,1 0,1 0,1.66667 0,3 0,0 0.01305,0.5 -0.5,0.5 C 36.998673,48.5 37,48 37,48 c 0,0 0,-3 0,-4 0,-1 -1,-1 -1,-1 0,0 -1,0 -1,1 z" - style="opacity:0.5;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter8013-4);enable-background:accumulate" /> + style="opacity:0.50000000000000000;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter8013-4);enable-background:accumulate" /> + transform="translate(25,-3.0625001e-6)" /> - - - - - - - - - - - - - - - - fix misalignment - - - - - RESET diff --git a/index.html b/index.html index 3be283a1f..ee00705ac 100644 --- a/index.html +++ b/index.html @@ -9,8 +9,8 @@ - - + + @@ -81,6 +81,7 @@ + @@ -142,7 +143,7 @@ -
- + @@ -151,6 +152,7 @@ + diff --git a/test/index_packaged.html b/test/index_packaged.html index ef91e2823..d21d48ff2 100644 --- a/test/index_packaged.html +++ b/test/index_packaged.html @@ -35,6 +35,7 @@ + diff --git a/test/spec/actions/connect.js b/test/spec/actions/connect.js new file mode 100644 index 000000000..3838d83c2 --- /dev/null +++ b/test/spec/actions/connect.js @@ -0,0 +1,110 @@ +describe("iD.actions.Connect", function() { + describe("#enabled", function () { + it("returns true for two or more nodes", function () { + expect(iD.actions.Connect(['a', 'b']).enabled()).to.be.true; + }); + + it("returns false for less than two nodes", function () { + expect(iD.actions.Connect(['a']).enabled()).to.be.false; + }); + }); + + it("removes all but the final node", function() { + var graph = iD.Graph({ + 'a': iD.Node({id: 'a'}), + 'b': iD.Node({id: 'b'}), + 'c': iD.Node({id: 'c'}) + }); + + graph = iD.actions.Connect(['a', 'b', 'c'])(graph); + + expect(graph.entity('a')).to.be.undefined; + expect(graph.entity('b')).to.be.undefined; + expect(graph.entity('c')).not.to.be.undefined; + }); + + it("replaces non-surviving nodes in parent ways", function() { + // a --- b --- c + // + // e + // | + // d + // + // Connect [e, b]. + // + // Expected result: + // + // a --- b --- c + // | + // d + // + var graph = iD.Graph({ + 'a': iD.Node({id: 'a'}), + 'b': iD.Node({id: 'b'}), + 'c': iD.Node({id: 'c'}), + 'd': iD.Node({id: 'd'}), + 'e': iD.Node({id: 'e'}), + '-': iD.Way({id: '-', nodes: ['a', 'b', 'c']}), + '|': iD.Way({id: '|', nodes: ['d', 'e']}) + }); + + graph = iD.actions.Connect(['e', 'b'])(graph); + + expect(graph.entity('-').nodes).to.eql(['a', 'b', 'c']); + expect(graph.entity('|').nodes).to.eql(['d', 'b']); + }); + + it("handles circular ways", function() { + // c -- a d === e + // | / + // | / + // | / + // b + // + // Connect [a, d]. + // + var graph = iD.Graph({ + 'a': iD.Node({id: 'a'}), + 'b': iD.Node({id: 'b'}), + 'c': iD.Node({id: 'c'}), + 'd': iD.Node({id: 'd'}), + 'e': iD.Node({id: 'e'}), + '-': iD.Way({id: '-', nodes: ['a', 'b', 'c', 'a']}), + '=': iD.Way({id: '=', nodes: ['d', 'e']}) + }); + + graph = iD.actions.Connect(['a', 'd'])(graph); + + expect(graph.entity('-').nodes).to.eql(['d', 'b', 'c', 'd']); + }); + + it("merges tags to the surviving node", function() { + var graph = iD.Graph({ + 'a': iD.Node({id: 'a', tags: {a: 'a'}}), + 'b': iD.Node({id: 'b', tags: {b: 'b'}}), + 'c': iD.Node({id: 'c', tags: {c: 'c'}}) + }); + + graph = iD.actions.Connect(['a', 'b', 'c'])(graph); + + expect(graph.entity('c').tags).to.eql({a: 'a', b: 'b', c: 'c'}); + }); + + it("merges memberships to the surviving node", function() { + var graph = iD.Graph({ + 'a': iD.Node({id: 'a'}), + 'b': iD.Node({id: 'b'}), + 'c': iD.Node({id: 'c'}), + 'd': iD.Node({id: 'c'}), + '-': iD.Way({id: '-', nodes: ['a', 'b']}), + '=': iD.Way({id: '=', nodes: ['c', 'd']}), + 'r1': iD.Relation({id: 'r1', members: [{id: 'b', role: 'r1', type: 'node'}]}), + 'r2': iD.Relation({id: 'r2', members: [{id: 'b', role: 'r1', type: 'node'}, {id: 'c', role: 'r2', type: 'node'}]}) + }); + + graph = iD.actions.Connect(['b', 'c'])(graph); + + expect(graph.entity('r1').members).to.eql([{id: 'c', role: 'r1', type: 'node'}]); + expect(graph.entity('r2').members).to.eql([{id: 'c', role: 'r2', type: 'node'}]); + }); +}); diff --git a/test/spec/actions/join.js b/test/spec/actions/join.js index 1cddb94bf..261fe607d 100644 --- a/test/spec/actions/join.js +++ b/test/spec/actions/join.js @@ -160,13 +160,13 @@ describe("iD.actions.Join", function () { 'c': iD.Node({id: 'c'}), '-': iD.Way({id: '-', nodes: ['a', 'b']}), '=': iD.Way({id: '=', nodes: ['b', 'c']}), - 'r1': iD.Relation({id: 'r1', members: [{id: '=', role: 'r1'}]}), - 'r2': iD.Relation({id: 'r2', members: [{id: '=', role: 'r1'}, {id: '-', role: 'r2'}]}) + 'r1': iD.Relation({id: 'r1', members: [{id: '=', role: 'r1', type: 'way'}]}), + 'r2': iD.Relation({id: 'r2', members: [{id: '=', role: 'r1', type: 'way'}, {id: '-', role: 'r2', type: 'way'}]}) }); graph = iD.actions.Join('-', '=')(graph); - expect(graph.entity('r1').members).to.eql([{id: '-', role: 'r1'}]); - expect(graph.entity('r2').members).to.eql([{id: '-', role: 'r2'}]); + expect(graph.entity('r1').members).to.eql([{id: '-', role: 'r1', type: 'way'}]); + expect(graph.entity('r2').members).to.eql([{id: '-', role: 'r2', type: 'way'}]); }); }); diff --git a/test/spec/svg/midpoints.js b/test/spec/svg/midpoints.js index c34ac0350..e00f6f78b 100644 --- a/test/spec/svg/midpoints.js +++ b/test/spec/svg/midpoints.js @@ -14,6 +14,8 @@ describe("iD.svg.Midpoints", function () { line = iD.Way({nodes: [a.id, b.id]}), graph = iD.Graph([a, b, line]); + // If no vertices are drawn, no midpoints are drawn. This dependence needs to be removed + surface.call(iD.svg.Vertices(projection), graph, [a], filter); surface.call(iD.svg.Midpoints(projection), graph, [line], filter); expect(surface.select('.midpoint').datum().loc).to.eql([25, 0]); @@ -42,6 +44,8 @@ describe("iD.svg.Midpoints", function () { graph = iD.Graph([a, b, c, d, l1, l2, l3, l4]), ab = function (d) { return d.id === [a.id, b.id].sort().join("-"); }; + // If no vertices are drawn, no midpoints are drawn. This dependence needs to be removed + surface.call(iD.svg.Vertices(projection), graph, [a], filter); surface.call(iD.svg.Midpoints(projection), graph, [l1, l2, l3, l4], filter); expect(surface.selectAll('.midpoint').filter(ab).datum().ways).to.eql([