ngx-mapbox-gl
ngx-mapbox-gl copied to clipboard
mglDraggable doesn't work without (mouseEnter) in mgl-layer
I don't seem to be able to add mglDraggable to mgl-features inside a ngFor loop. The dragging function just simply doesn't work.
<mgl-geojson-source id="route">
<ng-container *ngFor="let waypoint of [ [17.6392731, 59.2019309],
[17.6212388277054, 59.2010590531024],
[17.6082654576989, 59.2042359987876],
[17.6118, 59.20358]]; trackBy: trackByFn">
<mgl-feature
[properties]=""
[geometry]="{ 'type': 'Point', 'coordinates': waypoint }"
[mglDraggable]="layer"
(dragStart)="onDragStop($event)"></mgl-feature>
</ng-container>
</mgl-geojson-source>
<mgl-layer #layer
id="route"
type="circle"
source="route"
[layout]="{ 'visibility': 'visible' }"
[paint]="{ 'circle-radius': 10,
'circle-color': 'red',
'circle-stroke-color': 'white',
'circle-stroke-width': 2 }"></mgl-layer>
But if I add each of the mgl-features manually like below it works and I can drag any of the circles independently.
<mgl-feature
[properties]=""
[geometry]="{ 'type': 'Point', 'coordinates': [lng, lat] }"
[mglDraggable]="layer"
(dragStart)="onDragStop($event)"></mgl-feature>
Am I missing something? Or does this look like a bug?
Thanks!
What I could observe so far is that it actually works to have a loop of mgl-features, but:
- if I remove the
trackBy
function frommgl-feature
the dragging stops working; - if I add either a loop or an if around mgl-geojson-source (I'll need several sources) the dragging doesn't work either.
And all of that fails silently. Just for reference, the trackByFn
is:
trackByFn(index, item) {
return index; // or item.id
}
Another update: apparently, the problem occurs when the data isn't available before the initialization of the directive. Since I need to wait for an http call for my coordinates and I only make that call after the map starts up, the dragging simply doesn't "start up". I tested creating one of my objects manually at OnInit and the dragging actually worked inside a loop of mgl-geojson-sources and mgl-features.
I have managed to reproduce this. The problem was that I wasn't listening to the (mouseEnter) and (mouseLeave) events from the layers and for some reason they just won't work properly if I don't listen to these outputs.
I forked the drag example and removed the two properties from the layer and simulated a similar situation as I described up here in the issue.
https://stackblitz.com/edit/angular-29siqa
The first set of points that load with the map have the dragging working fine, but as soon as you add more layers afterwards by clicking on ADD, the dragging isn't enabled.
Once I added that to my layers in my project, the dragging worked, and this makes me believe that the event isn't being attached properly to the layer.
Pasting the code here in case stackblitz doesn't work.
import { Component } from '@angular/core';
import { MapMouseEvent } from 'mapbox-gl';
@Component({
selector: 'showcase-demo',
template: `
<mgl-map
[style]="'mapbox://styles/mapbox/streets-v9'"
[zoom]="[2]"
[center]="[0, 0]"
>
<ng-container *ngFor="let i of i_array">
<mgl-geojson-source
[id]="i+''"
>
<ng-container *ngFor="let j of j_array">
<mgl-feature
[properties]=""
[geometry]="{
'type': 'Point',
'coordinates': [i, j]
}"
[mglDraggable]="targetLayer"
></mgl-feature>
</ng-container>
</mgl-geojson-source>
<mgl-layer
#targetLayer
[id]="i+''"
type="circle"
[source]="i+''"
[paint]="layerPaint"
></mgl-layer>
</ng-container>
<mgl-control position="bottom-left">
<mat-card>
<button mat-raised-button color="primary" (click)="pushToArray()">ADD</button>
</mat-card>
</mgl-control>
</mgl-map>
`,
styleUrls: ['./examples.css']
})
export class NgxDragAPointComponent {
i_array = [1]
j_array: number[] = []
constructor() {
for(let i of [1,2,3,4]) {
this.j_array.push(35 * Math.random())
}
}
pushToArray() {
this.i_array.push(this.i_array.length + 10);
}
layerPaint = {
'circle-radius': 10,
'circle-color': '#3887be'
};
coordinates = [0, 0];
onDragStart(event: MapMouseEvent) {
// console.log('onDragStart', event);
}
onDragEnd(event: MapMouseEvent) {
// console.log('onDragEnd', event);
}
onDrag(event: MapMouseEvent) {
console.log('onDrag', event);
this.coordinates = event.lngLat.toArray();
}
changeColor(color: string) {
this.layerPaint = { ...this.layerPaint, 'circle-color': color };
}
}