All files / src/app/touchpad/transports transport-providers.ts

43.48% Statements 20/46
0% Branches 0/3
50% Functions 2/4
50% Lines 18/36

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113                                  1x   8x                 1x 1x 1x     1x 1x               1x                     1x 3x 3x     2x 2x                   2x                   1x 2x 2x                                                           1x  
import { HttpClient } from '@angular/common/http';
 
import { Station, TransportationLine, TrainStationSearchResult } from './utils';
import { GeoAdminCoordinates, squaredEuclideanDistance } from '../geography/utils';
import { busStationsSearchUrl, WGS84ToLV03Url, trainStationsSearchUrl, LV03ToWGS84Url } from 'src/config/urls';
 
/**
 * The interface of transport providers in the application.
 * Transport providers are objects that can be used to retrieve information
 * about public transportations on a map.
 */
export interface TransportProvider {
  getNearestBusStation(point: __esri.Point): Promise<Station | undefined>;
  getNearestStationByLine(point: __esri.Point, line: string): Promise<Station | undefined>;
  getNearestTrainStation(point: __esri.Point): Promise<Station | undefined>;
}
 
export class SwissTransportsProvider implements TransportProvider {
 
  constructor(private http: HttpClient) {}
 
  /**
   * Get the nearest bus or tram station for a point on a map with WGS84 coordinates.
   *
   * @param point An Esri Point with WGS84 coordinates.
   *
   * @returns The station that is nearest to the input point, or undefined if none was found.
   */
  async getNearestBusStation(point: __esri.Point): Promise<Station | undefined> {
    const request = busStationsSearchUrl + 'locations?x=' + point.x + '&y=' + point.y + '&type=station';
    const stations = await this.http.get<{stations: Station[]}>(request).toPromise();
 
    let nearestStation: Station | undefined;
    let shortestDistance = 100000;
    stations.stations.forEach(
      (station) => {
        if ((station.icon === 'bus' || station.icon === 'tram') && station.distance < shortestDistance) {
          nearestStation = station;
          shortestDistance = station.distance;
        }
      }
    );
    return nearestStation;
  }
 
  /**
   * Search for the nearest bus or tram station that serves a given line.
   *
   * @param point The Esri Point with WGS84 coordinates near which stations must be searched.
   * @param line The line for which stations must be found.
   *
   * @returns The nearest station serving the input line, or undefined if no such station was found.
   */
  async getNearestStationByLine(point: __esri.Point, line: string): Promise<Station | undefined> {
    let request = busStationsSearchUrl + 'locations?x=' + point.x + '&y=' + point.y + '&type=station';
    const stationsNearby = await this.http.get<{stations: Station[]}>(request).toPromise();
 
    let nearestStation: Station | undefined;
    let shortestDistance = 100000;
    for (const station of stationsNearby.stations) {
      request = busStationsSearchUrl + 'stationboard?station=' + station.name + '&limit=10';
      const lines = await this.http.get<{stationboard: TransportationLine[]}>(request).toPromise();
      if (lines.stationboard.some((transportationLine) => transportationLine.number.toLowerCase() === line)) {
        if (station.distance < shortestDistance) {
          nearestStation = station;
          shortestDistance = station.distance;
        }
      }
    }
    return nearestStation;
  }
 
  /**
   * Get the train station nearest to a point on a map.
   *
   * @param point An Esri Point with WGS84 coordinates near which train stations must be searched.
   *
   * @returns The nearest train station to the input point, or undefined if none was found.
   */
  async getNearestTrainStation(point: __esri.Point): Promise<Station | undefined> {
    let request = WGS84ToLV03Url + '?easting=' + point.x + '&northing=' + point.y;
    const lv03Coordinates = await this.http.get<GeoAdminCoordinates>(request).toPromise();
 
    request = trainStationsSearchUrl + lv03Coordinates.coordinates[0] + ',' + lv03Coordinates.coordinates[1] + '&tolerance=300';
    const stations = await this.http.get<{results: TrainStationSearchResult[]}>(request).toPromise();
 
    let nearestTrainStation: Station | undefined;
    let shortestDistance = 100000;
    for (const station of stations.results) {
      if (station.attributes.tuabkuerzung === 'SBB-CFF-FFS') {
        request = LV03ToWGS84Url + '?easting=' + station.geometry.points[0][0] + '&northing=' + station.geometry.points[0][1];
        const wgs84coordinates = await this.http.get<GeoAdminCoordinates>(request).toPromise();
 
        const distance = squaredEuclideanDistance(point, {x: wgs84coordinates.coordinates[0], y: wgs84coordinates.coordinates[1]});
        if (distance < shortestDistance) {
          nearestTrainStation = {
            id: '0',
            name: station.attributes.label,
            coordinate: {
              type: 'WGS84',
              x: wgs84coordinates.coordinates[1],
              y: wgs84coordinates.coordinates[0]
            },
            distance: 0
          };
          shortestDistance = distance;
        }
      }
    }
    return nearestTrainStation;
  }
}