OverlappingMarkerSpiderfier-Leaflet
OverlappingMarkerSpiderfier-Leaflet copied to clipboard
Integration with Angular
Any ides on how i can integrate this plugin with Angular?
Don`t know if you managed to integrate it but i did it like this:
- Install it via npm: npm i --save overlapping-marker-spiderfier-leaflet
- Then import it in the component where you need it:
import 'overlapping-marker-spiderfier-leaflet/dist/oms';
- Add this line on top of the file where you import it:
const OverlappingMarkerSpiderfier = (<any>window).OverlappingMarkerSpiderfier;
- Add the oms markup like that:
this.oms = new OverlappingMarkerSpiderfier(this.map, { nearbyDistance: 20, keepSpiderfied: true });
- Add the markers to oms at the same place where you add your markers to the map so oms can track them properly
this.oms.addMarker(marker);
What would step 3 be to integrate with React then? @jhenrich
What would step 3 be to integrate with React then? @jhenrich
This worked fine for me in my Vue project. So it should be, relatively, the same for a React project:
<template>
<l-map ref="myMap" style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 0" @ready="mapIsReady">
</l-map>
</template>
<script>
import L, { Icon, latLng, Polyline } from 'leaflet'
import { LMap, LTileLayer, LMarker, LControlLayers } from 'vue2-leaflet'
import 'overlapping-marker-spiderfier-leaflet/dist/oms'
const OverlappingMarkerSpiderfier = window.OverlappingMarkerSpiderfier;
export default {
data() {
return {
map: null,
oms: null,
}
},
methods: {
mapIsReady(){
this.map = this.$refs.myMap.mapObject; //.ANY_LEAFLET_MAP_METHOD();
this.oms = new OverlappingMarkerSpiderfier(this.map, { nearbyDistance: 20, keepSpiderfied: true });
}
}
}
</script>
I did not really get it working for angular:
TypeError: undefined is not a constructor (evaluating 'new window.OverlappingMarkerSpiderfier(this.map,{nearbyDistance:20,keepSpiderfied:!0})')
import { Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import 'overlapping-marker-spiderfier-leaflet/dist/oms';
import { JobOffer } from 'src/models/jobOffer';
import { SearchForm } from 'src/services/filter-form.service';
import { MapService } from 'src/services/map.service';
import { JobModalComponent } from '../job-modal/job-modal.component';
import { observeFields } from './util';
@Component({
selector: 'app-open-map',
templateUrl: './open-map.component.html',
styleUrls: ['./open-map.component.scss']
})
export class OpenMapComponent implements OnInit {
@Input() jobs!: JobOffer[];
@Input() height: number = 500;
@Input() filter!: SearchForm;
@Input() centerLng: number = 4.34878;
@Input() lat = 50.85045;
@Input() lng = 4.34878;
@ViewChild('leafletMap') leafletMap!: ElementRef;
fields = observeFields(this);
map!: L.Map;
oms: any;
constructor(private modalService: NgbModal, private mapService: MapService) {
}
ngOnInit(): void {
if (this.mapService.L) {
this.fields.leafletMap.subscribe(() => this.setupMap());
}
}
public selectJob(job: JobOffer): void {
let modal = this.modalService.open(JobModalComponent, { ariaLabelledBy: 'modal-basic-title', size: 'lg', centered: true, windowClass: 'pxp-user-modal' });
modal.componentInstance.job = job;
}
private setupMap() {
if (!this.map && this.leafletMap) {
this.map = this.mapService.L.map(this.leafletMap.nativeElement).setView([this.lat, this.lng], 12);
this.oms = new (<any>window).OverlappingMarkerSpiderfier(this.map, { nearbyDistance: 20, keepSpiderfied: true });
this.loadLocation()
if (this.filter.post.value)
this.centerMap(this.filter.post.value.latitude, this.filter.post.value.longitude);
else
this.centerMap(this.filter.latitude.value, this.filter.longitude.value);
this.mapService.L.tileLayer(
'https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png'
).addTo(this.map);
(document.querySelector('.leaflet-control-attribution') as HTMLElement).style.display = 'none';
if (this.jobs) this.loadJobs(this.jobs);
this.fields.jobs.subscribe((val) => {
this.loadJobs(val);
})
}
}
private loadJobs(val: JobOffer[]) {
if(val) {
for (let job of val) {
if(this.map && job.jobLocation.latitude && job.jobLocation.longitude) this.map.addLayer(this.mapService.L.marker([job.jobLocation.latitude, job.jobLocation.longitude], {
icon: this.mapService.L.icon({
iconSize: [ 48, 48],
iconUrl: 'assets/images/leaflet/location-pin.png',
})
}).on('click', () => {
this.selectJob(job);
}));
}
}
}
private loadLocation() {
this.filter.get("post")?.valueChanges.subscribe((val) => {
console.log(val)
if (val)
this.centerMap(val.latitude, val.longitude);
});
this.filter.latitude.valueChanges.subscribe((val) => {
this.centerMap(this.filter.latitude.value, this.filter.longitude.value);
});
}
centerMap(lat: number, lng: number) {
if (this.map) this.map.panTo(this.mapService.L.latLng(lat, lng));
}
}