Leaflet is a lightweight javascript library for interactive maps which relys on the openstreetmap.org free geospatial data open source community mapping tool. I previously had an example which integrated with google maps. Google map moved behind a paywall and while they are still very good value and have a freemium model which allows you to make many requests before having to pay, the increase complexity of accessing the Google Cloud Platform and understanding the myriad of offerings makes it less simple and accessible than it used to be.
Leaflet, on the other hand, is extremely easy to access and use. Developers can be up and running in a matter of minutes. Having got leaflet running and understood the process, developers who still wish to try Google maps will find the process of moving on relatively straightforward as most of the approaches and concepts are very simliar.
In order to implement this example, I will as I have done in the past, identify a Minimum Viable Product set of features that represents a useful interactive mapping tool. To this this I will imagine that the tennis club application allows members to book courts in a range of different venues/locations in a city. For the purposes of the example we are going to imagine that our tennis club is a virtual club that has to borrow facilities from various other clubs located in the Blanchardstown Area of Dublin. To allow members identify and locate different courts we will use an interactive map to display the location of different courts around the city. To achieve this the application should.
- Display existing court locations by displaying "pins" on an interactive map
- As a user rolls over a pin some information about that court should be displayed
- If an administrator wishes to add a new court they will simply click on the map on the exact location of the new court
- A modal form will appear requesting that the administrator enter additional details about the court.
- Once the administrator completes the form and submits the details of the new court will be stored along with the precise latitude and longitude coorordinates of the court's location.
In order to give tennis courts a location we need to add latitude and longitude columns to the court table. To do this, execute the following mysql script on the tennis court database
alter table court add column lat double, add column lng double; update court set lat=53.4111521, lng=-6.4453544 where id in (1,2); update court set lat=53.3775429, lng=-6.3881992 where id in (3,4); update court set lat=53.3701588, lng=-6.4157696 where id=5; update court set lat=53.3772317, lng=-6.4146323 where id=6;
This will add columns, lat and lng and assign co-ordinates to each of our existing courts. To allow our application to pick up on these changes we need to re-scaffold the court table - to do this execute the following command within the CLI.
php artisan infyom:scaffold court --fromTable --tableName=court
The leaflet application works well with json. At a basic level leaflet will allow us to view markers on an interactive map that have a latitude and longitude a name and a url. For the moment we will ignore the url but it would be nice to include some basic information about the court on the marker as a "tooltip" so that when users roll over the marker they will be able to see basic information about the court.
In order to get this tooltip to work we need to dynamically include a "name" attribute on the court. To make this work we need to a little bit of surgery on the court model. Open the file \app\Models\court.php and add the following line at the top of the class
protected $appends = ['name'];
To make this dynamic attribute work we can add a magic method to assign a value to it. Add the following function to the court.php model class
public function getNameAttribute() { $name = $this->surface; if ($this->floodlights) $name .= " Floodlights"; if ($this->indoor) $name .=" Indoor"; else $name .=" Outdoor"; return $name; }
This will dynamically assign a name attribute which to the court object which will be included in the json array. This attribute will show the surface type, whether the court is floodlit and whether its indoor or outdoor. Anyone rolling over the marker on the map will see this information
To display courts in json format we need to add a method to the courtController to return a json encoded collection of courts. To do this add the following function to \app\Http\Controllers\courtController.php
public function json() { $courts = \App\Models\Court::all(); return response()->json($courts); }
To make this new function work we need a corresponding route add the following line to the \routes\web.php
Route::get('/courts/all/json', 'courtController@json')->name(' courts.map.json ');
Now when you visit http://localhost:8000/courts/all/json you should see the following json encoded collection of Court objects. In the next post we will figure out how to install leaflet and get it to display a map.