terriajs
Version:
Geospatial data visualization platform.
149 lines (132 loc) • 6.15 kB
JavaScript
'use strict';
/*global require*/
var defined = require('terriajs-cesium/Source/Core/defined');
var defineProperties = require('terriajs-cesium/Source/Core/defineProperties');
var knockout = require('terriajs-cesium/Source/ThirdParty/knockout');
var overrideProperty = require('../Core/overrideProperty');
var FunctionParameter = require('./FunctionParameter');
var inherit = require('../Core/inherit');
var RegionProvider = require('../Map/RegionProvider');
var RegionProviderList = require('../Map/RegionProviderList');
/**
* A parameter that specifies a type of region.
*
* @alias RegionTypeParameter
* @constructor
* @extends FunctionParameter
*
* @param {Object} [options] Object with the following properties:
* @param {Terria} options.terria The Terria instance.
* @param {String} options.id The unique ID of this parameter.
* @param {String} [options.name] The name of this parameter. If not specified, the ID is used as the name.
* @param {String} [options.description] The description of the parameter.
* @param {String[]} [options.validRegionTypes] The region types from which this RegionTypeParameter selects. If this parameter is not specified, all region types
* known to {@link Terria} may be selected.
*/
var RegionTypeParameter = function(options) {
FunctionParameter.call(this, options);
this._regionProviderPromise = undefined;
this._regionProviderList = undefined;
this.validRegionTypes = options.validRegionTypes;
// Track this so that defaultValue can update once regionProviderList is known.
knockout.track(this, ['_regionProviderList']);
/**
* Gets the default region provider if the user has not specified one. If region-mapped data
* is loaded on the map, this property returns the {@link RegionProvider} of the topmost
* region-mapped catalog item. Otherwise, it returns the first region provider. If the
* parameter has not yet been loaded, this property returns undefined.
* @memberof RegionTypeParameter.prototype
* @type {RegionProvider}
*/
overrideProperty(this, 'defaultValue', {
get: function() {
if (defined(this._defaultValue)) {
return this._defaultValue;
}
const nowViewingItems = this.terria.nowViewing.items;
if (nowViewingItems.length > 0) {
for (let i = 0; i < nowViewingItems.length; ++i) {
const item = nowViewingItems[i];
if (defined(item.regionMapping) && defined(item.regionMapping.regionDetails) && item.regionMapping.regionDetails.length > 0) {
return item.regionMapping.regionDetails[0].regionProvider;
}
}
}
if (defined(this._regionProviderList) && this._regionProviderList.length > 0) {
return this._regionProviderList[0];
}
// No defaults available; have we requested the region providers yet?
this.load();
return undefined;
}
});
};
/**
* Resolves value that may be either a {@link RegionProvider} or a {@link RegionTypeParameter}
* to a {@link RegionProvider}.
* @param {RegionProvider|RegionTypeParameter} regionProviderOrParameter The region provider or parameter.
* @return {RegionProvider} If `regionProviderOrParameter` is a {@link RegionProvider}, that value is returned. If it is a
* {@link RegionTypeParameter}, the value of the parameter is returned.
* The return value may be undefined if `regionProviderOrParameter` is undefined, or if the value of the
* region type parameter is undefined.
*/
RegionTypeParameter.resolveRegionProvider = function(regionProviderOrParameter) {
if (regionProviderOrParameter instanceof RegionProvider) {
return regionProviderOrParameter;
} else if (regionProviderOrParameter instanceof RegionTypeParameter) {
return regionProviderOrParameter.value;
} else {
return undefined;
}
};
inherit(FunctionParameter, RegionTypeParameter);
defineProperties(RegionTypeParameter.prototype, {
/**
* Gets the type of this parameter.
* @memberof RegionTypeParameter.prototype
* @type {String}
*/
type: {
get: function() {
return 'regionType';
}
},
/**
* Gets or sets the value of this parameter.
* @memberof RegionTypeParameter.prototype
* @member {RegionProvider} value
*/
});
RegionTypeParameter.prototype._load = function() {
return this.getAllRegionTypes();
};
/**
* Gets all list of region types that may be selected for this parameter.
* Also caches the promise in this._regionProviderPromise, and the promise result in
* this._regionProviderList.
* @return {Promise.<RegionProvider[]>} [description]
*/
RegionTypeParameter.prototype.getAllRegionTypes = function() {
var that = this;
if (defined(this._regionProviderPromise)) {
return this._regionProviderPromise;
}
this._regionProviderPromise = RegionProviderList.fromUrl(this.terria.configParameters.regionMappingDefinitionsUrl, this.terria.corsProxy).then(function(regionProviderList) {
var result;
if (!defined(that.validRegionTypes)) {
result = regionProviderList.regionProviders;
} else {
result = regionProviderList.regionProviders.filter(function(regionProvider) {
return that.validRegionTypes.indexOf(regionProvider.regionType) >= 0;
});
}
// Filter out region types that don't have a WMS server associated (e.g. those that are purely vector tile)
result = result.filter(function(regionProvider) {
return defined(regionProvider.analyticsWmsServer);
});
that._regionProviderList = result;
return result;
});
return this._regionProviderPromise;
};
module.exports = RegionTypeParameter;