Introduction

OpenStreetMap (OSM) is a free, editable map of the world that can be integrated into Angular applications.

One of the most common ways to use OpenStreetMap in Angular is with Leaflet, a lightweight JavaScript library for creating interactive maps.

In this example, we will create an Angular component that displays an OpenStreetMap map, adds a marker, and shows a popup when the marker is selected.

Step 1: Install Leaflet

First, install Leaflet in your Angular project.

Run the following commands from the project directory:

npm install leaflet
npm install --save-dev @types/leaflet

The leaflet package provides the mapping functionality, while @types/leaflet provides TypeScript type definitions.

Step 2: Import Leaflet CSS

Leaflet requires its CSS file for the map and its controls to display correctly.

Add the following import to the global styles.css file:

@import "~leaflet/dist/leaflet.css";

This makes the Leaflet styles available throughout the Angular application.

Step 3: Create the Angular Map Component

Create a component for the map.

For example:

ng generate component osm-map

The component can then be implemented as follows:

import { Component, AfterViewInit } from '@angular/core';
import * as L from 'leaflet';

@Component({
  selector: 'app-osm-map',
  template: '<div id="map" style="height: 500px;"></div>',
  styleUrls: ['./osm-map.component.css']
})
export class OsmMapComponent implements AfterViewInit {

  private map!: L.Map;

  ngAfterViewInit(): void {
    this.initMap();
  }

  private initMap(): void {

    // Initialize the map centered on Kolkata
    this.map = L.map('map').setView(
      [22.5726, 88.3639],
      13
    );

    // Add OpenStreetMap tile layer
    L.tileLayer(
      'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
      {
        attribution: '© OpenStreetMap contributors'
      }
    ).addTo(this.map);

    // Add a marker
    L.marker([22.5726, 88.3639])
      .addTo(this.map)
      .bindPopup('Welcome to Kolkata!')
      .openPopup();
  }
}

Understanding the Map Initialization

The following code creates the Leaflet map:

this.map = L.map('map').setView(
  [22.5726, 88.3639],
  13
);

The first parameter, map, refers to the HTML element where the map will be rendered.

The coordinates represent Kolkata:

Latitude:  22.5726
Longitude: 88.3639

The value 13 represents the initial zoom level.

Add the OpenStreetMap Tile Layer

The following code loads map tiles from OpenStreetMap:

L.tileLayer(
  'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
  {
    attribution: '© OpenStreetMap contributors'
  }
).addTo(this.map);

The {z}, {x}, and {y} placeholders are replaced by Leaflet with the appropriate tile coordinates as the user navigates around the map.

The attribution is included to acknowledge OpenStreetMap contributors.

Add a Marker

A marker can be added using L.marker():

L.marker([22.5726, 88.3639])
  .addTo(this.map)
  .bindPopup('Welcome to Kolkata!')
  .openPopup();

This places a marker at the specified coordinates and displays a popup containing:

Welcome to Kolkata!

Step 4: Use the Map Component

Once the component has been created, add it to the application's template.

For example, in app.component.html:

<app-osm-map></app-osm-map>

When the application runs, the OsmMapComponent initializes the Leaflet map after the view has been created.

Expected Output

The application displays an interactive map centered on Kolkata.

The map provides standard Leaflet interactions such as:

The marker appears at the specified Kolkata coordinates with the message:

Welcome to Kolkata!

Why Use AfterViewInit?

The map is initialized inside ngAfterViewInit():

ngAfterViewInit(): void {
  this.initMap();
}

This lifecycle hook runs after Angular has initialized the component's view.

Because Leaflet needs the map DOM element to exist before initializing the map, AfterViewInit is an appropriate place to perform the initialization.

Enhancements You Can Add

The basic implementation can be extended with additional Leaflet functionality.

Multiple Markers

You can add markers for multiple locations.

L.marker([22.5726, 88.3639])
  .addTo(this.map)
  .bindPopup('Kolkata');

L.marker([19.0760, 72.8777])
  .addTo(this.map)
  .bindPopup('Mumbai');

This can be useful when displaying offices, stores, branches, customers, or other geographic locations.

Marker Clustering

When an application contains many markers, displaying all of them individually can make the map difficult to use.

Marker-clustering plugins can group nearby markers and display individual markers as the user zooms in.

Custom Icons

Leaflet also supports custom marker icons.

Custom icons can be useful for applications where different locations need different visual indicators.

For example, an application could use separate icons for:

Routing

Routing functionality can be added using compatible Leaflet plugins such as leaflet-routing-machine.

This can allow applications to display routes between geographic locations.

Conclusion

OpenStreetMap provides map data that can be integrated into Angular applications, while Leaflet provides the client-side mapping functionality required to create interactive maps.

The basic implementation involves installing Leaflet, importing its CSS, creating a map component, adding the OpenStreetMap tile layer, and placing markers on the map.

Once the basic map is working, the application can be extended with multiple markers, marker clustering, custom icons, and routing to support more advanced location-based requirements.