Skip to content

Commit 2dbabf4

Browse files
author
Wykks
committed
feat(layer): add click/mouseEnter/mouseLeave Output
add language switch example add center on symbol example
1 parent 9cc9abf commit 2dbabf4

10 files changed

+241
-31
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
"**/CVS": true,
77
"**/.DS_Store": true,
88
".ng_build": true
9-
}
9+
},
10+
"typescript.tsdk": "node_modules/typescript/lib"
1011
}

e2e/language-switch.e2e-spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { browser, element, by, ExpectedConditions as EC } from 'protractor';
2+
const PixelDiff = require('pixel-diff');
3+
const browserLogs = require('protractor-browser-logs');
4+
5+
describe('Language switch', () => {
6+
let logs: any;
7+
8+
beforeEach(() => {
9+
logs = browserLogs(browser);
10+
});
11+
12+
afterEach(() => {
13+
return logs.verify();
14+
});
15+
16+
it('should change language', async () => {
17+
await browser.get('/language-switch');
18+
const elm = element(by.tagName('canvas'));
19+
await browser.wait(EC.presenceOf(elm), 2000);
20+
const buttons = await browser.findElements(by.tagName('button'));
21+
await browser.sleep(4000);
22+
await buttons[0].click();
23+
await browser.sleep(2000);
24+
const screen1 = await browser.takeScreenshot();
25+
await buttons[1].click();
26+
await browser.sleep(2000);
27+
const screen2 = await browser.takeScreenshot();
28+
const result = new PixelDiff({
29+
imageA: new Buffer(screen1, 'base64'),
30+
imageB: new Buffer(screen2, 'base64')
31+
}).runSync();
32+
expect(result.differences).toBeGreaterThan(0);
33+
await buttons[0].click();
34+
await browser.sleep(2000);
35+
const screen1bis = await browser.takeScreenshot();
36+
const result2 = new PixelDiff({
37+
imageA: new Buffer(screen1, 'base64'),
38+
imageB: new Buffer(screen1bis, 'base64')
39+
}).runSync();
40+
expect(result2.differences).toBe(0);
41+
});
42+
});

