Skip to content

Commit

Permalink
feat: create bus stop query
Browse files Browse the repository at this point in the history
  • Loading branch information
aalises committed Dec 20, 2020
1 parent 878c001 commit 3d2e3e7
Show file tree
Hide file tree
Showing 24 changed files with 608 additions and 87 deletions.
30 changes: 28 additions & 2 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ type RootQuery {

"""Returns the information about a bike station"""
bikeStation(findBy: FindByInput!): BikeStationQueryResponse

"""Returns the information about a bus stop"""
busStop(findBy: FindByInput!): BusStopQueryResponse
}

"""A connection to a list of items."""
Expand Down Expand Up @@ -67,7 +70,7 @@ type MetroStation {
name: String

"""Location coordinates of the station"""
location: CoordinatesOutput
coordinates: CoordinatesOutput

"""Lines the station belongs to e.g. L1, L2"""
lines: [String]
Expand Down Expand Up @@ -195,7 +198,7 @@ type BikeStation {
capacity: Int

"""Location coordinates of the station"""
location: CoordinatesOutput
coordinates: CoordinatesOutput

"""Information about the available bikes and docks of the station"""
available: BikeStationAvailabilityInfo
Expand Down Expand Up @@ -243,3 +246,26 @@ input OnlyFilterByInputBike {
}

union BikeStationQueryResponse = BikeStation | NotFoundError

union BusStopQueryResponse = BusStop | NotFoundError

"""Bus stop information"""
type BusStop {
"""Unique ID of the stop"""
id: ID

"""Name of the stop"""
name: String

"""Location of the stop"""
location: Location
}

"""Location of a stop/station"""
type Location {
address: String
city: String
district: String
street: String
coordinates: CoordinatesOutput
}
3 changes: 3 additions & 0 deletions src/RootQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import metroLines from "./queries/MetroLinesQuery";
import bikeStations from "./queries/BikeStationsQuery";
import bikeStation from "./queries/BikeStationQuery";

import busStop from "./queries/BusStopQuery";

export default new GraphQLObjectType({
name: "RootQuery",
description: "Root Query",
Expand All @@ -19,5 +21,6 @@ export default new GraphQLObjectType({
metroLines,
bikeStations,
bikeStation,
busStop,
},
});
2 changes: 1 addition & 1 deletion src/datasources/BikeDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default class BikeDataSource extends RESTDataSource {
id: String(stationInfoData?.station_id) ?? null,
name: stationInfoData?.name ?? null,
capacity: stationInfoData?.capacity ?? null,
location: {
coordinates: {
latitude: stationInfoData?.lat ?? null,
longitude: stationInfoData?.lon ?? null,
altitude: stationInfoData?.altitude ?? null,
Expand Down
104 changes: 104 additions & 0 deletions src/datasources/BusDataSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import TmbApiDataSource, { ITmbApiFeatureCollection } from "./TmbApiDataSource";
import {
FindByInputType,
BusStopType,
CoordinatesInputType,
} from "../../types";
import { BusStopQueryResponseType } from "../../types";
import { getClosestTmbStation } from "../utils/getClosestStation";

export interface BusStopAPIType {
type: string;
id: string;
geometry: {
type: string;
coordinates: number[];
};
geometry_name: string;
properties: {
ID_PARADA: number;
CODI_PARADA: number;
NOM_PARADA: string;
DESC_PARADA: string;
CODI_INTERC: number;
NOM_INTERC: string;
NOM_TIPUS_PARADA: string;
NOM_TIPUS_SIMPLE_PARADA: string;
DESC_TIPUS_PARADA: string;
TIPIFICACIO_PARADA: string;
ADRECA: string;
ID_POBLACIO: number;
NOM_POBLACIO: string;
ID_DISTRICTE: number;
NOM_DISTRICTE: string;
DATA: string;
NOM_VIA: string;
NOM_PROPERA_VIA: string;
PUNTS_PARADA: number;
};
}

export default class BusDataSource extends TmbApiDataSource {
busStopReducer(data: BusStopAPIType): BusStopType {
return {
id: String(data.properties["CODI_PARADA"]),
name: data.properties["NOM_PARADA"],
location: {
address: data.properties["ADRECA"],
city: data.properties["NOM_POBLACIO"],
district: data.properties["NOM_DISTRICTE"],
street: data.properties["NOM_VIA"],
coordinates: {
longitude: data.geometry.coordinates[0],
latitude: data.geometry.coordinates[1],
altitude: null,
},
},
};
}

async getStop({
id,
name,
closest,
}: FindByInputType): Promise<BusStopQueryResponseType | null> {
const path = ["parades", id].filter(Boolean).join("/");
const nameFilterParameter = name ? { filter: `NOM_PARADA='${name}'` } : {};

const response: ITmbApiFeatureCollection<
BusStopAPIType
> | null = await this.get(path, nameFilterParameter);

if (Array.isArray(response?.features) && response?.features.length === 0) {
return {
params: {
id,
name,
closest,
},
};
}

//If returning more than one occurrence and closest exists, try to get the closest station
const getClosest = Number(response?.features?.length) > 1 && closest;

const stop: BusStopAPIType | null = getClosest
? getClosestTmbStation(
response?.features as BusStopAPIType[],
closest as CoordinatesInputType
)
: response?.features?.[0] ?? null;

if (stop == null) {
return {
params: {
id,
name,
closest,
},
};
}

return this.busStopReducer(stop);
}
}
53 changes: 13 additions & 40 deletions src/datasources/MetroDataSource.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import TmbApiDataSource from "./TmbApiDataSource";
import TmbApiDataSource, { ITmbApiFeatureCollection } from "./TmbApiDataSource";
import type {
FindByInputType,
MetroStationType,
Expand All @@ -7,7 +7,7 @@ import type {
MetroLineQueryResponseType,
CoordinatesInputType,
} from "../../types";
import { getClosestMetroStation } from "../utils/getClosestStation";
import { getClosestTmbStation } from "../utils/getClosestStation";

export interface MetroLineAPIType {
type: string;
Expand Down Expand Up @@ -41,21 +41,6 @@ export interface MetroLineAPIType {
};
}

interface MetroLinesAPIType {
type: "FeatureCollection";
features: ReadonlyArray<MetroLineAPIType>;
totalFeatures: number;
numberMatched: number;
numberReturned: number;
timeStamp: string;
crs: {
type: "name";
properties: {
name: string;
};
};
}

export interface MetroStationAPIType {
type: string;
id: string;
Expand All @@ -72,21 +57,6 @@ export interface MetroStationAPIType {
};
}

interface MetroStationsAPIType {
type: "FeatureCollection";
features: ReadonlyArray<MetroStationAPIType>;
totalFeatures: number;
numberMatched: number;
numberReturned: number;
timeStamp: string;
crs: {
type: "name";
properties: {
name: string;
};
};
}

export default class MetroDataSource extends TmbApiDataSource {
//Transforms e.g. L1L2 into [L1, L2]
parseLines(lines: string): string[] {
Expand All @@ -97,7 +67,7 @@ export default class MetroDataSource extends TmbApiDataSource {
return {
id: data.properties["CODI_GRUP_ESTACIO"],
name: data.properties["NOM_ESTACIO"],
location: {
coordinates: {
longitude: data.geometry.coordinates[0],
latitude: data.geometry.coordinates[1],
altitude: null,
Expand All @@ -114,10 +84,9 @@ export default class MetroDataSource extends TmbApiDataSource {
const path = ["estacions", id].filter(Boolean).join("/");
const nameFilterParameter = name ? { filter: `NOM_ESTACIO='${name}'` } : {};

const response: MetroStationsAPIType | null = await this.get(
path,
nameFilterParameter
);
const response: ITmbApiFeatureCollection<
MetroStationAPIType
> | null = await this.get(path, nameFilterParameter);

if (Array.isArray(response?.features) && response?.features.length === 0) {
return {
Expand All @@ -133,7 +102,7 @@ export default class MetroDataSource extends TmbApiDataSource {
const getClosest = Number(response?.features?.length) > 1 && closest;

const station: MetroStationAPIType | null = getClosest
? getClosestMetroStation(
? getClosestTmbStation(
response?.features as MetroStationAPIType[],
closest as CoordinatesInputType
)
Expand All @@ -153,7 +122,9 @@ export default class MetroDataSource extends TmbApiDataSource {
}

async getAllStations(): Promise<MetroStationType[]> {
const response: MetroStationsAPIType | null = await this.get("estacions");
const response: ITmbApiFeatureCollection<
MetroStationAPIType
> | null = await this.get("estacions");

const stations =
response?.features?.map((station: MetroStationAPIType) =>
Expand Down Expand Up @@ -236,7 +207,9 @@ export default class MetroDataSource extends TmbApiDataSource {
}

async getAllLines(): Promise<MetroLineType[]> {
const response: MetroLinesAPIType | null = await this.get("linies/metro");
const response: ITmbApiFeatureCollection<
MetroLineAPIType
> | null = await this.get("linies/metro");

const lines = await Promise.all(
(response?.features ?? []).map(async (line: MetroLineAPIType) => {
Expand Down
14 changes: 14 additions & 0 deletions src/datasources/TmbApiDataSource.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import { RESTDataSource } from "apollo-datasource-rest";
import { TMB_API_BASE_URL } from "../config";

export interface ITmbApiFeatureCollection<T> {
type: "FeatureCollection";
features: ReadonlyArray<T>;
totalFeatures: number;
numberMatched: number;
numberReturned: number;
timeStamp: string;
crs: {
type: "name";
properties: {
name: string;
};
};
}
export default class TmbApiDataSource extends RESTDataSource {
constructor() {
super();
Expand Down
10 changes: 5 additions & 5 deletions src/datasources/__fixtures__/BikeStationsFixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export const mockBikeStationsResponse: any = [
capacity: 46,
id: "1",
lastUpdated: 1605374084,
location: {
coordinates: {
altitude: 16,
latitude: 41.3979779,
longitude: 2.1801069,
Expand All @@ -184,7 +184,7 @@ export const mockBikeStationsResponse: any = [
capacity: 27,
id: "2",
lastUpdated: 1605374023,
location: {
coordinates: {
altitude: 17,
latitude: 41.3954877,
longitude: 2.1771985,
Expand All @@ -204,7 +204,7 @@ export const mockBikeStationsResponse: any = [
capacity: 27,
id: "3",
lastUpdated: 1605374102,
location: {
coordinates: {
altitude: 11,
latitude: 41.3941557,
longitude: 2.1813305,
Expand All @@ -224,7 +224,7 @@ export const mockBikeStationsResponse: any = [
capacity: 21,
id: "4",
lastUpdated: 1605374039,
location: {
coordinates: {
altitude: 8,
latitude: 41.3933173,
longitude: 2.1812483,
Expand All @@ -244,7 +244,7 @@ export const mockBikeStationsResponse: any = [
capacity: 39,
id: "5",
lastUpdated: 1605388149,
location: {
coordinates: {
altitude: 7,
latitude: 41.3911035,
longitude: 2.1801763,
Expand Down
Loading

0 comments on commit 3d2e3e7

Please # to comment.