Select Page
NOTE: This is a static archive of an old blog, no interactions like search or categories are current.

Since 1999 I kept record of most places I’ve traveled to. In the old days I used a map viewer from PARC Xerox to view these travels, I then used XPlanet which made a static image. Back in 2005 as Google Maps became usable from Javascript I made something to show my travels on an interactive map. It was using Gmaps EZ and PHP to draw points from a XML file.

Since then google made their v2 API defunct and something went bad with the old php code and so the time came to revisit all of this into the 4th iteration of a map tracking my travels.

Google Earth came out in 2005 as well – so just a bit late for me to use it’s data formats – but today it seems obvious that the data belong in a KML file. Hand building KML files though is not on, so I needed something to build the KML file in Ruby.

My new app maintains points in YAML files, have more or less an identical format to the old PHP system.

First to let people come up with categories of points you define a bunch of types of points first:

:types:
  :visit:
    :icon: http://your.site/markers/mini-ORANGE-BLANK.png
  :transit:
    :icon: http://your.site/markers/mini-BLUE-BLANK.png
  :lived:
    :icon: http://your.site/markers/mini-GREEN-BLANK.png

And then we have a series of points each referencing a type:

:points:
- :type: :visit
  :lon: -73.961334
  :title: New York
  :lat: 40.784506
  :country: United States
  :comment: Sample Data
  :href: http://en.wikipedia.org/wiki/New_York
  :linktext: Wikipedia
- :type: :transit
  :lon: -71.046524
  :title: Boston
  :lat: 42.363871
  :country: United States
  :comment: Sample Data
  :href: http://en.wikipedia.org/wiki/Boston
  :linkimg: https://pbs.twimg.com/profile_images/430836891198320640/_-25bnPr.jpeg

Here we have 2 points, both link to Wikipedia one using text and one using an image, one is a visit and one is a transit.

I use the ruby_kml Gem to convert this into KML:

First we set up the basic document and we set up the types using KML styles:

kml = KMLFile.new
document = KML::Document.new(:name => "Travlrmap Data")
 
@config[:types].each do |k, t|
  document.styles << KML::Style.new(
    :id         => "travlrmap-#{k}-style",
    :icon_style => KML::IconStyle.new(:icon => KML::Icon.new(:href => t[:icon]))
  )
end

This sets up the types and give them names like travlrmap-visited-style.

We’ll now reference these in the KML file for each point:

folder = KML::Folder.new(:name => "Countries")
folders = {}
 
@points.sort_by{|p| p[:country]}.each do |point|
  unless folders[point[:country]]
    folder.features << folders[point[:country]] = KML::Folder.new(:name => point[:country])
  end
 
  folders[point[:country]].features << KML::Placemark.new(
    :name        => point[:title],
    :description => point_comment(point),
    :geometry    => KML::Point.new(:coordinates => {:lat => point[:lat], :lng => point[:lon]}),
    :style_url   => "#travlrmap-#{point[:type]}-style"
  )
end
 
document.features << folder
kml.objects << document
 
kml.render

The points are put in folders by individual country. So in Google Earth I get a nice list of countries to enable/disable as I please etc.

I am not showing how I create the comment html here – it’s the point_comment method – it’s just boring code with a bunch of if’s around linkimg, linktext and href. KML documents does not support all of HTML but the basics are there so this is pretty easy.

So this is the basics of making a KML file from your own data, it’s fairly easy though the docs for ruby_kml isn’t that hot and specifically don’t tell you that you have to wrap all the points and styles and so forth in a document as I have done here – it seems a recent requirement of the KML spec though.

Next up we have to get this stuff onto a google map in a browser. As KML is the format Google Earth uses it’s safe to assume the Google Maps API support this stuff directly. Still, a bit of sugar around the Google APIs are nice because they can be a bit verbose. Previously I used GMapsEZ – which I ended up really hating as the author did all kinds of things like refuse to make it available for download instead hosting it on a unstable host. Now I’d say you must use gmaps.js to make it real easy.

For viewing a KML file, you basically just need this – more or less directly from their docs – there’s some ERB template stuff in here to set up the default view port etc:

<script type="text/javascript">
    var map;
    $(document).ready(function(){
      infoWindow = new google.maps.InfoWindow({});
      map = new GMaps({
        div: '#main_map',
        zoom: <%= @map_view[:zoom] %>,
        lat: <%= @map_view[:lat] %>,
        lng: <%= @map_view[:lon] %>,
      });
      map.loadFromKML({
        url: 'http://your.site/kml',
        suppressInfoWindows: true,
        preserveViewport: true,
        events: {
          click: function(point){
            infoWindow.setContent(point.featureData.infoWindowHtml);
            infoWindow.setPosition(point.latLng);
            infoWindow.open(map.map);
          }
        }
      });
    });
</script>

Make sure there’s a main_map div setup with your desired size and the map will show up there. Really easy.

You can see this working on my new travel site at travels.devco.net. The code is on Github as usual but it’s a bit early days for general use or release. The generated KML file can be fetched here.

Right now it supports a subset of older PHP code features – mainly drawing lines is missing. I hope to add a way to provide some kind of index to GPX files to show tracks as I have a few of those. Turning a GPX file into a KML file is pretty easy and the above JS code should show it without modification.

I’ll post a follow up here once the code is sharable, if you’re brave though and know ruby you can grab the travlrmap gem to install your own.