1 //= require templates/browse/feature
 
   2 //= require templates/browse/feature_list
 
   3 //= require templates/browse/feature_history
 
   5 $(document).ready(function () {
 
   6   $("#show_data").click(function (e) {
 
   7     $.ajax({ url: $(this).attr('href'), success: function (sidebarHtml) {
 
   8       startBrowse(sidebarHtml);
 
  13   function startBrowse(sidebarHtml) {
 
  15     var browseMode = "auto";
 
  17     var browseFeatureList;
 
  18     var browseActiveFeature;
 
  20     var browseSelectControl;
 
  22     var areasHidden = false;
 
  24     OpenLayers.Feature.Vector.style['default'].strokeWidth = 3;
 
  25     OpenLayers.Feature.Vector.style['default'].cursor = "pointer";
 
  27     map.dataLayer.active = true;
 
  29     $("#sidebar_title").html(I18n.t('browse.start_rjs.data_frame_title'));
 
  30     $("#sidebar_content").html(sidebarHtml);
 
  34     var vectors = new OpenLayers.Layer.Vector();
 
  36     browseBoxControl = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, {
 
  44     browseBoxControl.handler.callbacks.done = endDrag;
 
  45     map.addControl(browseBoxControl);
 
  47     map.events.register("moveend", map, updateData);
 
  48     map.events.triggerEvent("moveend");
 
  50     $("#browse_select_view").click(useMap);
 
  52     $("#browse_select_box").click(startDrag);
 
  54     $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas'));
 
  55     $("#browse_hide_areas_box").show();
 
  56     $("#browse_hide_areas_box").click(hideAreas);
 
  58     function updateData() {
 
  59       if (browseMode == "auto") {
 
  60         if (map.getZoom() >= 15) {
 
  63             setStatus(I18n.t('browse.start_rjs.zoom_or_select'));
 
  68     $("#sidebar").one("closed", function () {
 
  69       if (map.dataLayer.active) {
 
  70         map.dataLayer.active = false;
 
  72         if (browseSelectControl) {
 
  73           browseSelectControl.destroy();
 
  74           browseSelectControl = null;
 
  77         if (browseBoxControl) {
 
  78           browseBoxControl.destroy();
 
  79           browseBoxControl = null;
 
  82         if (browseActiveFeature) {
 
  83           browseActiveFeature.destroy();
 
  84           browseActiveFeature = null;
 
  87         if (browseDataLayer) {
 
  88           browseDataLayer.destroy();
 
  89           browseDataLayer = null;
 
  92         map.dataLayer.setVisibility(false);
 
  93         map.events.unregister("moveend", map, updateData);
 
  97     function startDrag() {
 
  98       $("#browse_select_box").html(I18n.t('browse.start_rjs.drag_a_box'));
 
 100       browseBoxControl.activate();
 
 105     function useMap(reload) {
 
 106       var bounds = map.getExtent();
 
 107       var projected = unproj(bounds);
 
 109       if (!browseBounds || !browseBounds.containsBounds(projected)) {
 
 110         var center = bounds.getCenterLonLat();
 
 111         var tileWidth = bounds.getWidth() * 1.2;
 
 112         var tileHeight = bounds.getHeight() * 1.2;
 
 113         var tileBounds = new OpenLayers.Bounds(center.lon - (tileWidth / 2),
 
 114                                                center.lat - (tileHeight / 2),
 
 115                                                center.lon + (tileWidth / 2),
 
 116                                                center.lat + (tileHeight / 2));
 
 118         browseBounds = tileBounds;
 
 119         getData(tileBounds, reload);
 
 123         $("#browse_select_view").hide();
 
 129     function hideAreas() {
 
 130       $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.show_areas'));
 
 131       $("#browse_hide_areas_box").show();
 
 132       $("#browse_hide_areas_box").click(showAreas);
 
 139     function showAreas() {
 
 140       $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas'));
 
 141       $("#browse_hide_areas_box").show();
 
 142       $("#browse_hide_areas_box").click(hideAreas);
 
 149     function endDrag(bbox) {
 
 150       var bounds = bbox.getBounds();
 
 151       var projected = unproj(bounds);
 
 153       browseBoxControl.deactivate();
 
 154       browseBounds = projected;
 
 157       browseMode = "manual";
 
 159       $("#browse_select_box").html(I18n.t('browse.start_rjs.manually_select'));
 
 160       $("#browse_select_view").show();
 
 163     function displayFeatureWarning(count, limit, callback) {
 
 166       var div = document.createElement("div");
 
 168       var p = document.createElement("p");
 
 169       p.appendChild(document.createTextNode(I18n.t("browse.start_rjs.loaded_an_area_with_num_features", { num_features: count, max_features: limit })));
 
 172       var input = document.createElement("input");
 
 173       input.type = "submit";
 
 174       input.value = I18n.t('browse.start_rjs.load_data');
 
 175       input.onclick = callback;
 
 176       div.appendChild(input);
 
 178       $("#browse_content").html("");
 
 179       $("#browse_content").append(div);
 
 182     function customDataLoader(resp, options) {
 
 183       if (map.dataLayer.active) {
 
 184         var request = resp.priv;
 
 185         var doc = request.responseXML;
 
 187         if (!doc || !doc.documentElement) {
 
 188           doc = request.responseText;
 
 191         resp.features = this.format.read(doc);
 
 193         if (!this.maxFeatures || resp.features.length <= this.maxFeatures) {
 
 194           options.callback.call(options.scope, resp);
 
 196           displayFeatureWarning(resp.features.length, this.maxFeatures, function () {
 
 197             options.callback.call(options.scope, resp);
 
 203     function getData(bounds, reload) {
 
 204       var projected = unproj(bounds);
 
 205       var size = projected.getWidth() * projected.getHeight();
 
 207       if (size > OSM.MAX_REQUEST_AREA) {
 
 208         setStatus(I18n.t("browse.start_rjs.unable_to_load_size", { max_bbox_size: OSM.MAX_REQUEST_AREA, bbox_size: size }));
 
 210         loadData("/api/" + OSM.API_VERSION + "/map?bbox=" + projected.toBBOX(), reload);
 
 214     function loadData(url, reload) {
 
 215       setStatus(I18n.t('browse.start_rjs.loading'));
 
 217       $("#browse_content").empty();
 
 219       var formatOptions = {
 
 221         interestingTagsExclude: ['source','source_ref','source:ref','history','attribution','created_by','tiger:county','tiger:tlid','tiger:upload_uuid']
 
 224       if (areasHidden) formatOptions.areaTags = [];
 
 226       if (!browseDataLayer || reload) {
 
 227         var style = new OpenLayers.Style();
 
 229         style.addRules([new OpenLayers.Rule({
 
 231             Polygon: { fillColor: '#ff0000', strokeColor: '#ff0000' },
 
 232             Line: { fillColor: '#ffff00', strokeColor: '#000000', strokeOpacity: '0.4' },
 
 233             Point: { fillColor: '#00ff00', strokeColor: '#00ff00' }
 
 237         if (browseDataLayer) browseDataLayer.destroyFeatures();
 
 240          * Modern browsers are quite happy showing far more than 100 features in
 
 241          * the data browser, so increase the limit to 2000 by default, but keep
 
 242          * it restricted to 500 for IE8 and 100 for older IEs.
 
 244         var maxFeatures = 2000;
 
 247           if (navigator.appVersion < 8) {
 
 249           } else if (navigator.appVersion < 9) {
 
 254         browseDataLayer = new OpenLayers.Layer.Vector("Data", {
 
 256             new OpenLayers.Strategy.Fixed()
 
 258           protocol: new OpenLayers.Protocol.HTTP({
 
 260             format: new OpenLayers.Format.OSM(formatOptions),
 
 261             maxFeatures: maxFeatures,
 
 262             handleRead: customDataLoader
 
 264           projection: new OpenLayers.Projection("EPSG:4326"),
 
 265           displayInLayerSwitcher: false,
 
 266           styleMap: new OpenLayers.StyleMap({
 
 268             'select': { strokeColor: '#0000ff', strokeWidth: 8 }
 
 271         browseDataLayer.events.register("loadend", browseDataLayer, dataLoaded );
 
 272         map.addLayer(browseDataLayer);
 
 274         browseSelectControl = new OpenLayers.Control.SelectFeature(browseDataLayer, { onSelect: onFeatureSelect });
 
 275         browseSelectControl.handlers.feature.stopDown = false;
 
 276         browseSelectControl.handlers.feature.stopUp = false;
 
 277         map.addControl(browseSelectControl);
 
 278         browseSelectControl.activate();
 
 280         browseDataLayer.destroyFeatures();
 
 281         browseDataLayer.refresh({ url: url });
 
 284       browseActiveFeature = null;
 
 287     function dataLoaded() {
 
 288       if (this.map.dataLayer.active) {
 
 292         for (var i = 0; i < this.features.length; i++) {
 
 293           var feature = this.features[i];
 
 295             typeName: featureTypeName(feature),
 
 296             url: "/browse/" + featureType(feature) + "/" + feature.osm_id,
 
 297             name: featureName(feature),
 
 302         browseObjectList = $(JST["templates/browse/feature_list"]({
 
 304           url: this.protocol.url
 
 311     function viewFeatureLink() {
 
 312       var feature = browseDataLayer.getFeatureById($(this).data("feature-id"));
 
 313       var layer = feature.layer;
 
 315       for (var i = 0; i < layer.selectedFeatures.length; i++) {
 
 316         var f = layer.selectedFeatures[i];
 
 317         layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default"));
 
 320       onFeatureSelect(feature);
 
 322       if (browseMode != "auto") {
 
 323         map.setCenter(feature.geometry.getBounds().getCenterLonLat());
 
 329     function loadObjectList() {
 
 330       $("#browse_content").html(browseObjectList);
 
 331       $("#browse_content").find("a[data-feature-id]").click(viewFeatureLink);
 
 336     function onFeatureSelect(feature) {
 
 337       // Unselect previously selected feature
 
 338       if (browseActiveFeature) {
 
 339         browseActiveFeature.layer.drawFeature(
 
 341           browseActiveFeature.layer.styleMap.createSymbolizer(browseActiveFeature, "default")
 
 345       // Redraw in selected style
 
 346       feature.layer.drawFeature(
 
 347         feature, feature.layer.styleMap.createSymbolizer(feature, "select")
 
 350       // If the current object is the list, don't innerHTML="", since that could clear it.
 
 351       if ($("#browse_content").firstChild == browseObjectList) {
 
 352         $("#browse_content").removeChild(browseObjectList);
 
 354         $("#browse_content").empty();
 
 357       $("#browse_content").html(JST["templates/browse/feature"]({
 
 358         name: featureNameSelect(feature),
 
 359         url: "/browse/" + featureType(feature) + "/" + feature.osm_id,
 
 360         attributes: feature.attributes
 
 363       $("#browse_content").find("a.browse_show_list").click(loadObjectList);
 
 364       $("#browse_content").find("a.browse_show_history").click(loadHistory);
 
 366       // Stash the currently drawn feature
 
 367       browseActiveFeature = feature;
 
 370     function loadHistory() {
 
 371       $(this).attr("href", "").text(I18n.t('browse.start_rjs.wait'));
 
 373       var feature = browseActiveFeature;
 
 376         url: "/api/" + OSM.API_VERSION + "/" + featureType(feature) + "/" + feature.osm_id + "/history",
 
 377         success: function (xml) {
 
 378           if (browseActiveFeature != feature || $("#browse_content").firstChild == browseObjectList) {
 
 385           var nodes = xml.getElementsByTagName(featureType(feature));
 
 386           for (var i = nodes.length - 1; i >= 0; i--) {
 
 388               user: nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user'),
 
 389               timestamp: nodes[i].getAttribute("timestamp")
 
 393           $("#browse_content").append(JST["templates/browse/feature_history"]({
 
 394             name: featureNameHistory(feature),
 
 395             url: "/browse/" + featureType(feature) + "/" + feature.osm_id,
 
 404     function featureType(feature) {
 
 405       if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
 
 412     function featureTypeName(feature) {
 
 413       if (featureType(feature) == "node") {
 
 414         return I18n.t('browse.start_rjs.object_list.type.node');
 
 415       } else if (featureType(feature) == "way") {
 
 416         return I18n.t('browse.start_rjs.object_list.type.way');
 
 420     function featureName(feature) {
 
 421       var lang = $('html').attr('lang');
 
 422       if (feature.attributes['name:' + lang]) {
 
 423         return feature.attributes['name:' + lang];
 
 424       } else if (feature.attributes.name) {
 
 425         return feature.attributes.name;
 
 427         return feature.osm_id;
 
 431     function featureNameSelect(feature) {
 
 432       var lang = $('html').attr('lang');
 
 433       if (feature.attributes['name:' + lang]) {
 
 434         return feature.attributes['name:' + lang];
 
 435       } else if (feature.attributes.name) {
 
 436         return feature.attributes.name;
 
 437       } else if (featureType(feature) == "node") {
 
 438         return I18n.t("browse.start_rjs.object_list.selected.type.node", { id: feature.osm_id });
 
 439       } else if (featureType(feature) == "way") {
 
 440         return I18n.t("browse.start_rjs.object_list.selected.type.way", { id: feature.osm_id });
 
 444     function featureNameHistory(feature) {
 
 445       var lang = $('html').attr('lang');
 
 446       if (feature.attributes['name:' + lang]) {
 
 447         return feature.attributes['name:' + lang];
 
 448       } else if (feature.attributes.name) {
 
 449         return feature.attributes.name;
 
 450       } else if (featureType(feature) == "node") {
 
 451         return I18n.t("browse.start_rjs.object_list.history.type.node", { id: feature.osm_id });
 
 452       } else if (featureType(feature) == "way") {
 
 453         return I18n.t("browse.start_rjs.object_list.history.type.way", { id: feature.osm_id });
 
 457     function setStatus(status) {
 
 458       $("#browse_status").html(status);
 
 459       $("#browse_status").show();
 
 462     function clearStatus() {
 
 463       $("#browse_status").html("");
 
 464       $("#browse_status").hide();