# How to Switch Basemaps in Gods Eye View: UI, API, and Voice Control

> Discover how to switch basemaps in Gods Eye View using UI, API, or voice control. Learn to manage map stacks efficiently and enhance your geospatial visualization.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: how-to-guide
- Published: 2026-09-12

---

**Basemaps are switched by calling `ui.setMapStack(stackId)`, which validates the request against available map stacks, delegates the imagery swap to the **Map‑Stack Controller**, and returns a confirmation object with an `ok` flag indicating whether the active basemap matches the request.**

In the open-source geospatial visualization project **Gods Eye View** (`bilawalsidhu/gods-eye-view`), changing the underlying map imagery requires coordination between the UI layer and the controller layer. Whether triggered by direct API calls, AI assistants, or voice commands, the basemap switching workflow follows a strict validation-then-execution pattern defined in the core JavaScript modules.

## The Public API Method (UI.setMapStack)

The entry point for all basemap changes is **`ui.setMapStack(stackId)`** in [[`src/ui.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/ui.js)](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/ui.js#L31-L36).

This public method performs several validation steps before executing the switch:

1. **Controller Existence Check** – It verifies that a `mapStackController` instance exists.
2. **Stack Registry Lookup** – It retrieves the list of defined stacks via `mapStackController.getStacks()` and validates that the requested `stackId` exists.
3. **Availability Validation** – Some stacks, such as **Esri World Imagery**, require a **Cesium Ion token**. If the requested stack is unavailable due to missing credentials, the method returns an error containing the list of valid stack IDs.

If validation fails, the method returns immediately with a descriptive error without attempting to modify the active imagery provider.

## Internal Execution via _setMapStack

After validation succeeds, `UI.setMapStack` delegates the actual swap to the private method **`this._setMapStack(stackId)`**.

This internal handler instructs the `mapStackController` to activate the new stack, which performs the low-level work of swapping the Cesium imagery provider or tile source. The controller abstracts the specific implementation details of how each basemap type (OpenStreetMap, Bing Aerial, etc.) is instantiated and rendered.

## State Confirmation and Return Values

Once the controller completes the swap, `UI.setMapStack` reads the current state via `mapStackController.getState()` and returns a standardized object:

```javascript
{
  ok: true,                 // Boolean: true if activeId matches requested stack
  activeStack: state.activeId,  // ID of the currently active basemap
  error: null               // String description only populated on failure
}

```

The **`ok`** flag definitively tells the caller whether the basemap actually changed to the requested stack, providing a reliable signal for UI updates or downstream logic.

## AI and Voice Control Integration

### OpenAI Provider Tool

The same switching capability is exposed to AI assistants via the **`set_map_stack`** tool defined in [[`server/providers/openai/tools.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/server/providers/openai/tools.js)](https://github.com/bilawalsidhu/gods-eye-view/blob/main/server/providers/openai/tools.js#L390-L398).

When an AI model invokes this tool with a JSON payload containing the `stackId`, the server translates the call into `ui.setMapStack(stackId)`, executing the identical validation and switching logic used by the native UI.

### Voice Command Mapping

Voice commands such as *"show the Bing aerial map"* are mapped to the basemap switching system in [[`src/voice/gevActions.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/voice/gevActions.js)](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/voice/gevActions.js#L869-L874). These intents trigger the **`set_map_stack`** tool, which ultimately routes to the UI method described above, allowing hands-free basemap control.

## Map Stack Definitions and Configuration

All available basemap stacks and their metadata are defined in [[`src/mapStackController.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/mapStackController.js)](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/mapStackController.js). Each stack entry includes:

- **`id`**: The machine-readable identifier (e.g., `osm`, `bing-aerial`, `esri-imagery`, `photoreal`)
- **`label`**: Human-readable display text
- **Token requirements**: Flags indicating whether a Cesium Ion token is mandatory for activation

The controller maintains the registry of these stacks and exposes `getStacks()` for validation and `getState()` for status reporting.

## Practical Implementation Examples

### Programmatic Basemap Switching

To switch basemaps directly from JavaScript:

```javascript
// Assume `ui` is an initialized instance of the UI class
ui.setMapStack('bing-aerial')
  .then(result => {
    if (result.ok) {
      console.log(`Basemap switched to ${result.activeStack}`);
    } else {
      console.error('Switch failed:', result.error);
    }
  });

```

### Voice and AI Triggering

When invoking via the OpenAI provider tool:

```json
{
  "name": "set_map_stack",
  "arguments": { "stackId": "osm" }
}

```

This tool call executes the same validation and state confirmation path as the programmatic API.

## Summary

- **Validation occurs first** in [`src/ui.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/ui.js) via `setMapStack()`, which checks controller availability and stack existence before attempting any switch.
- **The private `_setMapStack()` method** delegates the actual imagery provider swap to the `mapStackController`.
- **Return objects** contain `ok`, `activeStack`, and `error` fields for definitive state confirmation and error handling.
- **AI assistants** use the `set_map_stack` tool defined in [`server/providers/openai/tools.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/server/providers/openai/tools.js) to trigger basemap changes programmatically.
- **Available stacks** are configured in [`src/mapStackController.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/mapStackController.js), which manages metadata including Cesium Ion token requirements for premium layers like Esri World Imagery.

## Frequently Asked Questions

### What is the primary method for switching basemaps in Gods Eye View?

The primary method is **`ui.setMapStack(stackId)`** defined in [`src/ui.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/ui.js). This method validates the requested stack ID against the registry in `mapStackController`, checks for required credentials like Cesium Ion tokens, and delegates the actual imagery swap to the controller layer.

### How does Gods Eye View handle invalid basemap requests?

If the requested `stackId` is not found in `mapStackController.getStacks()`, or if the stack requires an unavailable Cesium Ion token, the method returns an error object listing all available stack IDs. The active basemap remains unchanged, and the `ok` flag in the return object will be `false`.

### Can AI assistants change the basemap in Gods Eye View?

Yes, the OpenAI provider exposes a **`set_map_stack`** tool in [`server/providers/openai/tools.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/server/providers/openai/tools.js). When invoked with a `stackId` argument, this tool executes the same `UI.setMapStack()` method used by the native interface, subject to identical validation and error handling.

### Which basemap stacks require a Cesium Ion token?

According to [`src/mapStackController.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/mapStackController.js), certain imagery sets like **Esri World Imagery** (`esri-imagery`) require a valid Cesium Ion token to activate. Other stacks such as OpenStreetMap (`osm`) or Bing Aerial (`bing-aerial`) do not require special tokens and are available immediately upon initialization.