Add a map to the changeset list page
authorMikel Maron <mikel_maron@yahoo.com>
Sat, 30 Apr 2011 20:07:47 +0000 (15:07 -0500)
committerTom Hughes <tom@compton.nu>
Sun, 1 May 2011 21:55:28 +0000 (22:55 +0100)
Add a map to the changeset list page, with a bounding box for each
changeset and highighting when the mouse is placed over either a box
on the map or a row of the table.

app/controllers/changeset_controller.rb
app/views/changeset/_changeset.html.erb
app/views/changeset/_changeset_map_add.html.erb [new file with mode: 0644]
app/views/changeset/_map.html.erb [new file with mode: 0644]
app/views/changeset/list.html.erb
public/javascripts/map.js
public/stylesheets/common.css

index 5a4dc36..0aeaf20 100644 (file)
@@ -312,6 +312,8 @@ class ChangesetController < ApplicationController
       @page = (params[:page] || 1).to_i
       @page_size = 20
 
       @page = (params[:page] || 1).to_i
       @page_size = 20
 
+      @bbox = bbox
+      
       @edits = Changeset.find(:all,
                               :include => [:user, :changeset_tags],
                               :conditions => conditions,
       @edits = Changeset.find(:all,
                               :include => [:user, :changeset_tags],
                               :conditions => conditions,
index 33d8cf1..2ba88b7 100644 (file)
@@ -1,7 +1,7 @@
-<tr>
-  <% cl = cycle('table0', 'table1') %>
+<% cl = cycle('table0', 'table1') %>
+<tr class="<%= cl %>" id="tr-changeset-<%= changeset.id%>" onMouseOver="highlightChangesetMap('changeset-<%= changeset.id %>');this.style.backgroundColor='#ffff55';" onMouseOut="unHighlightChangesetMap('changeset-<%= changeset.id %>');this.style.backgroundColor='';">
 
 
-  <td class="<%= cl %>">
+  <td>
     <%=
       id_link = link_to(changeset.id,
                         {:controller => 'browse', :action => 'changeset', :id => changeset.id},
     <%=
       id_link = link_to(changeset.id,
                         {:controller => 'browse', :action => 'changeset', :id => changeset.id},
     %>
   </td>
 
     %>
   </td>
 
-  <td class="<%= cl %> date">
+  <td class="date">
     <% if changeset.closed_at > DateTime.now %> <%= t'changeset.changeset.still_editing' %>
     <% else %><%= l changeset.closed_at, :format => :long %><% end %>
   </td>
 
     
   <%if showusername %>  
     <% if changeset.closed_at > DateTime.now %> <%= t'changeset.changeset.still_editing' %>
     <% else %><%= l changeset.closed_at, :format => :long %><% end %>
   </td>
 
     
   <%if showusername %>  
-    <td class="<%= cl %> user">
+    <td class="user">
     <% if changeset.user.data_public? %>
       <%= link_to h(changeset.user.display_name), :controller => "changeset", :action => "list", :display_name => changeset.user.display_name %>
     <% else %>
     <% if changeset.user.data_public? %>
       <%= link_to h(changeset.user.display_name), :controller => "changeset", :action => "list", :display_name => changeset.user.display_name %>
     <% else %>
@@ -26,7 +26,7 @@
     </td>
   <% end %>
     
     </td>
   <% end %>
     
-  <td class="<%= cl %> comment">
+  <td class="comment">
     <% if changeset.tags['comment'].to_s != '' %>
       <%= linkify(h(changeset.tags['comment'])) %>
     <% else %>
     <% if changeset.tags['comment'].to_s != '' %>
       <%= linkify(h(changeset.tags['comment'])) %>
     <% else %>
@@ -34,7 +34,7 @@
     <% end %>
   </td>
 
     <% end %>
   </td>
 
-  <td class="<%= cl %> area">
+  <td class="area">
     <% if changeset.min_lat.nil? %>
       <%= t'changeset.changeset.no_edits' %>
     <% else %>
     <% if changeset.min_lat.nil? %>
       <%= t'changeset.changeset.no_edits' %>
     <% else %>
diff --git a/app/views/changeset/_changeset_map_add.html.erb b/app/views/changeset/_changeset_map_add.html.erb
new file mode 100644 (file)
index 0000000..9244081
--- /dev/null
@@ -0,0 +1,8 @@
+        var minlon = <%= changeset_map_add.min_lon / GeoRecord::SCALE.to_f %>;
+        var minlat = <%= changeset_map_add.min_lat / GeoRecord::SCALE.to_f %>;
+        var maxlon = <%= changeset_map_add.max_lon / GeoRecord::SCALE.to_f %>;
+        var maxlat = <%= changeset_map_add.max_lat / GeoRecord::SCALE.to_f %>;
+        var bbox = new OpenLayers.Bounds(minlon, minlat, maxlon, maxlat);
+
+        bounds.extend(bbox);
+        box = addBoxToMap(bbox, {name: "changeset-<%= changeset_map_add.id %>"}, true);
diff --git a/app/views/changeset/_map.html.erb b/app/views/changeset/_map.html.erb
new file mode 100644 (file)
index 0000000..ddfac9f
--- /dev/null
@@ -0,0 +1,74 @@
+<%= javascript_include_tag '/openlayers/OpenLayers.js' %>
+<%= javascript_include_tag '/openlayers/OpenStreetMap.js' %>
+<%= javascript_include_tag 'map.js' %>
+<div id="browse_map_changeset">
+  <div id="small_map">
+  </div>
+  <span id="loading"><%= t 'browse.map.loading' %></span>
+</div>
+<script type="text/javascript">
+  OpenLayers.Lang.setCode("<%= I18n.locale.to_s %>");
+
+  /*
+    This function borrowed from the latest version of OpenLayers.Layer.Vector. OSM is using an older version.
+    http://trac.osgeo.org/openlayers/browser/trunk/openlayers/lib/OpenLayers/Layer/Vector.js
+  */
+  function getFeaturesByAttribute(obj, attrName, attrValue) {
+        var i,
+            feature,    
+            len = obj.features.length,
+            foundFeatures = [];
+        for(i = 0; i < len; i++) {            
+            feature = obj.features[i];
+            if(feature && feature.attributes) {
+                if (feature.attributes[attrName] === attrValue) {
+                    foundFeatures.push(feature);
+                }
+            }
+        }
+        return foundFeatures;
+  }
+  function highlightChangesetMap(name) {
+    getFeaturesByAttribute(vectors,'name',name)[0].style.strokeColor='#ffff55';
+    vectors.redraw(); 
+  } 
+  function unHighlightChangesetMap(name) {
+    getFeaturesByAttribute(vectors,'name',name)[0].style.strokeColor='#ee9900';
+    vectors.redraw(); 
+  }      
+  function init() {
+    var map = createMap("small_map", {
+      controls: [ new OpenLayers.Control.Navigation(), new OpenLayers.Control.PanZoom(), new OpenLayers.Control.PanZoomBar() ]
+    });
+    
+    var bounds = new OpenLayers.Bounds();
+    <%= render :partial => 'changeset_map_add', :collection => @edits unless @edits.nil? %>
+     
+    vectors.events.on({
+      'featureselected': function(feature) {
+         document.getElementById('tr-' + feature.feature.attributes['name']).style.backgroundColor = '#ffff55';
+         feature.feature.style.strokeColor='#ffff00';
+         vectors.redraw();
+       },
+       'featureunselected': function(feature) {
+         document.getElementById('tr-' + feature.feature.attributes['name']).style.backgroundColor = '';
+         feature.feature.style.strokeColor='#ee9900';
+         vectors.redraw();
+       }
+    });
+    var selectControl = new OpenLayers.Control.SelectFeature(vectors,
+      {multiple: false, hover:true});
+    map.addControl(selectControl);
+    selectControl.activate();
+
+    <!-- if bounds were passed, just use those -->
+    <% if ! @bbox.nil? %>
+      bounds = new OpenLayers.Bounds(<%= @bbox %>);
+    <% end %>
+    setMapExtent(bounds);
+
+    $("loading").innerHTML = "";
+  }
+
+  window.onload = init;
+</script>
index 0333be5..4ec450c 100644 (file)
@@ -1,6 +1,7 @@
 <h1><%= @heading %></h1>
 <p><%= @description %></p>
 
 <h1><%= @heading %></h1>
 <p><%= @description %></p>
 
+<%= render :partial => 'map' %>
 <%= render :partial => 'changeset_paging_nav' %>
 <%= render :partial => 'changesets', :locals => { :showusername => !params.has_key?(:display_name) } %>
 <%= render :partial => 'changeset_paging_nav' %>
 <%= render :partial => 'changeset_paging_nav' %>
 <%= render :partial => 'changesets', :locals => { :showusername => !params.has_key?(:display_name) } %>
 <%= render :partial => 'changeset_paging_nav' %>
index 090d4ab..df9d309 100644 (file)
@@ -149,7 +149,7 @@ function addObjectToMap(url, zoom, callback) {
    layer.loadGML();
 }
 
    layer.loadGML();
 }
 
-function addBoxToMap(boxbounds) {
+function addBoxToMap(boxbounds, attributes, line) {
    if (!vectors) {
      // Be aware that IE requires Vector layers be initialised on page load, and not under deferred script conditions
      vectors = new OpenLayers.Layer.Vector("Boxes", {
    if (!vectors) {
      // Be aware that IE requires Vector layers be initialised on page load, and not under deferred script conditions
      vectors = new OpenLayers.Layer.Vector("Boxes", {
@@ -157,8 +157,16 @@ function addBoxToMap(boxbounds) {
      });
      map.addLayer(vectors);
    }
      });
      map.addLayer(vectors);
    }
-   var geometry = boxbounds.toGeometry().transform(epsg4326, map.getProjectionObject());
-   var box = new OpenLayers.Feature.Vector(geometry, {}, {
+
+   var geometry;
+   if (line) {
+     vertices = boxbounds.toGeometry().getVertices();
+     vertices.push( new OpenLayers.Geometry.Point( vertices[0].x, vertices[0].y ) );
+     geometry = new OpenLayers.Geometry.LineString(vertices).transform(epsg4326, map.getProjectionObject());
+   } else {
+     geometry = boxbounds.toGeometry().transform(epsg4326, map.getProjectionObject());
+   }  
+   var box = new OpenLayers.Feature.Vector(geometry, attributes, {
       strokeWidth: 2,
       strokeColor: '#ee9900',
       fillOpacity: 0
       strokeWidth: 2,
       strokeColor: '#ee9900',
       fillOpacity: 0
index 6bc9666..098a9dd 100644 (file)
@@ -633,6 +633,19 @@ hr {
   border: solid 1px black;
 }
 
   border: solid 1px black;
 }
 
+#browse_map_changeset {
+  float: right;
+  width: 100%;
+  text-align: right;
+  margin-left: 10px;
+}
+
+#browse_map_changeset #small_map {
+  width: 100%;
+  height: 315px;
+  border: solid 1px black;
+}
+
 /* Rules for the trace list shown by the traces tab etc */
 
 #trace_list {
 /* Rules for the trace list shown by the traces tab etc */
 
 #trace_list {