aviation-model
Version:
Public methods for querying the information from aviation-pg
635 lines (598 loc) • 19.8 kB
JavaScript
;
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
};