File

src/lib/services/fit-bounds.ts

Description

The FitBoundsService is responsible for computing the bounds of the a single map.

Index

Properties
Methods

Constructor

constructor(loader: MapsAPILoader)
Parameters :
Name Type Optional
loader MapsAPILoader No

Methods

Protected _createIdentifier
_createIdentifier(latLng: google.maps.LatLng | google.maps.LatLngLiteral)
Parameters :
Name Type Optional
latLng google.maps.LatLng | google.maps.LatLngLiteral No
Returns : string
Public addToBounds
addToBounds(latLng: GeoPoint)
Parameters :
Name Type Optional
latLng GeoPoint No
Returns : void
Public changeFitBoundsChangeSampleTime
changeFitBoundsChangeSampleTime(timeMs: number)
Parameters :
Name Type Optional
timeMs number No
Returns : void
Protected Abstract generateBounds
generateBounds(includeInBounds: Map<string | GeoPoint>)
Parameters :
Name Type Optional
includeInBounds Map<string | GeoPoint> No
Returns : BoundsLiteral
Public getBounds$
getBounds$()
Public removeFromBounds
removeFromBounds(latLng: google.maps.LatLng | google.maps.LatLngLiteral)
Parameters :
Name Type Optional
latLng google.maps.LatLng | google.maps.LatLngLiteral No
Returns : void

Properties

Protected Readonly _boundsChangeSampleTime$
Default value : new BehaviorSubject<number>( 200, )
Protected Readonly _includeInBounds$
Default value : new BehaviorSubject<BoundsMap>( new Map<string, GeoPoint>(), )
Protected Readonly bounds$
Type : Observable<BoundsLiteral>
import { Injectable } from '@angular/core';
import { BehaviorSubject, from, Observable, timer } from 'rxjs';
import {
  flatMap,
  map,
  mergeMap,
  sample,
  shareReplay,
  switchMap,
} from 'rxjs/operators';

import { BoundsLiteral } from '../interface/bounds';
import { GeoPoint } from '../interface/geo-point';

import { MapsAPILoader } from './maps-api-loader/maps-api-loader';

export interface FitBoundsDetails {
  latLng: GeoPoint;
}

/**
 * @internal
 */
export type BoundsMap = Map<string, GeoPoint>;

/**
 * Class to implement when you what to be able to make it work with the auto fit bounds feature
 * of AGM.
 */
export abstract class FitBoundsAccessor {
  public abstract getFitBoundsDetails$(): Observable<FitBoundsDetails>;
}

/**
 * The FitBoundsService is responsible for computing the bounds of the a single map.
 */
@Injectable()
export abstract class FitBoundsService {
  protected readonly bounds$: Observable<BoundsLiteral>;
  protected readonly _boundsChangeSampleTime$ = new BehaviorSubject<number>(
    200,
  );
  protected readonly _includeInBounds$ = new BehaviorSubject<BoundsMap>(
    new Map<string, GeoPoint>(),
  );

  constructor(loader: MapsAPILoader) {
    this.bounds$ = from(loader.load()).pipe(
      mergeMap(() => this._includeInBounds$),
      sample(
        this._boundsChangeSampleTime$.pipe(switchMap((time) => timer(0, time))),
      ),
      map((includeInBounds) => this.generateBounds(includeInBounds)),
      shareReplay(1),
    );
  }

  protected abstract generateBounds(
    includeInBounds: Map<string, GeoPoint>,
  ): BoundsLiteral;

  public addToBounds(latLng: GeoPoint) {
    const id = this._createIdentifier(latLng);
    if (this._includeInBounds$.value.has(id)) {
      return;
    }
    const bounds = this._includeInBounds$.value;
    bounds.set(id, latLng);
    this._includeInBounds$.next(bounds);
  }

  public removeFromBounds(
    latLng: google.maps.LatLng | google.maps.LatLngLiteral,
  ) {
    const bounds = this._includeInBounds$.value;
    bounds.delete(this._createIdentifier(latLng));
    this._includeInBounds$.next(bounds);
  }

  public changeFitBoundsChangeSampleTime(timeMs: number) {
    this._boundsChangeSampleTime$.next(timeMs);
  }

  public getBounds$(): Observable<BoundsLiteral> {
    return this.bounds$;
  }

  protected _createIdentifier(
    latLng: google.maps.LatLng | google.maps.LatLngLiteral,
  ): string {
    return `${latLng.lat}+${latLng.lng}`;
  }
}

results matching ""

    No results matching ""