X-Git-Url: https://git.openstreetmap.org/rails.git/blobdiff_plain/87e8cf3b5860509c0344cb34ee939ae73ea99c00..04fbc71a40ba73f9d9ba7253fc076b54c3d7ec84:/app/assets/javascripts/index/browse.js diff --git a/app/assets/javascripts/index/browse.js b/app/assets/javascripts/index/browse.js index 769cc112e..a9bdbf2b7 100644 --- a/app/assets/javascripts/index/browse.js +++ b/app/assets/javascripts/index/browse.js @@ -1,151 +1,128 @@ -function startBrowse(sidebarHtml) { - var browseBoxControl; - var browseMode = "auto"; +//= require templates/browse/feature +//= require templates/browse/feature_list +//= require templates/browse/feature_history + +function initializeBrowse(map, params) { var browseBounds; - var browseFeatureList; - var browseActiveFeature; - var browseDataLayer; - var browseSelectControl; + var layersById; + var selectedLayer; var browseObjectList; var areasHidden = false; - - OpenLayers.Feature.Vector.style['default'].strokeWidth = 3; - OpenLayers.Feature.Vector.style['default'].cursor = "pointer"; - - map.dataLayer.active = true; - - $("#sidebar_title").html(I18n.t('browse.start_rjs.data_frame_title')); - $("#sidebar_content").html(sidebarHtml); - - openSidebar(); - - var vectors = new OpenLayers.Layer.Vector(); - - browseBoxControl = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, { - handlerOptions: { - sides: 4, - snapAngle: 90, - irregular: true, - persist: true + var locationFilter; + + var dataLayer = map.dataLayer; + + dataLayer.setStyle({ + way: { + weight: 3, + color: "#000000", + opacity: 0.4 + }, + area: { + weight: 3, + color: "#ff0000" + }, + node: { + color: "#00ff00" } }); - browseBoxControl.handler.callbacks.done = endDrag; - map.addControl(browseBoxControl); - - map.events.register("moveend", map, updateData); - map.events.triggerEvent("moveend"); - $("#browse_select_view").click(useMap); + dataLayer.isWayArea = function () { + return !areasHidden && L.OSM.DataLayer.prototype.isWayArea.apply(this, arguments); + }; - $("#browse_select_box").click(startDrag); - - $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas')); - $("#browse_hide_areas_box").show(); - $("#browse_hide_areas_box").click(hideAreas); + dataLayer.on("click", function (e) { + onSelect(e.layer); + }); - function updateData() { - if (browseMode == "auto") { - if (map.getZoom() >= 15) { - useMap(false); - } else { - setStatus(I18n.t('browse.start_rjs.zoom_or_select')); - } + map.on('layeradd', function (e) { + if (e.layer === dataLayer) { + $.ajax({ url: "/browse/start", success: function (sidebarHtml) { + startBrowse(sidebarHtml); + }}); } - } - - $("#sidebar").one("closed", function () { - if (map.dataLayer.active) { - map.dataLayer.active = false; - - if (browseSelectControl) { - browseSelectControl.destroy(); - browseSelectControl = null; - } - - if (browseBoxControl) { - browseBoxControl.destroy(); - browseBoxControl = null; - } - - if (browseActiveFeature) { - browseActiveFeature.destroy(); - browseActiveFeature = null; - } - - if (browseDataLayer) { - browseDataLayer.destroy(); - browseDataLayer = null; - } + }); - map.dataLayer.setVisibility(false); - map.events.unregister("moveend", map, updateData); + map.on('layerremove', function (e) { + if (e.layer === dataLayer) { + closeSidebar(); } }); - function startDrag() { - $("#browse_select_box").html(I18n.t('browse.start_rjs.drag_a_box')); - - browseBoxControl.activate(); - - return false; + if (OSM.STATUS != 'api_offline' && OSM.STATUS != 'database_offline') { + if (params.layers.indexOf(dataLayer.options.code) >= 0) { + map.addLayer(dataLayer); + } } - function useMap(reload) { - var bounds = map.getExtent(); - var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326); + function startBrowse(sidebarHtml) { + locationFilter = new L.LocationFilter({ + enableButton: false, + adjustButton: false + }).addTo(map); - if (!browseBounds || !browseBounds.containsBounds(projected)) { - var center = bounds.getCenterLonLat(); - var tileWidth = bounds.getWidth() * 1.2; - var tileHeight = bounds.getHeight() * 1.2; - var tileBounds = new OpenLayers.Bounds(center.lon - (tileWidth / 2), - center.lat - (tileHeight / 2), - center.lon + (tileWidth / 2), - center.lat + (tileHeight / 2)); + locationFilter.on("change", getData); - browseBounds = tileBounds; - getData(tileBounds, reload); + $("#sidebar_title").html(I18n.t('browse.start_rjs.data_frame_title')); + $("#sidebar_content").html(sidebarHtml); - browseMode = "auto"; + openSidebar(); - $("#browse_select_view").hide(); - } + if (browseObjectList) loadObjectList(); - return false; - } + map.on("moveend", updateData); + updateData(); - function hideAreas() { - $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.show_areas')); - $("#browse_hide_areas_box").show(); - $("#browse_hide_areas_box").click(showAreas); - - areasHidden = true; - - useMap(true); - } + $("#browse_filter_toggle").click(toggleFilter); - function showAreas() { $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas')); - $("#browse_hide_areas_box").show(); - $("#browse_hide_areas_box").click(hideAreas); + $("#browse_hide_areas_box").click(toggleAreas); - areasHidden = false; + $("#sidebar").one("closed", function () { + map.removeLayer(dataLayer); + map.removeLayer(locationFilter); + map.off("moveend", updateData); + locationFilter.off("change", getData); + }); + } - useMap(true); + function updateData() { + if (!locationFilter.isEnabled()) { + if (map.getZoom() >= 15) { + var bounds = map.getBounds(); + if (!browseBounds || !browseBounds.contains(bounds)) { + browseBounds = bounds; + getData(); + } + } else { + setStatus(I18n.t('browse.start_rjs.zoom_or_select')); + } + } } - function endDrag(bbox) { - var bounds = bbox.getBounds(); - var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326); + function toggleFilter() { + if (locationFilter.isEnabled()) { + $("#browse_filter_toggle").html(I18n.t('browse.start_rjs.manually_select')); + locationFilter.disable(); + } else { + $("#browse_filter_toggle").html(I18n.t('browse.start_rjs.view_data')); + locationFilter.setBounds(map.getBounds().pad(-0.2)); + locationFilter.enable(); + } - browseBoxControl.deactivate(); - browseBounds = projected; - getData(bounds); + getData(); + } - browseMode = "manual"; + function toggleAreas() { + if (areasHidden) { + $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas')); + areasHidden = false; + } else { + $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.show_areas')); + areasHidden = true; + } - $("#browse_select_box").html(I18n.t('browse.start_rjs.manually_select')); - $("#browse_select_view").show(); + getData(); } function displayFeatureWarning(count, limit, callback) { @@ -167,193 +144,111 @@ function startBrowse(sidebarHtml) { $("#browse_content").append(div); } - function customDataLoader(resp, options) { - if (map.dataLayer.active) { - var request = resp.priv; - var doc = request.responseXML; - - if (!doc || !doc.documentElement) { - doc = request.responseText; - } - - resp.features = this.format.read(doc); - - if (!this.maxFeatures || resp.features.length <= this.maxFeatures) { - options.callback.call(options.scope, resp); - } else { - displayFeatureWarning(resp.features.length, this.maxFeatures, function () { - options.callback.call(options.scope, resp); - }); - } - } - } + var dataLoader; - function getData(bounds, reload) { - var projected = bounds.clone().transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326")); - var size = projected.getWidth() * projected.getHeight(); + function getData() { + var bounds = locationFilter.isEnabled() ? locationFilter.getBounds() : map.getBounds(); + var size = bounds.getSize(); if (size > OSM.MAX_REQUEST_AREA) { setStatus(I18n.t("browse.start_rjs.unable_to_load_size", { max_bbox_size: OSM.MAX_REQUEST_AREA, bbox_size: size })); - } else { - loadData("/api/" + OSM.API_VERSION + "/map?bbox=" + projected.toBBOX(), reload); + return; } - } - function loadData(url, reload) { setStatus(I18n.t('browse.start_rjs.loading')); - $("#browse_content").empty(); + var url = "/api/" + OSM.API_VERSION + "/map?bbox=" + bounds.toBBoxString(); - var formatOptions = { - checkTags: true, - interestingTagsExclude: ['source','source_ref','source:ref','history','attribution','created_by','tiger:county','tiger:tlid','tiger:upload_uuid'] - }; + /* + * Modern browsers are quite happy showing far more than 100 features in + * the data browser, so increase the limit to 2000 by default, but keep + * it restricted to 500 for IE8 and 100 for older IEs. + */ + var maxFeatures = 2000; - if (areasHidden) formatOptions.areaTags = []; + /*@cc_on + if (navigator.appVersion < 8) { + maxFeatures = 100; + } else if (navigator.appVersion < 9) { + maxFeatures = 500; + } + @*/ - if (!browseDataLayer || reload) { - var style = new OpenLayers.Style(); + if (dataLoader) dataLoader.abort(); - style.addRules([new OpenLayers.Rule({ - symbolizer: { - Polygon: { fillColor: '#ff0000', strokeColor: '#ff0000' }, - Line: { fillColor: '#ffff00', strokeColor: '#000000', strokeOpacity: '0.4' }, - Point: { fillColor: '#00ff00', strokeColor: '#00ff00' } - } - })]); - - if (browseDataLayer) browseDataLayer.destroyFeatures(); - - /* - * Modern browsers are quite happy showing far more than 100 features in - * the data browser, so increase the limit to 2000 by default, but keep - * it restricted to 500 for IE8 and 100 for older IEs. - */ - var maxFeatures = 2000; - - /*@cc_on - if (navigator.appVersion < 8) { - maxFeatures = 100; - } else if (navigator.appVersion < 9) { - maxFeatures = 500; - } - @*/ - - browseDataLayer = new OpenLayers.Layer.Vector("Data", { - strategies: [ - new OpenLayers.Strategy.Fixed() - ], - protocol: new OpenLayers.Protocol.HTTP({ - url: url, - format: new OpenLayers.Format.OSM(formatOptions), - maxFeatures: maxFeatures, - handleRead: customDataLoader - }), - projection: new OpenLayers.Projection("EPSG:4326"), - displayInLayerSwitcher: false, - styleMap: new OpenLayers.StyleMap({ - 'default': style, - 'select': { strokeColor: '#0000ff', strokeWidth: 8 } - }) - }); - browseDataLayer.events.register("loadend", browseDataLayer, dataLoaded ); - map.addLayer(browseDataLayer); - - browseSelectControl = new OpenLayers.Control.SelectFeature(browseDataLayer, { onSelect: onFeatureSelect }); - browseSelectControl.handlers.feature.stopDown = false; - browseSelectControl.handlers.feature.stopUp = false; - map.addControl(browseSelectControl); - browseSelectControl.activate(); - } else { - browseDataLayer.destroyFeatures(); - browseDataLayer.refresh({ url: url }); - } + dataLoader = $.ajax({ + url: url, + success: function (xml) { + clearStatus(); - browseActiveFeature = null; - } + $("#browse_content").empty(); + dataLayer.clearLayers(); + selectedLayer = null; - function dataLoaded() { - if (this.map.dataLayer.active) { - clearStatus(); + var features = dataLayer.buildFeatures(xml); - browseObjectList = document.createElement("div"); + function addFeatures() { + dataLayer.addData(features); - var heading = document.createElement("p"); - heading.className = "browse_heading"; - heading.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.heading'))); - browseObjectList.appendChild(heading); + layersById = {}; - var list = document.createElement("ul"); + dataLayer.eachLayer(function (layer) { + var feature = layer.feature; + layersById[feature.id] = layer; + $.extend(feature, { + typeName: featureTypeName(feature), + url: "/browse/" + feature.type + "/" + feature.id, + name: featureName(feature) + }); + }); - for (var i = 0; i < this.features.length; i++) { - var feature = this.features[i]; + browseObjectList = $(JST["templates/browse/feature_list"]({ + features: features, + url: url + }))[0]; - // Type, for linking - var type = featureType(feature); - var typeName = featureTypeName(feature); - var li = document.createElement("li"); - li.appendChild(document.createTextNode(typeName + " ")); + loadObjectList(); + } - // Link, for viewing in the tab - var link = document.createElement("a"); - link.href = "/browse/" + type + "/" + feature.osm_id; - var name = featureName(feature); - link.appendChild(document.createTextNode(name)); - link.feature = feature; - link.onclick = OpenLayers.Function.bind(viewFeatureLink, link); - li.appendChild(link); + if (features.length < maxFeatures) { + addFeatures(); + } else { + displayFeatureWarning(features.length, maxFeatures, addFeatures); + } - list.appendChild(li); + dataLoader = null; } - - browseObjectList.appendChild(list); - - var link = document.createElement("a"); - link.href = this.protocol.url; - link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.api'))); - browseObjectList.appendChild(link); - - $("#browse_content").html(browseObjectList); - } + }); } function viewFeatureLink() { - var layer = this.feature.layer; - - for (var i = 0; i < layer.selectedFeatures.length; i++) { - var f = layer.selectedFeatures[i]; - layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default")); - } + var layer = layersById[$(this).data("feature-id")]; - onFeatureSelect(this.feature); + onSelect(layer); - if (browseMode != "auto") { - map.setCenter(this.feature.geometry.getBounds().getCenterLonLat()); + if (locationFilter.isEnabled()) { + map.panTo(layer.getBounds().getCenter()); } return false; } function loadObjectList() { - $("#browse_content").empty(); - $("#browse_content").append(browseObjectList); + $("#browse_content").html(browseObjectList); + $("#browse_content").find("a[data-feature-id]").click(viewFeatureLink); return false; } - function onFeatureSelect(feature) { + function onSelect(layer) { // Unselect previously selected feature - if (browseActiveFeature) { - browseActiveFeature.layer.drawFeature( - browseActiveFeature, - browseActiveFeature.layer.styleMap.createSymbolizer(browseActiveFeature, "default") - ); + if (selectedLayer) { + selectedLayer.setStyle(selectedLayer.originalStyle); } // Redraw in selected style - feature.layer.drawFeature( - feature, feature.layer.styleMap.createSymbolizer(feature, "select") - ); + layer.originalStyle = layer.options; + layer.setStyle({color: '#0000ff', weight: 8}); // If the current object is the list, don't innerHTML="", since that could clear it. if ($("#browse_content").firstChild == browseObjectList) { @@ -362,179 +257,75 @@ function startBrowse(sidebarHtml) { $("#browse_content").empty(); } - // Create a link back to the object list - var div = document.createElement("div"); - div.style.textAlign = "center"; - div.style.marginBottom = "20px"; - $("#browse_content").append(div); - var link = document.createElement("a"); - link.href = "#"; - link.onclick = loadObjectList; - link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.back'))); - div.appendChild(link); - - var table = document.createElement("table"); - table.width = "100%"; - table.className = "browse_heading"; - $("#browse_content").append(table); - - var tr = document.createElement("tr"); - table.appendChild(tr); - - var heading = document.createElement("td"); - heading.appendChild(document.createTextNode(featureNameSelect(feature))); - tr.appendChild(heading); - - var td = document.createElement("td"); - td.align = "right"; - tr.appendChild(td); - - var type = featureType(feature); - var link = document.createElement("a"); - link.href = "/browse/" + type + "/" + feature.osm_id; - link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.details'))); - td.appendChild(link); - - var div = document.createElement("div"); - div.className = "browse_details"; - - $("#browse_content").append(div); - - // Now the list of attributes - var ul = document.createElement("ul"); - for (var key in feature.attributes) { - var li = document.createElement("li"); - var b = document.createElement("b"); - b.appendChild(document.createTextNode(key)); - li.appendChild(b); - li.appendChild(document.createTextNode(": " + feature.attributes[key])); - ul.appendChild(li); - } - - div.appendChild(ul); + var feature = layer.feature; - var link = document.createElement("a"); - link.href = "/browse/" + type + "/" + feature.osm_id + "/history"; - link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.show_history'))); - link.onclick = OpenLayers.Function.bind(loadHistory, { - type: type, feature: feature, link: link - }); + $("#browse_content").html(JST["templates/browse/feature"]({ + name: featureNameSelect(feature), + url: "/browse/" + feature.type + "/" + feature.id, + attributes: feature.tags + })); - div.appendChild(link); + $("#browse_content").find("a.browse_show_list").click(loadObjectList); + $("#browse_content").find("a.browse_show_history").click(loadHistory); // Stash the currently drawn feature - browseActiveFeature = feature; + selectedLayer = layer; } function loadHistory() { - this.link.href = ""; - this.link.innerHTML = I18n.t('browse.start_rjs.wait'); - - $.ajax("/api/" + OSM.API_VERSION + "/" + this.type + "/" + this.feature.osm_id + "/history", { - complete: OpenLayers.Function.bind(displayHistory, this) - }); - - return false; - } - - function displayHistory(request) { - if (browseActiveFeature.osm_id != this.feature.osm_id || $("#browse_content").firstChild == browseObjectList) { - return false; - } - - this.link.parentNode.removeChild(this.link); - - var doc = request.responseXML; - - var table = document.createElement("table"); - table.width = "100%"; - table.className = "browse_heading"; - $("#browse_content").append(table); + $(this).attr("href", "").text(I18n.t('browse.start_rjs.wait')); - var tr = document.createElement("tr"); - table.appendChild(tr); + var feature = selectedLayer.feature; - var heading = document.createElement("td"); - heading.appendChild(document.createTextNode(I18n.t("browse.start_rjs.history_for_feature", { feature: featureNameHistory(this.feature) }))); - tr.appendChild(heading); - - var td = document.createElement("td"); - td.align = "right"; - tr.appendChild(td); + $.ajax({ + url: "/api/" + OSM.API_VERSION + "/" + feature.type + "/" + feature.id + "/history", + success: function (xml) { + if (selectedLayer.feature != feature || $("#browse_content").firstChild == browseObjectList) { + return; + } - var link = document.createElement("a"); - link.href = "/browse/" + this.type + "/" + this.feature.osm_id + "/history"; - link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.details'))); - td.appendChild(link); + $(this).remove(); - var div = document.createElement("div"); - div.className = "browse_details"; - - var nodes = doc.getElementsByTagName(this.type); - var history = document.createElement("ul"); - for (var i = nodes.length - 1; i >= 0; i--) { - var user = nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user'); - var timestamp = nodes[i].getAttribute("timestamp"); - var item = document.createElement("li"); - item.appendChild(document.createTextNode(I18n.t("browse.start_rjs.edited_by_user_at_timestamp", { user: user, timestamp: timestamp }))); - history.appendChild(item); - } - div.appendChild(history); + var history = []; + var nodes = xml.getElementsByTagName(feature.type); + for (var i = nodes.length - 1; i >= 0; i--) { + history.push({ + user: nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user'), + timestamp: nodes[i].getAttribute("timestamp") + }); + } - $("#browse_content").append(div); - } + $("#browse_content").append(JST["templates/browse/feature_history"]({ + name: featureNameHistory(feature), + url: "/browse/" + feature.type + "/" + feature.id, + history: history + })); + }.bind(this) + }); - function featureType(feature) { - if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") { - return "node"; - } else { - return "way"; - } + return false; } function featureTypeName(feature) { - if (featureType(feature) == "node") { - return I18n.t('browse.start_rjs.object_list.type.node'); - } else if (featureType(feature) == "way") { - return I18n.t('browse.start_rjs.object_list.type.way'); - } + return I18n.t('browse.start_rjs.object_list.type.' + feature.type); } function featureName(feature) { - var lang = $('html').attr('lang'); - if (feature.attributes['name:' + lang]) { - return feature.attributes['name:' + lang]; - } else if (feature.attributes.name) { - return feature.attributes.name; - } else { - return feature.osm_id; - } + return feature.tags['name:' + $('html').attr('lang')] || + feature.tags.name || + feature.id; } function featureNameSelect(feature) { - var lang = $('html').attr('lang'); - if (feature.attributes['name:' + lang]) { - return feature.attributes['name:' + lang]; - } else if (feature.attributes.name) { - return feature.attributes.name; - } else if (featureType(feature) == "node") { - return I18n.t("browse.start_rjs.object_list.selected.type.node", { id: feature.osm_id }); - } else if (featureType(feature) == "way") { - return I18n.t("browse.start_rjs.object_list.selected.type.way", { id: feature.osm_id }); - } + return feature.tags['name:' + $('html').attr('lang')] || + feature.tags.name || + I18n.t("browse.start_rjs.object_list.selected.type." + feature.type, { id: feature.id }); } function featureNameHistory(feature) { - var lang = $('html').attr('lang'); - if (feature.attributes['name:' + lang]) { - return feature.attributes['name:' + lang]; - } else if (feature.attributes.name) { - return feature.attributes.name; - } else if (featureType(feature) == "node") { - return I18n.t("browse.start_rjs.object_list.history.type.node", { id: feature.osm_id }); - } else if (featureType(feature) == "way") { - return I18n.t("browse.start_rjs.object_list.history.type.way", { id: feature.osm_id }); - } + return feature.tags['name:' + $('html').attr('lang')] || + feature.tags.name || + I18n.t("browse.start_rjs.object_list.history.type." + feature.type, { id: feature.id }); } function setStatus(status) {