@golemio/pid
Version:
Golemio PID Module
217 lines • 9.53 kB
JavaScript
"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