@dereekb/dbx-web 9.6.5 → 9.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,13 +2,14 @@ import * as i0 from '@angular/core';
2
2
  import { Injectable, Optional, Inject, Directive, Host, Component, ElementRef, ViewChild, Input, ChangeDetectionStrategy, SkipSelf, Injector, NgModule } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
- import { latLngPointFunction, latLngBoundFunction, isSameLatLngPoint, isDefaultLatLngPoint, swMostLatLngPoint, neMostLatLngPoint, isSameLatLngBound, latLngBoundWrapsMap, isWithinLatLngBoundFunction, overlapsLatLngBoundFunction, diffLatLngBoundPoints, latLngBoundCenterPoint, addLatLngPoints, latLngPoint, DestroyFunctionObject, getValueFromGetter } from '@dereekb/util';
5
+ import { latLngPointFunction, latLngBoundFunction, isSameLatLngPoint, isDefaultLatLngPoint, swMostLatLngPoint, neMostLatLngPoint, isSameLatLngBound, diffLatLngBoundPoints, latLngBoundWrapsMap, isWithinLatLngBoundFunction, overlapsLatLngBoundFunction, vectorsAreEqual, latLngBoundCenterPoint, addLatLngPoints, latLngPoint, DestroyFunctionObject, getValueFromGetter, LAT_LONG_10M_PRECISION, roundNumberToStepFunction } from '@dereekb/util';
6
6
  import * as i1 from 'ngx-mapbox-gl';
7
7
  import { NgxMapboxGLModule } from 'ngx-mapbox-gl';
8
- import { cleanup, filterMaybe, onTrueToFalse, SubscriptionObject } from '@dereekb/rxjs';
8
+ import { cleanup, filterMaybe, onTrueToFalse, SubscriptionObject, asObservable } from '@dereekb/rxjs';
9
9
  import { ComponentStore } from '@ngrx/component-store';
10
- import { switchMap, NEVER, defaultIfEmpty, map, tap, distinctUntilChanged, shareReplay, of, combineLatest, filter, first, startWith, interval, Subject, BehaviorSubject, throttleTime } from 'rxjs';
10
+ import { switchMap, NEVER, defaultIfEmpty, map, tap, distinctUntilChanged, shareReplay, of, combineLatest, filter, first, startWith, interval, Subject, BehaviorSubject, throttleTime, combineLatestWith } from 'rxjs';
11
11
  import * as MapboxGl from 'mapbox-gl';
12
+ import { bounds } from '@mapbox/geo-viewport';
12
13
  import * as i3$1 from '@dereekb/dbx-web';
13
14
  import { dbxColorBackground, disableRightClickInCdkBackdrop, DbxRouterAnchorModule } from '@dereekb/dbx-web';
14
15
  import * as i3 from '@angular/material/sidenav';
@@ -20,7 +21,7 @@ import { MatIconModule } from '@angular/material/icon';
20
21
  import * as i6 from 'angular-resize-event';
21
22
  import { AngularResizeEventModule } from 'angular-resize-event';
22
23
  import * as i2 from '@dereekb/dbx-core';
23
- import { AbstractSubscriptionDirective, safeMarkForCheck, DbxInjectionComponentModule } from '@dereekb/dbx-core';
24
+ import { AbstractSubscriptionDirective, safeMarkForCheck, tapDetectChanges, DbxInjectionComponentModule } from '@dereekb/dbx-core';
24
25
  import * as i2$1 from '@angular/material/menu';
25
26
 
26
27
  class DbxMapboxConfig {
@@ -63,6 +64,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
63
64
  }] }];
64
65
  } });
65
66
 
