UNPKG

aviation-model

Version:

Public methods for querying the information from aviation-pg

635 lines (598 loc) 19.8 kB
"use strict"; var Sequelize = require("sequelize"); var async = require("async"); var defaults = {}; var fs = require("fs"); var path = require("path"); var debug = require("debug")("aviation:model"); try { defaults = JSON.parse(fs.readFileSync("database.json", { encoding: "utf8" })); } catch (e) { debug("No db defaults found, trying env variables"); } var config = { "host": process.env.PG_HOST || defaults.host, "dialect": "postgres", "port": process.env.PG_PORT || defaults.port, "database": process.env.PG_DATABASE || defaults.database, "user": process.env.PG_USER || defaults.user, "password": process.env.PG_PASSWORD || defaults.password }; var sequelize = new Sequelize(config.database, config.user, config.password, { host: config.host, dialect: config.dialect, port: config.port, pool: { max: 5, min: 0, idle: 1 + 1000 }, logging: false }); // Importing models. var models = { Airport: sequelize.import("./models/airport.js"), Airline: sequelize.import("./models/airlines.js"), Airline_destinations: sequelize.import("./models/airline_destinations.js"), Airport_cities: sequelize.import("./models/airport_cities.js") }; /** * Handling errors globally. */ Sequelize.Promise.onPossiblyUnhandledRejection(function (e) { throw e; }); /** * * @description Gets data for a single airport. * * @param {Object} options * @param {String} options.type airport_id | name | latitude | longitude | nickname | iata | icao * @param {String} options.value the value according to the type specified. * @param {String} [options.method] airport_id | name | location | latitude | longitude | nickname | iata | icao * (if we don't specify the method, the whole airport data will be served). * @param {boolean} options.verbose specify if you want to have logging. * * @param {Function} callback * @return {string} requested information. * * @example * * aviationModel.getAirportData({ * value: "SFO", * type: "iata", * method: "latitude" * }, function (err, data) { * if (err) {throw err;} * console.log(data); * }); * * // returns: * // "37°37′08″N * */ function getAirportData(options, callback) { var logging = options.verbose || false; if (options.verbose === true) { logging = console.log; //eslint-disable-line no-console } sequelize.sync({ logging: logging }); models.Airport.findOne({ where: { [options.type]: options.value } }).then(function (data) { if (options.method !== undefined) { callback(null, data[options.method]); } else { callback(null, data); } }).catch(function (err) { callback(err); }); } /** * Gets data for a single airline * @param {Object} options Contains all the options. * @param {String} options.type name | logo_url | iata | icao | callsign | website * @param {String} options.value the value according to the type specified. * @param {String} options.method name | logo_url | iata | icao | callsign | website * Optional we can leave the method empty to get all the information from the airline. * @param {boolean} options.verbose specify if you want to have logging. * * * * @param {Function} callback * @return {string} returns the information requested. * * @example * * aviationModel.getAirlineData({ * value: "American_Airlines", * type: "airline_id", * method: "website" * }, function (err, data) { * if (err) {throw err;} * console.log("Web: ", data); * }); * * // This will print out: * // Web: http://www.aa.com */ function getAirlineData(options, callback) { var logging = options.verbose || false; if (options.verbose === true) { logging = console.log; //eslint-disable-line no-console } sequelize.sync({ logging: logging }); models.Airline.findOne({ where: { [options.type]: options.value } }).then(function (data) { if (options.method !== undefined) { callback(null, data[options.method]); } else { callback(null, data); } }).catch(function (err) { callback(err); }); } function findOneOf(searchOptions, type, callback) { models[type].findOne({ where: searchOptions }).then(function (instance) { callback(null, instance); }).catch(function (err) { callback(err); }); } function findAirport(searchOptions, callback) { findOneOf(searchOptions, "Airport", callback); } /** * This function retrieves all the information of an airport in a JSON format. * @param {Object} searchOptions key and value (string) to find. * @param {Function} callback * @return {object} JSON data of the airport requested. * * @example * * aviationModel.getAirportJson({ * airport_id: "San_Francisco_International_Airport" * }, function (err, airport) { * if (err) { * throw err; * } * console.log("Airport:", airport); * }); * * // this logs the following JSON object. * Airport: { location: '37°37′08″N 122°22′30″W', * airport_id: 'San_Francisco_International_Airport', * latitude: '37°37′08″N', * longitude: '122°22′30″W', * name: 'San Francisco International Airport', * nickname: 'SFO', * iata: 'SFO', * icao: 'KSFO' } */ function getAirportJson(searchOptions, callback) { findAirport(searchOptions, function (err, airport) { callback(err, !err && airport.toJSON()); }); } /** * It performs a search at the db and returns all the destinations of the * airline or airlines that match the string. * @param {String} airline the airline_id we want to look for, use wildcard % * @param {Function} callback * @return {Array} array composed with objects that include airline_id and airport_id * * @example * * aviationModel.getDestinations("American_Airlines", function (err, destinations) { * if (err) {throw err;} * console.log(JSON.stringify(destinations, null, 2)); * }); * * // this will return the following array: * * [ * { * "airline_id": "American_Airlines", * "airport_id": "V._C._Bird_International_Airport" * }, * { * "airline_id": "American_Airlines", * "airport_id": "Ministro_Pistarini_International_Airport" * }, * { * "airline_id": "American_Airlines", * "airport_id": "Queen_Beatrix_International_Airport" * }, * { * "airline_id": "American_Airlines", * "airport_id": "Sydney_Airport" * }, * { * "airline_id": "American_Airlines", * "airport_id": "Lynden_Pindling_International_Airport" * }, * // continue until complete the total destinations... * ] */ function getDestinations(airline, callback) { models.Airline_destinations.findAll({ where: { airline_id: { $like: airline } } }).then(function (destinations) { callback(null, destinations); }).catch(function (err) { callback(err); }); } /** * This method returns the cities of all the airports that an airline is flying to. * @param {String} airline airline_id value we want to search, we can use wildcard % * @param {Function} callback * @return {Array} All the cities. * * @example * * aviationModel.getAirlineCities("American_Airlines", function(err, cities) { * if (err) {throw err; } * console.log(cities); * }); * * // this returns the following array: * * [ * 'St._John%27s,_Antigua_and_Barbuda', * 'Buenos_Aires', * 'Oranjestad,_Aruba', * 'Sydney', * 'Nassau,_Bahamas', * 'Bridgetown,_Barbados', * 'Belize_City', * 'Brussels', * 'Hamilton,_Bermuda', * 'La_Paz', * // this continues to complete all the cities. * ] */ function getAirlineCities(airline, callback) { getDestinations(airline, function (err, destinations) { if (err) { throw err; } async.map(destinations, function (destination, callback) { getCity(destination.airport_id, function (err, city) { if (err) { throw err; } callback(null, city); }); }, function (err, result) { if (err) { throw err; } callback(null, result); }); }); } /** * Finds the city for the specific airport * @param {String} airport Exact airport_id * @param {Function} callback * @return {String} The name of the city where the airport is located. * * @example * * aviationModel.getCity("San_Francisco_International_Airport", function(err, city) { * if (err) {throw err;} * console.log("city: ", city); * }); * * // This will return the following: * // city: San_Francisco */ function getCity(airport, callback) { models.Airport_cities.findOne({ where: { airport_id: airport } }).then(function (city) { callback(null, city.city_id); }).catch(function (err) { callback(err); }); } // methods using queries. var queriesDirectory = path.normalize(__dirname + "/../sql/queries/"); var queries = { airportData: fs.readFileSync(queriesDirectory + "airport_data.sql").toString(), airlineDestinations: fs.readFileSync(queriesDirectory + "airline_destinations.sql").toString(), airportRunways: fs.readFileSync(queriesDirectory + "airport_runways.sql").toString(), citiesByAirline: fs.readFileSync(queriesDirectory + "cities_by_airline.sql").toString(), radiusAirports: fs.readFileSync(queriesDirectory + "radius_airports.sql").toString(), airlines: fs.readFileSync(queriesDirectory + "airlines.sql").toString(), airportsBounds: fs.readFileSync(queriesDirectory + "airports_bounds.sql").toString(), airlinesByAirport: fs.readFileSync(queriesDirectory + "airlines_by_airport.sql").toString(), airportsCountWithCoords: fs.readFileSync(queriesDirectory + "airports_count_with_coordinates.sql").toString(), airportsCountWithoutCoords: fs.readFileSync(queriesDirectory + "airports_count_without_coordinates.sql").toString(), airlinesCount: fs.readFileSync(queriesDirectory + "airlines_count.sql").toString(), airlinesCountNoCallsign: fs.readFileSync(queriesDirectory + "airlines_count_no_callsign.sql").toString(), airlinesCountNoIata: fs.readFileSync(queriesDirectory + "airlines_count_no_iata.sql").toString(), airlinesCountNoIcao: fs.readFileSync(queriesDirectory + "airlines_count_no_icao.sql").toString(), airlinesCountNoLogoUrl: fs.readFileSync(queriesDirectory + "airlines_count_no_logo_url.sql").toString(), airlinesCountNoWebsite: fs.readFileSync(queriesDirectory + "airlines_count_no_website.sql").toString() }; /** * formula to use all the queries stored at ./sql/queries/ * @param {Object} options pass all the values to use on the query. * @param {String} options.searchString text to use on the query. * @param {String} options.distance distance in meters to look for formulas using radius. * @param {String} query specified the name of the query you are going to use. * @param {String} query.airlines airline_id of the airline (wildcard %) * @param {String} query.airlineDestinations id of the airline (1 airline) (wildcard %) * will return the airports with complete data. * @param {String} query.citiesByAirline Name of the airline (wildcard %) * @param {String} query.airportData This query accepts the name (wildcard %) * @param {String} query.airportRunways Name of the airport (wildcard %) * @param {String} query.radiusAirports airport_id (wildcard %) and the distance of the radius in meters. * @param {String} query.airlinesByAirport airport_id (wildcard %) * @param {String} query.airportsCountWithCoords No params, returns a number * @param {String} query.airportsCountWithoutCoords No params, returns a number * @param {String} query.airlinesCount No params, returns a number * @param {String} query.airlinesCountNoCallsign No params, returns a number * @param {String} query.airlinesCountNoIata No params, returns a number * @param {String} query.airlinesCountNoIcao No params, returns a number * @param {String} query.airlinesCountNoLogoUrl No params, returns a number * @param {String} query.airlinesCountNoWebsite No params, returns a number * @param {Function} callback * @return {Array} returns an array with the data requested. * * @example * aviationModel.queryData({ * searchString: "San_Francisco%", * distance: 100 * 1000 * }, "radiusAirports", function (err, radiusAirports) { * if (err) {throw err;} * console.log(radiusAirports); * }); * * // This will return the following array: * [ * { airport_id: 'San_Francisco_International_Airport', * name: 'San Francisco International Airport', * latitude: '37°37′08″N', * longitude: '122°22′30″W', * distance: 0 }, * { airport_id: 'Half_Moon_Bay_Airport', * name: 'Eddie Andreini Sr. Airfield\nHalf Moon Bay Airport', * latitude: '37°30′48″N', * longitude: '122°30′04″W', * distance: 16183.33 }, * { airport_id: 'San_Carlos_Airport_(California)', * name: 'San Carlos Airport', * latitude: '37°30′43″N', * longitude: '122°14′58″W', * distance: 16262.58 }, * { airport_id: 'Oakland_International_Airport', * name: 'Oakland International Airport', * latitude: '37°43′17″N', * longitude: '122°13′15″W', * distance: 17740.59 }, * { airport_id: 'Hayward_Executive_Airport', * name: 'Hayward Executive Airport', * latitude: '37°39′32″N', * longitude: '122°07′18″W', * distance: 22771.33 }, * * // this continues to complete all the airports in the radius. * ] * * @example * aviationModel.queryData({ * searchString: "Vueling%" * }, "airlineDestinations" , function (err, destinations) { * if (err) {throw err;} * console.log(destinations); * }); * * // This will return the following array: * [ * { * "airline_id": "Vueling", * "airport_id": "Pulkovo_Airport", * "latitude": "59°48′01″N", * "longitude": "30°15′45″E", * "name": "Pulkovo Airport", * "nickname": "Аэропорт Пулково", * "iata": "LED", * "icao": "ULLI", * "dd_latitude": 59.80027777777777, * "dd_longitude": 30.2625 * }, * { * "airline_id": "Vueling", * "airport_id": "Belgrade_Nikola_Tesla_Airport", * "latitude": "44°49′10″N", * "longitude": "20°18′25″E", * "name": "Belgrade Nikola Tesla AirportAerodrom Nikola Tesla a.d.", * "nickname": "Аеродром Никола Тесла Београд", * "iata": "BEG", * "icao": "LYBE", * "dd_latitude": 44.81944444444445, * "dd_longitude": 20.306944444444444 * }, * { * "airline_id": "Vueling", * "airport_id": "Houari_Boumediene_Airport", * "latitude": "36°41′27.65″N", * "longitude": "003°12′55.47″E", * "name": "Houari Boumediene AirportHouari Boumediene AirportHouari Boumediene Airport", * "nickname": "مطار هواري بومدين الدولي", * "iata": "ALG", * "icao": "DAAG", * "dd_latitude": 36.69101388888888, * "dd_longitude": 3.2154083333333334 * }, * * // this continues to complete all the destinations. * ] */ function queryData(options, query, callback) { sequelize.query(queries[query], { replacements: { name: options.searchString, distance: options.distance }, type: sequelize.QueryTypes.SELECT }).then(function (data) { callback(null, data); }).catch(function (err) { callback(err); }); } /** * with this function we retrieve all the airports located inside a bound box. * @param {Object} options pass all the values to use on the query. * @param {String} options.latitude1 latitude of the first point * @param {String} options.longitude1 longitude of the first point * @param {String} options.latitude2 latitude of the first point * @param {String} options.longitude2 longitude of the first point * @param {Function} callback * @return {Array} returns an array with the data requested. * * @example * aviationModel.airportsBounds({ * latitude1: 38, * longitude1: -123, * latitude2: 37, * longitude2: -122 * }, function (err, boxAirports) { * if (err) {throw err;} * console.log(boxAirports); * }); * * // returns the following array * [ { airport_id: 'Buchanan_Field_Airport', * latitude: '37°59′23″N', * longitude: '122°03′25″W', * name: 'Buchanan International\nConcord Army Air Base', * nickname: 'CCR', * iata: 'CCR', * icao: 'KCCR', * dd_latitude: 37.98972222222222, * dd_longitude: -122.05694444444444 }, * { airport_id: 'Half_Moon_Bay_Airport', * latitude: '37°30′48″N', * longitude: '122°30′04″W', * name: 'Eddie Andreini Sr. Airfield\nHalf Moon Bay Airport', * nickname: 'HAF', * iata: 'HAF', * icao: 'KHAF', * dd_latitude: 37.513333333333335, * dd_longitude: -122.50111111111111 }, * { airport_id: 'Hayward_Executive_Airport', * latitude: '37°39′32″N', * longitude: '122°07′18″W', * name: 'Hayward Executive Airport', * nickname: '(former Hayward Army Air Field)', * iata: 'HWD', * icao: 'KHWD', * dd_latitude: 37.65888888888889, * dd_longitude: -122.12166666666666 }, * { airport_id: 'Moffett_Federal_Airfield', * latitude: '37°24′54″N', * longitude: '122°02′54″W', * name: 'Moffett Federal Airfield', * nickname: 'NUQ', * iata: 'NUQ', * icao: 'KNUQ', * dd_latitude: 37.415, * dd_longitude: -122.04833333333333 }, * { airport_id: 'Oakland_International_Airport', * latitude: '37°43′17″N', * longitude: '122°13′15″W', * name: 'Oakland International Airport', * nickname: 'OAK', * iata: 'OAK', * icao: 'KOAK', * dd_latitude: 37.72138888888889, * dd_longitude: -122.22083333333333 }, * { airport_id: 'Palo_Alto_Airport', * latitude: '37°27′40″N', * longitude: '122°06′54″W', * name: 'Palo Alto Airport', * nickname: 'PAO', * iata: 'PAO', * icao: 'KPAO', * dd_latitude: 37.461111111111116, * dd_longitude: -122.115 }, * { airport_id: 'San_Francisco_International_Airport', * latitude: '37°37′08″N', * longitude: '122°22′30″W', * name: 'San Francisco International Airport', * nickname: 'SFO', * iata: 'SFO', * icao: 'KSFO', * dd_latitude: 37.61888888888889, * dd_longitude: -122.375 }, * { airport_id: 'San_Carlos_Airport_(California)', * latitude: '37°30′43″N', * longitude: '122°14′58″W', * name: 'San Carlos Airport', * nickname: 'SQL', * iata: 'SQL', * icao: 'KSQL', * dd_latitude: 37.511944444444445, * dd_longitude: -122.24944444444445 } ] * */ function airportsBounds(options, callback) { var latMax = [options.latitude1, options.latitude2].sort(sortNumber)[1], latMin = [options.latitude1, options.latitude2].sort(sortNumber)[0], longMax = [options.longitude1, options.longitude2].sort(sortNumber)[1], longMin = [options.longitude1, options.longitude2].sort(sortNumber)[0]; sequelize.query(queries.airportsBounds, { replacements: { latmax: latMax, latmin: latMin, longmax: longMax, longmin: longMin }, type: sequelize.QueryTypes.SELECT }).then(function (data) { callback(null, data); }).catch(function (err) { callback(err); }); } function sortNumber(a,b) { return a - b; } /** * Exporting methods. */ module.exports = { getAirportData: getAirportData, getAirlineData: getAirlineData, findAirport: findAirport, getAirportJson: getAirportJson, getDestinations: getDestinations, getAirlineCities: getAirlineCities, getCity: getCity, queryData: queryData, airportsBounds: airportsBounds };