cesium/Apps/Sandcastle/gallery/Imagery Layers Manipulation...

334 lines
12 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>
<meta
name="description"
content="Layer imagery from multiple sources, including WMS servers, Bing Maps, ArcGIS Online, OpenStreetMaps, and more, and adjust the alpha of each independently."
/>
<meta name="cesium-sandcastle-labels" content="Showcases" />
<title>Cesium Demo</title>
<script type="text/javascript" src="../Sandcastle-header.js"></script>
<script
type="text/javascript"
src="../../../Build/CesiumUnminified/Cesium.js"
nomodule
></script>
<script type="module" src="../load-cesium-es6.js"></script>
</head>
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html">
<style>
@import url(../templates/bucket.css);
#toolbar {
background: rgba(42, 42, 42, 0.8);
padding: 4px;
border-radius: 4px;
}
#toolbar input {
vertical-align: middle;
padding-top: 2px;
padding-bottom: 2px;
}
#toolbar table tr {
transform: translateY(0);
transition: transform 0.4s ease-out;
}
#toolbar table tr.up {
transform: translateY(33px);
transition: none;
}
#toolbar table tr.down {
transform: translateY(-33px);
transition: none;
}
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar">
<table>
<tbody data-bind="foreach: layers">
<tr
data-bind="css: { up: $parent.upLayer === $data, down: $parent.downLayer === $data }"
>
<td><input type="checkbox" data-bind="checked: show" /></td>
<td>
<span
data-bind="text: name, visible: !$parent.isSelectableLayer($data)"
></span>
<select
data-bind="visible: $parent.isSelectableLayer($data), options: $parent.baseLayers, optionsText: 'name', value: $parent.selectedLayer"
></select>
</td>
<td>
<input
type="range"
min="0"
max="1"
step="0.01"
data-bind="value: alpha, valueUpdate: 'input'"
/>
</td>
<td>
<button
type="button"
class="cesium-button"
data-bind="click: function() { $parent.raise($data, $index()); }, visible: $parent.canRaise($index())"
>
</button>
</td>
<td>
<button
type="button"
class="cesium-button"
data-bind="click: function() { $parent.lower($data, $index()); }, visible: $parent.canLower($index())"
>
</button>
</td>
</tr>
</tbody>
</table>
</div>
<script id="cesium_sandcastle_script">
window.startup = async function (Cesium) {
"use strict";
//Sandcastle_Begin
const viewer = new Cesium.Viewer("cesiumContainer", {
baseLayerPicker: false,
geocoder: false,
});
const imageryLayers = viewer.imageryLayers;
const viewModel = {
layers: [],
baseLayers: [],
upLayer: null,
downLayer: null,
selectedLayer: null,
isSelectableLayer: function (layer) {
return this.baseLayers.indexOf(layer) >= 0;
},
raise: function (layer, index) {
imageryLayers.raise(layer);
viewModel.upLayer = layer;
viewModel.downLayer = viewModel.layers[Math.max(0, index - 1)];
updateLayerList();
window.setTimeout(function () {
viewModel.upLayer = viewModel.downLayer = null;
}, 10);
},
lower: function (layer, index) {
imageryLayers.lower(layer);
viewModel.upLayer =
viewModel.layers[Math.min(viewModel.layers.length - 1, index + 1)];
viewModel.downLayer = layer;
updateLayerList();
window.setTimeout(function () {
viewModel.upLayer = viewModel.downLayer = null;
}, 10);
},
canRaise: function (layerIndex) {
return layerIndex > 0;
},
canLower: function (layerIndex) {
return layerIndex >= 0 && layerIndex < imageryLayers.length - 1;
},
};
const baseLayers = viewModel.baseLayers;
Cesium.knockout.track(viewModel);
function setupLayers() {
// Create all the base layers that this example will support.
// These base layers aren't really special. It's possible to have multiple of them
// enabled at once, just like the other layers, but it doesn't make much sense because
// all of these layers cover the entire globe and are opaque.
addBaseLayerOption("Bing Maps Aerial", Cesium.createWorldImageryAsync());
addBaseLayerOption(
"Bing Maps Road",
Cesium.createWorldImageryAsync({
style: Cesium.IonWorldImageryStyle.ROAD,
}),
);
addBaseLayerOption(
"ArcGIS World Street Maps",
Cesium.ArcGisMapServerImageryProvider.fromUrl(
"https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
),
);
addBaseLayerOption("OpenStreetMaps", new Cesium.OpenStreetMapImageryProvider());
addBaseLayerOption(
"Stadia x Stamen Watercolor",
new Cesium.OpenStreetMapImageryProvider({
url: "https://tiles.stadiamaps.com/tiles/stamen_watercolor/",
fileExtension: "jpg",
credit: `&copy; <a href="https://stamen.com/" target="_blank">Stamen Design</a>
&copy; <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a>
&copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a>
&copy; <a href="https://www.openstreetmap.org/about/" target="_blank">OpenStreetMap contributors</a>`,
}),
);
addBaseLayerOption(
"Natural Earth II (local)",
Cesium.TileMapServiceImageryProvider.fromUrl(
Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"),
),
);
addBaseLayerOption(
"USGS Shaded Relief (via WMTS)",
new Cesium.WebMapTileServiceImageryProvider({
url: "https://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/WMTS",
layer: "USGSShadedReliefOnly",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "default028mm",
maximumLevel: 19,
credit: "U. S. Geological Survey",
}),
);
// Create the additional layers
addAdditionalLayerOption(
"United States GOES Infrared",
new Cesium.WebMapServiceImageryProvider({
url: "https://mesonet.agron.iastate.edu/cgi-bin/wms/goes/conus_ir.cgi?",
layers: "goes_conus_ir",
credit: "Infrared data courtesy Iowa Environmental Mesonet",
parameters: {
transparent: "true",
format: "image/png",
},
}),
);
addAdditionalLayerOption(
"United States Weather Radar",
new Cesium.WebMapServiceImageryProvider({
url: "https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi?",
layers: "nexrad-n0r",
credit: "Radar data courtesy Iowa Environmental Mesonet",
parameters: {
transparent: "true",
format: "image/png",
},
}),
);
addAdditionalLayerOption(
"TileMapService Image",
Cesium.TileMapServiceImageryProvider.fromUrl(
"../images/cesium_maptiler/Cesium_Logo_Color",
),
0.2,
);
addAdditionalLayerOption(
"Single Image",
Cesium.SingleTileImageryProvider.fromUrl(
"../images/Cesium_Logo_overlay.png",
{
rectangle: Cesium.Rectangle.fromDegrees(-115.0, 38.0, -107, 39.75),
},
),
1.0,
);
addAdditionalLayerOption("Grid", new Cesium.GridImageryProvider(), 1.0, false);
addAdditionalLayerOption(
"Tile Coordinates",
new Cesium.TileCoordinatesImageryProvider(),
1.0,
false,
);
}
async function addBaseLayerOption(name, imageryProviderPromise) {
try {
const imageryProvider = await Promise.resolve(imageryProviderPromise);
const layer = new Cesium.ImageryLayer(imageryProvider);
layer.name = name;
baseLayers.push(layer);
updateLayerList();
} catch (error) {
console.error(`There was an error while creating ${name}. ${error}`);
}
}
async function addAdditionalLayerOption(
name,
imageryProviderPromise,
alpha,
show,
) {
try {
const imageryProvider = await Promise.resolve(imageryProviderPromise);
const layer = new Cesium.ImageryLayer(imageryProvider);
layer.alpha = alpha ?? 0.5;
layer.show = show ?? true;
layer.name = name;
imageryLayers.add(layer);
Cesium.knockout.track(layer, ["alpha", "show", "name"]);
updateLayerList();
} catch (error) {
console.error(`There was an error while creating ${name}. ${error}`);
}
}
function updateLayerList() {
const numLayers = imageryLayers.length;
viewModel.layers.splice(0, viewModel.layers.length);
for (let i = numLayers - 1; i >= 0; --i) {
viewModel.layers.push(imageryLayers.get(i));
}
}
setupLayers();
//Bind the viewModel to the DOM elements of the UI that call for it.
const toolbar = document.getElementById("toolbar");
Cesium.knockout.applyBindings(viewModel, toolbar);
Cesium.knockout
.getObservable(viewModel, "selectedLayer")
.subscribe(function (baseLayer) {
// Handle changes to the drop-down base layer selector.
let activeLayerIndex = 0;
const numLayers = viewModel.layers.length;
for (let i = 0; i < numLayers; ++i) {
if (viewModel.isSelectableLayer(viewModel.layers[i])) {
activeLayerIndex = i;
break;
}
}
const activeLayer = viewModel.layers[activeLayerIndex];
const show = activeLayer.show;
const alpha = activeLayer.alpha;
imageryLayers.remove(activeLayer, false);
imageryLayers.add(baseLayer, numLayers - activeLayerIndex - 1);
baseLayer.show = show;
baseLayer.alpha = alpha;
updateLayerList();
});
//Sandcastle_End
};
if (typeof Cesium !== "undefined") {
window.startupCalled = true;
window.startup(Cesium).catch((error) => {
"use strict";
console.error(error);
});
Sandcastle.finishedLoading();
}
</script>
</body>
</html>