How to create an application with the MapBox suite?

First of all : the aim we want to reach.

Below is an exemple of the interface we are looking for : we have interactive maps with legend and tooltips. And the map displayed depends on the buttons selected by the user.

What we'll need :

We'll use 3 OpenSource software available in the mapbox suite : TileMill, TileStream and WAX.

TileMill will be useful for creating the maps and the interactions.

TileStream will serve the MBTiles created with TileMill.

And WAX will help use to create the html page.

 

TileMill :

You can import your data from several datasources as ShapeFiles or PostGis database. The documentation of TileMill is really well done. Here we'll use Postgis datasources. I won't explain all the steps for creating a map, because it's not difficult to do : you only need some basic CSS knowledge and to find the documentation button.

So, let's begin to create a layer :

In the parameters of the layer, you have to write the access parameter from your database like this:

dbname=your_dbname host=localhost port=5432 user=some_user pwd=some_password

and then you have to precise a query. This request should always be written like this:

(SELECT * FROM my_table WHERE some_conditions) AS some_name 


Don't forget to put the geometry field in your select request, precise the projection to use (you can use any projection : if it's not in the selection list, you only need to write it's parameters beside), and DON'T FORGET to set a unique_key field. If you do, the tooltips will be randomly displayed by TileStream (at least that was the case at the time I wrote this article).

 

When your data are mapped as you wish, you can add a legend and tooltips by clicking on the settings button.

 

Here is some example you might found useful for creating a legend :

<ul>

<span style='color:#FF6666'>▉</span> Barrage

<span style='color:#FF3333'>▉</span> Industrie

<span style='color:#CC0033'>▉</span> Nucléaire

<br />

</ul><ul>

<span style='color:#DAF2B0'>●</span> < 3

<span style='color:#FEF392'>●</span> [3;5]

</ul>

The cubes and circles are unicode box-drawing characters.

 

Now we'll see how to create tooltips :

 

First you have to select the layer on which you'll like the interaction, which mean you could only use the data from this layer. Then you can choose if you'd like to have the interaction showed on click(FULL) or hover(TEASER). One point amazing is that you can add google chart into your tooltips, only by pasting some code in the tooltip window. Here is an example :

<b> Port Name: [port_name] </b>

<br>

Total GT: [gt]

<br>

Number of ships: [num]

<br> <br>

<img src="http://chart.apis.google.com/chart?chxr=0,0,2000|1,0,10000000&chxt=y,r&chbh=a,5,15&chs=300x150&cht=bvg&chco=4D89F9,7777CC

&chds=0,2000,0,10000000&chd=t:[total_nb]|[total_gt]&chdl=Nb|GT&chdlp=b&chtt=Total+ships+and+GT+in+this+port&

chts=000000,11.5" width="300" height="150" alt="Number of ships and global tonnage in this port" />

Don't forget to save the settings and export your map as MBTiles.

 

TileStream :

Import the MBTiles generated with TileMill into the right folder of TileStream.

For each TileSet, TileStream is able to create a json with all the informations which will be needed by WAX , on condition that you define some parameters in the tilestream.conf.

In our case, I had to add in this file the name of the host used like this :

{"host":["our-host-name"]}


Then you will be able to access the json with an url of that kind:

http://tilestream-url/1.0.0/project-name/layer.json

 

WAX :

First you need to declare these 3 scripts :

<script src='mapbox-directory/ext/modestmaps.min.js' type='text/javascript'></script>

<script src='mapbox-directory/dist/wax.mm.js' type='text/javascript'></script>

<link href='mapbox-directory/theme/controls.css' rel='stylesheet' type='text/css' />

Then there are only few lines of code to write. Instead of writing a lot, i'll just show you a simple example which use the json generated by TileStream :

<div id="modestmaps-setup"></div>

<script type="application/javascript">

  function displayMap(mapName) {

    //clone necessary for having only one layer into modestmap-setup. Thus we always have only one popup

    $('#modestmaps-display').remove();

    $('#modestmaps-setup').clone().attr('id','modestmaps-display').prependTo('#modestmaps-setup');

    wax.tilejson('my_mbtiles_json_url', function(tilejson) {

    var mm = com.modestmaps;

    var m = new mm.Map('modestmaps-display',

    new wax.mm.connector(tilejson));

    //new mm.Point(600,500));

    m.setCenterZoom(new mm.Location(

    tilejson.center[1], // lon read in the json

    tilejson.center[0]), // lat read in the json

    tilejson.center[2]; // zoom read in the json

    $('.wax-legends').remove(); //otherwise if you have    several layers, all legend will be stacked

    //add zoom buttons

    wax.mm.zoomer(m).appendTo(m.parent);

    //add legend

    legend = wax.mm.legend(m, tilejson).appendTo(m.parent);

    wax.mm.interaction(m).appendTo(m.parent);

    });

  }

</script>

From this simple example you can add whatever element you'd like : button, table which display data...

You can also style the elements as you wish by declaring a css stylesheet. It will automatically override the default properties.

 

That's all, I hope you'll find things easier.

 

Mathilde Vienne, 19/09/2011

Votre notation : Aucun Moyenne : 1.8 (4 votes)

a few questions

Thanks for the code, it is a nice start. (wax sample code is a bit limited!!)

3 questions I have:
1) where is mapName, the argument to displayMap(), used ?
2) 'my_mbtiles_json_url' is to be substitued by the absolute url of the layer.json, correct ?
3) $ is jquery, correct ?

Anyway, there is one typo on line 29, a missing closing )