Creating a Member Map for your LoCo Team

A locomap is a very convenient tool to let user discover ubuntu neighbors, for the french speaking loco we used the Google map.

Here is the final result : Ubuntu users who speak French around the World

i'll try to describe each steps for creating this kind of map, and provide some code.

Get data from users

The first point is to get the Lat/Lng (Latitude, Longitude) for each user. Ubuntu-fr we use punbb for forum, but we wanted to stick to the idea : one usage : one tool. So we have a small batch witch duplicates authentication data from the forum's database to an ad'hoc db.

Then we can write a (php) script to provide authentication for users. Once they are authenticated we can redirect them to a profile page.

Basically, they can fill out a lot of information about themself :

  • First name
  • Name
  • Sex
  • Birth Date
  • Email
  • Irc Nick (on Freenode)
  • Jabber id
  • MSN / Y! / ICQ / AIM id (obviously we could record each of them, but you know, we love Jabber)
  • Personnal Website / Blog

And some info about Ubuntu

  • First release they used (Warty/Hoary/...)
  • Release they currently use
  • Version (K/Edu/X/Ubuntu)
  • Launchpad nick

Some data could be retrieve via the profile on our punbb, so we get as much as information as possible (all of them are editable, if they don't want to publish it on the map)

As you can imagine the big thing is to place the user on the map, we used GeoIP from Maxmind

// GeoIP Stuffs
$gi = geoip_open("GeoLiteCity.dat",GEOIP_STANDARD);
$record = geoip_record_by_addr($gi,$ip);
$geo_ip_lat             = $record->latitude;
$geo_ip_lng             = $record->longitude;
$geo_ip_pays            = $record->country_code3;

So from the ip we can at least find the user's isp router location, first try was to show a world map but it was very long to get to the user's position...

  • Then drag & drop the map to get the precise location :

GEvent.addListener(map, "moveend", function() {
                        center = map.getCenter();
                        document.getElementById("latitude").value = center.lat().toString();
                        document.getElementById("longitude").value = center.lng().toString();  

And store all of that in a dedicated table. The profile is always editable if the user changes location, her (last) name, email address, ...

Draw map

Each point on the map (Google called them markers) is clickable and reacts to a click with a small tabbed popup above the marker. First tab is for personnal/contact informations, second tab for info about Ubuntu (I should have use XSL to transform the user's info from xml to html, I parse it by hand wich is not really scalable).

So we have a global view of users around the globe, we can extend information by type of user in our community (regular users, forum moderators, wiki users,...) with a different icon, add local events on map... Possibility are endless the only limit is the capacity of the client's browser to deal with so much data.

Things start to get nasty here... We now have 1600 users to draw. That's a lot of point since the map uses javascript to get the data (from the database via xhtmlrequest), all those data goes into memory. To be honest I'm stuck here and not very happy with the current solution : if you zoom out the more points you draw the slower the map is.

I was thinking at something more graphical : if for the current view we have more than, say 200 users, we use multiple squares for the zone (50), the more users we have in that a given square the more brown (?) the square will be, so we draw only 50 regions, all the computation is made server side to get the number of data in the zone. Then the users will zoom and so on, if the total amount of users is below 200 we draw the points.

That will need knowledge on SVG and advanced javascript I don't have but it's really interesting.

Alternatives :

CategoryLoCoTeams CategoryLoCoObsolete

LoCoCreatingMap (last edited 2010-08-25 22:23:44 by paultag)