From 29dde3f2177eae270c163544d919dae8ba50ac03 Mon Sep 17 00:00:00 2001 From: Peter Neubauer Date: Tue, 12 Aug 2014 11:02:28 +0200 Subject: [PATCH] Implement Mapillary layer in iD - adding a temp wikipedia icon from http://upload.wikimedia.org/wikipedia/commons/4/45/Right-facing-Arrow-icon.jpg Making the click update and rotate an image marker on the map with comapss direction. Needs to be centered etc. now properly enabling/disabling the different Mapillary layers upon activation/deactivation Upgrade to faster Mapillary API better arrow icon, refactoring to have all single-image operations in the image-layer dist build adding mapillary translation adjusting image link trying to adjust the image link for github deploy better layout removing font-awesome, not needed. https for calls consistent quotes taking care of more translation, fix case of no images found on Mapillary more english translations - scoping image calls to selection. - .inspector-wrap and .panewrap are hard to scope, since they are outside the selection, same for the #mapillary-inspector. -scoping calls in sequences layer adding translation fixing jslint errors more jshint errors adding mapillary to tests trying to lay out single markers, please help with the geo translation, @jfirebaugh - adding the image layer to the active iD SVG instead of background - add a new mode for selecting Mapillary images - first stab of adding the image pane in the sidebar itself in order to contain the selections (needs to be layouted) cleaning trying to mark and keep selected image between mouseovers refactoring to contain mapillary into the iamge mode refactoring to contain mapillary into the iamge mode adding to test html cleaning up handling unset selected image cleanup better sidebar moving image into the lower right Minor visual adjustment mapillaryImage better no_image text and toggling of selected image handling of text disappearing intendation fixing test errors making sequences be below images open Mapillary links in new tabs better arrows and selectability on arrows as a workaround for real navigation in panos more contrast for the selected image adjusting image style - adjusting style, removing sequence lines - adding photos as a mode with shortcut 'm' - fix test errors moving switch back to right sidebar, keeping keyboard shortcut. cleanup file rename to avoid GIT mess with casing. - better scoping - removed unused hover function - making the checkbox follow mode changes removing unused icon handling automatic mode exit --- css/app.css | 47 +++++++++++ css/map.css | 40 +++++++++ data/core.yaml | 10 ++- dist/img/arrow-icon.png | Bin 0 -> 1734 bytes dist/img/cursor-select-mapillary.png | Bin 0 -> 751 bytes dist/img/cursor-select-mapillary2x.png | Bin 0 -> 1621 bytes dist/locales/en.json | 10 +++ index.html | 3 + js/id/id.js | 7 ++ js/id/modes/select_image.js | 100 +++++++++++++++++++++++ js/id/renderer/map.js | 6 ++ js/id/svg/sequences.js | 109 +++++++++++++++++++++++++ js/id/ui.js | 4 + js/id/ui/background.js | 32 ++++++++ js/id/ui/image_view.js | 36 ++++++++ test/index.html | 3 + 16 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 dist/img/arrow-icon.png create mode 100644 dist/img/cursor-select-mapillary.png create mode 100644 dist/img/cursor-select-mapillary2x.png create mode 100644 js/id/modes/select_image.js create mode 100644 js/id/svg/sequences.js create mode 100644 js/id/ui/image_view.js diff --git a/css/app.css b/css/app.css index ede9e7eae..432cbee0c 100644 --- a/css/app.css +++ b/css/app.css @@ -340,6 +340,7 @@ a.hide { right: -100%; } + .pane { position:absolute; width:50%; @@ -716,6 +717,52 @@ a:hover .icon.out-link { background-position: -500px -14px;} bottom: 0; } +#mapillaryImage { + position: absolute; + right: 0; + bottom: 30px; + padding: 8px; + background-color: #fff; +} +#mapillaryImage > div { + position: relative; +} + +#mapillaryImage > a { + display: block; + width: 100%; + height: auto; + color: white; + position: relative; +} + +#mapillaryImage .link { + background-color: black; + position: absolute; + bottom: 0; + width: 100%; + height: 20px; + text-align: center; +} + +#mapillaryImage img { + width: 100%; + heigth: auto; + display: block; +} + +#mapillaryImage.hidden { + visibility: hidden; +} + +#mapillaryImage .close { + cursor: pointer; + position: absolute; + right: 0; + top: 0; + background-color: #f2f2f2; +} + .feature-list-pane .inspector-body { top: 120px; } diff --git a/css/map.css b/css/map.css index 8c013fbec..d88b460ae 100644 --- a/css/map.css +++ b/css/map.css @@ -1140,6 +1140,46 @@ text.gpx { fill:#FF26D4; } +/* Mapillary Sequences */ +.sequence { + stroke: red; + stroke-width: 4; + fill: none; + pointer-events: visibleStroke; +} + +g.image.point.hover { + stroke-opacity: 0.3; +} + +g.image.point{ + stroke: orange; + stroke-width: 2; + fill: none; + cursor: pointer; /* Opera */ + cursor: url(img/cursor-select-mapillary.png) 6 1, pointer; /* FF */ +} + +g.image.point path{ + stroke-width: 3; + stroke: orange; + fill: orange; + /*marker-end:url(#mapillary_direction_arrow);*/ +} + +g.image.point circle{ + fill: orange; + fill-opacity: 0.3; +} +g.image.point.selected circle{ + fill: yellow; + fill-opacity: 0.9; +} + +#mapillary_direction_arrow { + fill: orange; +} + /* Modes */ .mode-draw-line .vertex.active, diff --git a/data/core.yaml b/data/core.yaml index 4c9afb483..ecf603004 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -13,13 +13,15 @@ en: description: "Add restaurants, monuments, postal boxes or other points to the map." tail: Click on the map to add a point. browse: - title: Browse description: Pan and zoom the map. draw_area: tail: Click to add nodes to your area. Click the first node to finish the area. draw_line: tail: "Click to add more nodes to the line. Click on other lines to connect to them, and double-click to end the line." + selectImage: + title: Photos + description: "Choose and fix a Mapillary image for mapping. Shortcut: 'm'" operations: add: annotation: @@ -293,6 +295,12 @@ en: drag_drop: "Drag and drop a .gpx file on the page, or click the button to the right to browse" zoom: "Zoom to GPX track" browse: "Browse for a .gpx file" + mapillary: + tooltip: "Mapillary street photos" + title: "Mapillary" + view_on_mapillary: "View this image on Mapillary." + no_image_found: | + No image found on Mapillary. Go and take some! help: title: "Help" help: | diff --git a/dist/img/arrow-icon.png b/dist/img/arrow-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..891492c1b4e72ff6c7baba805f452c2cb8e65eff GIT binary patch literal 1734 zcmV;%208hOP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 zVoOIv0RM-N%)bBt1>s3VK~zY`g_mEfT}2hfe>3|Q+Dl`htx{|2#X^z(H7K=KEk+6y z;vev8n@A$XgclQ{H8q-O8ltwmnh+i|F(HaP_@G3azQ6+sCe{{$ZPA8%3rZSFt7vM) zUfQ!~_RohsXPKH`?a ztUQ7dE-U{!?&o3JzYg#`uW^Q&iuo+%20qH&WFqo29_83&BszCY7GBT#fH!)Th}T*f z#UL(poe%n=*=%-qU*P~@F64e|8_zoFq5^`!XWSuHg5CK4G?Y zpUVqaWhHJgdBnv9HW&;1N*^;@d%@MtW!kjAU)Wf?!%Aqy262H0%qG9q@eE=#ij@zT zP1dezI)dFzgZs@U?=lGe>CxcbW>0w5*~0_91JYkInf%lP-tBO2?Kopmo?0La#&o@jSbi7C(xTO-8c-Yz(h8?xhWcHTgo?-EOY<$IR zGMk+;yK__vecRq@HaR%}-D~oZ5eKz*t4;pRizObDZ#iRfdAm4+ScnG4eB9*0KIk%& z$<5->rv&kbCSSEFkhRHali!)MVOq;>vo^V@1-;$IUl&`2A$x8z`B!sEBH8REd!918 zv2Um%znyoDzcaa8qVN$iPcuUV3<1D~c|1g54BPiKK%he48;scy392Q5z&U;ke5!qZ z(&Q&Qma(wdW_GHGP9*`htY0>}ec-N^Em6G7+T=vvq7yABgG}_S$T2a6qY~@w1E%`Un08LvfxQ3IwkI5pM5Fi8_;9s00 zup}}LoZ=!vv7Wq#9}`#(R0JRs2<@^&8m{94KVcPwF$J*o#YLu&ca2d2GbBRCMDAfJ zFR-}08RxyF3N)PIB7w+xHu6>WnnJYcGJfW50s%LeyMV$duIYlkE)IIrWY6qByNcD0 z+l5HyV6XN$lRL)f(J;Z4%n+b3`Ydk~OC_G+W*+13Eaf~`b3ZS$fJCI`3jR&7X|0OD zd{zN(;WB&HP862ymK)tIAGY?S$UP3b&zFY zAcS%kfQ{Tn;7|*ChP_1Yg@K?U#(mF*5{aP$83cW>q2fN^Acy)L%7@I>ZYVzNC$xT^ z++6bLX_IS8g$*O|QI)TfUu?RL@EH3Ee2e*JLYvS+48xKunvQQQS-dq*02&tZFz`oy z6$o94{(#Az5B6Df$*eN?F|#M_`FdeGoSpiK{hMa9+uE=gh}da1`)P6BtTM61e3k~ge+-@@aTzZGD?@4PLKQpKS zMscgjrc{9So#0ru^^THkt{*g%v)l70_%iTq9_Jho2{gQ)+xQOwS-{hr?V?qd@(|x6 z5LmqIkj{XfwDwTy}} zE^&4)$jHeMfd2w7awFYQLHa%b001R)MObuXVRU6WV{&C-bY%cCFflYOFgPtSGgL7! zIx;yrG&L(QGCD9Y#2PeE0000bbVXQnWMOn=I&E)cX=Zr;M1&07*qoM6N<$f?xzKNdN!< literal 0 HcmV?d00001 diff --git a/dist/img/cursor-select-mapillary.png b/dist/img/cursor-select-mapillary.png new file mode 100644 index 0000000000000000000000000000000000000000..bdfecf6a6c8d7ea4d3e57e0b0da29e4df6b8c660 GIT binary patch literal 751 zcmVZ2wrtsd7Z;bGY;0^hfu@B5F%P+>&Rw-?)qfE9 z^XJe1!-o(5PfSewFCigu320z35X+Kkurf` z%u1}mOziCJyN(<=0y7KjQWythFfT9f51?VZ#2N@v7XtL=Kae3HZ#z0V{#Q~``l+m} z`~!%;v#_vq0o9NcSv+E5VwdmVzYlhpoSfWGpaDieEC|KSKpKRZpct#+EI>&Z`10!2 ztNBZpF72(Zu4Vwb=s!^6URqijA2T!a!hiq%Sp#jt8itIFjK7(fn2!Ga`!^ohK#;*J zSFBi38Wj~K0c3+*!vHeO-quPiIM8nw)Dn;|3IGNXvP@shKpss8qfQ)l>fw6#CM)RJW2r7KtYt13(H?ApCoz{t?xou-ERkL^2l zN<@T(yd>GcSFc{Pyn6kL!_nUU)5_IrBwU;vU%!9>^@xvsHUo{fbK9Nq-I3`(@1boTDud)D-n z3Ld}KD#*MG07sshfE-@kunmXwhARZ(927^D^+I~Y!a3S?$x?uRC9a9YHs4k=;3 hB4{8mZOM_6^#CLjSk#riJ|+MF002ovPDHLkV1i8w@}an?F!2LK<}%IPjLQ~76=SyehYMNe zNcfYX12IDo1fdkr2?E*X2=XOZKnrvrFoDuS-_CjTl?N#lTHgNJNe<_}bMHOp*K_VY z_g+}6|7rOmK!7Pa*TDCFVD9p{u+9=49KGEQX3qk+RVo#cnwm-og+dCb9?Ta5zYol|%#~%caLo}IIa4$-F+pTy zWf2mIgaV4P2{;AV9++{$4MC>W6hOMpMEVC{?zh06Orpfy+Kp=t)4CWkk$xT6xCR`= z6wt50Fd>u47K6_?W}fsjf)Pu}C~gRJY6;;FG%zCo(dbX;05^msgmVoHf*Ha(r^nrD zig-L8SsQI_Z3!-yOK>NxQ?97; z1AuH`skvYL16Z6)PfwrMFs2ncZ4lgtvC&T~1&0oBF4{m_XcKLl1K0xt^Bz8YNT!w+ zz4K_$K!GSRa+JbaNwXDb4j}saevU%~C!^^^*q$4?>U;Mck0zz8CG;~JzMZ(zU%ytx}`F%dKl zUP@zc>>ex`tVfR;9opL3S0o%s3XG3C&>0>U`mDcSZLe0Vxe-x&0-RoP(q6nE`xD1j zR^D?)NhihtN~K$d&{11^JO4=1@$~^4{0B0AOmBU|Py7<~=Tg&r1_xj8D%hOW}mkE7MO|5%J=Tpb##y{jZSKY7XfgrN7uX~r36#nMo z;xg6P)Z~DD>(=^_K(S2`V-eI%>adQnTUy(k_r}I3eSEyh+W5G&)e)Stj~`2XvMESH zMiWwtn}&G%t@X3kAA)2IU`NMO9s-1G+0@1JvM1bm|*u3%iF z;f8J7+D`{YwHX6gR9vzWoj@w_KNBS7-TYOEjhLuN^|Xe?x^Xj~)E!Fr_&KGcOGW@r zO--@xmX(Wy!dFK_w{0Ckhgh)X6_rAFcenANppE3(gLe8+?xkpGa1iQYy2kOwuj4w835g0(uW5tp$+8M0PldP~a6 zMDVzpjE;;Lr0kX6EyuM+?1_moM)0|+cLny3jQqnn`S}^&uBn_;Xr?R@HAUz|Sq zjOs_Z902jm72#zQZz0~^uWOQzCAOvXtM{+cqm0^jEa z9Lvp2&-C~A?}3Z#p{L3&xAAceu~Hxye)=CE&xgzH&>k%JfA&p7vAXt};R TMFUo>00000NkvXXu0mjfgo6Vg literal 0 HcmV?d00001 diff --git a/dist/locales/en.json b/dist/locales/en.json index 78205649d..2342ca3f2 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -24,6 +24,10 @@ }, "draw_line": { "tail": "Click to add more nodes to the line. Click on other lines to connect to them, and double-click to end the line." + }, + "selectImage": { + "title": "Photos", + "description": "Choose and fix a Mapillary image for mapping. Shortcut: 'm'" } }, "operations": { @@ -354,6 +358,12 @@ "zoom": "Zoom to GPX track", "browse": "Browse for a .gpx file" }, + "mapillary": { + "tooltip": "Mapillary street photos", + "title": "Mapillary", + "view_on_mapillary": "View this image on Mapillary.", + "no_image_found": "No image found on Mapillary. Go and take some!\n" + }, "help": { "title": "Help", "help": "# Help\n\nThis is an editor for [OpenStreetMap](http://www.openstreetmap.org/), the\nfree and editable map of the world. You can use it to add and update\ndata in your area, making an open-source and open-data map of the world\nbetter for everyone.\n\nEdits that you make on this map will be visible to everyone who uses\nOpenStreetMap. In order to make an edit, you'll need a\n[free OpenStreetMap account](https://www.openstreetmap.org/user/new).\n\nThe [iD editor](http://ideditor.com/) is a collaborative project with [source\ncode available on GitHub](https://github.com/openstreetmap/iD).\n", diff --git a/index.html b/index.html index 69768a885..f267f5c3b 100644 --- a/index.html +++ b/index.html @@ -66,6 +66,7 @@ + @@ -76,6 +77,7 @@ + @@ -188,6 +190,7 @@ + diff --git a/js/id/id.js b/js/id/id.js index 3d135de22..0fe52e675 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -214,6 +214,13 @@ window.iD = function () { context.zoomIn = map.zoomIn; context.zoomOut = map.zoomOut; + + /* Mapillary image view */ + var imageView = iD.ui.ImageView(context); + context.imageView = function() { + return imageView; + }; + context.surfaceRect = function() { // Work around a bug in Firefox. // http://stackoverflow.com/questions/18153989/ diff --git a/js/id/modes/select_image.js b/js/id/modes/select_image.js new file mode 100644 index 000000000..483ca0d21 --- /dev/null +++ b/js/id/modes/select_image.js @@ -0,0 +1,100 @@ +iD.modes.SelectImage = function (context) { + var mode = { + button: 'selectImage', + id: 'selectImage', + title: t('modes.selectImage.title'), + description: t('modes.selectImage.description'), + key: 'm' + }, imageView, currentImage; + + var behaviors = [ + ]; + + function click() { + var datum = d3.event.target.__data__; + if (isImage(datum)) { + if (currentImage) { + context.surface().selectAll('.key_' + currentImage.properties.key) + .classed('selected', false); + } + if(currentImage === datum) { + context.surface().selectAll('.key_' + currentImage.properties.key) + .classed('selected', false); + currentImage = undefined; + + } else { + currentImage = datum; + context.surface().selectAll('.key_' + currentImage.properties.key) + .classed('selected', true); + } + imageView.show(currentImage); + } + } + + function isImage(datum) { + return datum !== undefined && datum && datum.properties !== undefined && datum.properties.entityType === 'image'; + } + + mode.enter = function () { +// console.log('selectImage.enter'); + context.map().enableSequences(true); + context.container().select('#select_image_checkbox') + .attr('checked','checked'); + behaviors.forEach(function (behavior) { + context.install(behavior); + }); + + // Get focus on the body. + if (document.activeElement && document.activeElement.blur) { + document.activeElement.blur(); + } + + imageView = context.imageView(); + imageView.showEmpty(); + context.surface() + .on('click.image', click); + context.surface() + .on('mouseover.image', function () { + var datum = d3.event.target.__data__; + if (isImage(datum)) { + imageView.show(datum); + } + }) + .on('mouseout.image', function () { + var datum = d3.event.target.__data__; + if (isImage(datum)) { + if(currentImage) { + imageView.show(currentImage); + } else { + imageView.showEmpty(); + } + } + }); + }; + + mode.exit = function () { + context.map().enableSequences(false); + context.container().select('#select_image_checkbox') + .attr('checked',null); + + if(!currentImage) { + context.container() + .select('#mapillaryImage') + .classed('hidden', true); + + } + behaviors.forEach(function (behavior) { + context.uninstall(behavior); + }); + + context.surface().select('defs').selectAll('marker.arrow') + .remove(); + context.surface().select('.layer-hit').selectAll('g.image') + .remove(); + context.surface().select('.layer-hit').selectAll('g.sequence') + .remove(); + + }; + + return mode; +}; diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index d5d3dd9de..3ebc18354 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -18,6 +18,7 @@ iD.Map = function(context) { areas = iD.svg.Areas(projection), midpoints = iD.svg.Midpoints(roundedProjection, context), labels = iD.svg.Labels(projection, context), + sequences = iD.svg.Sequences(projection, context), supersurface, surface, mouse, mousemove; @@ -113,6 +114,7 @@ iD.Map = function(context) { .call(vertices, graph, all, filter, map.extent(), map.zoom()) .call(lines, graph, all, filter) .call(areas, graph, all, filter) + .call(sequences, surface) .call(midpoints, graph, all, filter, map.trimmedExtent()) .call(labels, graph, all, filter, dimensions, !difference && !extent); @@ -400,5 +402,9 @@ iD.Map = function(context) { return map; }; + map.enableSequences = function (enable) { + sequences.enable(enable); + }; + return d3.rebind(map, dispatch, 'on'); }; diff --git a/js/id/svg/sequences.js b/js/id/svg/sequences.js new file mode 100644 index 000000000..fef3a41ff --- /dev/null +++ b/js/id/svg/sequences.js @@ -0,0 +1,109 @@ +iD.svg.Sequences = function (projection, context) { + var surface, enabled = false; + + + function drawSequences(_surface) { + surface = _surface; + + if (enabled) { + drawSequences.reloadMapillaryImages(); + } else { + drawSequences.removeAll(); + } + } + + drawSequences.removeAll = function () { + var hit_layer = surface.select('.layer-hit'); + if (hit_layer) { + hit_layer.selectAll('g.image').remove(); + hit_layer.selectAll('g.sequence').remove(); + } + }; + drawSequences.enable = function (enable) { + enabled = enable; + drawSequences(surface); + }; + + drawSequences.plotSequences = function (surface, context, sequences) { + var imagePoints = drawSequences.images(sequences, 1000); + var images = surface.select('.layer-hit').selectAll('g.image') + .data(imagePoints); + + + var image = images.enter() + .append('g') + .attr('class', function (d) { + return 'image point key_' + d.properties.key; + }) + .attr('transform', function (d) { + var translate = iD.svg.PointTransform(context.projection)({loc: d.geometry.coordinates}); + if (d.properties.ca) { + return translate + 'rotate(' + d.properties.ca + ',0,0)'; + } + return translate; + }) + .on('mouseover', function (d) { + surface.select('.key_' + d.properties.key).classed('hover', true); + }) + .on('mouseout', function (d) { + surface.select('.key_' + d.properties.key).classed('hover', false); + }); + + + image.append('path') + .call(drawSequences.markerPath, 'stroke'); + + image.append('circle') + .attr('dx', '0') + .attr('dy', '0') + .attr('r', '10'); + + // Selecting the following implicitly + // sets the data (point entity) on the element + images.select('.shadow'); + images.select('.stroke'); + + }; + + drawSequences.reloadMapillaryImages = function () { + var extent = context.map().extent(); + d3.json('https://mapillary-read-api.herokuapp.com/v1/s/search?min-lat=' + extent[0][1] + '&max-lat=' + extent[1][1] + '&min-lon=' + extent[0][0] + '&max-lon=' + extent[1][0] + '&max-results=100&geojson=true', function (error, data) { + drawSequences.plotSequences(context.surface(), context, data); + + }); + }; + + drawSequences.images = function (sequences, limit) { + var images = []; + + for (var i = 0; i < sequences.features.length; i++) { + var sequence = sequences.features[i]; + for (var j = 0; j < sequence.geometry.coordinates.length; j++) { + images.push({ + geometry: { + type: 'Point', + coordinates: sequence.geometry.coordinates[j] + }, + properties: { + key: sequence.properties.keys[j], + ca: sequence.properties.cas[j], + entityType: 'image' + } + }); + if (limit && images.length >= limit) break; + } + } + + return images; + }; + + drawSequences.markerPath = function (selection, klass) { + selection + .attr('class', klass) + .attr('transform', 'translate(0, 0)') + .attr('d', 'M 0,-10 l 0,-20 l -5,20 l 10,0 l -5,-20'); + }; + + + return drawSequences; +}; diff --git a/js/id/ui.js b/js/id/ui.js index eacf19f8f..614858cf5 100644 --- a/js/id/ui.js +++ b/js/id/ui.js @@ -31,6 +31,10 @@ iD.ui = function(context) { var m = content.append('div') .attr('id', 'map') .call(map); + content.append('div') + .attr('id', 'mapillaryImage') + .classed('hidden', true) + .call(iD.ui.ImageView(context)); bar.append('div') .attr('class', 'spacer col4'); diff --git a/js/id/ui/background.js b/js/id/ui/background.js index 4b7d8e39b..dd5d2535d 100644 --- a/js/id/ui/background.js +++ b/js/id/ui/background.js @@ -312,6 +312,34 @@ iD.ui.Background = function(context) { label.append('span') .text(t('gpx.local_layer')); + var mapillaryLayerItem = content.append('ul') + .attr('class', 'layer-list') + .append('li') + .classed('layer-toggle-gpx', true); + + var mapillaryLabel = mapillaryLayerItem.append('label') + .call(bootstrap.tooltip() + .title(t('modes.selectImage.description')) + .placement('top')); + + mapillaryLabel.append('input') + .attr('type', 'checkbox') + .attr('id', 'select_image_checkbox') + .on('change', function(){ + if(this.checked) { + context.enter(iD.modes.SelectImage(context)); + } else { + context.enter(iD.modes.Browse(context)); + } + update(); + + }); + + mapillaryLabel.append('span') + .text(t('mapillary.title')); + + + var adjustments = content.append('div') .attr('class', 'adjustments'); @@ -358,6 +386,10 @@ iD.ui.Background = function(context) { var keybinding = d3.keybinding('background'); keybinding.on(key, toggle); + keybinding.on('m', function() { + context.enter(iD.modes.SelectImage(context)); + }); + d3.select(document) .call(keybinding); diff --git a/js/id/ui/image_view.js b/js/id/ui/image_view.js new file mode 100644 index 000000000..36adccd79 --- /dev/null +++ b/js/id/ui/image_view.js @@ -0,0 +1,36 @@ +iD.ui.ImageView = function (context) { + function imageView() { + } + + imageView.showEmpty = function () { + var imageWrapper = context.container().select('#mapillaryImage'); + imageWrapper.html(''); + var content = imageWrapper + .append('div'); + content.append('div') + .on('click', function(){ + imageWrapper.classed('hidden', true); + }); + + content.append('div').html(marked(t('mapillary.no_image_found'))); + }; + + imageView.show = function (imageToShow) { + var key = imageToShow.properties.key; + var imageWrapper = context.container().select('#mapillaryImage'); + imageWrapper.classed('hidden', false); + imageWrapper.html(''); + var content = imageWrapper + .append('div'); + content.append('div') + .attr('class', 'icon close') + .on('click', function(){ + imageWrapper.classed('hidden', true); + }); + content.append('div').html('
View on Mapillary' + .replace(/KEY/g, key)); + + }; + + return imageView; +}; diff --git a/test/index.html b/test/index.html index f389e382b..02acf487d 100644 --- a/test/index.html +++ b/test/index.html @@ -60,6 +60,7 @@ + @@ -71,6 +72,7 @@ + @@ -164,6 +166,7 @@ +