67
+ function mapboxViewportBoundFunction(config) {
68
+ const { mapCanvasSize, tileSize = 512 } = config;
69
+ const dimensions = [mapCanvasSize.x, mapCanvasSize.y];
70
+ return ({ center, zoom }) => {
71
+ const boundingBox = bounds([center.lng, center.lat], zoom, dimensions, tileSize);
72
+ const [swLng, swLat, neLng, neLat] = boundingBox;
73
+ const result = {
74
+ sw: { lat: swLat, lng: swLng },
75
+ ne: { lat: neLat, lng: neLng }
76
+ };
77
+ return result;
78
+ };
79
+ }
80
+
66
81
  /**
67
82
  * Store used for retrieving information.
68
83
  */
@@ -76,8 +91,9 @@ class DbxMapboxMapStore extends ComponentStore {
76
91
  retainContent: true
77
92
  });
78
93
  this.dbxMapboxService = dbxMapboxService;
79
- this.latLngPoint = latLngPointFunction();
80
- this.latLngBound = latLngBoundFunction({ pointFunction: latLngPointFunction({ wrap: false, validate: false }) });
94
+ this.safeLatLngPoint = latLngPointFunction();
95
+ this.latLngPoint = latLngPointFunction({ wrap: false, validate: false });
96
+ this.latLngBound = latLngBoundFunction({ pointFunction: this.latLngPoint });
81
97
  // MARK: Effects
82
98
  this.setMapService = this.effect((input) => {
83
99
  return input.pipe(switchMap((service) => {
@@ -111,6 +127,12 @@ class DbxMapboxMapStore extends ComponentStore {
111
127
  addListener('click', (x) => this._setClickEvent(x));
112
128
  addListener('dblclick', (x) => this._setDoubleClickEvent(x));
113
129
  addListener('contextmenu', (x) => this._setRightClickEvent(x));
130
+ const refreshForResize = () => {
131
+ const { clientWidth: x, clientHeight: y } = map.getCanvas();
132
+ this._setMapCanvasSize({ x, y });
133
+ };
134
+ addListener('resize', refreshForResize);
135
+ refreshForResize();
114
136
  const subs = [];
115
137
  return {
116
138
  service,
@@ -143,7 +165,7 @@ class DbxMapboxMapStore extends ComponentStore {
143
165
  });
144
166
  this.setCenter = this.effect((input) => {
145
167
  return input.pipe(switchMap((center) => {
146
- const centerPoint = this.latLngPoint(center);
168
+ const centerPoint = this.safeLatLngPoint(center);
147
169
  return this.mapInstance$.pipe(tap((map) => map.setCenter(centerPoint)));
148
170
  }));
149
171
  });
@@ -263,7 +285,7 @@ class DbxMapboxMapStore extends ComponentStore {
263
285
  return input.pipe(switchMap((x) => {
264
286
  var _a, _b;
265
287
  const inputCenter = (_a = x.center) !== null && _a !== void 0 ? _a : (_b = x.to) === null || _b === void 0 ? void 0 : _b.center;
266
- const center = inputCenter ? this.latLngPoint(inputCenter) : undefined;
288
+ const center = inputCenter ? this.safeLatLngPoint(inputCenter) : undefined;
267
289
  return this.mapInstance$.pipe(tap((map) => map.jumpTo(Object.assign(Object.assign({}, x.to), { center }), x.eventData)));
268
290
  }));
269
291
  });
@@ -271,7 +293,7 @@ class DbxMapboxMapStore extends ComponentStore {
271
293
  return input.pipe(switchMap((x) => {
272
294
  var _a, _b;
273
295
  const inputCenter = (_a = x.center) !== null && _a !== void 0 ? _a : (_b = x.to) === null || _b === void 0 ? void 0 : _b.center;
274
- const center = inputCenter ? this.latLngPoint(inputCenter) : undefined;
296
+ const center = inputCenter ? this.safeLatLngPoint(inputCenter) : undefined;
275
297
  return this.mapInstance$.pipe(tap((map) => map.easeTo(Object.assign(Object.assign({}, x.to), { center }), x.eventData)));
276
298
  }));
277
299
  });
@@ -279,7 +301,7 @@ class DbxMapboxMapStore extends ComponentStore {
279
301
  return input.pipe(switchMap((x) => {
280
302
  var _a, _b;
281
303
  const inputCenter = (_a = x.center) !== null && _a !== void 0 ? _a : (_b = x.to) === null || _b === void 0 ? void 0 : _b.center;
282
- const center = inputCenter ? this.latLngPoint(inputCenter) : undefined;
304
+ const center = inputCenter ? this.safeLatLngPoint(inputCenter) : undefined;
283
305
  return this.mapInstance$.pipe(tap((map) => map.flyTo(Object.assign(Object.assign({}, x.to), { center }), x.eventData)));
284
306
  }));
285
307
  });
@@ -348,30 +370,34 @@ class DbxMapboxMapStore extends ComponentStore {
348
370
  const bound = x.getBounds();
349
371
  const boundSw = bound.getSouthWest();
350
372
  const boundNe = bound.getNorthEast();
351
- const sw = isDefaultLatLngPoint(boundSw) ? swMostLatLngPoint() : boundSw;
352
- const ne = isDefaultLatLngPoint(boundNe) ? neMostLatLngPoint() : boundNe;
373
+ const sw = isDefaultLatLngPoint(boundSw) ? swMostLatLngPoint() : { lat: boundSw.lat, lng: boundSw.lng };
374
+ const ne = isDefaultLatLngPoint(boundNe) ? neMostLatLngPoint() : { lat: boundNe.lat, lng: boundNe.lng };
353
375
  return this.latLngBound(sw, ne);
354
376
  }))), shareReplay(1))));
