david hall icon

GeoBlogging revisited

Revised Blogofile GeoBlogging used on this site, simplified and with new, cleaner url parsing ;)

Controller file

Firstly create a new Controller file (same as before), say map.py which contains:


from blogofile.cache import bf
def run():
    write_map(bf.posts, bf.util.path_join(bf.config.blog_path), "map.mako")
def write_map(posts, root, template):
    root = root.lstrip("/")
    path = bf.util.path_join(root,"map.html")
    bf.logger.info("Writing map: "+path)
    bf.writer.materialize_template(template, path, {"posts":posts, "root":root})

Map file

and now the new map.mako template file (full screen as before). This uses simple "," to break the url for parsing the latitude, longitude and zoom. Also, there is only the need for a single "psn" line in the article's mako header for the lat/long coordinates (the zoom level is handled by the post.mako file - in the link behind the GeoTagIcon):


<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="keywords" content="some stuff" />
<meta name="copyright" content="Copyright (c) Anon" />
<meta name="generator" content="Blogofile" />
<meta name="viewport" content="width=device-width" />
<title>Map</title>
<link rel="alternate" type="application/rss+xml" title="Your Site" href="http://yoursite.com/atom.xml" />
<link rel="alternate" type="application/rss+xml" title="Your Site geo" href="http://yoursite.com/georss.xml" />
<style type="text/css">
html, body, #map_canvas {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    font-family: Skia, Helvetica, Tahoma sans-serif;
    font-size: 1em;
    color: #003300;
}
h2 {
    font-size:1.3em;
    text-shadow: 1px 2px 5px rgba(0, 0, 0, 0.5);
    text-align: center;
}
a {
    text-decoration:none;
    color: #485c70;
}
a:hover, a:active {
    color:#4b8462;
}
</style>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
    <script type="text/JavaScript">
        if (location.search.substring(1)) {
            var qs = location.search.substring(1);
            var url = qs.split(',',3);
            var lat = parseFloat(url[0]);
            var lng = parseFloat(url[1]);
            var zmn = parseFloat(url[2]);
            var vars = url.vars;
        }
        else {
            var lat = 42.94033923363181;
            var lng = -2.8125;
            var zmn = 3;
            var map;
        }
    function initialize() {
        map = new google.maps.Map(document.getElementById("map_canvas"), {
            center: new google.maps.LatLng(lat,lng),
            zoom: zmn,
            mapTypeId: google.maps.MapTypeId.TERRAIN
        });
    var georssLayer = new google.maps.KmlLayer('http://picasaweb.google.com/data/feed/base/user/you/albumid/111111111111111?alt=rss&kind=photo&hl=en_GB', {preserveViewport:true});
    georssLayer.setMap(map);
    var ctaLayer = new google.maps.KmlLayer('http://yoursite.com/trails/country_a.kml', {preserveViewport:true});
    ctaLayer.setMap(map);
    var ctaLayer = new google.maps.KmlLayer('http://yoursite.com/trails/country_b.kml', {preserveViewport:true});
    ctaLayer.setMap(map);
% for post in posts:
% if hasattr(post, "psn"):
    var marker${post.id} = new google.maps.Marker({
        position: new google.maps.LatLng(${post.psn}),
        map: map,
        title: "${post.title}"
    });
    var infowindow${post.id} = new google.maps.InfoWindow({
        content: ('<h2><a href="${bf.config.blog_url}${post.permapath()}">${post.title}</a></h2><p>${post.excerpt}</p>')
    });
    google.maps.event.addListener(marker${post.id}, 'click', function() {
        infowindow${post.id}.open(map,marker${post.id});
    });
% endif
% endfor
    var url = getAttribute("url");
    }
    </script>
    </head>
    <body onload="initialize()">
        <div id="map_canvas"></div>
           <a href="/" title="home"><img src="http://yoursite.com/images/home.png" alt="home" style="border:0; position: absolute; bottom: 35px; left: 3px" /></a>
           <a href="http://yoursite.com/georss.xml" title="GeoRSS"><img src="http://yoursite.com/images/georss.png" alt="georss" style="position:absolute; bottom: 35px; left: 37px" /></a>
        <h2><a href="http://yoursite.com/map.html" title="reset map" style="position: absolute; bottom: 15px; right: 3px">RESET</a></h2>
    </body>
</html>

Notes

  • the if hasattr(post, "psn"): argument has to be there to enable the map to only pick-up geotagged articles or it will not load

You may need to alter one or two things:

  • path to your feed .xml file
  • adjust the initial zoom and centre coordinates (the first instance of else)
  • my map is set to TERRAIN at first
  • I've left in the section to show how to import .kml polygons, Picasa feeds etc.
  • the infowindow article excerpts amy be altered for length and content elsewhere in Blogofile

(There are some things absent from the previous mapping effort, such as crosshairs and centre coordinate readout, these may come later.)

Article link

This needs inserting somewhere in the Article meta - in the post.mako file - it actually only focusses onto the map where the marker has been placed by the map code. Thus, you may manually make links for the body of your posts using any lat, long and zoom values which are parsed by the map code to focus on any bit of the map.


    % if hasattr(post, "psn"):
      <a href="http://www.yoursite.com/map.html/?${post.psn},13" title="location on my Map"><img src="http://www.yoursite.com/images/geotag.png" alt="geotag" /></a>
    % endif

2010-10-16