Angular Google Maps | Draggable Radius Circle to show Markers using @agm Tutorial

Google Maps can be easily implemented in an Angular project using the @agm package as we have already discussed here.

In this tutorial, we will focus on adding a Circle Radius in the map to limit the markers shown to the user. A user can control up to how far the markers/ locations should be visible.

This is a practical situation where we can’t show all the country’s location if a person wants to view the same city results.

For the basic installation of Google Maps, you can check my previous post here. In this post, we will only focus on adding a Radius circle with logic on How to show only those markers that reside in the Radius Circle.

Check the working demo here.

Adding Google Map

In the component template, we will add 4 component directives provided by the @agm package to create a map.

agm-map: Add a map on the component.
agm-marker: Component directive to show a marker on the map.
agm-info-window: Each marker can have an info window to show data on marker click.
<strong>agm-circle</strong>: Creates Circle for Radius on map.

 

Let’s place the below HTML template in the component

<agm-map [latitude]="latitude" [longitude]="longitude" [zoom]="zoom">


    <ng-container *ngFor="let m of markers; let i = index">

        <agm-marker (markerClick)="clickedMarker(m.label, i)" [latitude]="m.lat" [longitude]="m.lng" [label]="m.label" [iconUrl]="m.icon" *ngIf="m.isShown">

            <agm-info-window>
                <div>{{m.content}}</div>
            </agm-info-window>

        </agm-marker>

    </ng-container>

    <agm-circle [latitude]="radiusLat" [longitude]="radiusLong" [radius]="radius" [fillColor]="'red'"
        [circleDraggable]="true" [editable]="false" (dragEnd)="radiusDragEnd($event)"
        (radiusChange)="event('radiusChange',$event)">
    </agm-circle>

</agm-map>

<div>Latitude: {{latitude}}</div>
<div>Longitude: {{longitude}}</div>

In the controller class import MapsAPILoader to get map load callback to call setCurrentLocation() method which will get current coordinates and fill the markers array with dummy 50 coordinates to test our Radius circle.

Also, add map height in CSS:

agm-map {
    height: 80vh;
}

 

Show Markers on Map which lie in Radius Circle

On Radius Circle dragEnd event we call the showHideMarkers() method to loop over all markers and ser its isShown property based on a check in the getDistanceBetween() method if the marker’s coordinates lie in Radius we set on the map.

How to get the distance between two Coordinates on a map?

To get the distance in meters between two coordinates google service provides the computeDistanceBetween() method which takes two LatLong objects to calculates the distance between them as a straight line on earth’s surface.

Final component class code will look as shown below:

// google-maps.component.ts
import { Component, OnInit } from '@angular/core';
import { MapsAPILoader } from '@agm/core';


// just an interface for type safety.
interface marker {
	lat: number;
	lng: number;
	label?: string;
  draggable: boolean;
  content?:string;
  isShown:boolean;
  icon:string;
}

@Component({
  selector: 'app-google-maps',
  templateUrl: './google-maps.component.html',
  styleUrls: ['./google-maps.component.scss']
})
export class GoogleMapsComponent implements OnInit {

  title: string = 'AGM project';
  latitude: number;
  longitude: number;
  zoom: number;
  address: string;
  private geoCoder;

  // Radius
  radius = 50000;
  radiusLat = 0;
  radiusLong = 0;
 
  markers: marker[] = []
 
  constructor(
    private mapsAPILoader: MapsAPILoader
  ) {
 
  }
 
 
  ngOnInit() {
    //load Map
    this.mapsAPILoader.load().then(() => {
      this.setCurrentLocation();
    });
  }
 
  // Get Current Location Coordinates
  private setCurrentLocation() {
    if ('geolocation' in navigator) {
      navigator.geolocation.getCurrentPosition((position) => {
        this.latitude = position.coords.latitude;
        this.longitude = position.coords.longitude;
        this.radiusLat = this.latitude;
        this.radiusLong = this.longitude;
        this.zoom = 6;
       
        for(let i=1;i<50;i++){
          this.markers.push(
            {
              lat: this.latitude+Math.random(),
              lng: this.longitude+Math.random(),
              label: `${i}`,
              draggable: false,
              content: `Content no ${i}`,
              isShown:false,
              icon:'./assets/marker-red.png'
            }
          );
        }

      });
    }
  }

  clickedMarker(label: string, index: number) {
    console.log(`clicked the marker: ${label || index}`)
  }

  radiusDragEnd($event: any) {
    console.log($event);
    this.radiusLat = $event.coords.lat;
    this.radiusLong = $event.coords.lng;
    this.showHideMarkers();
  }

  event(type,$event) {
    console.log(type,$event);
    this.radius = $event;
    this.showHideMarkers();
  }

  showHideMarkers(){
    Object.values(this.markers).forEach(value => {
      value.isShown = this.getDistanceBetween(value.lat,value.lng,this.radiusLat,this.radiusLong);
    });
  }

  getDistanceBetween(lat1,long1,lat2,long2){
    var from = new google.maps.LatLng(lat1,long1);
    var to = new google.maps.LatLng(lat2,long2);

    if(google.maps.geometry.spherical.computeDistanceBetween(from,to) <= this.radius){    
      console.log('Radius',this.radius);
      console.log('Distance Between',google.maps.geometry.spherical.computeDistanceBetween(
        from,to
      ));
      return true;
    }else{
      return false;
    }
  }
  
}

Also Check:

https://www.freakyjolly.com/angular-google-maps-integration-with-markers-info-windows-tutorial/

Leave a Comment

Your email address will not be published. Required fields are marked *