Partial fix for displaying mentors and students on Organization home page.
authorPawel Solyga <Pawel.Solyga@gmail.com>
Thu, 04 Jun 2009 20:55:30 +0200
changeset 2390 723dfa4811e8
parent 2389 4bfa82f58f4a
child 2391 c9283c3102ce
Partial fix for displaying mentors and students on Organization home page. Connections between mentors and students are not yet displayed and also there is some probably with displaying markers in Safari for some reason, everything works fine in FF.
app/soc/content/js/map-090420.js
app/soc/views/models/organization.py
--- a/app/soc/content/js/map-090420.js	Thu Jun 04 20:46:37 2009 +0200
+++ b/app/soc/content/js/map-090420.js	Thu Jun 04 20:55:30 2009 +0200
@@ -180,14 +180,13 @@
   // HTML div tag where map needs to be inserted
   var map_div = "org_home_map";
   
+  // Geo Data to be displayed on Google Maps
+  var geo_data = null;
+  var geo_data_keys = [];
+  
   // Geocoder object for obtaining locations from city/country
   var geocoder = new GClientGeocoder();
-  
-  // Lat/lng pairs stored for drawing polylines.
-  var student_lat = 0;
-  var student_lng = 0;
-  var mentor_lat = 0;
-  var mentor_lng = 0;
+  var numGeocoded = 0;
 
   // Setup required icons
   var base_icon = new GIcon();
@@ -202,92 +201,91 @@
   var mentor_icon = new GIcon(base_icon);
   mentor_icon.image = "/soc/content/images/mentor-marker.png";
 