355
377
  this.bound$ = this.whenInitialized$.pipe(switchMap(() => {
356
378
  return this.isRendering$.pipe(onTrueToFalse(), startWith(undefined), switchMap((x) => this.boundNow$.pipe(first())), distinctUntilChanged(isSameLatLngBound), shareReplay(1));
357
379
  }));
380
+ this.boundSizing$ = this.bound$.pipe(map((x) => diffLatLngBoundPoints(x)), shareReplay(1));
358
381
  this.boundWrapsAroundWorld$ = this.bound$.pipe(map((x) => latLngBoundWrapsMap(x)), distinctUntilChanged(), shareReplay(1));
359
382
  this.isWithinBoundFunction$ = this.bound$.pipe(map((x) => isWithinLatLngBoundFunction(x)), shareReplay(1));
360
383
  this.overlapsBoundFunction$ = this.bound$.pipe(map((x) => overlapsLatLngBoundFunction(x)), shareReplay(1));
361
384
  this.zoomNow$ = this.whenInitialized$.pipe(switchMap(() => this.mapInstance$.pipe(switchMap((x) => this._renderingTimer.pipe(map(() => x.getZoom()))), shareReplay(1))));
362
385
  this.zoom$ = this.whenInitialized$.pipe(switchMap(() => {
363
- return this.isZooming$.pipe(onTrueToFalse(), startWith(undefined), switchMap((x) => this.zoomNow$.pipe(first())), distinctUntilChanged(), shareReplay(1));
386
+ return this.isZooming$.pipe(onTrueToFalse(), startWith(undefined), switchMap(() => this.zoomNow$.pipe(first())), distinctUntilChanged(), shareReplay(1));
364
387
  }));
365
388
  this.pitchNow$ = this.whenInitialized$.pipe(switchMap(() => this.mapInstance$.pipe(switchMap((x) => this._movingTimer.pipe(map(() => x.getPitch()))), shareReplay(1))));
366
389
  this.pitch$ = this.whenInitialized$.pipe(switchMap(() => {
367
- return this.isRotating$.pipe(onTrueToFalse(), startWith(undefined), switchMap((x) => this.pitchNow$.pipe(first())), distinctUntilChanged(), shareReplay(1));
390
+ return this.isRotating$.pipe(onTrueToFalse(), startWith(undefined), switchMap(() => this.pitchNow$.pipe(first())), distinctUntilChanged(), shareReplay(1));
368
391
  }));
