UNPKG

@golemio/pid

Version:
217 lines 9.53 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GTFSStopModel = void 0; const StopEnums_1 = require("../../../helpers/StopEnums"); const const_1 = require("../../../schema-definitions/const"); const ropid_gtfs_1 = require("../../../schema-definitions/ropid-gtfs"); const StopDto_1 = require("../../../schema-definitions/ropid-gtfs/models/StopDto"); const CoreToken_1 = require("@golemio/core/dist/helpers/ioc/CoreToken"); const Geo_1 = require("@golemio/core/dist/output-gateway/Geo"); const ioc_1 = require("@golemio/core/dist/output-gateway/ioc"); const models_1 = require("@golemio/core/dist/output-gateway/models"); const golemio_errors_1 = require("@golemio/core/dist/shared/golemio-errors"); const sequelize_1 = __importDefault(require("@golemio/core/dist/shared/sequelize")); const OgPidToken_1 = require("../../pid/ioc/OgPidToken"); const Di_1 = require("../../pid/ioc/Di"); class GTFSStopModel extends models_1.SequelizeModel { constructor() { super(ropid_gtfs_1.RopidGTFS.stops.name, ropid_gtfs_1.RopidGTFS.stops.pgTableName, StopDto_1.StopDto.attributeModel, { schema: const_1.PG_SCHEMA, }); this.outputAttributes = []; this.Associate = () => { this.sequelizeModel.hasMany(this.sequelizeModel, { as: "stops_self", foreignKey: "asw_node_id", sourceKey: "asw_node_id", }); }; /** * Retrieve multiple GTFS stop ids by ASW node id */ this.getMultipleIdsByAswNode = async (aswNodeId) => { try { const stops = await this.sequelizeModel.findAll({ attributes: ["stop_id"], raw: true, where: { asw_node_id: aswNodeId, location_type: StopEnums_1.GtfsStopLocationType.StopOrPlatform, }, }); if (!stops || stops.length === 0) { return []; } return stops.map((stop) => stop.stop_id); } catch (error) { throw new golemio_errors_1.GeneralError("Error while getting GTFS stop ids", this.constructor.name, error, 500); } }; /** * Retrieve specific gtfs stop */ this.GetOne = async (id) => { return this.sequelizeModel.findByPk(id).then((data) => { if (data) { return (0, Geo_1.buildGeojsonFeature)(data, "stop_lon", "stop_lat", true); } return null; }); }; this.prepareCisStops = async (cisIds) => { const stops = await this.cisStopsModel.findAll({ raw: true, where: { [sequelize_1.default.Op.or]: { cis: cisIds, }, }, }); return stops; }; const connector = ioc_1.OutputGatewayContainer.resolve(CoreToken_1.CoreToken.PostgresConnector); this.gtfsStopParser = Di_1.OgPidContainer.resolve(OgPidToken_1.OgPidToken.GtfsStopParser); this.outputAttributes = Object.keys(StopDto_1.StopDto.attributeModel); const notUsedColumns = [ "stop_code", "stop_desc", "stop_url", "stop_timezone", "asw_node_id", "asw_stop_id", "computed_cis_stop_id", ]; for (const column of notUsedColumns) { this.sequelizeModel.removeAttribute(column); this.outputAttributes.splice(this.outputAttributes.indexOf(column), 1); } this.cisStopsModel = connector .getConnection() .define(ropid_gtfs_1.RopidGTFS.cis_stops.pgTableName, ropid_gtfs_1.RopidGTFS.cis_stops.outputSequelizeAttributes, { schema: const_1.PG_SCHEMA, }); } async GetAll(options) { let attributes = [...this.outputAttributes]; let order = []; let where = {}; let allGtfsIds = []; if (options.aswIds && options.aswIds.length > 0) { where[sequelize_1.default.Op.or] = this.gtfsStopParser.prepareAswWhereOptions(options.aswIds); } if (options.cisIds && options.cisIds.length > 0) { let stops; try { stops = await this.prepareCisStops(options.cisIds); } catch (err) { throw new golemio_errors_1.GeneralError("Database error", "GTFSStopModel", err, 500); } // after all stops by other than GTFS ids are collected, we create proper GTFS ids with % like sign. // GTFS stops must be split into more ids due to more tarriff zones even if it is one physical stop. for (const stop of stops) { allGtfsIds.push("(^U" + stop.id.replace("/", "Z") + "(P|N)?(_\\d+)?$)"); } // If aswIds and cisIds are not belong to any GTFS ids and no other gtfsIds or names are given, // then return empty stops array if (allGtfsIds.length === 0 && (options.gtfsIds === undefined || options.gtfsIds?.length === 0) && (options.names === undefined || options.names.length === 0)) { return options.returnRaw ? [] : (0, Geo_1.buildGeojsonFeatureCollection)([], "stop_lon", "stop_lat", true); } } if (options.lng && options.lat) { const location = sequelize_1.default.literal(`ST_GeomFromText('POINT(${options.lng} ${options.lat})')`); const distance = sequelize_1.default.fn("ST_DistanceSphere", sequelize_1.default.literal("ST_MakePoint(stop_lon, stop_lat)"), location); attributes.push([distance, "distance"]); order.push(["distance", "ASC"]); if (options.range) { where.distance = { [sequelize_1.default.Op.lte]: options.range, }; } } order.push(["stop_id", "ASC"]); for (const stop of options.gtfsIds ?? []) { allGtfsIds.push("(^" + stop + "$)"); } if (allGtfsIds.length > 0) { where.stop_id = { [sequelize_1.default.Op.regexp]: allGtfsIds.join("|"), }; } if (options.names && options.names?.length > 0) { where.stop_name = options.names; } if (options.locationType !== undefined) { where.location_type = options.locationType; } if (options.appendAswId) { const aswId = sequelize_1.default.fn("json_build_object", "node", sequelize_1.default.col(`${ropid_gtfs_1.RopidGTFS.stops.pgTableName}.asw_node_id`), "stop", sequelize_1.default.col(`${ropid_gtfs_1.RopidGTFS.stops.pgTableName}.asw_stop_id`)); attributes.push([aswId, "asw_id"]); } let include = undefined; if (options.includeMetroTrains) { // Workaround for distinct selection // https://github.com/sequelize/sequelize/issues/2996 attributes[0] = [ sequelize_1.default.literal(`DISTINCT ON(${ropid_gtfs_1.RopidGTFS.stops.pgTableName}.stop_id) ${ropid_gtfs_1.RopidGTFS.stops.pgTableName}.${attributes[0]}`), attributes[0], ]; const findOptions = this.prepareFindOptionsForMetro(where); include = findOptions.include; where = findOptions.where; } let data = []; try { data = await this.sequelizeModel.findAll({ attributes, include, where, order, limit: options.limit, offset: options.offset, raw: true, subQuery: false, }); } catch (err) { throw new golemio_errors_1.GeneralError("Database error", "GTFSStopModel", err, 500); } return options.returnRaw ? data : (0, Geo_1.buildGeojsonFeatureCollection)(data, "stop_lon", "stop_lat", true); } prepareFindOptionsForMetro(innerWhere) { // Select metro and train stops within a node // matching the previous where criteria // matching asw_node_id (stop_id U1040Z16P -> asw_node_id 1040) // with asw_stop_id greater than or equal to 100 (stop_id U1040Z101P -> asw_stop_id 101) // indicating a metro or train stop // EX: U1040Z16P Na Knížecí + U1040Z101P Anděl const include = { as: "stops_self", model: this.sequelizeModel, attributes: [], on: { asw_node_id: { [sequelize_1.default.Op.eq]: sequelize_1.default.col(`${ropid_gtfs_1.RopidGTFS.stops.pgTableName}.asw_node_id`), }, }, where: innerWhere, }; const where = { [sequelize_1.default.Op.or]: [ innerWhere, { asw_stop_id: { [sequelize_1.default.Op.gte]: 100 }, }, ], }; return { include, where }; } } exports.GTFSStopModel = GTFSStopModel; //# sourceMappingURL=GTFSStopModel.js.map