david hall icon

Leaflet

leaflet Leaflet is "a modern, lightweight open-source JavaScript library for mobile-friendly interactive maps" and here I show how my Stacey method of linking articles to a map works with Leaflet (refer to the previous posts for the Stacey end of things).

Implementation consists of a Leaflet Template and a geo Partial file, with a link in the Article/Post code - my link looks like:

<a href="/leaflet/?@psn,14" title="view location on Leaflet OpenStreetMap"><img src="/images/opengeo.png" alt="" /></a>

Template - leaflet.html

Remember to delete [remove] from the code - it's there to stop Stacey doing it's stuff even when written as code.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="keywords" content="map, cloudmade, leaflet, stamen" />
    <meta name="viewport" content="width=device-width" />
    <title>Leaflet Map</title>
    <link rel="alternate" type="application/atom+xml" href="@root_path/atom.xml">
    <link rel="stylesheet" href="/mapleaflet.css" />
    <!--[if lte IE 8]><link rel="stylesheet" href="/mapleaflet.ie.css" /><![endif]-->
    <script src="http://leaflet.cloudmade.com/dist/leaflet.js"></script>
    <script type="text/javascript" src="http://maps.stamen.com/js/tile.stamen.js"></script>
</head>
<body>

<div id="map"></div>

<script>
    var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/806690c0683a59ff9f57a5f5333ab86d/{styleId}/256/{z}/{x}/{y}.png',
        cloudmadeAttribution = 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery &copy; <a href="http://cloudmade.com">CloudMade</a>',
        cloudmadeOptions = {maxZoom: 18, attribution: cloudmadeAttribution};

    var cloudmade = new L.TileLayer(cloudmadeUrl, cloudmadeOptions, {styleId: 1}),
        fineline = new L.TileLayer(cloudmadeUrl, cloudmadeOptions, {styleId: 2});

    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]);
    }
    else {
        var lat = 42.94033923363181;
        var lng = -2.8125;
        var zmn = 4;
    }

    var map = new L.Map('map', {
        center: new L.LatLng(lat,lng),
        zoom: zmn,
        layers: [cloudmade]
    });

    var baseMaps = {
            "Cloudmade": cloudmade,
            "Fine Line": fineline,
            "Watercolour": new L.StamenTileLayer("watercolor"),
            "Terrain USA": new L.StamenTileLayer("terrain")
        };

    layersControl = new L.Control.Layers(baseMaps);

    map.addControl(layersControl);

    var dotIcon = L.Icon.extend({
                iconUrl: '/images/blue.png',
                shadowUrl: '/images/shadow.png',
                iconSize: new L.Point(12, 20),
                shadowSize: new L.Point(22, 20),
                iconAnchor: new L.Point(0, 0),
                popupAnchor: new L.Point(7, 0)
    });

    var blueIcon = new dotIcon(),
        greenIcon = new dotIcon('/images/green.png'),
        redIcon = new dotIcon('/images/red.png'),
        yellowIcon = new dotIcon('/images/yellow.png');

        :[remove]geoleaf


            map.on('click', onMapClick);

            function onMapClick(e) {
                var latlngStr = '(' + e.latlng.lat.toFixed(3) + ', ' + e.latlng.lng.toFixed(3) + ')';
                document.getElementById('message').innerHTML = e.latlng;
                displayMessage(latlngStr);
            }

    </script>

    <a href="/"><img src="/images/logos.png" alt="home" title="home" style="border:0; position: absolute; top: 0; left: 45px;" /></a>
    <div id="message" style="position:absolute; top: 32px; left: 50px;">Click = point</div>

</body>
</html>

Partial - geoleaf.html

foreach $root do<br />
if $children do<br />
foreach $children do<br />
if &#64;psn do<br />
var markerLocation = new L.LatLng(&#64;psn);<br />
var marker&#64;id = new L.Marker(markerLocation, {<br />
title: "&#64;title",<br />
icon: blueIcon<br />
});<br />
map.addLayer(marker&#64;id);<br />
marker&#64;id.bindPopup("&lt;h2&gt;&lt;a href='../&#64;url'&gt;&#64;title&lt;/a&gt;&lt;br /&gt;&lt;img src='&#64;th' style='width:95px;height:95px' /&gt;&lt;/h2&gt;&lt;h3&gt;&lt;a href='/leaflet/?&#64;psn,17'&gt;zoom&lt;/a&gt;&lt;/h3&gt;");<br />
endif<br />
endforeach<br />
endif<br />
endforeach

There is a zoom function in the popup window, but you can pass whatever you like through.

2012-04-06