Angular-google-maps: Recenter Map on a location

Created on 2 Oct 2017  ·  25Comments  ·  Source: SebastianM/angular-google-maps

Issue description

When we want to recenter the map to a location but the latitude and longitude attribute of agm-map didn't change (after a swip on the map for example) if we set lat and lng attribute to their current value the map don't recenter.

Steps to reproduce and a minimal demo of the problem

----Html side-----
(where lat and lng = 5)

User is swiping the map and change the current center. Then we wan't to recenter the map to lat=5 and lng=5
----Typescript-----
recenter(){
this.lat = 5;
this.lng = 5;
}

=> this is not working, the map don't move at all.

If we want to solve the issue we have to :

recenter(){
this.lat = 0;
this.lng = 0;
setTimeout(()=>{
this.lat = 5;
this.lng = 5;
}
}

=> this is working and the map recenter on lat = 5 and lng = 5

investigation

Most helpful comment

I have faced with the same issue, I had to use number type variables instead of string. First time I set with constant numbers, but after the new values came from the backend and from it came as string.

parsing to number did the thing.

recenterMap = (lt, lg) => {
    this.lat = Number(lt);
    this.lng = Number(lg);
}

Of corse store the data as number in db is better way, I will fix it there.

All 25 comments

I also want to recenter my map but can't find recenter() in the API. May I ask how you did it?

Sorry for late answer, didn't saw your question.

You have to set agm-map input with ts variable like this :
Html :

Ts :
lat = 5;
lng = 5;

recenterMap(lat,lng){
this.lat = lat;
this.lng = lng;
}

this will recenter your map where u want ;)

Its not working for me, I am changing value of lat and lan at runtime.
Below is my map html:

<agm-map [latitude]="lat" [longitude]="lng">
  <agm-marker [latitude]="lat" [longitude]="lng"></agm-marker>
</agm-map>

and in ts file , I have :

  selectItem = () => {
    var tmpSelectedItem = this.allItems.filter(v => v.name == this.selectedItem);
    this.recenterMap(tmpSelectedItem[0]["coordinates_lat"], tmpSelectedItem[0]["coordinates_lon"]);
  };

  recenterMap = (lt, lg) => {
    this.lat = lt;
    this.lng = lg;
  }

Please help.

Thanks in advance.

I have kind of the same use case, The map gets initialized at a position. Then the user drags the map arround, and then I would like to force the map to come back to it's initialized position.

Perhaps this can help:

https://stackoverflow.com/questions/44315771/setcenter-not-working-in-angular2-google-maps/44333134#44333134

[usePanning]="true" do the trick for me.

<agm-map [latitude]="latitude" [longitude]="longitude" [usePanning]="true"> <agm-marker [latitude]="latitude" [longitude]="longitude"></agm-marker> </agm-map>

Thank you @tluanga34. You saved my day..!!

usePanning did not work for me but the solution with setTimeout() in the first comment did.

I am unable to recenter map as per new lat/lng

(dragEnd)="draggEnded($event, i)" *ngFor="let mapPoint of this.mapPoints; let i = index"
[latitude]="mapPoint.Latitude"
[longitude]="mapPoint.Longitude" >


{{infoWinContent}}


please have any idea

having the exact same problem. Using "setTimeout" works but is really ugly.
A similar workaround can be achieved by explicitly setting the latitude and longitude of the agmMap Viewchild and use triggerResize(true).

when map is draggable, After dragging the map I am trying to keep marker at the centre but unable to do so

(mapReady)=mapReady($event) (mapClick)="mapClk($event)" (centerChange)="centerChange($event)" (idle)=idle($event) #pickupmap (dragEnd)="mapDragEnd($event)">
[latitude]="latPickup"
[longitude]="lngPickup"
[iconUrl] = "iconurl"
[markerDraggable]=true
(markerClick)="updateLocClk($events)"
(dragEnd)="markerDragEndd($event,3)"


ts ;

mapReady(evt) {
console.log("map ready",evt);
this.ma1 = evt;
console.log("lat",this.ma1.center.lat());
}

centerChange(ev) {
  var me = this;
  console.log("centre change called");
  me.gMaps.setCenter({ lat:ev.lat,lng:ev.lng});
}

help me in this issue

I have faced with the same issue, I had to use number type variables instead of string. First time I set with constant numbers, but after the new values came from the backend and from it came as string.

parsing to number did the thing.

recenterMap = (lt, lg) => {
    this.lat = Number(lt);
    this.lng = Number(lg);
}

Of corse store the data as number in db is better way, I will fix it there.

usePanning worked for me but only once.
It triggers an event when the latitude or longitude have changes, so, as the user's location is the same along the time, I did a little trick and worked good.

Just put an insignificant random number at the end of the latitude and longitude and works really fine.

getPosition(){
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition((position) => {        
    this.latitude=position.coords.latitude+(0.0000000000100*Math.random());
    this.longitude=position.coords.longitude+(0.0000000000100*Math.random());
      });
    } else {
      alert("Geolocation is not supported by this browser.");
    }
   }