369
392
  this.bearingNow$ = this.whenInitialized$.pipe(switchMap(() => this.mapInstance$.pipe(switchMap((x) => this._movingTimer.pipe(map(() => x.getBearing()))), shareReplay(1))));
370
393
  this.bearing$ = this.whenInitialized$.pipe(switchMap(() => {
371
- return this.isRotating$.pipe(onTrueToFalse(), startWith(undefined), switchMap((x) => this.bearingNow$.pipe(first())), distinctUntilChanged(), shareReplay(1));
394
+ return this.isRotating$.pipe(onTrueToFalse(), startWith(undefined), switchMap(() => this.bearingNow$.pipe(first())), distinctUntilChanged(), shareReplay(1));
372
395
  }));
373
396
  this.content$ = this.state$.pipe(map((x) => x.content), distinctUntilChanged(), shareReplay(1));
374
397
  this.hasContent$ = this.content$.pipe(map(Boolean));
398
+ this.currentMapCanvasSize$ = this.state$.pipe(map((x) => x.mapCanvasSize), distinctUntilChanged((a, b) => a != null && b != null && vectorsAreEqual(a, b)), shareReplay(1));
399
+ this.mapCanvasSize$ = this.currentMapCanvasSize$.pipe(filterMaybe());
400
+ this.viewportBoundFunction$ = this.mapCanvasSize$.pipe(map((x) => mapboxViewportBoundFunction({ mapCanvasSize: x })), shareReplay(1));
375
401
  this.clickEvent$ = this.state$.pipe(map((x) => x.clickEvent), distinctUntilChanged(), shareReplay(1));
376
402
  this.doubleClickEvent$ = this.state$.pipe(map((x) => x.doubleClickEvent), distinctUntilChanged(), shareReplay(1));
377
403
  this.rightClickEvent$ = this.state$.pipe(map((x) => x.rightClickEvent), distinctUntilChanged(), shareReplay(1));
