Featured Post

Create Your Own Geodatabase using Ruby on Rails and Google Maps

Geocoding with Ruby on Rails isn’t a big deal. But sometimes you have do more than simple geocoding. For real estate webpages you need information about state, county or suburb for a given address. This tutorial will show you how to build your own geodatabase without overusing google maps requests(limited...

Read More

Nokia Sportstracker GPS data on Google Maps with Ruby on Rails

Posted by Lars | Posted in Geocoding, Rails, Ruby, Tutorials | Posted on 10-05-2009

1

In my last tutorial i have explained how to import GPX files from Nokia Sportstracker Software. We have created a small Ruby on Rails application - navtracker - which we will use again. We will display the imported data on Google Maps with Ruby on Rails.

Its a good idea to read my previous tutorial before. Information about the Google Maps API can you find here. We need a key for our http://localhost:3000 development environment too.

At first we have to update track.rb and routes.rb

1
2
3
4
5
6
class Track < ActiveRecord::Base
  has_many :tracksegments, :dependent => :destroy
  has_many :points, :through => :tracksegments
  has_attached_file :gpx
  ...
end
1
2
3
map.resources :tracksegments, :has_many => :points
  map.resources :tracks, :has_many => :tracksegments
  map.resources :tracks, :has_many => :points

At second, we modifiy views/tracks/show.html.erb to get a better overview.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<h2><%=h @track.gpx_file_name %> </h2>
<table>
    <tr>
        <th>Point #</th><th>Latitude</th>
        <th>Longitude</th><th>Elevation</th>
        <th>Description</th><th>Timestamp</th>
    </tr>  
<% @track.tracksegments.each do |segment|%>
    <% segment.points.each do |point|%>
        <tr>
            <td><%= point.name%></td><td><%= point.latitude%></td>
            <td><%= point.longitude%></td><td><%= point.elevation%>m</td>
            <td><%= point.description%></td>
            <td>
            <%= point.point_created_at.strftime("%H:%M - %Y/%m/%d")%>
            </td>
        </tr>
    <%end%>
<%end%>
</table>

Next, we need the google maps api javascript code in layouts/tracks.html.erb

1
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=ABQIAAAA7oGKIGpyMHBf9frQDOIDqxTJQa0g3IQ9GZqIMmInSLzwtGDKaBTSyz-43dhS-cG7AWZa73AghbA31A" type="text/javascript"></script>

Next we add the google maps div to views/tracks/show.html.erb:

1
2
<h2><%=h @track.gpx_file_name %> </h2>
  <div id="map_canvas" style="width: 750px; height: 500px"></div>

Programming the google maps api requires some javascript skills. At first we create a javascript file: googlemaps.js in /public/javascripts. We create following functions here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function load_segment_points(map){
    GDownloadUrl("/tracks/"+track_id+"/points.xml", function(data, responseCode) {
        var points = new Array();
    var xml = GXml.parse(data);
    var xml_points = xml.documentElement.getElementsByTagName('point');
        for (var i = 0; i < xml_points.length; i++) {
            points[i] = new Object();
            points[i]["latitude"] = xml_points[i].getElementsByTagName('latitude')[0].firstChild.data;
            points[i]["longitude"] = xml_points[i].getElementsByTagName('longitude')[0].firstChild.data;
        }
        set_start_point(points,map);
        set_end_point(points,map);
        add_route(points,map);
    });
}

We use the GDownloadUrl to get a xml file of all points of current track. We assign the track_id parameter in views/layouts/tracks.html.erb

1
2
3
<script type="text/javascript">
  var track_id = <%= @track.id%>
</script>

And we add to views/layouts/tracks.html.erb the javascript_include_tag too:

1
<%= javascript_include_tag :all, :cache => true %>

In our googlemaps.js file we need following functions too:

1
2
3
4
5
function set_start_point(points,map){
    var point = new GLatLng(points[1]["latitude"], points[1]["longitude"]);
    map.setCenter(point, 13);
    map.addOverlay(new GMarker(point));
}

set_start_point marks the point the current segment of the route is starting.

1
2
3
4
5
6
function set_end_point(points,map){
    var max = points.length-1;
    var point = new GLatLng(points[max]["latitude"], points[max]["longitude"]);
    map.setCenter(point, 13);
    map.addOverlay(new GMarker(point));
}

set_end_point marks the latest point of current segment.

1
2
3
4
5
function init_map(){
    var map = new GMap2(document.getElementById("map_canvas"));
    map.setUIToDefault();  
    load_segment_points(map);
}

ini_map creates the Google Map and calls load_segment_points.

1
2
3
4
5
6
7
8
function add_route(points,map){
    var line = new Array();
    for (var i = 0; i < points.length; i++) {
        line[i] = new GLatLng(points[i]["latitude"],points[i]["longitude"]);
    }  
    var polyline = new GPolyline(line, "#aa0000", 5);
    map.addOverlay(polyline);
}

add_route creates the polyline and adds it on our Google Maps.

1
2
3
4
5
function initialize() {
  if (GBrowserIsCompatible()) {
    init_map();
  }
}

The function: initialize is called by body onload to add the map to our website. With all this javascript functions we can enter http://localhost:3000/tracks/3 (replace 3 with your test track number) and some screenshot like this:

bild-2

With the both tutorials about GPX file import and display it in google maps you should be able to write your own applications working with Nokia Sportstracker GPS data.

Update. I uploaded project files and gpx data file. Both are compressed with ZIP:

navtracker.zip
ersland-rundtgpx.zip

If you like this tutorial tell it your friends and share it.

delicious | digg | reddit | facebook | technorati | stumbleupon | chatintamil

Comments (1)

Excellent write up not only for GPX data on Sportstracker but on using Google Map with Rails in general.

Write a comment