- Timestamp:
- 10/30/07 03:07:34 (5 years ago)
- Location:
- hw/hw4
- Files:
-
- 53 added
- 2 modified
- 1 copied
-
. (copied) (copied from hw/hw3)
-
library/app/controllers/query1_controller.rb (modified) (1 diff)
-
library/app/views/query1/index.rhtml (modified) (1 diff)
-
library/config/gmaps_api_key.yml (added)
-
library/lib/ym4r (added)
-
library/lib/ym4r.rb (added)
-
library/lib/ym4r/google_maps (added)
-
library/lib/ym4r/google_maps.rb (added)
-
library/lib/ym4r/google_maps/api_key.rb (added)
-
library/lib/ym4r/google_maps/config (added)
-
library/lib/ym4r/google_maps/config/config.yml (added)
-
library/lib/ym4r/google_maps/geocoding.rb (added)
-
library/lib/ym4r/yahoo_maps (added)
-
library/lib/ym4r/yahoo_maps.rb (added)
-
library/lib/ym4r/yahoo_maps/app_id.rb (added)
-
library/lib/ym4r/yahoo_maps/building_block (added)
-
library/lib/ym4r/yahoo_maps/building_block.rb (added)
-
library/lib/ym4r/yahoo_maps/building_block/exception.rb (added)
-
library/lib/ym4r/yahoo_maps/building_block/geocoding.rb (added)
-
library/lib/ym4r/yahoo_maps/building_block/local_search.rb (added)
-
library/lib/ym4r/yahoo_maps/building_block/map_image.rb (added)
-
library/lib/ym4r/yahoo_maps/building_block/traffic.rb (added)
-
library/public/images/library.png (added)
-
library/public/javascripts/clusterer.js (added)
-
library/public/javascripts/geoRssOverlay.js (added)
-
library/public/javascripts/markerGroup.js (added)
-
library/public/javascripts/wms-gs.js (added)
-
library/public/javascripts/ym4r-gm.js (added)
-
library/vendor/plugins/ym4r_gm (added)
-
library/vendor/plugins/ym4r_gm/README (added)
-
library/vendor/plugins/ym4r_gm/gmaps_api_key.yml.sample (added)
-
library/vendor/plugins/ym4r_gm/init.rb (added)
-
library/vendor/plugins/ym4r_gm/install.rb (added)
-
library/vendor/plugins/ym4r_gm/javascript (added)
-
library/vendor/plugins/ym4r_gm/javascript/clusterer.js (added)
-
library/vendor/plugins/ym4r_gm/javascript/geoRssOverlay.js (added)
-
library/vendor/plugins/ym4r_gm/javascript/markerGroup.js (added)
-
library/vendor/plugins/ym4r_gm/javascript/wms-gs.js (added)
-
library/vendor/plugins/ym4r_gm/javascript/ym4r-gm.js (added)
-
library/vendor/plugins/ym4r_gm/lib (added)
-
library/vendor/plugins/ym4r_gm/lib/gm_plugin (added)
-
library/vendor/plugins/ym4r_gm/lib/gm_plugin/control.rb (added)
-
library/vendor/plugins/ym4r_gm/lib/gm_plugin/geocoding.rb (added)
-
library/vendor/plugins/ym4r_gm/lib/gm_plugin/helper.rb (added)
-
library/vendor/plugins/ym4r_gm/lib/gm_plugin/key.rb (added)
-
library/vendor/plugins/ym4r_gm/lib/gm_plugin/layer.rb (added)
-
library/vendor/plugins/ym4r_gm/lib/gm_plugin/map.rb (added)
-
library/vendor/plugins/ym4r_gm/lib/gm_plugin/mapping.rb (added)
-
library/vendor/plugins/ym4r_gm/lib/gm_plugin/overlay.rb (added)
-
library/vendor/plugins/ym4r_gm/lib/gm_plugin/point.rb (added)
-
library/vendor/plugins/ym4r_gm/lib/ym4r_gm.rb (added)
-
library/vendor/plugins/ym4r_gm/rakefile.rb (added)
-
library/vendor/plugins/ym4r_gm/tasks (added)
-
library/vendor/plugins/ym4r_gm/tasks/gm_tasks.rake (added)
-
library/vendor/plugins/ym4r_gm/test (added)
-
library/vendor/plugins/ym4r_gm/test/gm_test.rb (added)
Legend:
- Unmodified
- Added
- Removed
-
hw/hw4/library/app/controllers/query1_controller.rb
r71 r76 1 require 'ym4r/google_maps/geocoding' 2 1 3 class Query1Controller < ApplicationController 2 def index 3 @results = Author.find(:all, :conditions => "citizenship='France' or citizenship='Germany'") 4 end 4 def index 5 # Start timekeeping 6 starttime = Time.now 7 8 # Default library 9 libraryname = 'Evans Library' 10 11 # Get the library name from the form if it exists. 12 if params[:changelibrary] != nil 13 formobj = params[:changelibrary] 14 libraryname = formobj[:newlibrary] 15 end 16 17 # Retrieve the list of libraries for the Select (Drop Down) Box 18 # "@" preceeding a variable name indicates an instance variable. 19 # Instance variables can be passed to views, whereas 20 # local variables (variable names without preceeding "@") cannot 21 # be passed to views. 22 @alllibraries = Array.new 23 alllibraries1 = Library.find(:all, :order => "city,lname") 24 alllibraries1.each do |library| 25 @alllibraries << ["#{library.lname} in #{library.city}",library.lname] 26 end 27 28 # Find the lat/lon of the library of interest. 29 @mylibrary = Library.find(:first, 30 :conditions => "lname = '#{libraryname}'") 31 32 # This is a Remote Procedure Call (RPC). This particular type 33 # of call (translating a location name like "Berkeley" into 34 # lat/lon coordinates) is known as geocoding. 35 geoloc = Ym4r::GoogleMaps::Geocoding::get(@mylibrary.city) 36 if geoloc.status != Geocoding::GEO_SUCCESS 37 err = 'Library Coordinates Not Found' 38 return err 39 end 40 liblatlon = geoloc[0].latlon 41 42 # Initialize map and center it over the library of interest 43 @map = GMap.new("map_div") 44 @map.control_init(:large_map => true,:map_type => true) 45 @map.center_zoom_init(liblatlon,2) # zoom out a fair amount 46 47 # Make a library marker and icon 48 @map.icon_global_init(GIcon.new(:image => "/images/library.png", 49 :icon_size => GSize.new(20,20), 50 :icon_anchor => GPoint.new(10,10), 51 :info_window_anchor => GPoint.new(9,2)), 52 "icon_library") 53 icon_construction = Variable.new("icon_library") 54 @map.overlay_init(GMarker.new(liblatlon, 55 :icon => icon_construction, 56 :title => libraryname, 57 :info_window => libraryname)) 58 59 # Get all the authors. 60 @authors = Array.new 61 results = Author.find(:all) 62 results.each do |result| 63 64 # This is another geocoding RPC. 65 # A potentially large number of authors are all geocoded. 66 # This is a good candidate for caching. 67 geoloc = Ym4r::GoogleMaps::Geocoding::get(result.bplace) 68 69 # Calculate the author's birthplace's distance from the library 70 if geoloc.status == Geocoding::GEO_SUCCESS 71 authlatlon = geoloc[0].latlon 72 # Distances recalculated from a relativley stable set of libraries. 73 # This is a good candidate for caching. 74 dist = distance_between(authlatlon,liblatlon).floor 75 @map.overlay_init(GMarker.new(geoloc[0].latlon, 76 :title => result.name, 77 :info_window => "#{result.name} says:<br> I am #{dist} miles away<br> from #{@mylibrary.lname}")) 78 @authors << [result.name,result.bplace,dist] 79 end 80 end 81 82 # Sort authors in place by dist. "sort!" means in place. 83 @authors.sort! {|x,y| x[2] <=> y[2] } 84 85 # Measure speed of server-side operation. 86 # Typical times w/ RPC: 3.5 seconds 87 # Typical times w/o RPC: 0.3 seconds 88 # Rhombus server fluctuations will cause this value to vary. 89 endtime = Time.now 90 @elapsedtime = endtime - starttime 91 end 5 92 end 93 94 # helper functions copied from GeoKit by Andre Lewis 95 96 PI_DIV_RAD = 0.0174 97 KMS_PER_MILE = 1.609 98 EARTH_RADIUS_IN_MILES = 3963.19 99 EARTH_RADIUS_IN_KMS = EARTH_RADIUS_IN_MILES * KMS_PER_MILE 100 MILES_PER_LATITUDE_DEGREE = 69.1 101 KMS_PER_LATITUDE_DEGREE = MILES_PER_LATITUDE_DEGREE * KMS_PER_MILE 102 LATITUDE_DEGREES = EARTH_RADIUS_IN_MILES / MILES_PER_LATITUDE_DEGREE 103 104 105 def distance_between(from, to, options={}) 106 # units = options[:units] || GeoKit::default_units 107 # formula = options[:formula] || GeoKit::default_formula 108 units = :miles 109 formula = :sphere 110 case formula 111 when :sphere 112 units_sphere_multiplier(units) * 113 Math.acos( Math.sin(deg2rad(from[0])) * Math.sin(deg2rad(to[0])) + 114 Math.cos(deg2rad(from[0])) * Math.cos(deg2rad(to[0])) * 115 Math.cos(deg2rad(to[1]) - deg2rad(from[1]))) 116 when :flat 117 Math.sqrt((units_per_latitude_degree(units)*(from[0]-to[0]))**2 + 118 (units_per_longitude_degree(from[0], units)*(from[1]-to[1]))**2) 119 end 120 end 121 122 def deg2rad(degrees) 123 degrees.to_f / 180.0 * Math::PI 124 end 125 126 def rad2deg(rad) 127 rad.to_f * 180.0 / Math::PI 128 end 129 130 def to_heading(rad) 131 (rad2deg(rad)+360)%360 132 end 133 134 # Returns the multiplier used to obtain the correct distance units. 135 def units_sphere_multiplier(units) 136 units == :miles ? EARTH_RADIUS_IN_MILES : EARTH_RADIUS_IN_KMS 137 end 138 139 # Returns the number of units per latitude degree. 140 def units_per_latitude_degree(units) 141 units == :miles ? MILES_PER_LATITUDE_DEGREE : KMS_PER_LATITUDE_DEGREE 142 end 143 144 # Returns the number units per longitude degree. 145 def units_per_longitude_degree(lat, units) 146 miles_per_longitude_degree = (LATITUDE_DEGREES * Math.cos(lat * PI_DIV_RAD)).abs 147 units == :miles ? miles_per_longitude_degree : miles_per_longitude_degree * KMS_PER_MILE 148 end -
hw/hw4/library/app/views/query1/index.rhtml
r71 r76 1 <h1> Query 1</h1> 1 <html><head><title>Inspirational Libraries</title> 2 <%= GMap.header %> 3 <%= @map.to_html %> 4 </head><body> 2 5 3 Print the names of the authors that are citizens either of France or Germany 6 <h1>Inspirational Libraries</h1> 4 7 5 <h3>Ruby Code</h3> 6 <pre> 7 @results = Author.find(:all, :conditions => "citizenship='France' or 8 citizenship='Germany'") 9 </pre> 8 <i> 9 The map below shows birthplaces of authors relative to a particular library. On the side bar to the right, authors have been sorted by their bithplaces' distance to the library. Notice the "Elapsed Time" below. Your job is to speed up this elapsed time by building a cache for the queries involving distances of authors' birthplaces to libraries. 10 </i> 10 11 11 <h3>Result</h3> 12 12 <table> 13 <tr> 14 <!-- main map --> 15 <td> 16 <%= @map.div(:width => 600, :height => 400) %> 17 </td> 18 <td> 19 20 </td> 21 <!-- side bar --> 22 <td> 23 <h3><%= @mylibrary.lname %> in <%= @mylibrary.city %></h3> 13 24 <table border=1> 14 <tr><td><b> Name</b></td></tr>15 <% for result in @results -%>16 <tr><td><%= result.name%></td></tr>25 <tr><td><b>Author</b></td><td><b>Birthplace</b></td><td><b>Distance</b></td></tr> 26 <% for author in @authors -%> 27 <tr><td><%= author[0] %></td><td><%= author[1] %></td><td><%= author[2] %></td></tr> 17 28 <% end %> 18 29 </table> 30 </td> 31 </tr> 32 </table> 19 33 34 <% form_for :changelibrary, :url => { :action => :index } do |form| %> 35 <%= form.select :newlibrary, @alllibraries, :prompt => "-- Library Name --" %> 36 <%= submit_tag "Switch Library", :class => "submit" %> 37 <% end %> 38 39 Elapsed Time: <%= @elapsedtime %> Seconds. 40 41 </body></html>
