diff --git a/Makefile b/Makefile index 8b9d9bc39..f8f775db4 100644 --- a/Makefile +++ b/Makefile @@ -166,6 +166,7 @@ dist/iD.js: \ js/id/renderer/tile_layer.js \ js/id/svg.js \ js/id/svg/areas.js \ + js/id/svg/debug.js \ js/id/svg/defs.js \ js/id/svg/gpx.js \ js/id/svg/icon.js \ diff --git a/css/app.css b/css/app.css index a243d63aa..cb482605d 100644 --- a/css/app.css +++ b/css/app.css @@ -2312,7 +2312,6 @@ img.tile-removing { /* Map-In-Map ------------------------------------------------------- */ - .map-in-map { position: absolute; overflow: hidden; @@ -2338,8 +2337,8 @@ img.tile-removing { user-select: none; } -.map-in-map-svg, -.map-in-map-gpx { +.map-in-map-viewport, +.map-in-map-data { top: 0; left: 0; overflow: hidden; @@ -2347,11 +2346,11 @@ img.tile-removing { width: 100%; } -.map-in-map-svg { +.map-in-map-viewport { position: absolute; } -.map-in-map-gpx { +.map-in-map-data { position: relative; z-index: 10; } @@ -2371,19 +2370,23 @@ img.tile-removing { /* Debug ------------------------------------------------------- */ .debug { + stroke: currentColor; fill: none; stroke-width: 2; - shape-rendering: crispEdges; } -.red { stroke: rgba(255, 0, 0, 0.75); } -.green { stroke: rgba(0, 255, 0, 0.75); } -.blue { stroke: rgba(0, 0, 255, 0.75); } -.yellow { stroke: rgba(255, 255, 0, 0.75); } -.cyan { stroke: rgba(0, 255, 255, 0.75); } -.magenta { stroke: rgba(255, 0, 255, 0.75); } -.orange { stroke: rgba(255, 153, 0, 0.75); } -.pink { stroke: rgba(255, 0, 153, 0.75); } -.purple { stroke: rgba(153, 0, 255, 0.75); } +.map-in-map-data .debug { + stroke-width: 1; +} + +.red { color: rgba(255, 0, 0, 0.75); } +.green { color: rgba(0, 255, 0, 0.75); } +.blue { color: rgba(0, 0, 255, 0.75); } +.yellow { color: rgba(255, 255, 0, 0.75); } +.cyan { color: rgba(0, 255, 255, 0.75); } +.magenta { color: rgba(255, 0, 255, 0.75); } +.orange { color: rgba(255, 153, 0, 0.75); } +.pink { color: rgba(255, 0, 153, 0.75); } +.purple { color: rgba(153, 0, 255, 0.75); } /* Info Box diff --git a/index.html b/index.html index d7eb05479..656c00597 100644 --- a/index.html +++ b/index.html @@ -61,6 +61,7 @@ + diff --git a/js/id/svg/debug.js b/js/id/svg/debug.js new file mode 100644 index 000000000..2ca3b0e24 --- /dev/null +++ b/js/id/svg/debug.js @@ -0,0 +1,88 @@ +iD.svg.Debug = function(projection, context) { + + function drawDebug(surface) { + var showsImagery = context.getDebug('imagery'), + showsImperial = context.getDebug('imperial'), + showsDriveLeft = context.getDebug('driveLeft'), + enabled = showsImagery || showsImperial || showsDriveLeft, + path = d3.geo.path().projection(projection); + + var layer = surface.selectAll('.layer-debug') + .data(enabled ? [0] : []); + + layer.enter() + .append('g') + .attr('class', 'layer-debug'); + + layer.exit() + .remove(); + + + var legend = d3.select('#content') + .selectAll('#debugLegend') + .data(enabled ? [0] : []); + + legend.enter() + .append('div') + .attr('id', 'debugLegend') + .attr('class', 'fillD') + .attr('style', 'position:absolute; top:70px; right:80px; padding:5px;'); + + legend.exit() + .remove(); + + + var imagery = layer.selectAll('path.debug-imagery') + .data(showsImagery ? [] : []); // TODO + + imagery.enter() + .append('path') + .attr('class', 'debug-imagery debug orange'); + + imagery.exit() + .remove(); + + + var imperial = layer + .selectAll('path.debug-imperial') + .data(showsImperial ? [iD.data.imperial] : []); + + imperial.enter() + .append('path') + .attr('class', 'debug-imperial debug cyan'); + + imperial.exit() + .remove(); + + + var driveLeft = layer + .selectAll('path.debug-drive-left') + .data(showsDriveLeft ? [iD.data.driveLeft] : []); + + driveLeft.enter() + .append('path') + .attr('class', 'debug-drive-left debug green'); + + driveLeft.exit() + .remove(); + + + // update + layer.selectAll('path') + .attr('d', path); + } + + // This looks strange because `enabled` methods on other layers are + // chainable getter/setters, and this one is just a getter. + drawDebug.enabled = function() { + if (!arguments.length) { + return context.getDebug('imagery') || + context.getDebug('imperial') || + context.getDebug('driveLeft'); + } else { + return this; + } + }; + + return drawDebug; +}; diff --git a/js/id/svg/layers.js b/js/id/svg/layers.js index 34b84e6f1..fea38d417 100644 --- a/js/id/svg/layers.js +++ b/js/id/svg/layers.js @@ -5,7 +5,8 @@ iD.svg.Layers = function(projection, context) { { id: 'osm', layer: iD.svg.Osm(projection, context, dispatch) }, { id: 'gpx', layer: iD.svg.Gpx(projection, context, dispatch) }, { id: 'mapillary-images', layer: iD.svg.MapillaryImages(projection, context, dispatch) }, - { id: 'mapillary-signs', layer: iD.svg.MapillarySigns(projection, context, dispatch) } + { id: 'mapillary-signs', layer: iD.svg.MapillarySigns(projection, context, dispatch) }, + { id: 'debug', layer: iD.svg.Debug(projection, context, dispatch) } ]; diff --git a/js/id/ui/map_in_map.js b/js/id/ui/map_in_map.js index ba4f28987..2d3d525cd 100644 --- a/js/id/ui/map_in_map.js +++ b/js/id/ui/map_in_map.js @@ -6,6 +6,7 @@ iD.ui.MapInMap = function(context) { overlayLayers = {}, projection = iD.geo.RawMercator(), gpxLayer = iD.svg.Gpx(projection, context).showLabels(false), + debugLayer = iD.svg.Debug(projection, context), zoom = d3.behavior.zoom() .scaleExtent([ztok(0.5), ztok(24)]) .on('zoom', zoomPan), @@ -13,7 +14,7 @@ iD.ui.MapInMap = function(context) { panning = false, hidden = true, zDiff = 6, // by default, minimap renders at (main zoom - 6) - tStart, tLast, tCurr, kLast, kCurr, tiles, svg, timeoutId; + tStart, tLast, tCurr, kLast, kCurr, tiles, viewport, timeoutId; function ztok(z) { return 256 * Math.pow(2, z); } function ktoz(k) { return Math.log(k) / Math.LN2 - 8; } @@ -51,7 +52,7 @@ iD.ui.MapInMap = function(context) { tY = (tCurr[1] / scale - tLast[1]) * scale; iD.util.setTransform(tiles, tX, tY, scale); - iD.util.setTransform(svg, 0, 0, scale); + iD.util.setTransform(viewport, 0, 0, scale); transformed = true; queueRedraw(); @@ -112,7 +113,7 @@ iD.ui.MapInMap = function(context) { if (transformed) { iD.util.setTransform(tiles, 0, 0); - iD.util.setTransform(svg, 0, 0); + iD.util.setTransform(viewport, 0, 0); transformed = false; } } @@ -188,33 +189,35 @@ iD.ui.MapInMap = function(context) { .remove(); - var gpx = tiles - .selectAll('.map-in-map-gpx') - .data(gpxLayer.enabled() ? [0] : []); + var dataLayers = tiles + .selectAll('.map-in-map-data') + .data([0]); - gpx.enter() + dataLayers.enter() .append('svg') - .attr('class', 'map-in-map-gpx'); + .attr('class', 'map-in-map-data'); - gpx.exit() + dataLayers.exit() .remove(); - gpx.call(gpxLayer); + dataLayers + .call(gpxLayer) + .call(debugLayer); - // redraw bounding box + // redraw viewport bounding box if (!panning) { var getPath = d3.geo.path().projection(projection), bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] }; - svg = wrap.selectAll('.map-in-map-svg') + viewport = wrap.selectAll('.map-in-map-viewport') .data([0]); - svg.enter() + viewport.enter() .append('svg') - .attr('class', 'map-in-map-svg'); + .attr('class', 'map-in-map-viewport'); - var path = svg.selectAll('.map-in-map-bbox') + var path = viewport.selectAll('.map-in-map-bbox') .data([bbox]); path.enter() diff --git a/test/index.html b/test/index.html index 24aa35963..faa84ce6b 100644 --- a/test/index.html +++ b/test/index.html @@ -67,6 +67,7 @@ +