Leaflet with GeoJSON Layer and Features

In our previous tutorial, we created a Leaflet map with a GeoJSON layer.

In this tutorial, we’ll use jQuery to add add pop-up feature information to our map.

As with the previous tutorial, we’ll cover using both a GeoJSON file as well as GeoJSON from a GeoServer url.

Let’s start with our basic Leaflet map with GeoJSON layer that we created earlier:

<!DOCTYPE html>
<html lang="en">
<head>
    <base target="_top">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>Leaflet GeoJSON Example</title>
    
    <!-- Leafletjs and CSS -->    
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
    
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>

    <style>
        html, body {
            height: 100%;
            margin: 0;
        }
        .leaflet-container {
            height: 80%;
            width: 80%;
            max-width: 100%;
            max-height: 100%;
        }
    </style>

    </head>
<body>

    <div id="map"></div>
   
    <script>

    // Add OpenStreetMap basemap
        var map = L.map('map').setView([41.8916, -87.7219], 4);

        var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
            maxZoom: 19,
            attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
        }).addTo(map);

     
       /*Add JSON location or url*/

       var url = 'states.json';  // path to json file

    	/*fetch JSON data and to map*/

       fetch(url)
       .then(function(response) {
          return response.json()
       })
       .then(function(data) {
         L.geoJson(data).addTo(map);
       })  

</script>
</body>
</html>

We now want to make our layer display feature data on click.

First, we need to add the jQuery library to the <head> section of our file.

:

<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>

Next, we need to add some jQuery to get our data.

Each section is commented below.

//Loop through JSON file for features information -->
	function forEachFeature(feature, layer) {
    
	// Print all feature information
    var mypopupContent = '<pre>'+JSON.stringify(feature.properties,null,' ').replace(/[\{\}"]/g,'')+'</pre>';
    
	// above Bind to popup content
    layer.bindPopup(mypopupContent);
            
		}
	
    // Null var that will hold layer
	var myLayer = L.geoJson(null, {onEachFeature: forEachFeature});

    // Add mylayer above to map
	$.getJSON(url, function(data) {
   	myLayer.addData(data);
	});
	myLayer.addTo(map);

With our jQuery in place, our html code now looks like below:

<!DOCTYPE html>
<html lang="en">
<head>
    <base target="_top">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>Leaflet GeoJSON Example</title>
    
    <!-- Leafletjs and CSS -->    
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
    
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
	
	<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>

    <!-- Inline map styling -->
    
    <style>
        html, body {
            height: 100%;
            margin: 0;
        }
        .leaflet-container {
            height: 80%;
            width: 80%;
            max-width: 100%;
            max-height: 100%;
        }
    </style>

    
</head>
<body>

    <div id="map"></div>


<script>
	

	var map = L.map('map').setView([47.7541, -107.05078], 3); 

	var osm = new L.tileLayer('https://{s}.tile.osm.org/{z}/{x}/{y}.png',{ 
				attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'}).addTo(map);
	
	var url = 'states.json';  // GeoJSON data source. Can be file or GeoServer url.
		
	//Loop through JSON file for features information -->
	function forEachFeature(feature, layer) {
    
	// Print all feature information
    var mypopupContent = '<pre>'+JSON.stringify(feature.properties,null,' ').replace(/[\{\}"]/g,'')+'</pre>';
    
	// above Bind to popup content
    layer.bindPopup(mypopupContent);
            
		}
	
    // Null var that will hold layer
	var myLayer = L.geoJson(null, {onEachFeature: forEachFeature});

    // Add mylayer above to map
	$.getJSON(url, function(data) {
   	myLayer.addData(data);
	});
	myLayer.addTo(map);

</script>
</body>
</html>

Now, when we click on our map, the data for the feature is returned.

In the code above, we are looping through all of the features and displaying them.

You can limit this by substituting individual features.

We can replace line below:

var popupContent = '<pre>'+JSON.stringify(feature.properties,null,' ').replace(/[\{\}"]/g,'')+'</pre>';

With this, which returns only the State name:

var popupContent = "State Name: " + feature.properties.STATE_NAME;

Note the url that is generated:

https://yourdomain.com/geoserver/topp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=topp:states&maxFeatures=50&outputFormat=application/json

Now, paste the url in place of ‘states.json’ in your code as below:

 var url = 'https://yourdomain.com/geoserver/topp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=topp:states&maxFeatures=50&outputFormat=application/json';  // path to json file