Factor out javascript code to support OpenLayers maps into a common file
authorTom Hughes <tom@compton.nu>
Sat, 23 Jun 2007 18:29:01 +0000 (18:29 +0000)
committerTom Hughes <tom@compton.nu>
Sat, 23 Jun 2007 18:29:01 +0000 (18:29 +0000)
that is shared by both the (current) pages that display maps.

app/views/site/index.rhtml
app/views/user/account.rhtml
public/javascripts/map.js [new file with mode: 0644]
public/stylesheets/site.css

index b383c4b5e5e057e21a3c23309c1c332d084b7da1..6e893d1a124f232417f597da159eaaf2a6493fa8 100644 (file)
@@ -7,10 +7,6 @@
 <% lon =  params['mlon'] %>
 <% lat =  params['mlat']  %>
 <% zoom =  params['zoom'] || '12' %>
-<script type="text/javascript">
-  var mlat = <%= lat %>;
-  var mlon = <%= lon %>;
-</script>
 <% elsif @user and params['lon'].nil? and params['lat'].nil? %> 
 <% lon =  @user.home_lon %>
 <% lat =  @user.home_lat %>
 <% zoom =  params['zoom'] || '4' %>
 <% end %>
 
-
-
-<script type="text/javascript">
-  var lat = <%= lat %>;
-  var lon = <%= lon %>;
-  var zoom = <%= zoom %>;
-  var PI = 3.14159265358979323846;
-
-
-
-  <% if params['scale'] and params['scale'].length > 0 then %>
-  zoom = Math.log(360.0/(( <% print params['scale'].to_f() %> ) * 512.0)) / Math.log(2.0);
-  <% end %>
-  zoom = zoom;
-  lon = lon * 20037508.34 / 180;
-  lat = Math.log(Math.tan( (90 + lat) * PI / 360)) / (PI / 180);
-  lat = lat * 20037508.34 / 180;
-  <% if marker %>
-  mlon = mlon * 20037508.34 / 180;
-  mlat = Math.log(Math.tan( (90 + mlat) * PI / 360)) / (PI / 180);
-  mlat = mlat * 20037508.34 / 180;
-  <%end%>
-
-</script>
-<script type="text/javascript" src="/openlayers/OpenLayers.js"></script>
+<%= javascript_include_tag '/openlayers/OpenLayers.js' %>
+<%= javascript_include_tag 'map.js' %>
 
 <script type="text/javascript">
   <!--
-  var map, layer, markers;
   var ie6 = ! ( window.addEventListener || window.XMLHttpRequest );
+  var map;
 
   function init(){
+    var centre = lonLatToMercator(new OpenLayers.LonLat(<%= lon %>, <%= lat %>));
+    var zoom = <%= zoom %>;
 
-    OpenLayers.Util.onImageLoadError = function() {
-      this.src = OpenLayers.Util.getImagesLocation() + "404.png";
-    }
-    map = new OpenLayers.Map( "map", 
-        {maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34), numZoomLevels:19, maxResolution:156543, units:'m', projection: "EPSG:41001"} );
-    layer = new OpenLayers.Layer.TMS( "Mapnik", "http://tile.openstreetmap.org/", {type:'png', getURL:getTileURL} );
-    map.addLayer(layer);
-    layer = new OpenLayers.Layer.TMS( "Osmarender", "http://dev.openstreetmap.org/~ojw/Tiles/tile.php/", {type:'png', getURL:getTileURL} );
-    map.addLayer(layer);
+    <% if params['scale'] and params['scale'].length > 0 then %>
+    zoom = scaleToZoom(<%= params['scale'].to_f() %>);
+    <% end %>
 
-    //Marker stuff
+    var map = createMap("map", centre, zoom);
 
     <% if marker %>
-    markers = new OpenLayers.Layer.Markers("markers");
-    map.addLayer(markers); 
-
-    marker = new OpenLayers.Marker(new OpenLayers.LonLat(mlon,mlat));
-    markers.addMarker(marker);
-    <%end%>
-
-    map.setOptions({theme:''});
-    map.addControl(new OpenLayers.Control.LayerSwitcher());
-    map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
+    addMarkerToMap(lonLatToMercator(new OpenLayers.LonLat(<%= mlon %>, <%= mlat %>)));
+    <% end %>
 
     map.events.register("moveend", map, updateLocation);
-    document.getElementById( 'map_OpenLayers_ViewPort' ).style.position = 'absolute';
-    if( ie6 ) {
+    updateLocation();
+
+    document.getElementById('map_OpenLayers_ViewPort').style.position = 'absolute';
+    if ( ie6 ) {
       handleResize();
     }
-    updateLocation();
   }        
 