e2e/runtime-check.e2e-spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ describe('Generic runtime error check', () => {
3030
'locate-user',
3131
'ngx-attribution',
3232
'ngx-scale-control',
33-
'interactive-false'
33+
'interactive-false',
34+
'center-on-symbol'
3435
].forEach((route: string) => {
3536
it(`should display a map without errors for /${route}`, async () => {
3637
await browser.get(`/${route}`);
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { MapComponent } from '../../lib';
2+
import { Component, ViewChild } from '@angular/core';
3+
import { MapMouseEvent } from 'mapbox-gl';
4+
5+
@Component({
6+
template: `
7+
<mgl-map
8+
[style]="'mapbox://styles/mapbox/light-v9'"
9+
[zoom]="8"
10+
[center]="center"
11+
#map
12+
>
13+
<mgl-geojson-source
14+
id="symbols-source"
15+
>
16+
<mgl-feature
17+
*ngFor="let geometry of geometries"
18+
[geometry]="geometry"
19+
></mgl-feature>
20+
</mgl-geojson-source>
21+
<mgl-layer
22+
id="symbols"
23+
type="symbol"
24+
source="symbols-source"
25+
[layout]="{
26+
'icon-image': 'rocket-15'
27+
}"
28+
(click)="centerMapTo($event)"
29+
(mouseEnter)="changeCursorToPointer()"
30+
(mouseLeave)="changeCursorToDefault()"
31+
>
32+
</mgl-layer>
33+
</mgl-map>
34+
`,
35+
styleUrls: ['./examples.css']
36+
})
37+
export class CenterOnSymbolComponent {
38+
@ViewChild('map') map: MapComponent;
39+
40+
center = [-90.96, -0.47];
41+
42+
geometries = [
43+
{
44+
'type': 'Point',
45+
'coordinates': [
46+
-91.395263671875,
47+
-0.9145729757782163
48+
49+
]
50+
},
51+
{
52+
'type': 'Point',
53+
'coordinates': [
54+
-90.32958984375,
55+
-0.6344474832838974
56+
]
57+
},
58+
{
59+
'type': 'Point',
60+
'coordinates': [
61+
-91.34033203125,
62+
0.01647949196029245
63+
]
64+
}
65+
];
66+
67+
centerMapTo(evt: MapMouseEvent) {
68+
this.center = (<any>evt).features[0].geometry.coordinates;
69+
}
70+
71+
changeCursorToPointer() {
72+
this.map.mapInstance.getCanvas().style.cursor = 'pointer';
73+
}
74+
75+
changeCursorToDefault() {
76+
this.map.mapInstance.getCanvas().style.cursor = '';
77+
}
78+
}
File renamed without changes.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Component, ViewChild } from '@angular/core';
2+
import { MapComponent } from '../../lib';
3+
4+
@Component({
5+
template: `
6+
<mgl-map
7+
style="mapbox://styles/mapbox/light-v9"
8+
[zoom]="2.9"
9+
[center]="[16.05, 48]"
10+
#map
11+
>
12+
<mgl-control>
13+
<button
14+
mat-raised-button
15+
(click)="changeLangTo('fr')"
16+
>French</button>
17+
<button
18+
mat-raised-button
19+
(click)="changeLangTo('ru')"
20+
>Russian</button>
21+
<button
22+
mat-raised-button
23+
(click)="changeLangTo('de')"
24+
>German</button>
25+
<button
26+
mat-raised-button
27+
(click)="changeLangTo('es')"
28+
>Spanish</button>
29+
</mgl-control>
30+
</mgl-map>
31+
`,
32+
styleUrls: ['./examples.css', './toggle-layers.component.css']
33+
})
34+
export class LanguageSwitchComponent {
35+
@ViewChild('map') map: MapComponent;
36+
37+
changeLangTo(language: string) {
38+
this.map.mapInstance.setLayoutProperty('country-label-lg', 'text-field', '{name_' + language + '}');
39+
}
40+
}

src/app/demo/module.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms';
44
import { MatButtonToggleModule, MatRadioModule, MatButtonModule } from '@angular/material';
55
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
66
import { RouterModule, Routes } from '@angular/router';
7-
import { NgxMapboxGLModule } from '../lib/lib.module';
7+
import { NgxMapboxGLModule } from '../lib';
88
import { AddImageGeneratedComponent } from './examples/add-image-generated.component';
99
import { AddImageComponent } from './examples/add-image.component';
1010
import { AttachPopupComponent } from './examples/attach-popup.component';
@@ -29,7 +29,9 @@ import { LocateUserComponent } from './examples/locate-user.component';
2929
import { NgxAttributionComponent } from './examples/ngx-attribution.component';
3030
import { NgxScaleControlComponent } from './examples/ngx-scale-control.component';
3131
import { NgxCustomControlComponent } from './examples/ngx-custom-control.component';
32-
import { InteractiveFalseComponent } from './examples/interactive-false';
32+
import { InteractiveFalseComponent } from './examples/interactive-false.component';
33+
import { LanguageSwitchComponent } from './examples/language-switch.component';
34+
import { CenterOnSymbolComponent } from './examples/center-on-symbol.component';
3335

3436
export const demoRoutes: Routes = [
3537
{ path: '', component: IndexComponent },
@@ -56,6 +58,8 @@ export const demoRoutes: Routes = [
5658
{ path: 'ngx-scale-control', component: NgxScaleControlComponent },
5759
{ path: 'ngx-custom-control', component: NgxCustomControlComponent },
5860
{ path: 'interactive-false', component: InteractiveFalseComponent },
61+
{ path: 'language-switch', component: LanguageSwitchComponent },
62+
{ path: 'ngx-center-on-symbol', component: CenterOnSymbolComponent },
5963
];
6064

6165
@NgModule({
@@ -96,7 +100,9 @@ export const demoRoutes: Routes = [
96100
NgxAttributionComponent,
97101
NgxScaleControlComponent,
98102
NgxCustomControlComponent,
99-
InteractiveFalseComponent
103+
InteractiveFalseComponent,
104+
LanguageSwitchComponent,
105+
CenterOnSymbolComponent
100106
]
101107
})
102108
export class DemoModule { }

src/app/lib/layer/layer.component.ts

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, Input, OnDestroy, OnInit, SimpleChanges, OnChanges } from '@angular/core';
1+
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
22
import {
33
BackgroundLayout,
44
CircleLayout,
@@ -20,7 +20,8 @@ import {
2020
LinePaint,
2121
SymbolPaint,
2222
RasterPaint,
23-
CirclePaint
23+
CirclePaint,
24+
MapMouseEvent
2425
} from 'mapbox-gl';
2526
import { MapService } from '../map/map.service';
2627

@@ -34,9 +35,7 @@ export class LayerComponent implements OnInit, OnDestroy, OnChanges, Layer {
3435
@Input() source?: string | VectorSource | RasterSource | GeoJSONSource | ImageSource | VideoSource | GeoJSONSourceRaw;
3536
@Input() type?: 'symbol' | 'fill' | 'line' | 'circle' | 'fill-extrusion' | 'raster' | 'background';
3637
@Input() metadata?: any;
37-
@Input() ref?: string;
3838
@Input() sourceLayer?: string;
39-
@Input() interactive?: boolean;
4039

4140
/* Dynamic inputs */
4241
@Input() filter?: any[];
@@ -46,30 +45,45 @@ export class LayerComponent implements OnInit, OnDestroy, OnChanges, Layer {
4645
@Input() minzoom?: number;
4746
@Input() maxzoom?: number;
4847

48+
@Output() click = new EventEmitter<MapMouseEvent>();
49+
@Output() mouseEnter = new EventEmitter<MapMouseEvent>();
50+
@Output() mouseLeave = new EventEmitter<MapMouseEvent>();
51+
52+
private layerAdded = false;
53+
4954
constructor(
5055
private MapService: MapService
5156
) { }
5257

5358
ngOnInit() {
5459
this.MapService.mapLoaded$.subscribe(() => {
5560
this.MapService.addLayer({
56-
id: this.id,
57-
type: this.type,
58-
source: this.source,
59-
metadata: this.metadata,
60-
ref: this.ref,
61-
'source-layer': this.sourceLayer,
62-
minzoom: this.minzoom,
63-
maxzoom: this.maxzoom,
64-
interactive: this.interactive,
65-
filter: this.filter,
66-
layout: this.layout,
67-
paint: this.paint
61+
layerOptions: {
62+
id: this.id,
63+
type: this.type,
64+
source: this.source,
65+
metadata: this.metadata,
66+
'source-layer': this.sourceLayer,
67+
minzoom: this.minzoom,
68+
maxzoom: this.maxzoom,
69+
filter: this.filter,
70+
layout: this.layout,
71+
paint: this.paint
72+
},
73+
layerEvents: {
74+
click: this.click,
75+
mouseEnter: this.mouseEnter,
76+
mouseLeave: this.mouseLeave
77+
}
6878
}, this.before);
79+
this.layerAdded = true;
6980
});
7081
}
7182

7283
ngOnChanges(changes: SimpleChanges) {
84+
if (!this.layerAdded) {
85+
return;
86+
}
7387
if (changes.paint && !changes.paint.isFirstChange()) {
7488
this.MapService.setAllLayerPaintProperty(this.id, changes.paint.currentValue!);
7589
}

src/app/lib/map/map.component.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MapService, SetupOptions } from './map.service';
1+
import { MapService, SetupMap } from './map.service';
22
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
33

44
import { MapComponent } from './map.component';
@@ -43,7 +43,7 @@ describe('MapComponent', () => {
4343
it('should init with custom inputs', (done: DoneFn) => {
4444
component.accessToken = 'tokenTest';
4545
component.style = 'style';
46-
msSpy.setup.and.callFake((options: SetupOptions) => {
46+
msSpy.setup.and.callFake((options: SetupMap) => {
4747
expect(options.accessToken).toEqual('tokenTest');
4848
expect(options.mapOptions.style).toEqual('style');
4949
done();

0 commit comments

Comments
 (0)