@@ -382,6 +408,7 @@ class DbxMapboxMapStore extends ComponentStore {
382
408
  this._setMoveState = this.updater((state, moveState) => (Object.assign(Object.assign({}, state), { moveState })));
383
409
  this._setZoomState = this.updater((state, zoomState) => (Object.assign(Object.assign({}, state), { zoomState })));
384
410
  this._setRotateState = this.updater((state, rotateState) => (Object.assign(Object.assign({}, state), { rotateState })));
411
+ this._setMapCanvasSize = this.updater((state, mapCanvasSize) => (Object.assign(Object.assign({}, state), { mapCanvasSize })));
385
412
  this._setClickEvent = this.updater((state, clickEvent) => (Object.assign(Object.assign({}, state), { clickEvent })));
386
413
  this._setDoubleClickEvent = this.updater((state, doubleClickEvent) => (Object.assign(Object.assign({}, state), { doubleClickEvent })));
387
414
  this._setRightClickEvent = this.updater((state, rightClickEvent) => (Object.assign(Object.assign({}, state), { rightClickEvent })));
@@ -428,7 +455,7 @@ class DbxMapboxMapStore extends ComponentStore {
428
455
  }
429
456
  calculateNextCenterOffsetWithScreenMarginChange(sizing) {
430
457
  return this.atNextIdle().pipe(switchMap(() => this.bound$.pipe(first(), map((bounds) => {
431
- const diff = diffLatLngBoundPoints(bounds);
458
+ const diff = diffLatLngBoundPoints(bounds, true);
432
459
  const center = latLngBoundCenterPoint(bounds);
433
460
  const offsetWidth = sizing.leftMargin + sizing.rightMargin; // 300 + 0
434
461
  const newWidth = sizing.fullWidth - offsetWidth; // 1000 - 300 - 0
@@ -905,7 +932,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImpor
905
932
  * Component used to render a set of DbxMapboxMarker values from the input data and marker factory.
906
933
  */
907
934
  class DbxMapboxMarkersComponent {
908
- constructor() {
935
+ constructor(cdRef) {
936
+ this.cdRef = cdRef;
909
937
  this._data = new BehaviorSubject(undefined);
910
938
  this._markerFactory = new BehaviorSubject(undefined);
911
939
  this.markers$ = combineLatest([this._data.pipe(distinctUntilChanged()), this._markerFactory.pipe(distinctUntilChanged())]).pipe(map(([data, markerFactory]) => {
@@ -915,7 +943,7 @@ class DbxMapboxMarkersComponent {
915
943
  else {
916
944
  return [];
917
945
  }
918
- }), shareReplay(1));
946
+ }), tapDetectChanges(this.cdRef), shareReplay(1));
919
947
  }
920
948
  get data() {
921
949
  return this._data.value;
@@ -934,19 +962,20 @@ class DbxMapboxMarkersComponent {
934
962
  this._markerFactory.complete();
935
963
  }
936
964
  }
937
- DbxMapboxMarkersComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: DbxMapboxMarkersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
965
+ DbxMapboxMarkersComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: DbxMapboxMarkersComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
938
966
  DbxMapboxMarkersComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.2", type: DbxMapboxMarkersComponent, selector: "dbx-mapbox-markers", inputs: { data: "data", markerFactory: "markerFactory" }, ngImport: i0, template: `
939
967
  <dbx-mapbox-marker *ngFor="let marker of markers$ | async" [marker]="marker"></dbx-mapbox-marker>
940
- `, isInline: true, dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: DbxMapboxMarkerComponent, selector: "dbx-mapbox-marker", inputs: ["marker"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }] });
968
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: DbxMapboxMarkerComponent, selector: "dbx-mapbox-marker", inputs: ["marker"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
941
969
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.2", ngImport: i0, type: DbxMapboxMarkersComponent, decorators: [{
942
970
  type: Component,
943
971
  args: [{
944
972
  selector: 'dbx-mapbox-markers',
945
973
  template: `
946
974
  <dbx-mapbox-marker *ngFor="let marker of markers$ | async" [marker]="marker"></dbx-mapbox-marker>
947
- `
975
+ `,
976
+ changeDetection: ChangeDetectionStrategy.OnPush
948
977
  }]
949
- }], propDecorators: { data: [{
978
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { data: [{
950
979
  type: Input
951
980
  }], markerFactory: [{
952
981
  type: Input
@@ -1051,6 +1080,56 @@ function dbxMapboxColoredDotStyle(background, color) {
1051
1080
  };
1052
1081
  }
1053
1082
 
1083
+ /**
1084
+ * Filters the input objects based on their center and zoom values.
1085
+ *
1086
+ * This function caches the bounds computations for each of the input values.
1087
+ *
1088
+ * @param config
1089
+ * @returns
1090
+ */
1091
+ function filterByMapboxViewportBound(config) {
1092
+ const { boundDecisionObs: inputBoundDecisionObs, boundFunctionObs: inputBoundFunctionObs, defaultZoom: inputDefaultZoom = 17, readValue, zoomRounding, precision = LAT_LONG_10M_PRECISION } = config;
1093
+ const _latLngPoint = latLngPointFunction({ wrap: false, validate: false, precision });
1094
+ const _roundZoom = roundNumberToStepFunction(zoomRounding || { step: 0.5, round: 'floor' });
1095
+ const boundDecisionObs = asObservable(inputBoundDecisionObs);
1096
+ const boundFunctionObs = asObservable(inputBoundFunctionObs);
1097
+ return (input) => {
1098
+ return boundFunctionObs.pipe(distinctUntilChanged(), switchMap((viewportBoundFunction) => {
1099
+ const cache = new Map();
1100
+ return input.pipe(map((values) => {
1101
+ return values.map((value) => {
1102
+ const item = readValue(value);
1103
+ const centerLatLng = _latLngPoint(item.center);
1104
+ const zoomStep = _roundZoom(item.zoom || inputDefaultZoom);
1105
+ const cacheKey = `${zoomStep}_${centerLatLng.lat}_${centerLatLng.lng}`;
1106
+ const cachedValue = cache.get(cacheKey);
1107
+ let bound;
1108
+ if (!cachedValue) {
1109
+ bound = viewportBoundFunction({ center: centerLatLng, zoom: zoomStep });
1110
+ cache.set(cacheKey, bound);
1111
+ }
1112
+ else {
1113
+ bound = cachedValue;
1114
+ }
1115
+ return {
1116
+ value,
1117
+ bound
1118
+ };
1119
+ });
1120
+ }), combineLatestWith(boundDecisionObs), map(([items, boundFunction]) => {
1121
+ let valuesInBounds = [];
1122
+ items.forEach((item) => {
1123
+ if (boundFunction(item.bound)) {
1124
+ valuesInBounds.push(item.value);
1125
+ }
1126
+ });
1127
+ return valuesInBounds;
1128
+ }));
1129
+ }), shareReplay(1));
1130
+ };
1131
+ }
1132
+
1054
1133
  const KNOWN_MAPBOX_STYLES = [
1055
1134
  //
1056
1135
  'mapbox://styles/mapbox/streets-v11',
@@ -1072,5 +1151,5 @@ function mapboxZoomLevel(input) {
1072
1151
  * Generated bundle index. Do not edit.
1073
1152
  */
1074
1153
 
1075
- export { DEFAULT_MAPBOX_CENTER, DEFAULT_MAPBOX_MAP_STORE_TIMER_REFRESH_PERIOD, DEFAULT_MAPBOX_STYLE, DEFAULT_MAPBOX_ZOOM, DbxMapboxConfig, DbxMapboxLayoutComponent, DbxMapboxLayoutDrawerComponent, DbxMapboxMapDirective, DbxMapboxMapStore, DbxMapboxMapStoreInjectionBlockDirective, DbxMapboxMapStoreProviderBlock, DbxMapboxMarkerComponent, DbxMapboxMarkersComponent, DbxMapboxMenuComponent, DbxMapboxModule, DbxMapboxService, KNOWN_MAPBOX_STYLES, MAPBOX_MAX_ZOOM_LEVEL, MAPBOX_MIN_ZOOM_LEVEL, dbxMapboxColoredDotStyle, mapboxZoomLevel, provideMapboxStoreIfParentIsUnavailable };
1154
+ export { DEFAULT_MAPBOX_CENTER, DEFAULT_MAPBOX_MAP_STORE_TIMER_REFRESH_PERIOD, DEFAULT_MAPBOX_STYLE, DEFAULT_MAPBOX_ZOOM, DbxMapboxConfig, DbxMapboxLayoutComponent, DbxMapboxLayoutDrawerComponent, DbxMapboxMapDirective, DbxMapboxMapStore, DbxMapboxMapStoreInjectionBlockDirective, DbxMapboxMapStoreProviderBlock, DbxMapboxMarkerComponent, DbxMapboxMarkersComponent, DbxMapboxMenuComponent, DbxMapboxModule, DbxMapboxService, KNOWN_MAPBOX_STYLES, MAPBOX_MAX_ZOOM_LEVEL, MAPBOX_MIN_ZOOM_LEVEL, dbxMapboxColoredDotStyle, filterByMapboxViewportBound, mapboxViewportBoundFunction, mapboxZoomLevel, provideMapboxStoreIfParentIsUnavailable };
1076
1155
  //# sourceMappingURL=dereekb-dbx-web-mapbox.mjs.map