From 0a60463cc592f2519da0ad14c0042afbc3c18a90 Mon Sep 17 00:00:00 2001 From: Dmytro Gokun Date: Mon, 1 Jul 2019 19:04:07 +0300 Subject: [PATCH] Add support for dynamically changing image source properties (#139) --- package.json | 2 +- .../ngx-mapbox-gl/src/lib/map/map.service.ts | 2 +- .../src/lib/source/image-source.component.ts | 47 ++++++------ projects/showcase/src/app/demo/demo.module.ts | 3 + .../live-update-image-srource.component.ts | 71 ++++++++++++++++++ projects/showcase/src/assets/blue.png | Bin 0 -> 149 bytes projects/showcase/src/assets/red.png | Bin 0 -> 149 bytes yarn.lock | 8 +- 8 files changed, 101 insertions(+), 32 deletions(-) create mode 100644 projects/showcase/src/app/demo/examples/live-update-image-srource.component.ts create mode 100644 projects/showcase/src/assets/blue.png create mode 100644 projects/showcase/src/assets/red.png diff --git a/package.json b/package.json index f94ac543d..c3d42f38f 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@types/jasmine": "^3.3.12", "@types/jasminewd2": "^2.0.6", "@types/lodash-es": "^4.17.3", - "@types/mapbox-gl": "^0.51.7", + "@types/mapbox-gl": "^0.51.9", "@types/node": "^11.13.0", "@types/supercluster": "^5.0.1", "codelyzer": "^5.0.0", diff --git a/projects/ngx-mapbox-gl/src/lib/map/map.service.ts b/projects/ngx-mapbox-gl/src/lib/map/map.service.ts index a687c6d43..db575f322 100644 --- a/projects/ngx-mapbox-gl/src/lib/map/map.service.ts +++ b/projects/ngx-mapbox-gl/src/lib/map/map.service.ts @@ -56,7 +56,7 @@ export interface SetupMarker { export type AllSource = MapboxGl.VectorSource | MapboxGl.RasterSource | MapboxGl.GeoJSONSource | - MapboxGl.ImageSourceOptions | + MapboxGl.ImageSource | MapboxGl.VideoSourceOptions | MapboxGl.GeoJSONSourceRaw | MapboxGl.CanvasSourceOptions; diff --git a/projects/ngx-mapbox-gl/src/lib/source/image-source.component.ts b/projects/ngx-mapbox-gl/src/lib/source/image-source.component.ts index f7d137707..9653c1487 100644 --- a/projects/ngx-mapbox-gl/src/lib/source/image-source.component.ts +++ b/projects/ngx-mapbox-gl/src/lib/source/image-source.component.ts @@ -1,7 +1,6 @@ import { ChangeDetectionStrategy, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; -import { ImageSourceOptions } from 'mapbox-gl'; -import { fromEvent, Subscription } from 'rxjs'; -import { filter } from 'rxjs/operators'; +import { ImageSourceOptions, ImageSource } from 'mapbox-gl'; +import { Subscription } from 'rxjs'; import { MapService } from '../map/map.service'; @Component({ @@ -17,42 +16,38 @@ export class ImageSourceComponent implements OnInit, OnDestroy, OnChanges, Image @Input() url: string; @Input() coordinates: number[][]; - private sourceAdded = false; - private sub = new Subscription(); + private sub: Subscription; + private sourceId?: string; constructor( private MapService: MapService ) { } ngOnInit() { - this.MapService.mapLoaded$.subscribe(() => { - this.init(); - const sub = fromEvent(this.MapService.mapInstance, 'styledata').pipe( - filter(() => !this.MapService.mapInstance.getSource(this.id)) - ).subscribe(() => { - this.init(); - }); - this.sub.add(sub); - }); + this.sub = this.MapService.mapLoaded$ + .subscribe(() => this.init()); } ngOnChanges(changes: SimpleChanges) { - if (!this.sourceAdded) { + if (this.sourceId === undefined) { return; } - if ( - changes.url && !changes.url.isFirstChange() || - changes.coordinates && !changes.coordinates.isFirstChange() - ) { - this.ngOnDestroy(); - this.ngOnInit(); - } + + const source = this.MapService.getSource(this.sourceId); + // TODO: we need this cast until mapbox typings are fixed (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/36589). + (source as any).updateImage({ + url: changes.url === undefined ? undefined : this.url, + coordinates: changes.coordinates === undefined ? undefined : this.coordinates + }); } ngOnDestroy() { - this.sub.unsubscribe(); - if (this.sourceAdded) { - this.MapService.removeSource(this.id); + if (this.sub !== undefined) { + this.sub.unsubscribe(); + } + + if (this.sourceId !== undefined) { + this.MapService.removeSource(this.sourceId); } } @@ -62,6 +57,6 @@ export class ImageSourceComponent implements OnInit, OnDestroy, OnChanges, Image url: this.url, coordinates: this.coordinates }); - this.sourceAdded = true; + this.sourceId = this.id; } } diff --git a/projects/showcase/src/app/demo/demo.module.ts b/projects/showcase/src/app/demo/demo.module.ts index 5f0684643..ecd1ebcb2 100644 --- a/projects/showcase/src/app/demo/demo.module.ts +++ b/projects/showcase/src/app/demo/demo.module.ts @@ -27,6 +27,7 @@ import { HoverStylesComponent } from './examples/hover-styles.component'; import { InteractiveFalseComponent } from './examples/interactive-false.component'; import { LanguageSwitchComponent } from './examples/language-switch.component'; import { LiveUpdateFeatureComponent } from './examples/live-update-feature.component'; +import { LiveUpdateImageSourceComponent } from './examples/live-update-image-srource.component'; import { LocateUserComponent } from './examples/locate-user.component'; import { MapboxGlGeocoderComponent } from './examples/mapbox-gl-geocoder.component'; import { NavigationComponent } from './examples/navigation.component'; @@ -78,6 +79,7 @@ export const DEMO_ROUTES: Routes = [ { path: 'custom-marker-icons', component: CustomMarkerIconsComponent, data: { label: 'Add custom icons with Markers', cat: Category.CONTROLS_AND_OVERLAYS } }, { path: 'ngx-custom-marker-icons', component: NgxCustomMarkerIconsComponent, data: { label: '[NGX] Add custom icons with Markers', cat: Category.CONTROLS_AND_OVERLAYS } }, { path: 'live-update-feature', component: LiveUpdateFeatureComponent, data: { label: 'Update a feature in realtime', cat: Category.SOURCES } }, + { path: 'live-update-image-source', component: LiveUpdateImageSourceComponent, data: { label: 'Update an image source in realtime', cat: Category.SOURCES } }, { path: 'popup', component: PopupComponent, data: { label: 'Display a popup', cat: Category.CONTROLS_AND_OVERLAYS } }, { path: 'set-popup', component: SetPopupComponent, data: { label: 'Attach a popup to a marker instance', cat: Category.CONTROLS_AND_OVERLAYS } }, { path: 'fullscreen', component: FullscreenComponent, data: { label: 'View a fullscreen map', cat: Category.CONTROLS_AND_OVERLAYS } }, @@ -133,6 +135,7 @@ export const DEMO_ROUTES: Routes = [ CustomMarkerIconsComponent, NgxCustomMarkerIconsComponent, LiveUpdateFeatureComponent, + LiveUpdateImageSourceComponent, PopupComponent, SetPopupComponent, FullscreenComponent, diff --git a/projects/showcase/src/app/demo/examples/live-update-image-srource.component.ts b/projects/showcase/src/app/demo/examples/live-update-image-srource.component.ts new file mode 100644 index 000000000..51a65e1df --- /dev/null +++ b/projects/showcase/src/app/demo/examples/live-update-image-srource.component.ts @@ -0,0 +1,71 @@ +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { interval, Subscription } from 'rxjs'; + +@Component({ + selector: 'showcase-demo', + template: ` + + + + + + + + `, + styleUrls: ['./examples.css'] +}) +export class LiveUpdateImageSourceComponent implements OnInit, OnDestroy { + private sub: Subscription; + private readonly size = 0.001; + center: number[]; + + url = 'assets/red.png'; + coordinates: number[][]; + + async ngOnInit() { + const data: GeoJSON.FeatureCollection = await import('./hike.geo.json'); + const points = data.features[0].geometry!.coordinates; + const coordinates = points.map(c => this.makeRectangle(c)); + + this.center = points[0]; + this.coordinates = coordinates[0]; + + let i = 0; + + this.sub = interval(250) + .subscribe(() => { + this.url = Math.random() < 0.5 ? 'assets/red.png' : 'assets/blue.png'; + this.coordinates = coordinates[i]; + i = (i + 1) % coordinates.length; + }); + } + + ngOnDestroy() { + if (this.sub !== undefined) { + this.sub.unsubscribe(); + } + } + + private makeRectangle([long, lat]: number[]): number[][] { + return [ + [long, lat], + [long + this.size, lat], + [long + this.size, lat - this.size], + [long, lat - this.size] + ]; + } +} diff --git a/projects/showcase/src/assets/blue.png b/projects/showcase/src/assets/blue.png new file mode 100644 index 0000000000000000000000000000000000000000..c8320be9f63cbe2296354711997322c0f8037c6b GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{1|(OCFP#RY7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0h7I;J!GcfQS0b$0e+I-SLK`l=g#}Etuk44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`0h7I;J!GcfQS0b$0e+I-SLK`l=g#}Etuc p_