-  function getTileURL( bounds ) {
-    var res = this.map.getResolution();
-    var x = Math.round ((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
-    var y = Math.round ((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
-    var z = this.map.getZoom();
-    return this.url + z + "/" + x + "/" + y + "." + this.type; 
-  }
-
   function updateLocation() {
-    var lonlat = map.getCenter();
-
-    var lon_deg = (lonlat.lon / 20037508.34) * 180;
-    var lat_deg = (lonlat.lat / 20037508.34) * 180;
-    var PI = 3.14159265358979323846;
-    lat_deg = 180/PI * (2 * Math.atan(Math.exp(lat_deg * PI / 180)) - PI / 2);
+    var lonlat = mercatorToLonLat(map.getCenter());
     var zoom = map.getZoom();
 
-    updatelinks(lon_deg,lat_deg,zoom);
+    updatelinks(lonlat.lon, lonlat.lat, zoom);
   }
 
   function getStyle( el, property ) {
         }, 200 );
   }
 
-if( ie6 ) {
-  window.onresize = handleResize;
-}
-window.onload = init;
+  if ( ie6 ) {
+    window.onresize = handleResize;
+  }
+
+  window.onload = init;
 // -->
 </script>
index 938d3ea9b7a99e9395ab3483563def0bfe1f880e..177e9ac9743639f599d06d39b491d0c12e8e47a3 100644 (file)
 </script>
 
 <% if @user.home_lat and @user.home_lon %>
-    <% marker = true %>
-    <% mlon = @user.home_lon %> 
-    <% mlat = @user.home_lat %>
-    <% lon =  @user.home_lon %>
-    <% lat =  @user.home_lat  %>
-    <% zoom =  '12' %>
-<script type="text/javascript">
-  var mlat = <%= mlat %>;
-  var mlon = <%= mlon %>;
-</script>
+  <% marker = true %>
+  <% mlon = @user.home_lon %> 
+  <% mlat = @user.home_lat %>
+  <% lon =  @user.home_lon %>
+  <% lat =  @user.home_lat  %>
+  <% zoom =  '12' %>
 <% else %>
-    <% lon =  params['lon'] || '-0.1' %>
-    <% lat =  params['lat'] || '51.5' %>
-    <% zoom =  params['zoom'] || '4' %> 
+  <% lon =  params['lon'] || '-0.1' %>
+  <% lat =  params['lat'] || '51.5' %>
+  <% zoom =  params['zoom'] || '4' %> 
 <% end %>
 
-
-
-<script type="text/javascript">
-  var lat = <%= lat %>;
-  var lon = <%= lon %>;
-  var zoom = <%= zoom %>;
-  var PI = 3.14159265358979323846;
-
-
-
-  <% if params['scale'] and params['scale'].length > 0 then %>
-  zoom = Math.log(360.0/(( <% print params['scale'].to_f() %> ) * 512.0)) / Math.log(2.0);
-  <% end %>
-  zoom = zoom;
-  lon = lon * 20037508.34 / 180;
-  lat = Math.log(Math.tan( (90 + lat) * PI / 360)) / (PI / 180);
-  lat = lat * 20037508.34 / 180;
-  <% if marker %>
-  mlon = mlon * 20037508.34 / 180;
-  mlat = Math.log(Math.tan( (90 + mlat) * PI / 360)) / (PI / 180);
-  mlat = mlat * 20037508.34 / 180;
-  <%end%>
-
-</script>
-<script type="text/javascript" src="/openlayers/OpenLayers.js"></script>
+<%= javascript_include_tag '/openlayers/OpenLayers.js' %>
+<%= javascript_include_tag 'map.js' %>
 
 <script type="text/javascript">
   <!--
-  var map, layer, markers, marker, popup;
-
-  function mercator2lonlat( merc ) {
-    var lon_deg = (merc.lon / 20037508.34) * 180;
-    var lat_deg = (merc.lat / 20037508.34) * 180;
-    var PI = 3.14159265358979323846;
-    lat_deg = 180/PI * (2 * Math.atan(Math.exp(lat_deg * PI / 180)) - PI / 2);
-    return new OpenLayers.LonLat(lon_deg,lat_deg);
-  }
-
-  function lonlat2mercator( ll ) {
-      var lon = ll.lon * 20037508.34 / 180;
-      var lat = Math.log(Math.tan( (90 + ll.lat) * PI / 360)) / (PI / 180);
-      lat = lat * 20037508.34 / 180;
-      return new OpenLayers.LonLat(lon,lat);
-  }
+  var marker;
 
   function init(){
+    var centre = lonLatToMercator(new OpenLayers.LonLat(<%= lon %>, <%= lat %>));
+    var zoom = <%= zoom %>;
 
-    OpenLayers.Util.onImageLoadError = function() {
-      this.src = OpenLayers.Util.getImagesLocation() + "404.png";
-    }
-    map = new OpenLayers.Map( "map", 
-        {maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34), maxZoomLevel:18, maxResolution:156543, units:'m', projection: "EPSG:41001"} );
-    layer = new OpenLayers.Layer.TMS( "Mapnik", "http://tile.openstreetmap.org/", {type:'png', getURL:getTileURL} );
-    map.addLayer(layer);
-    layer = new OpenLayers.Layer.TMS( "Osmarender", "http://dev.openstreetmap.org/~ojw/Tiles/tile.php/", {type:'png', getURL:getTileURL} );
-    map.addLayer(layer);
-
-    //Marker stuff
+    <% if params['scale'] and params['scale'].length > 0 then %>
+    zoom = scaleToZoom(<%= params['scale'].to_f() %>);
+    <% end %>
 
-    markers = new OpenLayers.Layer.Markers("markers");
-    map.addLayer(markers); 
+    var map = createMap("map", centre, zoom);
 
     <% if marker %>
-    marker = new OpenLayers.Marker(new OpenLayers.LonLat(mlon,mlat));
-    marker.events.register("click", "marker", markerOnClick );
-    markers.addMarker(marker);
-    <%end%>
+    marker = addMarkerToMap(lonLatToMercator(new OpenLayers.LonLat(<%= mlon %>, <%= mlat %>)), null, "Your location");
+    <% end %>
 
     var near_icon = OpenLayers.Marker.defaultIcon();
     near_icon.url = OpenLayers.Util.getImagesLocation() + "marker-green.png";;
     var i = nearest.length;
     while( i-- ) {
-        var nearmarker = new OpenLayers.Marker( lonlat2mercator( new OpenLayers.LonLat( nearest[i].home_lon, nearest[i].home_lat ) ), near_icon.clone() );
-        markers.addMarker( nearmarker );
-        nearmarker.events.register("click", "nearmarker", makeMarkerFunction( i ) );
+      var description = 'Nearby mapper: <a href="/user/'+nearest[i].display_name+'">'+nearest[i].display_name+'</a>'
+      var nearmarker = addMarkerToMap(lonLatToMercator(new OpenLayers.LonLat(nearest[i].home_lon, nearest[i].home_lat)), near_icon.clone(), description);
     }
 
-    map.addControl(new OpenLayers.Control.LayerSwitcher());
-    map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
-
     map.events.register("click", map, setHome);
   }        
 
-  function getTileURL( bounds ) {
-    var res = this.map.getResolution();
-    var x = Math.round ((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
-    var y = Math.round ((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
-    var z = this.map.getZoom();
-    return this.url + z + "/" + x + "/" + y + "." + this.type; 
-  }
+  function setHome( e ) { 
+    closeMapPopup();
 
-  function makeMarkerFunction( i ) {
-    return function() { markerOnClick( i ); };
-  }
+    if (document.getElementById('updatehome').checked) {
+      var merc = map.getLonLatFromViewPortPx(e.xy);
+      var lonlat = mercatorToLonLat(merc);
+
+      document.getElementById('homerow').className = '';
+      document.getElementById('home_lat').value = lonlat.lat;
+      document.getElementById('home_lon').value = lonlat.lon;
 
-  function markerOnClick( i ) {
-    var html, position;
-    if( typeof( i ) == 'number'  ) {
-        html = '<p>Nearby mapper: <a href="/user/'+nearest[i].display_name+'">'+nearest[i].display_name+'</a></p>';
-        html += '<p style="text-align:right">(<a href="#" onclick="return closePopup();">close</a>)</p>';
-        position = lonlat2mercator( new OpenLayers.LonLat( nearest[i].home_lon, nearest[i].home_lat ) );
-    } else {
-        html = '<p>Your location (<a href="#" onclick="return closePopup()">close</a>)</p>';
-        position = new OpenLayers.LonLat(mlon,mlat);
+      if (marker) {
+        removeMarkerFromMap(marker);
+      }
+
+      marker = addMarkerToMap(merc, null, "Your location");
     }
-    var box = document.getElementById( 'highlightinfo' );
-    box.innerHTML = html;
-    closePopup();
-    popup = new OpenLayers.Popup.AnchoredBubble( 'popup', position, new OpenLayers.Size( box.offsetWidth, box.offsetHeight ), html, OpenLayers.Marker.defaultIcon(), true );
-    map.addPopup( popup );
   }
-  
-    function closePopup() {
-        if( popup ) {
-            map.removePopup( popup );
-            delete popup;
-        }
-        return false;
-    }
 
-    function setHome( e ) { 
-        closePopup();
-        if( ! document.getElementById( 'updatehome' ).checked )
-            return;
-        var lonlat = map.getLonLatFromViewPortPx(e.xy)
-
-        var lon_deg = (lonlat.lon / 20037508.34) * 180;
-        var lat_deg = (lonlat.lat / 20037508.34) * 180;
-        var PI = 3.14159265358979323846;
-        lat_deg = 180/PI * (2 * Math.atan(Math.exp(lat_deg * PI / 180)) - PI / 2);
-        var homerow = document.getElementById( 'homerow' );
-        var home_lat = document.getElementById( 'home_lat' );
-        var home_lon = document.getElementById( 'home_lon' );
-        homerow.className = '';
-        home_lat.value = lat_deg;
-        home_lon.value = lon_deg;
-        if( marker ) {
-            markers.removeMarker(marker);
-        }
-        marker = new OpenLayers.Marker(lonlat);
-        markers.addMarker(marker);
-    }
-window.onload = init;
+  window.onload = init;
 // -->
 </script>
 
diff --git a/public/javascripts/map.js b/public/javascripts/map.js
new file mode 100644 (file)
index 0000000..4ba66b0
--- /dev/null
@@ -0,0 +1,110 @@
+var map;
+var markers;
+var popup;
+
+function createMap(divName, centre, zoom) {
+   OpenLayers.Util.onImageLoadError = function() {
+      this.src = OpenLayers.Util.getImagesLocation() + "404.png";
+   }
+
+   map = new OpenLayers.Map(divName,
+                            { maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
+                              numZoomLevels: 19,
+                              maxResolution: 156543,
+                              units: 'm',
+                              projection: "EPSG:41001" });
+
+   var mapnik = new OpenLayers.Layer.TMS("Mapnik",
+                                         "http://tile.openstreetmap.org/",
+                                         { type: 'png', getURL: getTileURL });
+   map.addLayer(mapnik);
+
+   var osmarender = new OpenLayers.Layer.TMS("Osmarender",
+                                             "http://dev.openstreetmap.org/~ojw/Tiles/tile.php/",
+                                             { type: 'png', getURL: getTileURL });
+   map.addLayer(osmarender);
+
+   map.addControl(new OpenLayers.Control.LayerSwitcher());
+   map.setCenter(centre, zoom);
+
+   return map;
+}
+
+function getTileURL(bounds) {
+   var res = this.map.getResolution();
+   var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
+   var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
+   var z = this.map.getZoom();
+
+   return this.url + z + "/" + x + "/" + y + "." + this.type;
+}
+
+function addMarkerToMap(position, icon, description) {
+   if (markers == null) {
+      markers = new OpenLayers.Layer.Markers("markers");
+      map.addLayer(markers);
+   }
+
+   var marker = new OpenLayers.Marker(position, icon);
+
+   markers.addMarker(marker);
+
+   if (description) {
+      marker.events.register("click", marker, function() { openMapPopup(marker, description) });
+   }
+
+   return marker;
+}
+
+function openMapPopup(marker, description) {
+//   var box = document.createElement("div");
+//   box.innerHTML = description;
+//   box.style.display = 'none';
+//   box.style.width = "200px";
+//   document.body.appendChild(box);
+
+   closeMapPopup();
+
+   popup = new OpenLayers.Popup.AnchoredBubble("popup", marker.lonlat,
+                                               new OpenLayers.Size(200, 50),
+                                               "<p>" + description + "</p>",
+                                               marker.icon, true);
+   popup.setBackgroundColor("#E3FFC5");
+   map.addPopup(popup);
+
+   return popup;
+}
+
+function closeMapPopup() {
+   if (popup) {
+      map.removePopup(popup);
+      delete popup;
+   }
+}
+
+function removeMarkerFromMap(marker){
+   markers.removeMarker(marker);
+}
+
+function mercatorToLonLat(merc) {
+   var lon = (merc.lon / 20037508.34) * 180;
+   var lat = (merc.lat / 20037508.34) * 180;
+   var PI = 3.14159265358979323846;
+
+   lat = 180/PI * (2 * Math.atan(Math.exp(lat * PI / 180)) - PI / 2);
+
+   return new OpenLayers.LonLat(lon, lat);
+}
+
+function lonLatToMercator(ll) {
+   var lon = ll.lon * 20037508.34 / 180;
+   var lat = Math.log(Math.tan((90 + ll.lat) * PI / 360)) / (PI / 180);
+
+   lat = lat * 20037508.34 / 180;
+
+   return new OpenLayers.LonLat(lon, lat);
+}
+
+function scaleToZoom(scale) {
+   return Math.log(360.0/(scale * 512.0)) / Math.log(2.0);
+}
index 5f672216e14fe121d28b160d26a985035339a67a..e06a6bf810a01093db398a54f27cf2c71bc50c7c 100644 (file)
@@ -470,10 +470,6 @@ input {
     padding : 2px;\r
 }\r
 \r
-#popup p, #popup span {\r
-    background-color : #E3FFC5 !important;\r
-}\r
-\r
 #map p#highlightinfo p, #popup p {\r
     margin : 0;\r
     padding : 2px;\r