```
--------------------------------
### Manage Layers in WorldWind.js
Source: https://context7.com/worldwindearth/worldwindjs/llms.txt
Demonstrates how to control layers within WorldWind.js. This includes toggling visibility, setting opacity, defining altitude-based visibility ranges, reordering layers, removing layers, and iterating through all available layers. Assumes layers like 'bmngLayer', 'bingLayer', and 'placemarkLayer' are already defined.
```javascript
// Toggle layer visibility
bmngLayer.enabled = true;
bingLayer.enabled = false;
// Set layer opacity (0.0 to 1.0)
bmngLayer.opacity = 0.5;
// Control altitude-based visibility
placemarkLayer.minActiveAltitude = 0;
placemarkLayer.maxActiveAltitude = 1000000;
// Reorder layers
var layerIndex = wwd.indexOfLayer(placemarkLayer);
wwd.insertLayer(layerIndex + 1, placemarkLayer);
// Remove layer
wwd.removeLayer(placemarkLayer);
// Iterate through all layers
for (var i = 0; i < wwd.layers.length; i++) {
var layer = wwd.layers[i];
console.log(layer.displayName + ": " + layer.enabled);
}
```
--------------------------------
### Include Knockout.js Library via CDN
Source: https://github.com/worldwindearth/worldwindjs/blob/develop/docs/lesson-3.md
This HTML snippet includes the Knockout.js library from a CDN. Knockout.js is a JavaScript library that helps you create responsive user interfaces with a clear separation between layers of your application. It's used here to bind model data to HTML views, automatically updating the UI when data changes.
```html
```
--------------------------------
### Table Row for Preview Selection (HTML/JavaScript)
Source: https://github.com/worldwindearth/worldwindjs/blob/develop/apps/web-app-template/index.html
This HTML snippet, utilizing Knockout.js data-binding, defines a table row for displaying preview selection data. It binds click events to a parent function for previewing, and displays the 'display_name' and 'type' of the data item. This is useful for lists of selectable items within the application.
```html
| |
```
--------------------------------
### Create Layers View Model (JavaScript)
Source: https://github.com/worldwindearth/worldwindjs/blob/develop/docs/lesson-3.md
Defines a JavaScript view model for the layers panel using Knockout.js. It manages observable arrays for base and overlay layers, subscribing to globe changes to automatically update the UI. Dependencies include Knockout.js and the Globe object.
```javascript
/**
* View model for the layers panel.
* @param {Globe} globe - Our globe object
*/
function LayersViewModel(globe) {
var self = this;
self.baseLayers = ko.observableArray(globe.getLayers('base').reverse());
self.overlayLayers = ko.observableArray(globe.getLayers('overlay').reverse());
// Update the view model whenever the model changes
globe.getCategoryTimestamp('base').subscribe(newValue =>
self.loadLayers(globe.getLayers('base'), self.baseLayers));
globe.getCategoryTimestamp('overlay').subscribe(newValue =>
self.loadLayers(globe.getLayers('overlay'), self.overlayLayers));
// Utility to load the layers in reverse order to show last rendered on top
self.loadLayers = function(layers, observableArray) {
observableArray.removeAll();
layers.reverse().forEach(layer => observableArray.push(layer));
};
// Click event handler for the layer panel's buttons
self.toggleLayer = function(layer) {
globe.toggleLayer(layer);
};
}
```
--------------------------------
### Create Text Annotations with JavaScript
Source: https://context7.com/worldwindearth/worldwindjs/llms.txt
Adds text annotations with customizable appearance to the globe. It involves creating a WorldWind.Annotation object at a specific position, configuring its label and attributes (like background color, text color, and leader lines) using AnnotationAttributes, and adding it to a RenderableLayer. Inputs are a WorldWind.Position and AnnotationAttributes. Outputs are visible text annotations on the globe.
```javascript
var position = new WorldWind.Position(45, -100, 1000);
var annotation = new WorldWind.Annotation(position, null);
annotation.label = "Important Location\nMultiple lines supported";
var annotationAttributes = new WorldWind.AnnotationAttributes(null);
annotationAttributes.cornerRadius = 5;
annotationAttributes.backgroundColor = new WorldWind.Color(0, 0, 0, 0.7);
annotationAttributes.textColor = WorldWind.Color.WHITE;
annotationAttributes.drawLeader = true;
annotationAttributes.leaderGapHeight = 10;
annotationAttributes.scale = 1.5;
annotationAttributes.insets = new WorldWind.Insets(10, 10, 10, 10);
annotation.attributes = annotationAttributes;
annotation.altitudeMode = WorldWind.RELATIVE_TO_GROUND;
var annotationLayer = new WorldWind.RenderableLayer("Annotations");
annotationLayer.addRenderable(annotation);
wwd.addLayer(annotationLayer);
```
--------------------------------
### Change Map Projection in WorldWindJS
Source: https://context7.com/worldwindearth/worldwindjs/llms.txt
Demonstrates how to switch between 3D globe and 2D map projections using WorldWindJS. It defines available projections and provides code to set the globe to a 2D Mercator projection and then back to a 3D globe. Dependencies include the WorldWindJS library.
```javascript
// Available projections
var projections = {
"3D": new WorldWind.Globe(new WorldWind.EarthElevationModel()),
"Equirectangular": new WorldWind.Globe2D(),
"Mercator": new WorldWind.ProjectionMercator(),
"North Polar": new WorldWind.ProjectionPolarEquidistant("North"),
"South Polar": new WorldWind.ProjectionPolarEquidistant("South"),
"UPS North": new WorldWind.ProjectionUPS("North"),
"UPS South": new WorldWind.ProjectionUPS("South")
};
// Switch to 2D Mercator
wwd.globe = new WorldWind.Globe2D();
wwd.globe.projection = new WorldWind.ProjectionMercator();
wwd.redraw();
// Switch back to 3D
wwd.globe = new WorldWind.Globe(new WorldWind.EarthElevationModel());
wwd.redraw();
```
--------------------------------
### Parse and Style GeoJSON Data with WorldWind.js
Source: https://context7.com/worldwindearth/worldwindjs/llms.txt
Imports GeoJSON data and visualizes it on the globe. It includes custom styling for point, line, and polygon features based on their geometry and properties. Requires the WorldWind library.
```javascript
var placemarkAttributes = new WorldWind.PlacemarkAttributes(null);
placemarkAttributes.imageScale = 0.05;
placemarkAttributes.imageColor = WorldWind.Color.WHITE;
placemarkAttributes.imageSource = WorldWind.configuration.baseUrl + "images/white-dot.png";
placemarkAttributes.labelAttributes.offset = new WorldWind.Offset(
WorldWind.OFFSET_FRACTION, 0.5,
WorldWind.OFFSET_FRACTION, 1.5
);
var shapeConfigurationCallback = function(geometry, properties) {
var configuration = {};
if (geometry.isPointType() || geometry.isMultiPointType()) {
configuration.attributes = new WorldWind.PlacemarkAttributes(placemarkAttributes);
if (properties && (properties.name || properties.Name)) {
configuration.name = properties.name || properties.Name;
}
if (properties && properties.POP_MAX) {
configuration.attributes.imageScale = 0.01 * Math.log(properties.POP_MAX);
}
}
else if (geometry.isLineStringType() || geometry.isMultiLineStringType()) {
configuration.attributes = new WorldWind.ShapeAttributes(null);
configuration.attributes.drawOutline = true;
configuration.attributes.outlineColor = WorldWind.Color.BLUE;
configuration.attributes.outlineWidth = 2.0;
}
else if (geometry.isPolygonType() || geometry.isMultiPolygonType()) {
configuration.attributes = new WorldWind.ShapeAttributes(null);
configuration.attributes.interiorColor = new WorldWind.Color(
0.375 + 0.5 * Math.random(),
0.375 + 0.5 * Math.random(),
0.375 + 0.5 * Math.random(),
0.5
);
configuration.attributes.outlineColor = new WorldWind.Color(
0.5 * configuration.attributes.interiorColor.red,
0.5 * configuration.attributes.interiorColor.green,
0.5 * configuration.attributes.interiorColor.blue,
1.0
);
}
return configuration;
};
var geoJSONParser = new WorldWind.GeoJSONParser(geoJSONString);
var layer = geoJSONParser.addGeoJSONLayer(
geoJSONString,
{shapeConfigurationCallback: shapeConfigurationCallback}
);
layer.displayName = "GeoJSON Layer";
wwd.addLayer(layer);
wwd.redraw();
```
--------------------------------
### Bind View Models to HTML Elements (JavaScript)
Source: https://github.com/worldwindearth/worldwindjs/blob/develop/docs/lesson-3.md
Initializes and applies Knockout.js bindings to connect the LayersViewModel and SettingsViewModel to their respective HTML elements. This step makes the UI interactive based on the view model data.
```javascript
// Activate the Knockout bindings between our view models and the html
let layersViewModel = new LayersViewModel(globe);
let settingsViewModel = new SettingsViewModel(globe);
ko.applyBindings(layersViewModel, document.getElementById('layers'));
ko.applyBindings(settingsViewModel, document.getElementById('settings'));
```
--------------------------------
### Layer List Template (HTML)
Source: https://github.com/worldwindearth/worldwindjs/blob/develop/docs/lesson-3.md
A Knockout.js view template for rendering individual layers as buttons within a list. It binds click events to a toggleLayer function and dynamically sets the button's active state and text based on layer data.
```html
```
--------------------------------
### Custom CSS for WorldWindJS Layout and Interaction
Source: https://github.com/worldwindearth/worldwindjs/blob/develop/docs/lesson-1.md
This CSS code customizes the appearance and behavior of WorldWindJS elements. It includes styles for the body padding to accommodate a navbar, defines the dimensions and background for the main world window, and controls the positioning and interactivity of overlay elements.
```css
body {
/*Account for the height of the navbar component*/
padding-top: 3.5rem;
}
.worldwindow {
width: 100%;
height: calc(100vh - 3.5rem);
background-color: black;
}
.worldwindow-overlay {
position: absolute;
width: 100%;
top: 3.5rem;
}
/* Prevents an element, like a
from consuming user input */
.noninteractive {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
pointer-events: none;
}
/* Allows an element to receive user input */
/* Useful if a parent element is using .noniteractive */
.interactive {
-webkit-touch-callout: auto !important;
-webkit-user-select: auto !important;
-khtml-user-select: auto !important;
-moz-user-select: auto !important;
-ms-user-select: auto !important;
-o-user-select: auto !important;
pointer-events: auto !important;
}
```
--------------------------------
### Display KMZ Archive with Layer and Time Interval in JavaScript
Source: https://github.com/worldwindearth/worldwindjs/blob/develop/src/formats/kml/README.MD
Loads a KMZ archive, creates a new layer, sets a time interval for it, adds the parsed KML content as a renderable, and adds the layer to the globe. Requires WorldWindJS library.
```javascript
var kmlFilePromise = new KmlFile('data/KML_Samples.kmz', []);
kmlFilePromise.then(function (kmlFile) {
var renderableLayer = new WorldWind.RenderableLayer("Surface Shapes");
renderableLayer.currentTimeInterval = [
new Date("Mon Aug 09 2015 12:10:10 GMT+0200 (Střední Evropa (letní čas))").valueOf(),
new Date("Mon Aug 11 2015 12:10:10 GMT+0200 (Střední Evropa (letní čas))").valueOf()
];
renderableLayer.addRenderable(kmlFile);
wwd.addLayer(renderableLayer);
wwd.redraw();
});
```
--------------------------------
### Initialize Category Timestamps Map in Globe Constructor
Source: https://github.com/worldwindearth/worldwindjs/blob/develop/docs/lesson-3.md
This JavaScript code initializes a Map object to store category timestamps within the Globe's constructor. This map will hold pairs of layer categories and their corresponding Knockout observable timestamps, enabling the application to track changes within each category and update the UI accordingly.
```javascript
// Holds a map of category and observable timestamp pairs
this.categoryTimestamps = new Map();
```
--------------------------------
### Create Globe Class for WorldWindow Management (JavaScript)
Source: https://github.com/worldwindearth/worldwindjs/blob/develop/docs/lesson-2.md
Defines a Globe class that encapsulates the WorldWind.WorldWindow object. It provides methods to add layers with categories and options, and to retrieve layers by category. This class helps manage application-specific layer interactions.
```javascript
/**
* The Globe encapsulates the WorldWindow object (wwd) and provides application
* specific logic for interacting with layers.
* @param {String} canvasId The ID of the canvas element that will host the globe
* @returns {Globe}
*/
class Globe {
constructor(canvasId) {
// Create a WorldWindow globe on the specified HTML5 canvas
this.wwd = new WorldWind.WorldWindow(canvasId);
// Holds the next unique id to be assigned to a layer
this.nextLayerId = 1;
// Add a BMNGOneImageLayer background layer. We're overriding the default
// minimum altitude of the BMNGOneImageLayer so this layer always available.
this.addLayer(new WorldWind.BMNGOneImageLayer(), {
category: "background",
minActiveAltitude: 0
});
}
/**
* Adds a layer to the globe. Applies the optional options' properties to the
* layer, and assigns the layer a unique ID and category.
* @param {WorldWind.Layer} layer
* @param {Object|null} options E.g., {category: "base", enabled: true}
*/
addLayer(layer, options) {
// Copy all properties defined on the options object to the layer
if (options) {
for (let prop in options) {
if (!options.hasOwnProperty(prop)) {
continue; // skip inherited props
}
layer[prop] = options[prop];
}
}
// Assign a default category property if not already assigned
if (typeof layer.category === 'undefined') {
layer.category = 'overlay'; // the default category
}
// Assign a unique layer ID to ease layer management
layer.uniqueId = this.nextLayerId++;
// Add the layer to the globe
this.wwd.addLayer(layer);
}
/**
* Returns a new array of layers in the given category.
* @param {String} category E.g., "base", "overlay" or "setting".
* @returns {Array}
*/
getLayers(category) {
return this.wwd.layers.filter(layer => layer.category === category);
}
}
```