Using Leaflet to draw your Smart Building
Apr 11, 2016 • Guillermo Amat
In this article we will learn how to use Leaflet to show the indoor maps of our smart building. We will take a common basemap and then we will overlay our indoor spaces getting the data stored previously in Osiris. We assume a basic knowledge of Leaflet however, the contents of this blog post are easy to understand. Another component we will need is JQuery, which will be used for makng AJAX requests to our Osiris server.
Leaflet is a JavaScript library for interactive maps. Used in many web sites and mobile friendly, its API Reference is quite well documented and the project is Open Source having its code hosted at GitHub.
The steps we are going to follow are:
1- Upload a map to our server
2- Display a basemap using Leaflet
3- Write an AJAX function with JQuery to make petitions to our server
4- Process the information received and use some Leaflet classes to draw polygons and polylines.
Uploading the map
Here the same map and procedure described in the documentation will be used. It is supposed the Osiris installation and running correctly. Otherwise, follow this instructions.
Get the example map from the sample maps repository and use the import command to upload it. Remember that the first parameter is your api_key (“Aachen” in this case) and it will be used for the API calls.
If everything is right you should be able to make API calls as explained in the previous article.
Displaying a basemap in Leaflet
Now we are starting to code the client application. Before adding a map, some configuration variables must be explained:
- api_key: as said before, is the identifier of our indoor map within Osiris
- place: the geographical coordinates where our Leaflet map will be centered
- levels: the set of different levels of our building. It will be explained in detail later.
In our application a black and white version of OpenStreetMap will be included, just for making clear what is being drawn over the basemap. However, it is possible to choose many other options. You can have a look to this Leaflet providers page and paste the code of your preferred map provider. As you can see, most of the listed maps allow a maximum zoom value of 18 or 19. This is a little problem because for indoor maps we need a higher zoom. To override this, Leaflet defines a property called “maxNativeZoom” which determines the maximum zoom of the tiles available from the map provider. In our example we have maxNativeZoom = 18 (limited by the provider) and maxZoom = 22 (maximum zoom in our application defined by us). When the current zoom value is higher than the maxNativeZoom, the tiles of the basemap are auto-scaled.
Writing and AJAX function for our API Calls
The Osiris’s method we are interesting in is “search”. For using it, we have to include a query in the body and specify that it is a POST petition. So, we have to use JQuery’s $.ajax function but we will wrap it in our own function in order to reuse it with different queries:
Now we can use “queryMap” to retrieve our building’s data. The third parameter is a callback method that will process the received response data.
In our example, our building will be drawn in two steps:
- First, we will obtain the level outlines as a base shape for all the other spaces in the same floor.
- Second, the data of all the remaining spaces that are of our interest will be get.
Obtaining the level outlines
Following our mapping procedure, levels are tagged as indoor:’level’. Using our function, the query can be written as follows:
The response is a JSON string that is passed as a parameter to createLevels. This function creates the levels of the building in Leaflet. Each level is used to generate a LayerGroup. Secondly, the same level is assigned as a Polygon layer to the LayerGroup in order to be sure that it will be at the bottom of the group at the time of drawing all the shapes of the same floor.
There is one more thing: we cannot be sure about the order of the results. This means that our code could generate the second level before the first and so on. To fix this issue a function called orderLevels that reorders our groups by their keys is available. As a result a new object is created (“levelGroups”) which is an ordered copy of “levels” with a more friendly key that will be used in the LayerControl to display each floor name. The last two sentences in this function are used to add the default LayerGroup (the one to be shown after loading the page) to the Leaflet map object and to add the layers control at the top right of the map.
Getting the remaining indoor spaces
Our second query to Osiris will be this one:
The query fetches all the items containing the “indoor” tag but excluding those assigned with ‘level’ as value (the ones we already have). The callback function iterates through the results calling createGeometry which is the responsible of drawing all the polygons or polylines needed, including different colors depending on the space type. When the geometry is created, it is added to its LevelGroup.
As you can see in createGeometry, depending on the type of the space, a polygon or a polyline is generated with different options in terms of style. Moreover, a Popup is associated to each space to give some information about its usage.
And that’s all. We have explained a basic usage of our indoor data for displaying maps. Now you can experiment changing styles, adding markers, making custom controls, including more objects from the indoor data such as doors, etc. You can get the full source of this article in the Osiris’s leaflet example repository.