Raspberry Pi Pico Tips and Tricks

Tuesday, 4 February 2014

Load KML, GPX or GeoJSON traces into a leaflet.js map with the Leaflet.FileLayer plugin


The following post is a portion of the Leaflet Tips and Tricks book which is free to download. To use this post in context, consider it with the others in this blog or just download the the book as a pdf / epub or mobi .
----------------------------------------------------------

The Leaflet.FileLayer plugin adds the ability to load a gps trace in the form of a KML, GPX or GeoJSON file to a Leaflet map. The idea being that if you have gone on a journey and captured the trip using a gps it can be loaded easily onto a map for viewing.
The plugin was developed by Mathieu Leplatre and is hosted on GitHub where it can be downloaded from.

Leaflet.FileLayer code description

The following is a code listing that we will use to describe the required changes from our simple-map.html example to enable Leaflet.FileLayer. There is also an online version on bl.ocks.org and GitHub.
<!DOCTYPE html>
<html>
<head>
    <title>LeafletFileLayer Plugin</title>
    <meta charset="utf-8" />
    <link 
        rel="stylesheet" 
        href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css"
    />
    <link 
        rel="stylesheet" 
        href="http://makinacorpus.github.io/Leaflet.FileLayer/Font-Awesome/css/font-awesome.min.css"
    />
</head>
<body>
    <div id="map" style="width: 600px; height: 400px"></div>

    <script
        src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js">
    </script>
    <script
        src="http://makinacorpus.github.io/Leaflet.FileLayer/leaflet.filelayer.js">
    </script>
    <script
        src="http://makinacorpus.github.io/Leaflet.FileLayer/togeojson/togeojson.js">
    </script>

    <script>
        var map = L.map('map').setView([-41.2858, 174.78682], 14);
        mapLink = 
            '<a href="http://openstreetmap.org">OpenStreetMap</a>';
        L.tileLayer(
            'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; ' + mapLink + ' Contributors',
            maxZoom: 18,
            }).addTo(map);

        var style = {color:'red', opacity: 1.0, fillOpacity: 1.0, weight: 2, clickable: false};
        L.Control.FileLayerLoad.LABEL = '<i class="fa fa-folder-open"></i>';
        L.Control.fileLayerLoad({
            fitBounds: true,
            layerOptions: {style: style,
                           pointToLayer: function (data, latlng) {
                              return L.circleMarker(latlng, {style: style});
                           }},
        }).addTo(map);

    </script>
</body>
</html>
There are three ‘blocks’ that have changed in the code from our simple map example.
The first is an additional link to load more CSS code;
<link 
    rel="stylesheet" 
    href="http://makinacorpus.github.io/Leaflet.FileLayer/Font-Awesome/css/font-awesome.min.css"
/>
(Because of the length of the URL for the file, the formatting may make cutting and pasting from the ebook problematic. For a more reliable snippet of code, download the live version from GitHub)
This loads the css file directly from the Leaflet.FileLayer repository on GitHub, so if you are loading from a local file you will need to adjust the path appropriately.
The second is the block that loads the leaflet.filelayer.js script and an additional script togeojson.js that was written by Tom MacWright to perform the internal conversion of the GPX and KML traces to GeoJSON.
<script
    src="http://makinacorpus.github.io/Leaflet.FileLayer/leaflet.filelayer.js">
</script>
<script
    src="http://makinacorpus.github.io/Leaflet.FileLayer/togeojson/togeojson.js">
</script>
(Again because of the length of the URL for the file, the formatting may make cutting and pasting from the ebook problematic. For a more reliable snippet of code, download the live version from GitHub).
leaflet.filelayer.js exists as a separate block of JavaScript code and we are loading the file directly from the Leaflet.FileLayer repository on GitHub (as per the earlier advice, if you are loading from a local file you will need to adjust the path appropriately). Likewise we are also loading the togeojson.js file from GitHub.
The last change to the file is the block of code that runs and configures Leaflet.FileLayer.
var style = {color:'red', opacity: 1.0, fillOpacity: 1.0, weight: 2, clickable: false};
L.Control.FileLayerLoad.LABEL = '<i class="fa fa-folder-open"></i>';
L.Control.fileLayerLoad({
    fitBounds: true,
    layerOptions: {style: style,
                   pointToLayer: function (data, latlng) {
                      return L.circleMarker(latlng, {style: style});
                   }},
}).addTo(map);
The fist line (starting with var style =) sets the styles for the control and the loaded gps traces. Then the icon to initiate the file opening process is declared (L.Control.FileLayerLoad.LABEL = '<i class="fa fa-folder-open"></i>';).
The script then sets the options for Leaflet.FileLayer. The first is the fitBounds option which will present a loaded gps trace in a window that is zoomed to show its full extent. The second is the layerOptions option which will apply the styling to the trace based on our previously declared values (this included the shortpointToLayer function that makes circles from point values in the traces).
Lastly we add the layer to our map with .addTo(map).
So when we load our page we can see the folder icon in the top left hand corner.
Leaflet.FileLayer plugin
If we click on this folder we will be presented with a dialogue box where we can select a file to load and when we do…
Leaflet.FileLayer plugin with gps trace from Hanmer Springs
Our gps trace is automatically zoomed and panned to present our trace to its full extent.
A copy of this file and a copy of all the files that appear in the book can be downloaded (in a zip file) when youdownload the book from Leanpub


