david hall icon

Stacey geoblogging

A method of linking articles to a map, and back.

This method works with the following file structure in Stacey:

folder structure

My front page has the current year, the Archives contain all previous years.

Partials

There are three new partials files which reside in the navigation folder. Firstly "siblings" that runs through the years:


  if $siblings do
  <ol>
  foreach $children do
  <li>
  <a href="@year">@year</a>
  </li>
  endforeach
  </ol>
  endif

and two others that draw the location data from the articles are as follows:

geotags.html


  foreach $root do
  if $children do
  foreach $children do
  if @psn do
  var marker@id = new google.maps.Marker({
    position: new google.maps.LatLng(@psn),
    map: map,
    title: "@title"
  });
  var infowindow@id = new google.maps.InfoWindow({
    content: ('<h2><a href="../@url">@title</a></h2><h3><a href="/archives/map/?@psn,18">Zoom</a></h3>')
  });
  google.maps.event.addListener(marker@id, 'click', function() {infowindow@id.open(map,marker@id);});
  endif
  endforeach
  endif
  endforeach

and

geotagged.html


  foreach $siblings do
  if $children do
  foreach $children do
  if @psn do
  var marker@id = new google.maps.Marker({
    position: new google.maps.LatLng(@psn),
    map: map,
    title: "@title"
  });
  var infowindow@id = new google.maps.InfoWindow({
    content: ('<h2><a href="../@url">@title</a></h2><h3><a href="/archives/map/?@psn,18">Zoom</a></h3>')
  });
  google.maps.event.addListener(marker@id, 'click', function() {
    infowindow@id.open(map,marker@id);
  });
  endif
  endforeach
  endif
  endforeach

These are present in the code of the Map page by (Note: Remove the space between the colon and text, in the complete Map code, below):

:geotags
:geotagged

Map Code

The complete Map code, which includes a geocode search is:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <meta name="keywords" content="your name" />
    <meta name="copyright" content="Copyright (c) your name" />
    <meta name="generator" content="Stacey" />
    <meta name="viewport" content="width=device-width" />
    <title>Map</title>
    <link rel="alternate" type="application/atom+xml" title="feed title" href="http://your-site.com/feed/atom.xml" />

<style type="text/css">
    html, body, #map_canvas {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        font-family: 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;
    }
    h3 {
        font-size:1em;
        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;
    }
    var url = getAttribute("url");

    var geocoder;

    function initialize() {
    geocoder = new google.maps.Geocoder();
        map = new google.maps.Map(document.getElementById("map_canvas"), {
        center: new google.maps.LatLng(lat,lng),
        zoom: zmn,
        draggableCursor: "crosshair",
            mapTypeId: google.maps.MapTypeId.SATELLITE
        });

        google.maps.event.addListener(map, 'click', function onClickCallback(event){
            document.getElementById("message").innerHTML = event.latLng.toString();
            geocode({ 'latLng': event.latLng });
        });

    : geotags
    : geotagged
    }

    function codeAddress() {
    var address = document.getElementById("address").value;
    geocoder.geocode( { 'address': address}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
            map.setCenter(results[0].geometry.location);
            var image = new google.maps.MarkerImage('http://your-site.com/images/marker.png',
                new google.maps.Size(12, 20),
                new google.maps.Point(0,0),
                new google.maps.Point(7, 21));
            var shadow = new google.maps.MarkerImage('http://your-site.com/images/marker-shadow.png',
                new google.maps.Size(22, 20),
                new google.maps.Point(0, 0),
                new google.maps.Point(6, 20));
            var marker = new google.maps.Marker({
                map: map,
            shadow: shadow,
                icon: image,
                position: results[0].geometry.location,
            title: address
            });
        } else {
            alert("Geocode was not successful for the following reason: " + status);
        }
    });
    }
    </script>
  </head>

    <body onload="initialize()">
        <div id="map_canvas"></div>
        <div id="message" style="position:absolute; bottom: 60px; left: 3px;" >Click coordinates</div>
        <div id="geocode" style="position:absolute; bottom: 30px; left: 3px;" >
            <input id="address" style="color:green" type="textbox" value="" />
        <input type="button" style="color:green" value="Search" onclick="codeAddress()" />
        </div>
    </body>
</html>

Project file

In the templates folder > project.html file use the following to pick-up the position coordinates. Mine is in the date line of the article:


  if @psn do <a href="/archives/map/?@psn,12" title="view location on Map"><img src="/images/geotag.png" alt="" /></a> endif

Article file

Put a new line in the Article text file to push through the coordinates, I use:


  psn:
  -

Icons

Here are some icons:   

2011-03-04