I am using AGM maps for my angular 4 application, there I am facing issues, I will be having the multiple markers which are fetched from api as an array of Latitude and Longitude. I want to set the zoom level exactly covering all the markers on the map. Even if one marker in one country and other in some other country also, It should set the zoom level on load to show all the markers on the map. Is there a way to do that in AGM angular maps? Could anyone please help me
7 Answers
Objectives
We would like to set a zoom level of AGM map to show all the markers on the map. Typically in Google Maps JavaScript API you use the fitBounds()
method of the google.maps.Map class to achieve this.
https://developers.google.com/maps/documentation/javascript/reference/3/map
So, we have to get instance of the map object (the JavaScript API instance) and apply fitBounds()
on it.
Solution
I have created a simple example that has a mock service that provides JSON data for 5 markers and draws map and markers using AGM map. In this example I used @ViewChild decorator to get the instance of AGM map and listen the mapReady
event to get instance of map object (from JavaScript API). Once I get map instance I can easily create LatLngBounds object and call fitBounds()
on map object. Have a look at the ngAfterViewInit()
method in the app.component.ts to get an idea.
Code snippet
app.component.ts
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { MyMarker } from './marker';
import { MarkersService } from './markers.service';
import { GoogleMapsAPIWrapper, AgmMap, LatLngBounds, LatLngBoundsLiteral} from '@agm/core';
declare var google: any;
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, AfterViewInit {
title = 'AGM project (so48865595)';
lat = 41.399115;
lng = 2.160962;
markers: MyMarker[];
@ViewChild('AgmMap') agmMap: AgmMap;
constructor(private markersService: MarkersService) { }
ngOnInit() {
this.getMarkers();
}
ngAfterViewInit() {
console.log(this.agmMap);
this.agmMap.mapReady.subscribe(map => {
const bounds: LatLngBounds = new google.maps.LatLngBounds();
for (const mm of this.markers) {
bounds.extend(new google.maps.LatLng(mm.lat, mm.lng));
}
map.fitBounds(bounds);
});
}
getMarkers(): void {
this.markers = this.markersService.getMarkers();
}
mapIdle() {
console.log('idle');
}
}
app.component.html
<h1>{{ title }}</h1>
<!-- this creates a google map on the page with the given lat/lng from -->
<!-- the component as the initial center of the map: -->
<agm-map #AgmMap [latitude]="lat" [longitude]="lng" (idle)="mapIdle()">
<agm-marker *ngFor="let p of markers" [latitude]="p.lat" [longitude]="p.lng"></agm-marker>
</agm-map>
Conclusion
If you would like to check complete example please download the sample project:
https://github.com/xomena-so/so48865595
I hope this helps!