The description above (and heaps of other stuff) is in the Leaflet Tips and Tricks book that can be downloaded for free (or donate if you really want to :-)).

Sunday, 2 February 2014

Searching a leaflet.js map using the OSMGeocoder plugin


The following post is a portion of the Leaflet Tips and Tricks book which is free to download. To use this post in context, consider it with the others in this blog or just download the the book as a pdf / epub or mobi .
----------------------------------------------------------
OSMGeocoder Search
The OSMGeocoder plugin adds a search facility to a leaflet map that uses the OpenStreetMap tool ‘Nominatim’ to search for a location and provide a reverse geolocation on the search term to pinpoint the position on the map.
The plugin was developed by ‘kartenkarsten’ and is hosted on GitHub where it can be downloaded from.
There are a number of configurable options which we shall describe in a moment.

OSMGeocoder code description

The following code is a ‘bare bones’ listing which we will flesh out with some options. The version with the added options will be in the appendices and there will be a link to a live version on bl.ocks.org.
<!DOCTYPE html>
<html>
<head>
    <title>osmGeocoder Search Plugin for Leaflet Map</title>
    <meta charset="utf-8" />
    <link 
        rel="stylesheet" 
        href="http://cdn.leafletjs.com/leaflet-0.7/leaflet.css"
    />
    <link 
        rel="stylesheet" 
        href="http://k4r573n.github.io/leaflet-control-osm-geocoder/Control.OSMGeocoder.css"
    />
        
</head>
<body>
    <div id="map" style="width: 600px; height: 400px"></div>

    <script
        src="http://cdn.leafletjs.com/leaflet-0.7/leaflet.js">
    </script>
    <script
        src="http://k4r573n.github.io/leaflet-control-osm-geocoder/Control.OSMGeocoder.js">
    </script>
    
    <script>
        var map = L.map('map').setView([-41.2858, 174.78682], 14);
        mapLink = 
            '<a href="http://openstreetmap.org">OpenStreetMap</a>';
        L.tileLayer(
            'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; ' + mapLink + ' Contributors',
            maxZoom: 18,
            }).addTo(map);
            
        var osmGeocoder = new L.Control.OSMGeocoder();

        map.addControl(osmGeocoder);
        
    </script>
</body>
</html>
There are only three ‘blocks’ that have changed in the code from our simple map example.
The first is an additional link to load more CSS code;
<link 
    rel="stylesheet" 
    href="http://k4r573n.github.io/leaflet-control-osm-geocoder/Control.OSMGeocoder.css"
/>
(Because of the length of the URL for the file, the formatting may make cutting and pasting from the ebook problematic. For a more reliable snippet of code, download the live version from GitHub)
This loads the file directly from the OSMGeocoder repository on GitHub, so if you are loading from a local file you will need to adjust the path appropriately.
The second is the block that loads the Control.OSMGeocoder.js script.
<script
    src="http://k4r573n.github.io/leaflet-control-osm-geocoder/Control.OSMGeocoder.js">
</script>
(Again because of the length of the URL for the file, the formatting may make cutting and pasting from the ebook problematic. For a more reliable snippet of code, download the live version from GitHub).
Control.OSMGeocoder.js exists as a separate block of JavaScript code and again, here we are loading the file directly from the OSMGeocoder repository on GitHub (as per the earlier advice, if you are loading from a local file you will need to adjust the path appropriately).
The last change to the file is the block of code that runs and configures Leaflet.draw.
        var osmGeocoder = new L.Control.OSMGeocoder();

        map.addControl(osmGeocoder);
The fist line (var osmGeocoder = new L.Control.OSMGeocoder();) initializes the osmGeocoder control and the second (map.addControl(osmGeocoder);) adds the search controls to the map.
There is not a lot of additional code required to get this plugin up and running and the following is what we see on the screen;
OSMGeocoder plugin
The only noticeable addition is a svelte magnifying glass in the top left hand corner. If we hover our mouse over the magnifying glass a search box appears.
OSMGeocoder plugin
If we then type in an address and click on ‘locate’…
OSMGeocoder plugin
… we are taken to a view of the location of our search.
OSMGeocoder plugin

OSMGeocoder configuration options

As I mentioned earlier, the sample code described above is in it’s most basic form and it can be extended using a range of options available to OSMGeocoder.
Adding in options is a simple matter of declaring them when we initialize the OSMGeocoder control. The three options we are going to introduce (there are more, but I’m opting for the simple ones) are to leave the search box up on the screen (no need to hover over the magnifying glass), we will position the search box in the bottom right corner (I’m not advocating this, it’s just for the sake of demonstration) and we will change the text for the button to ‘Find!’. The following are the options added to the OSMGeocoder control that will accomplish this;
        var osmGeocoder = new L.Control.OSMGeocoder({
            collapsed: false,
            position: 'bottomright',
            text: 'Find!',
   });
Resulting in a map that looks a little like this…
OSMGeocoder plugin
A copy of this file and all the files that appear in the book can be downloaded (in a zip file) when you download the book from Leanpub


The description above (and heaps of other stuff) is in the Leaflet Tips and Tricks book that can be downloaded for free (or donate if you really want to :-)).