Customized marker content in Leaflet

Leaflet is my favourite mapping library, and hence is always my first choice when it comes to building apps around maps.

A project I recently worked on required data to be attached to markers, which needed to be used outside the map. To achieve this, I would need to add custom options to the ones that already exist in the Marker class. I’ve put together a small and simple tutorial that would help you achieve this.

Objective: To store custom content in a leaflet marker.

Step 1: Set up a leaflet map object.

var map = L.map('map').setView([28.63278, 77.21972], 14);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(map);

Step 2:  Create a custom class that extend the Marker class.


customMarker = L.Marker.extend({
options: {
name: '',
type: ''
}
});

Step 3:  Create a new object of this class and initialize the new custom options.


var marker = new customMarker([28.63278, 77.21972],{
clickable: true,
name: 'Connaught Place',
type: 'Neighbourhood'
}).addTo(map);

Step 4:  Your custom content has been successfully been added to the marker! Now, let’s display this content on the web page to test it. To do this, we will invoke a custom function ‘onClick’ on the ‘click’ event of the marker. In this function, we will use a bit of jQuery to display the custom content in a div with the id ‘content’.


var marker = new customMarker([28.63278, 77.21972],{
clickable: true,
name: 'Connaught Place',
type: 'Neighbourhood'
}).on('click', onClick).addTo(map);
function onClick(e) {
$('#content').html("
Name: "+this.options.name+"
Type: "+this.options.type+"
">;")
}

And you’re done! You have successfully added custom content to a marker and displayed the new content in a div!

This is the JFiddle of the code: http://jsfiddle.net/cartofy/shJ4A/

You can read more about extending Leaflet classes here.

Happy coding!

 

How to customize the GetFeatureInfo response in GeoServer

The default GetFeatureInfo response in GeoServer churns out all the attributes of the queried feature. We’ll see how we can play around with GetFeatureInfo to craft a more elegantly styled response.

To do this, we need to play with the GetFeatureInfo template. In a nutshell, the GetFeatureInfo template is a group of files that work together in telling GeoServer what to return on receiving a GetFeatureInfo request, and in what format to return it.

The GetFeatureInfo template consists of three different files- header.ftl, content.ftl and footer.ftl. These files contain HTML markup that define the style and structure of the response. This means that you can apply all of your normal HTML/CSS styling tricks on the template to get an awesome-looking GetFeatureInfo response.

Let’s see how we can create our own, custom GetFeatureInfo response step by step. I assume that you already know how publish your data using Geoserver. We will use Twitter Boostrap for the styling.

THE DATA
In this tutorial, we will use the River + Lake centerline data made available by the good folks over at Natural Earth. Once published, the layer preview should look something like this:

Layer preview with the default GetFeatureInfo output.
Layer preview with the default GetFeatureInfo output.

THE PROCESS

  1. Go to the folder where Geoserver is installed. Navigate to data>workspaces>[WORKSPACE]>[STORE]>[LAYER]. You should see two files listed: featuretype.xml and layer.xml.
  2. Create three new files and name them header.ftl, content.ftl and footer.ftl in this folder.
  3. Open header.ftl. This file should contain the , ,<!–
    and the opening tags. Basically, all the tags that lie semantically above the tag in an HTML file would be contained in this file. You can import stylesheets for your template here.
    –>
  4. We import our stylesheets and any external references. In this case, we will import the Bootstrap css for styling (the link should point to the location where you have installed Bootstrap on your server):

    <html>
      <head>
       <span class="hiddenSpellError" pre="">Geoserver</span> GetFeatureInfo output
        <link href="http://localhost/bootstrap/css/bootstrap.min.css" rel="stylesheet">
      </head>
      <body>
  5. Now open content.ftl. This file is where we will code the markup for the response body. By default, GetFeatureInfo detches all of the attributes of a particular feature. We will format the response so that only the attributes name, featurecla and scalerank are returned. We will format this response as a description list rather than a table with the tags <dl>, <dt> and <dd>. To do this, we will modify content.ftl with this markup:

    <#list features as feature>
    <dl class="dl-horizontal">
    <dt>Name:</dt>
    <dd class="text-info">${feature.name.value}</dd>


    <dt>Type:</dt>
    <dd class="text-info">${feature.featurecla.value}</dd>


    <dt>Scale Rank:</dt>
    <dd class="text-info">${feature.scalerank.value}</dd>
    </dl>
    </#list>

    #list features as feature lists all of the features by each feature and returns only the specified attributes. <dl>, <dt> and <dd> are used to construct the description list. the text-info class is a Boostrap class which styles the description.
  6. Finally, open footer.ftl. This file only contains closing tags at the end of the markup. The footer.ftl tag will contain this code:
    </body>
    </html>

Your GetFeatureOutput should look something like this:

A custom styled response
A custom styled response.

Congratulations! you have successfully crafted your custom Geoserver response. You can see that this response is much more readable and humanized than the default response.

You can read more about GeoServer templates here: http://docs.geoserver.org/latest/en/user/tutorials/GetFeatureInfo/index.html