I want to display a ngx-leaflet map inside a ng-bootstrap modal, centered in a determinate point. The map is encapsulated in a component like this:
HTML
<div class="modal-header">
<h4 class="modal-title">Map</h4>
<button type="button" class="close" aria-label="Close"
(click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="map"
leaflet
[leafletOptions]="options"
[leafletLayersControl]="layersControl"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
TS
constructor(public activeModal: NgbActiveModal) { }
ngOnInit() {
}
streetMap = L.tileLayer('http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}', {
maxZoom: 20,
subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
});
hybridMap = L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
maxZoom: 20,
subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
});
vehicleMarker = L.marker([40.4168, -3.703790], {
icon: L.icon({
iconSize: [25, 41],
iconAnchor: [13, 41],
iconUrl: 'assets/marker-icon.png',
shadowUrl: 'assets/marker-shadow.png'
})
});
layersControl = {
baseLayers: {
'Map view': this.streetMap,
'Map hybrid': this.hybridMap
},
overlays: {
'Vehicle': this.vehicleMarker
}
};
options = {
layers: [this.streetMap, this.vehicleMarker],
zoom: 5,
center: L.latLng([40.4168, -3.703790])
};
And in another component I open the modal like this:
constructor(private modalService: NgbModal) { }
ngOnInit() {
}
openMap() {
this.modalService.open(MapComponent);
}
Everything works fine outside the modal (the map is centered in the given point) but when I render the map inside the modal the map is not centered. How can I solve this issue?
I realice that in small screens (like Galaxy S5 360x460) the map is displayed fine (centered).
Leaflet is very sensitive to changes to page layout and sizing. Generally, when the page layout changes you need to call Map.invalidateSize()
.
ngx-leaflet automatically tracks window resize events and calls invalidateSize()
for you, so you don't usually have to worry about it. But, when you're using something like Bootstrap or JQuery to manipulate the page layout independently of resizing the window, you may need to manually call it.
First, grab a reference to the Map using the instructions in the README: https://github.com/Asymmetrik/ngx-leaflet#getting-a-reference-to-the-map
<div leaflet
[leafletOptions]="options"
(leafletMapReady)="onMapReady($event)">
</div>
map: Map;
onMapReady(map: Map) {
this.map = map;
}
Then, add a call to this.map.invalidateSize()
whenever you open/show/resize the map modal.
If this doesn't help, please provide an angular CLI project on GitHub that reproduces the problem and I can take a closer look.