Building a General Purpose GeoJSON Viewer with Leaflet

Last week I shared my initial experiences with Leaflet and I thought I’d share a small demo I built with it – a general purpose GeoJSON viewer.

GeoJSON and Leaflet

As I mentioned at the end of my last post, GeoJSON is a specification for encoding ad hoc geographic data. Here’s an example:

{    "type": "FeatureCollection",    "features": [        {            "type": "Feature",            "id": 0,            "properties": {                "Code": "FRLA",                "Name": "Frederick Law Olmsted National Historic Site"            },            "geometry": {                "type": "Point",                "coordinates": [                    -71.13112956925647,                    42.32550867371509                ]            }        },        {            "type": "Feature",            "id": 1,            "properties": {                "Code": "GLDE",                "Name": "Gloria Dei Church National Historic Site"            },            "geometry": {                "type": "Point",                "coordinates": [                    -75.14358360598474,                    39.93437740957208                ]            }        },	]}

GeoJSON can encode points, lines, polygons, and more, and support a properties section that can have anything in it. Leaflet makes it easy to use GeoJSON. Here’s the example I used in that last post:

let dataReq = await fetch('https://assets.codepen.io/74045/national-parks.geojson');let data = await dataReq.json();L.geoJSON(data).bindPopup(function (layer) {		return layer.feature.properties.Name;}).addTo(map);

That’s literally it. Given how easy this, I thought I’d build a demo where the data was provided by the user.

The Application

My application is built with simple vanilla JavaScript, no Alpine even, and lets you drop a file into the browser to load the information.

The Leaflet demo

My code waits for DOMContentLoaded and then registers event handlers for dragdrop support:

document.addEventListener('dragover', e => e.preventDefault());document.addEventListener('drop', handleDrop);

When you drop a file, I then use a bit of code to read it in.

function handleDrop(e) {		e.preventDefault();		let droppedFiles = e.dataTransfer.files;		if(!droppedFiles) return;		let myFile = droppedFiles[0];		let ext = myFile.name.split('.').pop();		if(ext !== 'geojson') {			alert('Drag/drop a .geojson file only.');			return;		}				let reader = new FileReader();		reader.onload = e => {			loadGeoJSON(JSON.parse(e.target.result));		};				updateStatus('Reading .geojson');		reader.readAsText(myFile);	}

The loadGeoJSON function handles adding the data to Leaflet:

async function loadGeoJSON(data) {	updateStatus(`.geojson loaded with $ {data.features.length} features. Adding to map now.`);	L.geoJSON(data, {	}).bindPopup(function (layer) {			return `			<p>			<b>Properties:</b><br>			<pre style='white-space:pre-wrap'><code>$ {JSON.stringify(layer.feature.properties,null,'  ')}			</code></pre>			</p>			`;	},{minWidth:450}).addTo(map);}

This is pretty much the same code as before, except that my popup uses a basic dump (stringify) of the properties key. Note that this will not work for all files, especially if there’s a lot of data there. I could get fancier with my output there and perhaps add a max height with overflow. That being said, here is how it looks after adding America’s parks to it (and clicking one feature):

The Leaflet demo - with data

You can test it out here (full screen): https://codepen.io/cfjedimaster/full/GRbxVVR

And here’s the full code:

See the Pen Leaflet geojson viewer (v2) by Raymond Camden (@cfjedimaster) on CodePen.

Raymond Camden

Posted in: JavaScript

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.