From 8a8a29013ed77dff22e53c5dbeeee8ed7dbc5ec2 Mon Sep 17 00:00:00 2001 From: Ian B Date: Sat, 9 Feb 2013 15:22:02 +0100 Subject: [PATCH 1/3] Search results area Display multiple search results --- css/app.css | 15 ++++++++++++++ js/id/ui/geocoder.js | 47 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/css/app.css b/css/app.css index 99904d953..35f7c3821 100644 --- a/css/app.css +++ b/css/app.css @@ -848,6 +848,21 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;} margin: 4px; } +.geocode-control div { + top: 50px; + width: 340px; + margin: 4px; + padding: 5px; +} +.geocode-control div span { + display: inline-block; + border-bottom: 1px solid #333; +} + +.geocode-control div span:hover { + background-color: #333; +} + /* Geolocator */ .geolocate-control { diff --git a/js/id/ui/geocoder.js b/js/id/ui/geocoder.js index 8883dc934..52fcb1672 100644 --- a/js/id/ui/geocoder.js +++ b/js/id/ui/geocoder.js @@ -8,21 +8,54 @@ iD.ui.geocoder = function() { d3.event.preventDefault(); var searchVal = this.value; d3.json('http://nominatim.openstreetmap.org/search/' + - encodeURIComponent(searchVal) + '?limit=10&format=json', function(err, resp) { + encodeURIComponent(searchVal) + '?limit=10&format=json', function (err, resp) { if (err) return hide(); - hide(); if (!resp.length) { return iD.ui.flash(context.container()) .select('.content') .append('h3') .text('No location found for "' + searchVal + '"'); } - var bounds = resp[0].boundingbox; - map.extent(iD.geo.Extent([parseFloat(bounds[3]), parseFloat(bounds[0])], [parseFloat(bounds[2]), parseFloat(bounds[1])])); - if (map.zoom() > 19) map.zoom(19); + if(resp.length > 1) { + for (var i=0; i < resp.length; i++) { + var displayName, elementType, typeStr, span; + displayName = resp[i].display_name, + elementType = resp[i].type, + typeStr = elementType.charAt(0).toUpperCase() + elementType.slice(1) + ': ', + span = resultsList.append('span').text(typeStr); + if(displayName.length > 80) displayName = displayName.substr(0,80) + '...'; + span.append('a') + .attr('data-min-lon',resp[i].boundingbox[3]) + .attr('data-min-lat',resp[i].boundingbox[0]) + .attr('data-max-lon',resp[i].boundingbox[2]) + .attr('data-max-lat',resp[i].boundingbox[1]) + .text(displayName) + .on('click', clickResult); + } + resultsList.classed('hide',false); + } else { + var bounds = resp[0].boundingbox; + var extent = iD.geo.Extent([parseFloat(bounds[3]), parseFloat(bounds[0])], [parseFloat(bounds[2]), parseFloat(bounds[1])]); + applyBounds(extent); + } }); } + function clickResult() { + var result = d3.select(this); + var extent = iD.geo.Extent( + [parseFloat(result.attr('data-min-lon')), parseFloat(result.attr('data-min-lat'))], + [parseFloat(result.attr('data-max-lon')), parseFloat(result.attr('data-max-lat'))] + ); + applyBounds(extent); + } + + function applyBounds(extent) { + hide(); + map.extent(extent); + if (map.zoom() > 19) map.zoom(19); + } + function clickoutside(selection) { selection .on('click.geocoder-inside', function() { @@ -38,6 +71,7 @@ iD.ui.geocoder = function() { function setVisible(show) { button.classed('active', show); gcForm.classed('hide', !show); + if (!show) resultsList.classed('hide', !show); if (show) inputNode.node().focus(); else inputNode.node().blur(); } @@ -55,6 +89,9 @@ iD.ui.geocoder = function() { .attr({ type: 'text', placeholder: t('geocoder.find_a_place') }) .on('keydown', keydown); + var resultsList = selection.append('div') + .attr('class','content fillD map-overlay hide'); + selection.call(clickoutside); } From 78cdc3aec2a0d186f24bd8e8010f3a7fbf7f9197 Mon Sep 17 00:00:00 2001 From: Alex Barth Date: Sat, 9 Feb 2013 10:52:01 -0500 Subject: [PATCH 2/3] Title for installation instructions --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8cf1daeeb..e185fbb4f 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ * [Read up on Contributing and the code style of iD](CONTRIBUTING.md) * See [open issues in the issue tracker](https://github.com/systemed/iD/issues?state=open) if you're looking for something to do +## Installation + To run the current development version, fork this project and serve it locally. If you have Python handy, just `cd` into the project root directory and run From cc51fdc4beba0ddf3f59f9ea84f0fae96faabf37 Mon Sep 17 00:00:00 2001 From: Ian B Date: Sat, 9 Feb 2013 22:27:19 +0100 Subject: [PATCH 3/3] Refactored geocoder to use data joins --- js/id/ui/geocoder.js | 66 +++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/js/id/ui/geocoder.js b/js/id/ui/geocoder.js index 52fcb1672..22c897653 100644 --- a/js/id/ui/geocoder.js +++ b/js/id/ui/geocoder.js @@ -9,44 +9,40 @@ iD.ui.geocoder = function() { var searchVal = this.value; d3.json('http://nominatim.openstreetmap.org/search/' + encodeURIComponent(searchVal) + '?limit=10&format=json', function (err, resp) { - if (err) return hide(); - if (!resp.length) { - return iD.ui.flash(context.container()) - .select('.content') - .append('h3') - .text('No location found for "' + searchVal + '"'); - } - if(resp.length > 1) { - for (var i=0; i < resp.length; i++) { - var displayName, elementType, typeStr, span; - displayName = resp[i].display_name, - elementType = resp[i].type, - typeStr = elementType.charAt(0).toUpperCase() + elementType.slice(1) + ': ', - span = resultsList.append('span').text(typeStr); - if(displayName.length > 80) displayName = displayName.substr(0,80) + '...'; - span.append('a') - .attr('data-min-lon',resp[i].boundingbox[3]) - .attr('data-min-lat',resp[i].boundingbox[0]) - .attr('data-max-lon',resp[i].boundingbox[2]) - .attr('data-max-lat',resp[i].boundingbox[1]) - .text(displayName) - .on('click', clickResult); + if (err) return hide(); + if (!resp.length) { + return iD.ui.flash(context.container()) + .select('.content') + .append('h3') + .text('No location found for "' + searchVal + '"'); } - resultsList.classed('hide',false); - } else { - var bounds = resp[0].boundingbox; - var extent = iD.geo.Extent([parseFloat(bounds[3]), parseFloat(bounds[0])], [parseFloat(bounds[2]), parseFloat(bounds[1])]); - applyBounds(extent); - } - }); + if(resp.length > 1) { + var spans = resultsList.selectAll('span') + .data(resp, function (d) { return d.place_id; }); + spans.enter() + .append('span') + .text(function(d) { + return d.type.charAt(0).toUpperCase() + d.type.slice(1) + ': '; + }) + .append('a') + .text(function(d) { + if(d.display_name > 80) return d.display_name.substr(0,80) + '...'; + return d.display_name; + }) + .on('click', clickResult); + spans.exit().remove(); + resultsList.classed('hide',false); + } else { + var bounds = resp[0].boundingbox; + var extent = iD.geo.Extent([parseFloat(bounds[3]), parseFloat(bounds[0])], [parseFloat(bounds[2]), parseFloat(bounds[1])]); + applyBounds(extent); + } + }); } - function clickResult() { - var result = d3.select(this); - var extent = iD.geo.Extent( - [parseFloat(result.attr('data-min-lon')), parseFloat(result.attr('data-min-lat'))], - [parseFloat(result.attr('data-max-lon')), parseFloat(result.attr('data-max-lat'))] - ); + function clickResult(data) { + var bounds = data.boundingbox; + var extent = iD.geo.Extent([parseFloat(bounds[3]), parseFloat(bounds[0])], [parseFloat(bounds[2]), parseFloat(bounds[1])]); applyBounds(extent); }