Creating a Leaflet Map
Part 2 - The JavaScript.
File Structure
In the previous post I introduced why I was writing up my process and started by looking at the HMTL side of the map. Now it is time to get into the JavaScript that makes the map.
I started by creating a JavaScript file. You can decide how to structure your website in a lot of ways. But the folder structure I have seen on static sites like this is to have an assets folder that has a css, and js folder inside it.
Within the js folder is where you would want to put your JavaScript
This is where I store the JavaScript. I like to name the JavaScript the same as the HTML to make it a bit less confusing for me.
Now that I have a JavaScript file started I need to reference it in my HTML. In
my structure I have the HTML page for the map in the webMaps folder, and the
JavaScript in the js folder within the assets folder. That means in my HTML it will
look like this <script> src = “../assets/js/maps/leaflet_AlamedaCovidMap.js”><script>
The ../
means to go up one level from the webMaps folder to the billparkermapping
folder and then follow the rest of the path to get to the JavaScript file.
Now the JavaScript.
The HTML is fully set up but now I have a blank JavaScipt file. Where do I start
with that? Just the same as within the <script>
tags in the
Leaflet Quick Start Guide.
I create a variable to store my map in.
Var map = L.map(‘viewDiv’)
That ‘viewDiv’ needs to be the same id that I used in my HTML for defining
my map container. As the L.map()
function is looking for a div
container to put my map into.
That creates my map but I want to set some parameters for it. At a minimum I
want the center and zoom level to display. The L.map()
function can
take an object with multiple methods after the div container. So my map
variable now looks like this
Var map = L.map(‘viewDiv’, {
Center: [37.700936,-121.841812],
Zoom: 10,
});
That center point is in latitude/longitude and will show my map with Alameda County centered. The zoom of 10 means I can see the entire county. A good place to find the center and zoom level is bboxfinder.com.
This alone does not show the map. I still have to add in layers. I will start with the baselayer, and there are a lot of options to choose from.
I am going to use two different baselayers. One will be using open street maps and the other will be an ESRI basemap layer. This is to show how to use two different types and add in a basemap layer switcher. Because I am going to use two I need to define a LayerGroup. Leaflet has an excellent tutorial about how to add LayerGroups to your map and get the default icons.
The first step is to create a var for the LayerGroup var basemaps = L.layerGroup()
Then I need to create variables to hold my two basemap layers.
The first is the open street maps streets layer.
This is a tile layer so it uses L.tileLayer()
and looks like this.
var osmBase = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
});
It takes the location as the first argument and then an array to add things like the attribution.
If you were using basemaps from StamenMaps or mapbox this is the function you would use to add them.
The next layer I am adding is an ESRI basemap layer. The example code for this I followed is in part of the ESRI Leaflet tools. There are many examples of how to consume ESRI data in a Leaflet map, including this one on basemaps.
To add an ESRI basemap I used L.esri.basemapLayer()
and looks like this
var grayBase = L.esri.basemapLayer('DarkGray');
I used a dark gray because it was in the example. But what other ESRI basemaps are available?
There are a couple different answers to that.
First, for use with the L.ersi.basemapLayer()
function this
example
has all of them listed with how you would call them.
Second, there are more but you need to have a developer API key or ArcGIS Online account or ArcGIS Enterprise License . Scrolling down the reference document for the Map Class in ArcGIS API for JavaScript shows the different basemaps available to the different account level. Both of those will have different cost levels associated with them and would involve using the ArcGIS API for JavaScript with Leaflet.
The beginner tutorials show that you just use the .addTo(map)
to add a
single baselayer. But I have two and I want to let the user switch between them.
So how do I do that?
I start by creating an object of my baseLayers
Var baseLayers = {
“Gray”: grayBase,
“Street Map”: osmBase,
};
The notation and naming here is important. I can call the variable anything I want but what I name the property/value pairs in the object matter. The property has to be a string and is what will show up in the map as the name for the layer. The value is the variable that holds the baselayer. The order is important too as that is the order they will be in in the layer switcher.
Now I have my baselayers defined I just need to add in my overlay layer for the Alameda County COVID-19 percentage positive. The county has made available some geospatial datasets of COVID data. I have chosen to use the percentage positive by Zip Code data.
To just display this data I need a link for the API I use the link for GeoService since I am using the ESRI Leaflet tools.
I could just add this to the map, but that would not allow me to turn it on and off. And I want to do that so I can add more layers in the future, I already have a layerswitcher object set up so I just use that.
This layer will not be part of the basemaps though, it will be an overlay layer that can be displayed with any other overlays I add in the future. I need to define my overlay layers in a similar way as the baselayers with a method of property:value pairs.
Var overlays = {
‘COVID Percent Positive’ : alamedaCovid,
};
Again the property is the name that will show up in the layer switcher and the value
is the variable holding the layer.
I now have a list of baselayers and a list of overlay layers (my overlays is just a single layer but since it is in a method it is a list of 1) and I need to add them to the map. I can decide what layers I want to display on the map load. I do that in the map variable by accessing the Layers methods available in L.map. The code looks like this
Var map = L.map(‘viewDiv’ , {
Center: [37.700936,-121.841812],
Zoom: 10,
Layers: [grayBase,alamedaCovid]
});
Now when the map is loaded it will show the grayBase as the baselayer and the
Alameda County COVID data as an overlay.
All that is left is to add the control for the layers. That is done using the
L.control.layers()
function. This adds a simple control for the
layers using radio buttons for the baselayers and checkboxes for the overlay layers.
L.control.layers(baseLayers,overlays).addTo(map);
Now my map has a layer switcher for the different baselayers and my overlay layers.
One issue I had was with the CSS for my website not showing the basic radio button or checkbox. I fixed this by using developer tools in Chrome to identify where in the CSS the issue was and how to fix it. This is something I would like to explore further in another post as using developer tools in your browser can really help you identify and fix a lot of issues.
So I can pull the data from two different sources in for baselayers, and an API showing COVI-19 positive rates. But the COVID-19 data isn’t styled and there are no popups to show the actual numbers. I will look at the code for that in the following post. I will also post the full code for this JavaScript in the tutorials section with just a few comments and link to it in my github.