So when I call the getPosition method, the map centers to the user's location

Hello all,

I'm having similar issue while trying to fetch location information from database. I've created a sample demo to show you my case. Any help will be appreciated :)

https://stackblitz.com/edit/angular-phjnwd

As @Twois mentioned, strings wont work. Make sure your lats and longs are number!

This is the "cleanest" solution I could think about when dealing with this problem.
I swear it worked like a charm for me.

Component Class Declaration

public getMapInstance(map) {
    this.map = map;
  }

public updateMapCenter() {
    this.mapCenter = {
      latitude: this.map.center.lat(),
      longitude: this.map.center.lng()
    }
  }

Template Declaration

<agm-map
        (idle)="updateMapCenter()"
        (mapReady)="getMapInstance($event)"
        [(zoom)]="mapZoom" [latitude]="mapCenter.latitude"
        [longitude]="mapCenter.longitude"
        [mapTypeControl]="true"
        [showDefaultInfoWindow]="true"
        [usePanning]="true"
>

I take the (mapReady) Output binding to get a instance of this googleMap which does currently updates its center coordinates properly, then I take the (idle) Output binding that listens when a zoom or drag is finished so I can update the component coordinates to match the ones of the googleMap instance.

So none of the other solutions really worked for me, so I just cheated and used a private method:

this.agmMap.latitude = centerCoords.lat
this.agmMap.longitude = centerCoords.lng

// @ts-ignore
this.agmMap._setCenter()

I have no idea why this method is even private as it's exactly what should be used for recentering the map.

As always, be careful of using private methods.

@justindmyers you should use the triggerResize function:

this.agmMap.triggerResize(true)

where agmMap is @ViewChild(AgmMap) agmMap: AgmMap

As @Twois mentioned, strings wont work. Make sure your lats and longs are number!

Solved here. mea culpa.

It works as expected, since its relying on Angular ChangeDetection. To fix, you can attach to centerChanged event, and update this.lat and this.lng on each center changed. THen, when you need to recenter to original value, set it back to what it was.

Fixing this would require duplicating code for every single parameter that can be changed programatically or by user, such as zoom, Layer, rotation, etc.

Another workaround I'd suggest is as following:

setCenter() {
  this.lat = 0;
  this.lng = 0;
  this.changeDetector.detectChanges();
  this.lat = <desired lat>;
  this.lng = <desired lng>
}

Parse to the Float in Js/Ts it get worked.

this.location.lat = parseFloat(latitude);
this.location.lng = parseFloat(longitude);

I had the same problem for 2 days now and that's what worked out for me
HTML
<agm-map [latitude]="latitude" [longitude]="longitude" (mapReady)="getMapInstance($event)" #AgmMap> </agm-map>

TS
public getMapInstance(map: any): void { this.map = map; }

private setCurrentLocation() {
if ('geolocation' in navigator) {
navigator.geolocation.getCurrentPosition((position) => {
this.latitude = position.coords.latitude;
this.longitude = position.coords.longitude;
this.map.setCenter({ lat: this.latitude, lng: this.longitude });
});
}
}

I had kind of the same "problem", but I noticed it was the values in lat and lng, I didn't cast them as number. When the lat and lng were strings, the marker moved, but the map center didn't.

To set the map center, use the below code

const map = new google.maps.Map(this.mapNativeElement.nativeElement, {
center: {lat: this.latitude, lng: this.longitude},
zoom: 16
});
/location object/
const pos = {
lat: this.latitude,
lng: this.longitude
};
map.setCenter(pos);

  const icon = {
    url: 'assets/img/marker-user.png', // image url
    scaledSize: new google.maps.Size(50, 50), // scaled size
  };
  const marker = new google.maps.Marker({
    position: pos,
    map: map,
    title: 'Your location!',
    icon: icon
  });

  google.maps.event.addListener(map, 'center_changed', function() {
    // set back the marker position.
    setTimeout(()=>  {
      var center = map.getCenter();
      marker.setPosition(center);

      self.latitude = marker.getPosition().lat();
      self.longitude = marker.getPosition().lng();
    }, 10);
  });

Faced this issue and got me going crazy.

Solution was (Basically I'm initializing the map again after set lat and long properties):

HTML
<agm-map #agmMap [latitude]="initLat" [longitude]="initLong" [fitBounds]="fitBounds" [zoomControl]="true" [zoom]="zoom" (mapClick)="mapClicked($event)">

TS
export class RequestMapComponent implements OnInit { initLat = 25.79587281132488; initLong= -80.28705596923828;

TS: ngOnInit
@ViewChild(AgmMap, { static: true}) agmMap: AgmMap;

  ngOnInit() {
    this.agmMap.ngOnInit();
  }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

gnujeremie picture gnujeremie  ·  3Comments

gizm0bill picture gizm0bill  ·  4Comments

ChrisDevinePimss picture ChrisDevinePimss  ·  3Comments

PeterSisovsky picture PeterSisovsky  ·  3Comments

marcelinobadin picture marcelinobadin  ·  3Comments