On the client side, the library [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) is used. This is a very interesting tool improving quickly.
Just for information the creator of Leaflet, Vladimir Agafonkin, is now working for Mapbox.
For each geographical dataset it's possible to display the data on a map. Here is what have been done to make this happen.
## How the map data is fetched ?
The main difficulty to display correctly the data was the heterogeneity of the datasets, both in size and in types. For example we can have a dataset with millions of polygons to display, or a very small one but with personnalized icons instead of a geometric figure.
To manage this very broad range of display we came with the following strategy.
*Note: this is for unrestricted datasets. For restricted datasets there will be one specific strategy that we will explain later.*
At the begigning, we wanted to display just one MVT layer. It's vector, fast and integration is awesome with Mapbox. One difficutly, as we mentionned, is that one data can be represented by one circle, one polygon, or one icon, and different colors. It is because the producer of the data can apply a style that will make sense for them. And for this reason we needed to keep using the WMS service to represent with fidelity? the data.
So first, **to display and see the data, the WMS service is used**. Using cache make it quite fast and we respect the style of the data producers.
Then the question of the interaction. **To let the user interact with the map, we load the MVT layer**. The trick is to draw it transparent by default, and apply a color on hover or click events. The user has the feeling to interact directly with the features on the map (displayed by WMS), but in reality interacts with the MVT layer above it.
#### Restricted datasets
For these datasets here is the rules:
* display all the data on the map
* display only a sample into the table
* on the map, only the sample data can be interacted with
So we can not anymore use the MVT service for the interaction layer, because it uses all the data (and we don't want that). In this case we use instead the sample data retrieved by Elasticsearch (the ones displayed in the table), to construct a geojson and use it to create the layer.
At the end we can see all the data displayed on the map, but the interaction and the one visible inside the table are only a sample.
## Vector & satellite base layers
There are two base layers available: vector and satellite.
* the vector tiles are retrieved by the Métropolole of Lyon using the Open Map Tiles specification. It only covers the area of Métropole de Lyon but the details are more important than the Etalab data
* the satellite layer is using the pictures of the *Orthophotographie 2018 de la Métropole de Lyon* dataset.
#### 3D display
This is an emulated 3D, using 2D information. The vector base layer contains the height of the buidings. With Mapbox GL JS it is possible to create a layer by setting some style to the polygons with the *fill-extrusion* property.
## Research by address & Geolocalisation
It is possible to search an address in the map. We use an internal geocoder API based on [Photon](https://github.com/komoot/photon)(open source geocoder built for OpenStreetMap data, based on Elasticsearch).
It's also possible to center the map to the user position, using the native [Navigator API](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/geolocation).
## *Copy the map* feature
This allow with a button click to copy the link of the map with the current context.
This context contains: the zoom, position, bearing, pitch and base layer.
Then when you access the map in a new tab, the application will load and display the map with all the correct settings.
## Interactions
* detail of a data on map feature click
Mapbox GL JS
On the client side, the library [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) is used. This is a very interesting tool improving quickly. The only drawback using it with Angular is that we cannot always use its last version. Indeed as we are using Typescript, we need to wait until the @types are updated.
## Styling
...
...
@@ -25,10 +62,24 @@ Mapbox use the [Mapbox style specification](https://docs.mapbox.com/mapbox-gl-js
In our project we have created different styles depending on how we want to display the map. For example when we display the aerial layer, we don't necessary want the names of, say the roads and the river, to have the same color than when we display the vectorial layer.
So when we change these layers, we load the appropriate style.
## How is the data fetched ?
#### Sprites
The map uses some custom sprites, as the grass in green area, so it was needed to create and host custom sprites. The worflow for this has been the following:
* get the [Mapbox icons](https://labs.mapbox.com/maki-icons/)(the Maki icons)
* add the custom SVG we want to use in our style (for example grass.svg and water.svg)
* clone and install [spritezero-cli](https://github.com/mapbox/spritezero-cli), a command-line interface for [spritezero](https://github.com/mapbox/spritezero)
*`spritezero [output filename] [input directory]` . It generates a JSON layout file and the associated PNG spritesheet.
Also generate it with the `--retina` option to have the @2x sprites
* Once the folder containing these files is hosted, we reference it in the style file:
`"sprites": 'path/to/the/sprites/folder/'`
* Finally we can style the custom grass in green area:
```
"paint": {
"fill-pattern": "grass"
}
```
#### Glyphs
Initially we were using Web Feature Service (WFS) and Web Map Service protocols to get the data (geojson or images). But for WFS we realized that when our needs became more complex and precise, this could sometimes be not so easy (filters are not the most funny thing to do).
So we used...Elasticsearch. It is super fast and even have geographical research. We fetch the data from ES, format it into a `.geojson` and voilà ! This will also allow us in the future to have more advanced features on the map (like filters).