Leaflet.js is an open-source JavaScript library for interactive maps. After copying a couple lines of code into your application, you have full access to the library. I’ve added two plugins, Leaflet.Arc for drawing great circle polylines and Leaflet.TextPath for displaying text labels above the polylines.

// site_analytics.html
{% block head %}
<!-- Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css"
  integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ=="
  crossorigin="" />
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js"
  integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
  crossorigin=""></script>
<!-- Leaflet Plugins -->
{% sri_static 'leaflet_plugins/leaflet.textpath.js' %}
{% sri_static 'leaflet_plugins/leaflet-arc.min.js' %}
{% endblock head %}

I place leaflet.js code in a separate file and inject it into the template underneath a <div> tag.

// site_analytics.html
<div id="map"></div>
{% sri_static 'maps/leaflet_server_map.js' %}

In main.css, I set the map width to 100% of the container and the height to 40% of the viewport.

// main.css
#map{ 
  height: 40vh;
  width : 100%;
}

First, I add a map

// leaflet_map.js
var map = L.map('map', {
    center: [39, -98],
    zoom: 4,
});

Then, a scalebar

L.control.scale({ imperial: true, metric: true }).addTo(map); 

A basemap

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

Now we have a map centered at the geographic center of the US. Next, I add three markers for the cities of Los Angeles, Dallas, and NYC.

var LaLatLng = { lat: 34.1, lon: -118.2 }
var DallasLatLng = { lat: 32.8, lon: -96.8 }
var NYCLatLng = { lat: 40.7, lon: -73.9 }

For each marker, I include a title and alt text. I wanted to use a custom marker icon for the Dallas marker, so I found one on Flaticon. After adding the icon png to /static, I reference it from within the JavaScript file.

var IPAddressIcon = L.icon({
    iconUrl: "static/icons/ip-address.png",
    iconSize: [40, 40]
});
var DallasMarkerOptions = {
    title: "Blogthedata.com Server",
    alt: "The city of Dallas, Texas. USA",
    icon: IPAddressIcon
}

After adding the markers, I add polylines connecting the markers. The Polyline.Arc syntax is leveraging the Leaflet.Arc plugin to draw a great circle route. A plane would take this path when traveling between these locations.

var DallasToNYC = L.Polyline.Arc([DallasLatLng.lat, DallasLatLng.lon], [NYCLatLng.lat, NYCLatLng.lon], { color: 'orange' })

Next, I want to show the distance between the two cities. I could have hard-coded this, but it was easy enough to do it in the client since I am only performing a couple calculations.

var DallasToNYCDistance = (Math.floor(map.distance(DallasLatLng, NYCLatLng) / 1000)).toString()

With the distance as a string, I add it to the polyline and then add the polyline to the map.

DallasToNYC.setText(DallasToNYCDistance.concat(' km'), {
    center: true,
    offset: -5,
    attributes: { 'font-size': '24', 'font-weight': 'bold', fill: 'orange' }
})
DallasToNYC.addTo(map)

And we've got a map!

Back to Home
 Profile Picture
Profile Picture

About John Solly

I am a Senior Software Engineer with a focus on geospatial applications, based in the Columbus, OH metropolitan area. This blog is where I delve into the intricacies of GIS (Geographic Information Systems), offering deep dives into different components of the geospatial technology stack. For those who share a passion for GIS and its applications, you've found a spot to explore and learn.

Interested in collaborating or learning more about my work? Take a look at my portfolio for a showcase of my projects and expertise.

Comments

  • No comments yet.
Login to Comment