From 078059b76b8304368fd7ddac2dd563470e83472e Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Sat, 8 Mar 2014 17:40:27 +0000 Subject: [PATCH] Initial work on overpass based query API --- app/assets/images/sprite.png | Bin 3222 -> 3439 bytes app/assets/images/sprite.svg | 33 +++- app/assets/javascripts/index.js | 10 +- app/assets/javascripts/index/query.js | 244 ++++++++++++++++++++++++ app/assets/javascripts/leaflet.query.js | 19 ++ app/assets/stylesheets/common.css.scss | 14 +- app/views/browse/query.html.erb | 22 +++ config/i18n-js.yml | 1 + config/locales/en.yml | 14 +- config/routes.rb | 1 + 10 files changed, 346 insertions(+), 12 deletions(-) create mode 100644 app/assets/javascripts/index/query.js create mode 100644 app/assets/javascripts/leaflet.query.js create mode 100644 app/views/browse/query.html.erb diff --git a/app/assets/images/sprite.png b/app/assets/images/sprite.png index e7490c84cbca1a7852d89a3011b3c1f23d541e3f..e3ed0e7f81185d93ae6d75b8aab27d20d521242a 100644 GIT binary patch literal 3439 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 O03NPBE_Ke(U;hJ?BOq!3 diff --git a/app/assets/images/sprite.svg b/app/assets/images/sprite.svg index b61018d13..b50b969e9 100644 --- a/app/assets/images/sprite.svg +++ b/app/assets/images/sprite.svg @@ -13,8 +13,8 @@ height="200" id="svg2" version="1.1" - inkscape:version="0.48.2 r9819" - inkscape:export-filename="/Users/tmcw/src/openstreetmap-website/app/assets/images/sprite.png" + inkscape:version="0.48.4 r9939" + inkscape:export-filename="/home/tom/rails/app/assets/images/sprite.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" sodipodi:docname="sprite.svg"> @@ -27,16 +27,16 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="4" - inkscape:cx="210.42032" - inkscape:cy="175.54808" + inkscape:zoom="16" + inkscape:cx="258.2457" + inkscape:cy="193.60262" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" - inkscape:window-width="1436" - inkscape:window-height="856" - inkscape:window-x="4" - inkscape:window-y="0" + inkscape:window-width="1366" + inkscape:window-height="702" + inkscape:window-x="0" + inkscape:window-y="27" inkscape:window-maximized="1" showguides="true" inkscape:guide-bbox="true" @@ -113,6 +113,10 @@ orientation="1,0" position="260,195" id="guide11761" /> + @@ -265,5 +269,16 @@ inkscape:export-filename="/Users/saman/work_repos/osm-redesign/renders/share-1.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90" /> + ? diff --git a/app/assets/javascripts/index.js b/app/assets/javascripts/index.js index dc3c93277..ddec2bffe 100644 --- a/app/assets/javascripts/index.js +++ b/app/assets/javascripts/index.js @@ -5,6 +5,7 @@ //= require leaflet.key //= require leaflet.note //= require leaflet.share +//= require leaflet.query //= require index/search //= require index/browse //= require index/export @@ -12,6 +13,7 @@ //= require index/history //= require index/note //= require index/new_note +//= require index/query //= require router (function() { @@ -123,6 +125,11 @@ $(document).ready(function () { sidebar: sidebar }).addTo(map); + L.OSM.query({ + position: position, + sidebar: sidebar + }).addTo(map); + L.control.scale() .addTo(map); @@ -294,7 +301,8 @@ $(document).ready(function () { "/node/:id(/history)": OSM.Browse(map, 'node'), "/way/:id(/history)": OSM.Browse(map, 'way'), "/relation/:id(/history)": OSM.Browse(map, 'relation'), - "/changeset/:id": OSM.Browse(map, 'changeset') + "/changeset/:id": OSM.Browse(map, 'changeset'), + "/query": OSM.Query(map) }); if (OSM.preferred_editor == "remote" && document.location.pathname == "/edit") { diff --git a/app/assets/javascripts/index/query.js b/app/assets/javascripts/index/query.js new file mode 100644 index 000000000..8d04efd5f --- /dev/null +++ b/app/assets/javascripts/index/query.js @@ -0,0 +1,244 @@ +OSM.Query = function(map) { + var queryButton = $(".control-query .control-button"), + uninterestingTags = ['source', 'source_ref', 'source:ref', 'history', 'attribution', 'created_by', 'tiger:county', 'tiger:tlid', 'tiger:upload_uuid'], + marker; + + queryButton.on("click", function (e) { + e.preventDefault(); + e.stopPropagation(); + + if (queryButton.hasClass("active")) { + disableQueryMode(); + + OSM.router.route("/"); + } else { + enableQueryMode(); + } + }); + + $("#sidebar_content") + .on("mouseover", ".query-results li", function () { + var geometry = $(this).data("geometry") + if (geometry) map.addLayer(geometry); + $(this).addClass("selected"); + }) + .on("mouseout", ".query-results li", function () { + var geometry = $(this).data("geometry") + if (geometry) map.removeLayer(geometry); + $(this).removeClass("selected"); + }); + + function interestingFeature(feature) { + if (feature.tags) { + for (var key in feature.tags) { + if (uninterestingTags.indexOf(key) < 0) { + return true; + } + } + } + + return false; + } + + function featurePrefix(feature) { + var tags = feature.tags; + var prefix = ""; + + if (tags.boundary === "administrative") { + prefix = I18n.t("geocoder.search_osm_nominatim.admin_levels.level" + tags.admin_level) + } else { + var prefixes = I18n.t("geocoder.search_osm_nominatim.prefix"); + + for (var key in tags) { + var value = tags[key]; + + if (prefixes[key]) { + if (prefixes[key][value]) { + return prefixes[key][value]; + } else { + var first = value.substr(0, 1).toUpperCase(), + rest = value.substr(1).replace(/_/g, " "); + + return first + rest; + } + } + } + } + + if (!prefix) { + prefix = I18n.t("javascripts.query." + feature.type); + } + + return prefix; + } + + function featureName(feature) { + var tags = feature.tags; + + if (tags["name"]) { + return tags["name"]; + } else if (tags["ref"]) { + return tags["ref"]; + } else if (tags["addr:housenumber"] && tags["addr:street"]) { + return tags["addr:housenumber"] + " " + tags["addr:street"]; + } else { + return "#" + feature.id; + } + } + + function featureLink(feature) { + if (feature.type === "area") { + if (feature.id >= 3600000000) { + var id = feature.id - 3600000000; + + return "/browse/relation/" + id; + } else if (feature.id >= 2400000000) { + var id = feature.id - 2400000000; + + return "/browse/way/" + id; + } else { + return "/browse/node/" + feature.id; + } + } else { + return "/browse/" + feature.type + "/" + feature.id; + } + } + + function featureGeometry(feature, nodes) { + var geometry; + + if (feature.type === "node") { + geometry = L.circleMarker([feature.lat, feature.lon]); + } else if (feature.type === "way") { + geometry = L.polyline(feature.nodes.map(function (node) { + return nodes[node]; + })); + } + + return geometry; + } + + function runQuery(query, $section) { + var $ul = $section.find("ul"); + + $ul.empty(); + $section.show(); + + $section.find(".loader").oneTime(1000, "loading", function () { + $(this).show(); + }); + + $.ajax({ + url: "http://overpass-api.de/api/interpreter", + method: "GET", + data: { + data: "[timeout:5][out:json];" + query, + }, + success: function(results) { + var nodes = {}; + + $section.find(".loader").stopTime("loading").hide(); + + results.elements.forEach(function (element) { + if (element.type === "node") { + nodes[element.id] = [element.lat, element.lon]; + } + }); + + for (var i = 0; i < results.elements.length; i++) { + var element = results.elements[i]; + + if (interestingFeature(element)) { + var $li = $("
  • ") + .data("geometry", featureGeometry(element, nodes)) + .appendTo($ul); + var $p = $("

    ") + .addClass("inner12 search_results_entry clearfix") + .text(featurePrefix(element) + " ") + .appendTo($li); + + $("") + .attr("href", featureLink(element)) + .text(featureName(element)) + .appendTo($p); + } + } + } + }); + } + + function queryOverpass(lat, lng) { + var latlng = L.latLng(lat, lng), + around = "around:10.0," + lat + "," + lng, + features = "(node(" + around + ");way(" + around + ");relation(" + around + "))", + nearby = "((" + features + ";way(bn));node(w));out;", + isin = "(is_in(" + lat + "," + lng + ");>);out;"; + + $("#sidebar_content .query-intro") + .hide(); + + if (marker) { + marker.setLatLng(latlng).addTo(map); + } else { + marker = L.circle(latlng, 10, { clickable: false }).addTo(map); + } + + $(document).everyTime(75, "fadeQueryMarker", function (i) { + if (i == 10) { + map.removeLayer(marker); + } else { + marker.setStyle({ + opacity: 0.5 - i * 0.05, + fillOpacity: 0.2 - i * 0.02 + }); + } + }, 10); + + runQuery(nearby, $("#query-nearby")); + runQuery(isin, $("#query-isin")); + } + + function clickHandler(e) { + var precision = OSM.zoomPrecision(map.getZoom()), + lat = e.latlng.lat.toFixed(precision), + lng = e.latlng.lng.toFixed(precision); + + OSM.router.route("/query?lat=" + lat + "&lon=" + lng); + } + + function enableQueryMode() { + queryButton.addClass("active"); + map.on("click", clickHandler); + $(map.getContainer()).addClass("query-active"); + } + + function disableQueryMode() { + if (marker) map.removeLayer(marker); + $(map.getContainer()).removeClass("query-active"); + map.off("click", clickHandler); + queryButton.removeClass("active"); + } + + var page = {}; + + page.pushstate = page.popstate = function(path) { + OSM.loadSidebarContent(path, function () { + page.load(path); + }); + }; + + page.load = function(path) { + var params = querystring.parse(path.substring(path.indexOf('?') + 1)); + + queryOverpass(params.lat, params.lon); + enableQueryMode(); + + return map.getState(); + }; + + page.unload = function() { + disableQueryMode(); + }; + + return page; +}; diff --git a/app/assets/javascripts/leaflet.query.js b/app/assets/javascripts/leaflet.query.js new file mode 100644 index 000000000..3eab9054d --- /dev/null +++ b/app/assets/javascripts/leaflet.query.js @@ -0,0 +1,19 @@ +L.OSM.query = function (options) { + var control = L.control(options); + + control.onAdd = function (map) { + var $container = $('

    ') + .attr('class', 'control-query'); + + var link = $('') + .attr('class', 'control-button') + .attr('href', '#') + .attr('data-original-title', I18n.t('javascripts.site.queryfeature_tooltip')) + .html('') + .appendTo($container); + + return $container[0]; + }; + + return control; +}; diff --git a/app/assets/stylesheets/common.css.scss b/app/assets/stylesheets/common.css.scss index 533e91c69..c088e9429 100644 --- a/app/assets/stylesheets/common.css.scss +++ b/app/assets/stylesheets/common.css.scss @@ -171,7 +171,7 @@ small, aside { .icon.close:hover { background-position: -200px -20px; } .icon.check { background-position: -220px 0; } .icon.note { background-position: -240px 0; } -.icon.gear { background-position: -260px 0; } +.icon.query { background-position: -260px 0; } /* Rules for links */ @@ -683,6 +683,10 @@ nav.secondary { #map { height: 100%; overflow: hidden; + + &.query-active { + cursor: help; + } } #map-ui { @@ -1119,6 +1123,14 @@ header .search_form { overflow: hidden; margin: 0 0 10px 10px; } + + .query-results { + display: none; + + ul.results-list li.selected { + background: #FFFFE6; + } + } } /* Rules for export sidebar */ diff --git a/app/views/browse/query.html.erb b/app/views/browse/query.html.erb new file mode 100644 index 000000000..62ab94efd --- /dev/null +++ b/app/views/browse/query.html.erb @@ -0,0 +1,22 @@ +<% set_title(t "browse.query.title") %> + +

    + + <%= t "browse.query.title" %> +

    + +
    +

    <%= t("browse.query.introduction") %>

    +
    + +
    +

    <%= t("browse.query.nearby") %>

    + <%= image_tag "searching.gif", :class => "loader" %> +
      +
      + +
      +

      <%= t("browse.query.enclosing") %>

      + <%= image_tag "searching.gif", :class => "loader" %> +
        +
        diff --git a/config/i18n-js.yml b/config/i18n-js.yml index 026ece64c..369fa340a 100644 --- a/config/i18n-js.yml +++ b/config/i18n-js.yml @@ -31,3 +31,4 @@ translations: - "*.site.sidebar.search_results" - "*.diary_entry.edit.marker_text" - "*.layouts.project_name.title" + - "*.geocoder.search_osm_nominatim.*" diff --git a/config/locales/en.yml b/config/locales/en.yml index 94537c1fb..4db668b38 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -197,6 +197,11 @@ en: reopened_by: "Reactivated by %{user} %{when} ago" reopened_by_anonymous: "Reactivated by anonymous %{when} ago" hidden_by: "Hidden by %{user} %{when} ago" + query: + title: "Query Features" + introduction: "Click on the map to find nearby features." + nearby: "Nearby features" + enclosing: "Enclosing features" changeset: changeset_paging_nav: showing_page: "Page %{page}" @@ -507,7 +512,7 @@ en: primary_link: "Primary Road" proposed: "Proposed Road" raceway: "Raceway" - residential: "Residential" + residential: "Residential Road" rest_area: "Rest Area" road: "Road" secondary: "Secondary Road" @@ -718,6 +723,8 @@ en: tram: "Tramway" tram_stop: "Tram Stop" yard: "Railway Yard" + route: + bus: "Bus Route" shop: alcohol: "Off License" antiques: "Antiques" @@ -2101,6 +2108,7 @@ en: createnote_disabled_tooltip: Zoom in to add a note to the map map_notes_zoom_in_tooltip: Zoom in to see map notes map_data_zoom_in_tooltip: Zoom in to see map data + queryfeature_tooltip: Query features notes: new: intro: "Spotted a mistake or something missing? Let other mappers know so we can fix it. Move the marker to the correct position and type a note to explain the problem. (Please don't enter personal information here.)" @@ -2113,6 +2121,10 @@ en: comment_and_resolve: Comment & Resolve comment: Comment edit_help: Move the map and zoom in on a location you want to edit, then click here. + query: + node: Node + way: Way + relation: Relation redaction: edit: description: "Description" diff --git a/config/routes.rb b/config/routes.rb index e9f593d92..e03c5d632 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -150,6 +150,7 @@ OpenStreetMap::Application.routes.draw do match '/offline' => 'site#offline', :via => :get match '/key' => 'site#key', :via => :get match '/id' => 'site#id', :via => :get + match '/query' => 'browse#query', :via => :get match '/user/new' => 'user#new', :via => :get match '/user/new' => 'user#create', :via => :post match '/user/terms' => 'user#terms', :via => :get -- 2.43.2