UNPKG

terriajs

Version:

Geospatial data visualization platform.

267 lines (225 loc) 9.7 kB
'use strict'; /*global require*/ var URI = require('urijs'); var clone = require('terriajs-cesium/Source/Core/clone'); var defined = require('terriajs-cesium/Source/Core/defined'); var defineProperties = require('terriajs-cesium/Source/Core/defineProperties'); var freezeObject = require('terriajs-cesium/Source/Core/freezeObject'); var knockout = require('terriajs-cesium/Source/ThirdParty/knockout'); var loadJson = require('../Core/loadJson'); var objectToQuery = require('terriajs-cesium/Source/Core/objectToQuery'); var AbsIttCatalogItem = require('./AbsIttCatalogItem'); var CatalogGroup = require('./CatalogGroup'); var inherit = require('../Core/inherit'); var TerriaError = require('../Core/TerriaError'); var proxyCatalogItemUrl = require('./proxyCatalogItemUrl'); /** * A {@link CatalogGroup} representing a collection of items from an Australian Bureau of Statistics * (ABS) ITT server, formed by querying for all the codes in a given dataset and concept. * * @alias AbsIttCatalogGroup * @constructor * @extends CatalogGroup * * @param {Terria} terria The Terria instance. */ var AbsIttCatalogGroup = function(terria) { CatalogGroup.call(this, terria, 'abs-itt-by-concept'); /** * Gets or sets the URL of the ABS ITT API, typically http://stat.abs.gov.au/itt/query.jsp. * This property is observable. * @type {String} */ this.url = undefined; /** * Gets or sets the filter for the ABS dataset. You can obtain a list of all datasets by querying * http://stat.abs.gov.au/itt/query.jsp?method=GetDatasetList (or equivalent). This property * is observable. * @type {String[]} */ this.filter = undefined; /** * Gets or sets the styling for the abs data. This property is observable. * @type {object} * @default undefined */ // this.tableStyle = undefined; /** * Gets or sets the URL of a JSON file containing human-readable names of Australian Bureau of Statistics concept codes. * @type {String} */ this.conceptNamesUrl = undefined; /** * Gets or sets the start of a URL of a csv file containing the total number of people in each region, eg. * SA4,Tot_P_M,Tot_P_F,Tot_P_P * 101,100000,23450,123450 * 102,130000,100000,234560 * The region code and '.csv' are appended to the end of this URL for the request, eg. * 'data/2011Census_TOT_' -> 'data/2011Census_TOT_SA4.csv' (and other region types). * @type {String} */ this.regionPopulationsUrlPrefix = undefined; /** * Gets or sets a description of the custodian of the data sources in this group. * This property is an HTML string that must be sanitized before display to the user. * This property is observable. * @type {String} */ this.dataCustodian = undefined; /** * Gets or sets a hash of names of blacklisted datasets. A dataset that appears in this hash * will not be shown to the user. In this hash, the keys should be the name of the dataset to blacklist, * and the values should be "true". This property is observable. * @type {Object} */ this.blacklist = undefined; /** * Gets or sets a hash of names of whitelisted datasets. A dataset that doesn't appears in this hash * will not be shown to the user. In this hash, the keys should be the name of the dataset to blacklist, * and the values should be "true". This property is observable. * @type {Object} */ this.whitelist = undefined; /** * Gets or sets a hash of properties that will be set on each child item. * For example, { 'treat404AsError': false } */ this.itemProperties = undefined; knockout.track(this, ['url', 'filter', 'dataCustodian', 'blacklist', 'whitelist', 'itemProperties']); }; inherit(CatalogGroup, AbsIttCatalogGroup); defineProperties(AbsIttCatalogGroup.prototype, { /** * Gets the type of data member represented by this instance. * @memberOf AbsIttCatalogGroup.prototype * @type {String} */ type : { get : function() { return 'abs-itt-dataset-list'; } }, /** * Gets a human-readable name for this type of data source, such as 'Web Map Service (WMS)'. * @memberOf AbsIttCatalogGroup.prototype * @type {String} */ typeName : { get : function() { return 'ABS.Stat Dataset List'; } }, /** * Gets the set of functions used to serialize individual properties in {@link CatalogMember#serializeToJson}. * When a property name on the model matches the name of a property in the serializers object literal, * the value will be called as a function and passed a reference to the model, a reference to the destination * JSON object literal, and the name of the property. * @memberOf AbsIttCatalogGroup.prototype * @type {Object} */ serializers : { get : function() { return AbsIttCatalogGroup.defaultSerializers; } } }); /** * Gets or sets the set of default serializer functions to use in {@link CatalogMember#serializeToJson}. Types derived from this type * should expose this instance - cloned and modified if necesary - through their {@link CatalogMember#serializers} property. * @type {Object} */ AbsIttCatalogGroup.defaultSerializers = clone(CatalogGroup.defaultSerializers); AbsIttCatalogGroup.defaultSerializers.items = CatalogGroup.enabledShareableItemsSerializer; freezeObject(AbsIttCatalogGroup.defaultSerializers); AbsIttCatalogGroup.prototype._getValuesThatInfluenceLoad = function() { return [this.url, this.blacklist, this.whitelist]; }; AbsIttCatalogGroup.prototype._load = function() { var baseUrl = cleanAndProxyUrl(this, this.url); var parameters = { method: 'GetDatasetList', format: 'json' }; var that = this; var url = baseUrl + '?' + objectToQuery(parameters); return loadJson(url).then(function(json) { var datasets = json.datasets; var p; var blacklistWildcardTerms = []; for (p in that.blacklist) { if (that.blacklist.hasOwnProperty(p)) { if (p[0] === '?') { blacklistWildcardTerms.push(p.substring(1)); } } } var whitelistWildcardTerms = []; for (p in that.whitelist) { if (that.whitelist.hasOwnProperty(p)) { if (p[0] === '?') { whitelistWildcardTerms.push(p.substring(1)); } } } for (var i = 0; i < datasets.length - 1; ++i) { var dataset = datasets[i]; var w; //apply blacklist var blacklist = (defined(that.blacklist) && defined(that.blacklist[dataset.description])); for (w = 0; w < blacklistWildcardTerms.length && !blacklist; w++) { if (dataset.id.indexOf(blacklistWildcardTerms[w]) !== -1) { blacklist = true; } } //now apply whitelist for (w = 0; w < whitelistWildcardTerms.length && !blacklist; w++) { if (dataset.id.indexOf(whitelistWildcardTerms[w]) === -1) { blacklist = true; } } if (defined(that.whitelist) && defined(that.whitelist[dataset.description])) { blacklist = true; } if (blacklist) { console.log('Provider Feedback: Filtering out ' + dataset.description + ' (' + dataset.id + ') because it is blacklisted.'); continue; } that.add(createItemForDataset(that, dataset)); } }).otherwise(function(e) { console.log(e.message); throw new TerriaError({ sender: that, title: 'Group is not available', message: '\ An error occurred while invoking GetCodeListValue on the ABS ITT server. \ <p>This error may indicate that the group you opened is temporarily unavailable or there is a \ problem with your internet connection. Try opening the group again, and if the problem persists, please report it by \ sending an email to <a href="mailto:'+that.terria.supportEmail+'">'+that.terria.supportEmail+'</a>.</p>' }); }); }; function cleanAndProxyUrl(catalogGroup, url) { // Strip off the search portion of the URL var uri = new URI(url); uri.search(''); var cleanedUrl = uri.toString(); return proxyCatalogItemUrl(catalogGroup, cleanedUrl, '1d'); } function createItemForDataset(absGroup, dataset) { var result = new AbsIttCatalogItem(absGroup.terria); result.name = dataset.description; result.description = dataset.description; result.dataCustodian = absGroup.dataCustodian; result.url = absGroup.url; result.datasetId = dataset.id; result.filter = absGroup.filter; result.conceptNamesUrl = absGroup.conceptNamesUrl; result.regionPopulationsUrlPrefix = absGroup.regionPopulationsUrlPrefix; // result.tableStyle = absGroup.tableStyle; // TODO: do we need to be able to define TableStyle on the group? if (typeof(absGroup.itemProperties) === 'object') { result.updateFromJson(absGroup.itemProperties); } return result; } module.exports = AbsIttCatalogGroup;