UNPKG

terriajs

Version:

Geospatial data visualization platform.

314 lines (274 loc) 12.1 kB
'use strict'; /*global require*/ var CatalogItem = require('./CatalogItem'); var defined = require('terriajs-cesium/Source/Core/defined'); var defineProperties = require('terriajs-cesium/Source/Core/defineProperties'); var GeoJsonCatalogItem = require('./GeoJsonCatalogItem'); var inherit = require('../Core/inherit'); var knockout = require('terriajs-cesium/Source/ThirdParty/knockout'); var loadXML = require('../Core/loadXML'); var proxyCatalogItemUrl = require('./proxyCatalogItemUrl'); var ShortReportSection = require('./ShortReportSection'); var URI = require('urijs'); var when = require('terriajs-cesium/Source/ThirdParty/when'); var xml2json = require('../ThirdParty/xml2json'); var createCatalogMemberFromType = require('./createCatalogMemberFromType'); /** * A catalog item representing the result of invoking a web processing service (WPS). * * @alias WebProcessingServiceCatalogItem * @constructor * @extends CatalogItem * * @param {Terria} terria The Terria instance. */ function WebProcessingServiceCatalogItem(terria) { CatalogItem.call(this, terria); this._geoJsonItem = undefined; /** * Gets or sets the parameters to the WPS function. * All parameter names must be entered in lowercase in order to be consistent with references in TerrisJS code. * @type {FunctionParameter[]} */ this.parameters = undefined; /** * Gets or sets the values of the parameters that were used to invoke this function. * @type {Object} */ this.parameterValues = undefined; /** * Gets or sets the URL of the WPS completed response. This property is ignored if * {@link WebProcessingServiceCatalogItem#wpsResponse} is defined. This property is observable. * @type {String} */ this.wpsResponseUrl = undefined; /** * Gets or sets the completed WPS response, as either XML or the result of passing the * XML through {@link xml2json}. * @type {Object|Document} */ this.wpsResponse = undefined; knockout.track(this, ['wpsResponseUrl', 'wpsResponse']); } inherit(CatalogItem, WebProcessingServiceCatalogItem); defineProperties(WebProcessingServiceCatalogItem.prototype, { /** * Gets the type of data member represented by this instance. * @memberOf WebProcessingServiceCatalogItem.prototype * @type {String} */ type : { get : function() { return 'wps-result'; } }, /** * Gets a human-readable name for this type of data source, 'Web Processing Service Result'. * @memberOf WebProcessingServiceCatalogItem.prototype * @type {String} */ typeName : { get : function() { return 'Web Processing Service Result'; } }, /** * Gets the data source associated with this catalog item. * @memberOf WebProcessingServiceCatalogItem.prototype * @type {DataSource} */ dataSource : { get : function() { return defined(this._geoJsonItem) ? this._geoJsonItem.dataSource : undefined; } } }); WebProcessingServiceCatalogItem.prototype._getValuesThatInfluenceLoad = function() { return [this.wpsResponseUrl, this.wpsResponse]; }; WebProcessingServiceCatalogItem.prototype._load = function() { if (defined(this._geoJsonItem)) { this._geoJsonItem._hide(); this._geoJsonItem._disable(); this._geoJsonItem = undefined; } var that = this; return getGeoJson(this).then(function(geojson) { var wpsResponsePromise; if (defined(that.wpsResponse)) { wpsResponsePromise = when(that.wpsResponse); } else { wpsResponsePromise = loadXML(proxyCatalogItemUrl(that, that.wpsResponseUrl, '1d')); } return wpsResponsePromise.then(function(xmlOrJson) { var json; if (xmlOrJson instanceof Document) { json = xml2json(xmlOrJson); } else { json = xmlOrJson; } var processOutputs = json.ProcessOutputs; if (!defined(processOutputs)) { return; } var outputs = processOutputs.Output; if (!defined(outputs)) { return; } else if (!Array.isArray(outputs)) { outputs = [outputs]; } for (var i = 0; i < outputs.length; ++i) { if (!defined(outputs[i].Data)) { continue; } // skip process contexts if (defined(outputs[i].Identifier) && outputs[i].Identifier === '.context') { continue; } if (defined(outputs[i].Data.LiteralData)) { that.shortReportSections.push(new ShortReportSection({ name: outputs[i].Title, content: formatOutputValue(outputs[i].Title, outputs[i].Data.LiteralData) })); } else if (defined(outputs[i].Data.ComplexData)) { var content = outputs[i].Data.ComplexData; if (outputs[i].Data.ComplexData.mimeType === 'text/csv') { content = '<collapsible title="' + outputs[i].Title + '" open="' + (i === 0 ? 'true' : 'false') + '">'; content += '<chart can-download="true" hide-buttons="false" title="' + outputs[i].Title + '" data=\'' + outputs[i].Data.ComplexData + '\' styling="histogram"></chart>'; content += '</collapsible>'; } else if (outputs[i].Data.ComplexData.mimeType === 'application/vnd.terriajs.catalog-member+json') { content = 'Chart ' + outputs[i].Title + ' generated.'; var jsonCatalogItem = JSON.parse(outputs[i].Data.ComplexData.text); var catalogItem = createCatalogMemberFromType(jsonCatalogItem.type, that.terria); catalogItem.updateFromJson(jsonCatalogItem); } that.shortReportSections.push(new ShortReportSection({ content: content })); } } var inputsSection = '<table class="cesium-infoBox-defaultTable">' + (that.parameters || []).reduce(function(previousValue, parameter) { return previousValue + '<tr>' + '<td style="vertical-align: middle">' + parameter.name + '</td>' + '<td style="padding-left: 4px">' + parameter.formatValueAsString(that.parameterValues[parameter.id]) + '</td>' + '</tr>'; }, '') + '</table>'; var outputsSection = '<table class="cesium-infoBox-defaultTable">' + (outputs || []).reduce(function(previousValue, output) { if (!defined(output.Data) || (!defined(output.Data.LiteralData) && !defined(output.Data.ComplexData))) { return previousValue; } var content = ""; if (defined(output.Data.LiteralData)) { content = formatOutputValue(output.Title, output.Data.LiteralData); } else if (defined(output.Data.ComplexData)) { if (output.Data.ComplexData.mimeType === 'text/csv' ) { content = '<chart can-download="true" hide-buttons="false" title="' + output.Title + '" data=\'' + output.Data.ComplexData + '\' styling: "feature-info">'; } else if (output.Data.ComplexData.mimeType === 'application/vnd.terriajs.catalog-member+json') { content = 'Chart ' + output.Title + ' generated.'; } // Support other types of ComplexData here as it becomes necessary. } return previousValue + '<tr>' + '<td style="vertical-align: middle">' + output.Title + '</td>' + '<td>' + content + '</td>' + '</tr>'; }, '') + '</table>'; var section = that.findInfoSection('Inputs'); if (!defined(section)) { that.info.push({ name: 'Inputs', content: inputsSection }); } if (!defined(that.featureInfoTemplate)) { that.featureInfoTemplate = '#### Inputs\n\n' + inputsSection + '\n\n' + '#### Outputs\n\n' + outputsSection; } if (defined(geojson)) { that._geoJsonItem = new GeoJsonCatalogItem(that.terria); that._geoJsonItem.name = that.name; that._geoJsonItem.data = geojson; return that._geoJsonItem.load().then(function() { if (!defined(that.rectangle)) { that.rectangle = that._geoJsonItem.rectangle; } }); } }); }); }; WebProcessingServiceCatalogItem.prototype._enable = function() { if (defined(this._geoJsonItem)) { this._geoJsonItem._enable(); } }; WebProcessingServiceCatalogItem.prototype._disable = function() { if (defined(this._geoJsonItem)) { this._geoJsonItem._disable(); } }; WebProcessingServiceCatalogItem.prototype._show = function() { if (defined(this._geoJsonItem)) { this._geoJsonItem._show(); } }; WebProcessingServiceCatalogItem.prototype._hide = function() { if (defined(this._geoJsonItem)) { this._geoJsonItem._hide(); } }; function formatOutputValue(title, value) { if (!defined(value)) { return ''; } var values = value.split(','); return values.reduce(function(previousValue, currentValue) { if (value.match(/[.\/](png|jpg|jpeg|gif|svg)/i)) { return previousValue + '<a href="' + currentValue + '"><img src="' + currentValue + '" alt="' + title + '" /></a>'; } else if (currentValue.indexOf('http:') === 0 || currentValue.indexOf('https:') === 0) { var uri = new URI(currentValue); return previousValue + '<a href="' + currentValue + '">' + uri.filename() + '</a>'; } else { return previousValue + currentValue; } }, ''); } function getGeoJson(catalogItem) { if (!defined(catalogItem.parameters) || !defined(catalogItem.parameterValues)) { return when(undefined); } var features = []; for (var i=0; i<catalogItem.parameters.length; i++) { if (typeof catalogItem.parameters[i].getGeoJsonFeature === 'function') { var potentialFeature = catalogItem.parameters[i].getGeoJsonFeature(catalogItem.parameterValues[catalogItem.parameters[i].id]); if (defined(potentialFeature)) { if (potentialFeature instanceof Array) { features = features.concat(potentialFeature); } else { features.push(potentialFeature); } } } } return when.all(features).then(function(results) { var geojson = { "type":"FeatureCollection", "features": results, "totalFeatures": results.length }; return geojson; }); } module.exports = WebProcessingServiceCatalogItem;