UNPKG

sg-gov-nea

Version:

API to access the Singaporean Government National Environment Agency's Dataset

145 lines (110 loc) 4.7 kB
/// <reference path='typings/tsd.d.ts' /> import _ = require('lodash'); export module sg.gov.nea { import EventEmitter = NodeJS.EventEmitter; export interface IAPIConfig { key?:string; baseUrl?:string; } export class APIConfig implements IAPIConfig { public key:string; public baseUrl:string; constructor(config:IAPIConfig) { _.extend(this, config); } static defaults:IAPIConfig = { key: '[insert_your_own_API_key]', baseUrl: 'http://www.nea.gov.sg/api/WebAPI' } } export class APIEvent { static DATA:string = 'data'; static ERROR:string = 'error'; } export interface IDataSet { name:string; on(event:string, callback:Function) : void; } export class DataSet implements IDataSet { private emitter:EventEmitter; constructor(public name:string, private config:IAPIConfig) { this.config = _.extend({}, APIConfig.defaults, config); var events = require('events'); this.emitter = new events.EventEmitter(); this.refresh(); } public on(event:string, callback:Function):void { this.emitter.addListener(event, callback); } public off(event:string, callback:Function):void { this.emitter.removeListener(event, callback); } private refresh():void { var context:DataSet = this; var transport:DataSetTransport = new DataSetTransport(this.config.baseUrl + '?dataset=' + this.name + '&keyref=' + this.config.key); transport.fetch(function (err:Error, result:any):void { if (err) { context.emitter.emit(APIEvent.ERROR, err); return; } switch (context.name) { case DataSet.PSI_UPDATE: result = _.map(result.channel.item.region, function(region:any) : any { var result:any = { region: region.id, latitude: parseFloat(region.latitude), longitude: parseFloat(region.longitude), timestamp: parseInt(region.record.timestamp), readings: {} }; _.each(region.record.reading, function(reading:any) : any { _.set(result.readings, reading.type.toLowerCase(), parseFloat(reading.value)); }) return result; }) break; case DataSet.NOWCAST: result = { datentime: result.channel.item.issue_datentime, forecasts: _.map(result.channel.item.weatherForecast.area, function(forecast:any) : any { var result:any = { name: _.get(forecast, 'name'), forecast: _.trim(_.get(forecast, 'forecast').toString()), icon: _.get(forecast, 'icon'), zone: _.get(forecast, 'zone'), latitude: parseFloat(_.get(forecast, 'lat').toString()), longitude: parseFloat(_.get(forecast, 'lon').toString()), }; return result; }) } break; default: // ignore for now break; } context.emitter.emit(APIEvent.DATA, result); }) } static PSI_UPDATE:string = 'psi_update' static NOWCAST:string = 'nowcast' } export class DataSetTransport { constructor(private url:string) { } public fetch(callback:Function):void { var request = require('request'); request(this.url, function (err:Error, response:any, body:string):void { if (err) { return callback(err); } var parser = require('xml2json'); var result = parser.toJson(body); result = JSON.parse(result); callback(null, result); }) } static END:string = 'end'; static DATA:string = 'data'; } }