- 31,125
- 6
- 88
- 117
-
1Hi.. I am loading the data from the server so it takes some time to come. I would like to setBounds only when the data from the server is received. Could you please help – Renil Babu Jul 27 '18 at 06:07
-
3You imported `LatLngBounds` from @agm/core but the types don't quite match up. Using types from @types/googlemaps fixed my error: `const bounds: google.maps.LatLngBounds = new google.maps.LatLngBounds();` – inorganik Jul 30 '18 at 21:26
-
another simpler solution to the `LatLngBounds` `Cannot invoke an expression whose type lacks a call signature` typescript error is to just add `// @ts-ignore` to the line above `map.fitBounds(bounds)`. Also, I wish I could vote up this answer twice! XD – Jared Sep 12 '18 at 08:02
-
4also, you need to add `(mapReady)="onMapReady($event)"` to your `
` html then throw the `fitBounds` stuff into your `onMapReady(map: AgmMap)` function, since `agmMap.mapReady.subscribe` doesn't work anymore – Jared Sep 12 '18 at 08:58 -
I used this implementation and in some instances, this.agmMap is undefined. Any idea how it happens? – devC Dec 19 '18 at 09:20
-
I figured out that I have to access the map as window['google'].maps – devC Dec 20 '18 at 08:34
-
@RenilBabu did you find a way to initialize this after the data has been received from the server? – Krushna Joshi Aug 20 '19 at 11:30
-
@xomena any suggestion for this (question)[https://stackoverflow.com/q/62386201/9380480] – Sai Manoj Jul 31 '20 at 19:43
-
Tried that. But fitBounds is ignored - all the time I see a whole piece of map. Could it be related to disabled Billing on the Google Cloud Project? – Alexander Mar 30 '22 at 09:41
Since September 2018 there is the AgmFitBounds
directive. Super easy.
<agm-map
style="width:100vw; height:100vh;"
[fitBounds]="true">
<agm-marker
*ngFor="let location of locations"
[latitude]="location.latitude"
[longitude]="location.longitude"
[agmFitBounds]="true"></agm-marker>
</agm-map>

- 17,558
- 5
- 27
- 35
-
2For this you need to upgrade your rxjs to version 6: npm install rxjs@6 rxjs-compat@6 --save – raulchopi Jan 29 '19 at 10:39
-
1Doesn't work for me. If I put this code the map always stays zoomed in. It doesn't get changed according to the data. Is there anyway you can help me? – Krushna Joshi Aug 20 '19 at 09:45
-
@KrushnaJoshi Best you make a new question and show us the code you have so far. – Papa Mufflon Aug 21 '19 at 11:29
-
@PapaMufflon no problem figured out a way to do it. I worked it out by initializing the map all over again when data gets changed. – Krushna Joshi Aug 22 '19 at 08:00
-
github guide: https://github.com/SebastianM/angular-google-maps/blob/master/docs/content/guides/implement-auto-fit-bounds.md – benLIVE Oct 21 '19 at 01:14
-
-
1Dose exist something similar for polygons ? https://stackblitz.com/edit/agm-polygon-tujfxa?file=app%2Fapp.component.html – DuFuS Jul 07 '20 at 14:02
@renil-babu
Instead of doing the fitBounds
on mapReady
, you have to do it in your adding markers subscription block
const bounds: LatLngBounds = new google.maps.LatLngBounds();
for (const mm of this.markers) {
bounds.extend(new google.maps.LatLng(mm.lat, mm.lng));
}
// @ts-ignore
this.agmMap._mapsWrapper.fitBounds(bounds);
-
@Papa Mufflon hi it is giving me some error No provider for FitBoundsAccessor ("S" style="position: relative; overflow: hidden;"> – K.S Feb 15 '20 at 07:16
Objectives
As we know AGM map allows fitbound
to the marker, not the zone.
Based on the accepted answer above I tried using this.agmMap.mapReady.subscribe
But in the latest version we don't have the subscribe or the fitbound
function in the AgmMap
object.
Sollution
I found an easy way to make fitbound
available to the zone by adding markers to the zone borders.
i.e, We know a zone is a combination of coordinates
so take the first and 3 middle coordinates of any zone and add them as hidden markers, That's all !!.
Check the below code snippet on how I did. It's a working tested code.
Code snippet
<agm-map [zoom]="map_zoom" [fitBounds]="fit_bound" [disableDoubleClickZoom]="true" [latitude]="latitude" [longitude]="longitude">
<span *ngFor="let mapData of list_map_geojsons">
<agm-marker [iconUrl]="marker_icon" [latitude]="mapData.lat" [longitude]="mapData.lng" [agmFitBounds]="true"></agm-marker>
<agm-data-layer [geoJson]="mapData.geojson" [style]="mapData.colors"></agm-data-layer>
<!--this is our magic code to make fitbound for zones -->
<span *ngFor="let geoMarkers of mapData.geo_makrkers">
<agm-marker [visible]="false" [latitude]="geoMarkers[1]" [longitude]="geoMarkers[0]" [agmFitBounds]="true"></agm-marker>
</span>
<!--magic code ends-->
</span>
</agm-map>
import { AgmMap} from '@agm/core';
// My geojson
const parsed_json = JSON.parse(result.geojson);
/* ----------- This code is wriitern for making fitbound to the zone,
Keeping in mind that first and last co ordinates are same Here we take
start mid, mid2 and mid3 of the zone coordinates and put it in the map
as hidden markers so that fitbound will be available for the zone ------ */
let len = parsed_json.features[0].geometry.coordinates[0].length - 1;
let mid = Math.round(len / 2);
let mid2 = Math.round(mid / 2);
let mid3 = mid + mid2;
let geo_makrkers = [
parsed_json.features[0].geometry.coordinates[0][0],
parsed_json.features[0].geometry.coordinates[0][mid],
parsed_json.features[0].geometry.coordinates[0][mid2],
parsed_json.features[0].geometry.coordinates[0][mid3]
]
/* ---- End of zone fitbound -----*/
const map_data = {
geojson: parsed_json,
lat: latitude,
lng: longitude,
colors: map_colors,
geo_makrkers: geo_makrkers
};

- 11
- 3
I got it to work with the LatLngBounds()
function. Here is the snippet.
import {AgmInfoWindow, MapsAPILoader} from '@agm/core';
latlngBounds: any;
// fits the map to the bounds
if (this.points.length.) {
this.mapsAPILoader.load().then(() => {
this.latlngBounds = new window['google'].maps.LatLngBounds();
_.each(this.points, location => {
this.latlngBounds.extend(new window['google'].maps.LatLng(location.lat, location.lng));
});
}
);
}

- 2,283
- 3
- 22
- 36
If you don't use agm-marker for some reason (you use html markers, as me) Then it is possible that your component is not supporting agmFitBounds accessor. In order to make it work write your custom component which implements FitBoundsAccessor:
import { ChangeDetectionStrategy, Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FitBoundsAccessor, FitBoundsDetails } from '@agm/core';
import { BehaviorSubject, Observable } from 'rxjs';
@Component({
selector: 'guide-map-bounds',
template: `<ng-content></ng-content>`,
providers: [{ provide: FitBoundsAccessor, useExisting: forwardRef(() => MapBoundsComponent) }],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MapBoundsComponent implements FitBoundsAccessor, OnChanges {
@Input() latitude: number;
@Input() longitude: number;
private fitBoundsDetails$ = new BehaviorSubject<FitBoundsDetails>(null);
constructor() { }
ngOnChanges(changes: SimpleChanges): void {
const latLng: google.maps.LatLngLiteral = { lat: this.latitude, lng: this.longitude };
this.fitBoundsDetails$.next({ latLng });
}
getFitBoundsDetails$(): Observable<FitBoundsDetails> {
return this.fitBoundsDetails$.asObservable();
}
}
Then in your html, inside agm-map
<guide-map-bounds [agmFitBounds]="true" *ngFor="let marker of markers" [latitude]="marker.lat" [longitude]="marker.lon">
<agm-html-overlay [latitude]="marker.lat" [longitude]="marker.lon">
<div class="marker" >
</div>
</agm-html-overlay>
</guide-map-bounds>
Please notice agm-html-overlay is custom component that doesn't support agmFitBounds

- 991
- 1
- 12
- 26
<agm-map #agmap
[zoom]="zoom"
[disableDefaultUI]="false"
[zoomControl]="false"
[fitBounds]="true">
<agm-marker [agmFitBounds]="true" [latitude]="curretAddLat" [longitude]="curretAddLng"></agm-marker>
</agm-map>
***Above code will help you with AGM MAP.

- 1
-
As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 15 '21 at 12:01