You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
304 lines
9.0 KiB
JavaScript
304 lines
9.0 KiB
JavaScript
import defaultValue from "../../Core/defaultValue.js";
|
|
import defined from "../../Core/defined.js";
|
|
import DeveloperError from "../../Core/DeveloperError.js";
|
|
import EllipsoidTerrainProvider from "../../Core/EllipsoidTerrainProvider.js";
|
|
import knockout from "../../ThirdParty/knockout.js";
|
|
import createCommand from "../createCommand.js";
|
|
|
|
/**
|
|
* The view model for {@link BaseLayerPicker}.
|
|
* @alias BaseLayerPickerViewModel
|
|
* @constructor
|
|
*
|
|
* @param {Object} options Object with the following properties:
|
|
* @param {Globe} options.globe The Globe to use.
|
|
* @param {ProviderViewModel[]} [options.imageryProviderViewModels=[]] The array of ProviderViewModel instances to use for imagery.
|
|
* @param {ProviderViewModel} [options.selectedImageryProviderViewModel] The view model for the current base imagery layer, if not supplied the first available imagery layer is used.
|
|
* @param {ProviderViewModel[]} [options.terrainProviderViewModels=[]] The array of ProviderViewModel instances to use for terrain.
|
|
* @param {ProviderViewModel} [options.selectedTerrainProviderViewModel] The view model for the current base terrain layer, if not supplied the first available terrain layer is used.
|
|
*
|
|
* @exception {DeveloperError} imageryProviderViewModels must be an array.
|
|
* @exception {DeveloperError} terrainProviderViewModels must be an array.
|
|
*/
|
|
function BaseLayerPickerViewModel(options) {
|
|
options = defaultValue(options, defaultValue.EMPTY_OBJECT);
|
|
|
|
var globe = options.globe;
|
|
var imageryProviderViewModels = defaultValue(
|
|
options.imageryProviderViewModels,
|
|
[]
|
|
);
|
|
var terrainProviderViewModels = defaultValue(
|
|
options.terrainProviderViewModels,
|
|
[]
|
|
);
|
|
|
|
//>>includeStart('debug', pragmas.debug);
|
|
if (!defined(globe)) {
|
|
throw new DeveloperError("globe is required");
|
|
}
|
|
//>>includeEnd('debug');
|
|
|
|
this._globe = globe;
|
|
|
|
/**
|
|
* Gets or sets an array of ProviderViewModel instances available for imagery selection.
|
|
* This property is observable.
|
|
* @type {ProviderViewModel[]}
|
|
*/
|
|
this.imageryProviderViewModels = imageryProviderViewModels.slice(0);
|
|
|
|
/**
|
|
* Gets or sets an array of ProviderViewModel instances available for terrain selection.
|
|
* This property is observable.
|
|
* @type {ProviderViewModel[]}
|
|
*/
|
|
this.terrainProviderViewModels = terrainProviderViewModels.slice(0);
|
|
|
|
/**
|
|
* Gets or sets whether the imagery selection drop-down is currently visible.
|
|
* @type {Boolean}
|
|
* @default false
|
|
*/
|
|
this.dropDownVisible = false;
|
|
|
|
knockout.track(this, [
|
|
"imageryProviderViewModels",
|
|
"terrainProviderViewModels",
|
|
"dropDownVisible",
|
|
]);
|
|
|
|
var imageryObservable = knockout.getObservable(
|
|
this,
|
|
"imageryProviderViewModels"
|
|
);
|
|
var imageryProviders = knockout.pureComputed(function () {
|
|
var providers = imageryObservable();
|
|
var categories = {};
|
|
var i;
|
|
for (i = 0; i < providers.length; i++) {
|
|
var provider = providers[i];
|
|
var category = provider.category;
|
|
if (defined(categories[category])) {
|
|
categories[category].push(provider);
|
|
} else {
|
|
categories[category] = [provider];
|
|
}
|
|
}
|
|
var allCategoryNames = Object.keys(categories);
|
|
|
|
var result = [];
|
|
for (i = 0; i < allCategoryNames.length; i++) {
|
|
var name = allCategoryNames[i];
|
|
result.push({
|
|
name: name,
|
|
providers: categories[name],
|
|
});
|
|
}
|
|
return result;
|
|
});
|
|
this._imageryProviders = imageryProviders;
|
|
|
|
var terrainObservable = knockout.getObservable(
|
|
this,
|
|
"terrainProviderViewModels"
|
|
);
|
|
var terrainProviders = knockout.pureComputed(function () {
|
|
var providers = terrainObservable();
|
|
var categories = {};
|
|
var i;
|
|
for (i = 0; i < providers.length; i++) {
|
|
var provider = providers[i];
|
|
var category = provider.category;
|
|
if (defined(categories[category])) {
|
|
categories[category].push(provider);
|
|
} else {
|
|
categories[category] = [provider];
|
|
}
|
|
}
|
|
var allCategoryNames = Object.keys(categories);
|
|
|
|
var result = [];
|
|
for (i = 0; i < allCategoryNames.length; i++) {
|
|
var name = allCategoryNames[i];
|
|
result.push({
|
|
name: name,
|
|
providers: categories[name],
|
|
});
|
|
}
|
|
return result;
|
|
});
|
|
this._terrainProviders = terrainProviders;
|
|
|
|
/**
|
|
* Gets the button tooltip. This property is observable.
|
|
* @type {String}
|
|
*/
|
|
this.buttonTooltip = undefined;
|
|
knockout.defineProperty(this, "buttonTooltip", function () {
|
|
var selectedImagery = this.selectedImagery;
|
|
var selectedTerrain = this.selectedTerrain;
|
|
|
|
var imageryTip = defined(selectedImagery)
|
|
? selectedImagery.name
|
|
: undefined;
|
|
var terrainTip = defined(selectedTerrain)
|
|
? selectedTerrain.name
|
|
: undefined;
|
|
|
|
if (defined(imageryTip) && defined(terrainTip)) {
|
|
return imageryTip + "\n" + terrainTip;
|
|
} else if (defined(imageryTip)) {
|
|
return imageryTip;
|
|
}
|
|
return terrainTip;
|
|
});
|
|
|
|
/**
|
|
* Gets the button background image. This property is observable.
|
|
* @type {String}
|
|
*/
|
|
this.buttonImageUrl = undefined;
|
|
knockout.defineProperty(this, "buttonImageUrl", function () {
|
|
var selectedImagery = this.selectedImagery;
|
|
if (defined(selectedImagery)) {
|
|
return selectedImagery.iconUrl;
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Gets or sets the currently selected imagery. This property is observable.
|
|
* @type {ProviderViewModel}
|
|
* @default undefined
|
|
*/
|
|
this.selectedImagery = undefined;
|
|
var selectedImageryViewModel = knockout.observable();
|
|
|
|
this._currentImageryProviders = [];
|
|
knockout.defineProperty(this, "selectedImagery", {
|
|
get: function () {
|
|
return selectedImageryViewModel();
|
|
},
|
|
set: function (value) {
|
|
if (selectedImageryViewModel() === value) {
|
|
this.dropDownVisible = false;
|
|
return;
|
|
}
|
|
|
|
var i;
|
|
var currentImageryProviders = this._currentImageryProviders;
|
|
var currentImageryProvidersLength = currentImageryProviders.length;
|
|
var imageryLayers = this._globe.imageryLayers;
|
|
var hadExistingBaseLayer = false;
|
|
for (i = 0; i < currentImageryProvidersLength; i++) {
|
|
var layersLength = imageryLayers.length;
|
|
for (var x = 0; x < layersLength; x++) {
|
|
var layer = imageryLayers.get(x);
|
|
if (layer.imageryProvider === currentImageryProviders[i]) {
|
|
imageryLayers.remove(layer);
|
|
hadExistingBaseLayer = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (defined(value)) {
|
|
var newProviders = value.creationCommand();
|
|
if (Array.isArray(newProviders)) {
|
|
var newProvidersLength = newProviders.length;
|
|
for (i = newProvidersLength - 1; i >= 0; i--) {
|
|
imageryLayers.addImageryProvider(newProviders[i], 0);
|
|
}
|
|
this._currentImageryProviders = newProviders.slice(0);
|
|
} else {
|
|
this._currentImageryProviders = [newProviders];
|
|
if (hadExistingBaseLayer) {
|
|
imageryLayers.addImageryProvider(newProviders, 0);
|
|
} else {
|
|
var baseLayer = imageryLayers.get(0);
|
|
if (defined(baseLayer)) {
|
|
imageryLayers.remove(baseLayer);
|
|
}
|
|
imageryLayers.addImageryProvider(newProviders, 0);
|
|
}
|
|
}
|
|
}
|
|
selectedImageryViewModel(value);
|
|
this.dropDownVisible = false;
|
|
},
|
|
});
|
|
|
|
/**
|
|
* Gets or sets the currently selected terrain. This property is observable.
|
|
* @type {ProviderViewModel}
|
|
* @default undefined
|
|
*/
|
|
this.selectedTerrain = undefined;
|
|
var selectedTerrainViewModel = knockout.observable();
|
|
|
|
knockout.defineProperty(this, "selectedTerrain", {
|
|
get: function () {
|
|
return selectedTerrainViewModel();
|
|
},
|
|
set: function (value) {
|
|
if (selectedTerrainViewModel() === value) {
|
|
this.dropDownVisible = false;
|
|
return;
|
|
}
|
|
|
|
var newProvider;
|
|
if (defined(value)) {
|
|
newProvider = value.creationCommand();
|
|
}
|
|
|
|
this._globe.depthTestAgainstTerrain = !(
|
|
newProvider instanceof EllipsoidTerrainProvider
|
|
);
|
|
this._globe.terrainProvider = newProvider;
|
|
selectedTerrainViewModel(value);
|
|
this.dropDownVisible = false;
|
|
},
|
|
});
|
|
|
|
var that = this;
|
|
this._toggleDropDown = createCommand(function () {
|
|
that.dropDownVisible = !that.dropDownVisible;
|
|
});
|
|
|
|
this.selectedImagery = defaultValue(
|
|
options.selectedImageryProviderViewModel,
|
|
imageryProviderViewModels[0]
|
|
);
|
|
this.selectedTerrain = defaultValue(
|
|
options.selectedTerrainProviderViewModel,
|
|
terrainProviderViewModels[0]
|
|
);
|
|
}
|
|
|
|
Object.defineProperties(BaseLayerPickerViewModel.prototype, {
|
|
/**
|
|
* Gets the command to toggle the visibility of the drop down.
|
|
* @memberof BaseLayerPickerViewModel.prototype
|
|
*
|
|
* @type {Command}
|
|
*/
|
|
toggleDropDown: {
|
|
get: function () {
|
|
return this._toggleDropDown;
|
|
},
|
|
},
|
|
|
|
/**
|
|
* Gets the globe.
|
|
* @memberof BaseLayerPickerViewModel.prototype
|
|
*
|
|
* @type {Globe}
|
|
*/
|
|
globe: {
|
|
get: function () {
|
|
return this._globe;
|
|
},
|
|
},
|
|
});
|
|
export default BaseLayerPickerViewModel;
|