-  // Mark mentor marker if he has published the location and call 
-  // drawStudentMarker function.
-  function drawMarkers(map_elem) {
-    function iterateStudents(students, mentor_name, mentor_published) {
-      for (student in students) {
-        drawStudentMarker(students[student], mentor_name, mentor_published);
-      }
+  Object.prototype.keys = function ()
+  {
+    var keys = [];
+    for(i in this) if (this.hasOwnProperty(i))
+    {
+      keys.push(i);
     }
-    if (map_elem.type == 'mentor') {
-      geocoder.setBaseCountryCode(map_elem.ccTLD);
-      geocoder.getLatLng(
-        map_elem.city,
-        function(point) {
-          if (point) {
-            var marker = new GMarker(point, mentor_icon);
-            mentor_lat = marker.getPoint().lat();
-            mentor_lng = marker.getPoint().lng();
-            var html = "<strong>" + map_elem.name + "</strong><br> Mentor";
+    return keys;
+  }
+  
+  
+  // Mark student and enable a popup box upon click
+  function drawMarker(person) {
+    geocoder.setBaseCountryCode(person.ccTLD);
+    geocoder.getLocations(
+      person.city,
+      function(response) {
+        var delay = 0;
+        if (response.Status.code == 620) {
+          // Too fast, try again, with a small pause
+          delay = 100;
+        } else {
+          if (response.Status.code == 200) {
+            // Success; do something with the address.
+            var html = "";
+            var marker = null;
+            
+            place = response.Placemark[0];
+            point = new GLatLng(place.Point.coordinates[1],
+                                place.Point.coordinates[0]);
+            if (person.type == 'mentor') {
+              marker = new GMarker(point, mentor_icon);
+              html = "<strong>" + person.name + "</strong><br> Mentor";
+            } else if (person.type == 'student') {
+              marker = new GMarker(point, student_icon);
+              html = "<strong>" + person.name + "</strong><br>";
+              html += "<a href='"+ person.url + "'>" + person.summary + "</a><br>";
+              html += "Mentor: " + person.mentor;
+            }
+
             GEvent.addListener(marker, "click", function() {
-                 marker.openInfoWindowHtml(html);
+              marker.openInfoWindowHtml(html);
             });
+
             map.addOverlay(marker);
-          } else {
-            mentor_lat = null;
-            mentor_lng = null;
           }
-          iterateStudents(map_elem.students, map_elem.name, true);
+          
+          // Move onto the next address; this skips bad addresses, too.
+          numGeocoded += 1;
         }
-      );
-    } else if (map_elem.type == 'none') {
-      drawStudentMarker(map_elem.student, map_elem.name, false);
-    }
-  }
-
-  // Mark student and enable a popup box upon click
-  function drawStudentMarker(student, mname, mentor_published) {
-    geocoder.setBaseCountryCode(student.ccTLD);
-    geocoder.getLatLng(
-      student.city,
-      function(point) {
-        if (point) {
-          var marker = new GMarker(point, student_icon);
-          var html = "<strong>" + student.name + "</strong><br>";
-          html += "<a href='"+ student.url + "'>" + student.summary + "</a><br>";
-          html += "Mentor: " + mname;
-          GEvent.addListener(marker, "click", function() {
-            marker.openInfoWindowHtml(html);
-          });
-          student_lat = marker.getPoint().lat();
-          student_lng = marker.getPoint().lng();
-          map.addOverlay(marker);
-        } else {
-          student_lat = null;
-          student_lng = null;
-        }
-        if (mentor_published) {
-          drawPolyLine();
-        }
+        
+        window.setTimeout(geocodeAll, delay);
       }
     );
   }
 
-  // Draw a polyline between the student and his mentor
-  drawPolyLine = function() {
-    var polyline = new GPolyline([
-      new GLatLng(mentor_lat, mentor_lng),
-      new GLatLng(student_lat, student_lng)
-      ], "#ff0000", 3);
+  // Draw a polyline between two points
+  drawPolyLine = function(from, to) {
+    var polyline = new GPolyline([from, to], "#ff0000", 3);
     map.addOverlay(polyline);
   }
-    
+
+  function geocodeAll() {
+    if (numGeocoded < geo_data_keys.length) {
+      drawMarker(geo_data[geo_data_keys[numGeocoded]])
+    }
+  }
+
   // Map load function
   this.map_load = function(map_data) {
     // Check if browser is gmap compatible.
     if (GBrowserIsCompatible()) {
+      geo_data = map_data;
+      
       // Create the map and add small controls
       map = new GMap2(document.getElementById(map_div));
       map.addControl(new GLargeMapControl());
-        map.addControl(new GMapTypeControl());
+      map.addControl(new GMapTypeControl());
       
       // Set map center and initial zoom level
       map.setCenter(new GLatLng(0, 0), 1);
+      geocoder.setCache(null);
+      geo_data_keys = geo_data.keys()
+      window.setTimeout(geocodeAll, 50);
       
-      for (elem in map_data) {
-        drawMarkers(map_data[elem])
-      }
     }
   }
 };
--- a/app/soc/views/models/organization.py	Thu Jun 04 20:46:37 2009 +0200
+++ b/app/soc/views/models/organization.py	Thu Jun 04 20:55:30 2009 +0200
@@ -421,40 +421,20 @@
     return self._list(request, params, contents, page_name)
 
   def _getMapData(self, student_project_params, filter=None):
-    """Constructs the JSON object required to generate a 
-      Google map on organization home page.
+    """Constructs the JSON object required to generate 
+       Google Maps on organization home page.
 
     Args:
       student_project_params: params for student project view
       filter: a dict for the properties that the entities should have
 
     Returns: 
-      A JSON object containing map data with the following structure.
-      [
-        {
-          'type': 'mentor',
-          'name': MentorName,
-          'city': CityName,
-          'ccTLD': ccTLD,
-          'students': [{'name': Name, 'city': CityName, 'ccTLD': ccTLD,
-                      'summary': Summary, 'url': URL}, 
-                   {'name': Name, 'city': CityName, 'ccTLD': ccTLD,
-                      'summary': Summary, 'url': URL}, ]
-        },
-        {
-          'type': 'none',
-          'name': MentorName,
-          'student': {'name': Name, 'city': CityName, 'ccTLD': ccTLD, 
-                      'summary': Summary, 'url': URL}
-        }
-      ]
+      A JSON object containing map data.
     """
 
     from soc.logic.models.student_project import logic as student_project_logic
 
-    map_data = []
-    mentors = {}
-    student_only = []
+    people = {}
 
     # get all the student_project entities for this organization
     student_project_entities = student_project_logic.getForFields(filter=filter)
@@ -465,67 +445,31 @@
     # have allowed to publish their locations.
     for entity in student_project_entities:
 
-      if entity.mentor.publish_location and entity.mentor not in mentors:
+      if entity.mentor.publish_location and (entity.mentor.key().name() not in people.keys()):
         # if mentor has allowed to publish his location add it to the 
         # mentors dictionary
-        mentors[entity.mentor] = []
+        people[entity.mentor.key().name()] = {
+            'type': 'mentor',
+            'name': entity.mentor.name(),
+            'city': entity.mentor.res_city,
+            'ccTLD': entity.mentor.ccTld(),
+            'students': []
+            }
 
       if entity.student.publish_location:
-        # if student has allowed to publish his location, add it to the
-        # corresponding mentor list, otherwise add it to the 'none' list
-        if entity.mentor in mentors:
-          mentors[entity.mentor].append(
-              (entity.student, entity.title,
-              redirects.getPublicRedirect(entity, student_project_params)))
-        else:
-          student_only.append(
-              (entity.student, entity.title,
-               redirects.getPublicRedirect(entity, student_project_params),
-               entity.mentor))
-
-    # from the index built in the form of mentors dictionary we now build
-    # the map_data for all the mentors who have allowed to publish their
-    # location
-    for mentor in mentors:
-      mentor_map = {
-          'type': 'mentor',
-          'name': mentor.name(),
-          'city': mentor.res_city,
-          'ccTLD': mentor.ccTld(),
-          'students': []
+        if entity.mentor.publish_location:
+          people[entity.mentor.key().name()]['students'].append(entity.student.key().name())
+        people[entity.student.key().name()] = {
+          'type': 'student',
+          'name': entity.student.name(),
+          'city': entity.student.res_city,
+          'ccTLD': entity.student.ccTld(),
+          'summary': entity.title,
+          'url': redirects.getPublicRedirect(entity, student_project_params),
+          'mentor': entity.mentor.name()
           }
 
-      for student, summary, url in mentors[mentor]:
-        student_map = {
-           'name': student.name(),
-           'city': student.res_city,
-           'ccTLD': student.ccTld(),
-           'summary': summary,
-           'url': url
-           }
-
-        mentor_map['students'].append(student_map)
-
-      map_data.append(mentor_map)
-
-    # construct the 'type': 'none' dictionary for those students, whose
-    # mentors haven't allowed to publish location
-    for student, summary, url, mentor in student_only:
-      nomentor_map = {
-          'type': 'none',
-          'name': mentor.name(), 
-          'student': {
-              'name': student.name(),
-              'city': student.res_city,
-              'ccTLD': student.ccTld(),
-              'summary': summary,
-              'url': url
-              }
-          }
-
-      map_data.append(nomentor_map)
-
-    return simplejson.dumps(map_data)
+    return simplejson.dumps(people)
 
   def _public(self, request, entity, context):
     """See base.View._public().