# Studio Map Configuration

At the top level, a Studio map configuration object contains a version string and an object with map state, map style and visualization state.

The map configuration does not contain the actual data in the map, just configuration information for the visual and interactive aspects of the map. Rendering of a map typically requires both a map configuration and one or more associated datasets.

## Configuration Parameters

| Field | Type | Description |
| --- | --- | --- |
| `version` | `string` | Version string, for future format changes. Currently must always be the string `'v1'`. |
| `config` | `object` | Map configuration data. |
| `config.mapState` | `MapState` | Current view state of the map (location, zoom, tilt etc), various view settings and optionally globe parameters. |
| `config.mapStyle` | `MapStyle` | Base map style and configuration. |
| `config.visState` | `VisState` | Detailed visualization and interaction configurations, including the map's visualization layers. |

## Map State

The map state contains the current view of the map (location, zoom, tilt) as well as the various view (2D, 3D, Globe, split screen etc) and base map settings.

The `config.mapState` object can have the following fields:

| Field | Type | Description |
| --- | --- | --- |
| `latitude` | `number` | Latitude of map center. |
| `longitude` | `number` | Longitude of map center. |
| `zoom` | `number` | Current zoom of the map. |
| `bearing` | `number` | Map up direction. 0 = north. |
| `pitch` | `number` | Angle of view, 0 = look from above. |
| `dragRotate` | `boolean` | Enables user to tilt and rotate map. |
| `isSplit` | `boolean` | Whether map is split. |
| `mapViewMode` | `'MODE_GLOBE'`, ... | 2D, 3D or globe. |
| `mapSplitMode` | `'SINGLE_MAP'`, ... | Single, Split, Swipe-to-compare. |
| `globe?` | `object` | Globe mode configuration. |
| `globe.enabled` | `boolean` | Enable globe mode. |
| `globe.config` | `object` | Globe parameters. |
| `globe.config.atmosphere` | `boolean` |  |
| `globe.config.azimuth` | `boolean` | Enable azimuth. |
| `globe.config.azimuthAngle` | `number` | Angle of azimuth. |
| `globe.config.basemap` | `boolean` | Whether to render a basemap on the globe. |
| `globe.config.labels` | `boolean` | Whether to render basemap labels on the globe. |
| `globe.config.terminator` | `boolean` | Whether to show a terminator (night shadow) on the globe. |
| `globe.config.terminatorOpacity` | `number` | Opacity of the night shadow. |

## Map Styles

| Setting | Type | Description |
| --- | --- | --- |
| `styleType` | `'dark'`, `'light'`, ... | Base map style. |
| `mapStyles` | `{[styleName: string]: CustomMapStyle}` | Map of custom map styles. |
| `visibleLayerGroups` | `{[layerName: string]: boolean}` | Indicating which base map layers are visible. |
| `topLayerGroups` | `{[layerName: string]: boolean}` | Which base map layers should be shown on top of the Studio layers. |
| `threeDBuildingColor` | `[number, number, number]` | RGB color. |

Custom map styles can be added:

| Setting | Type | Description |
| --- | --- | --- |
| `mapStyles[stylename].url` | `string` |  |
| `mapStyles[stylename].accessToken` | `string` | Mapbox access token |
| `mapStyles[stylename].custom` | `boolean` |  |
| `mapStyles[stylename].icon` | `boolean` |  |
| `mapStyles[stylename].icon` | `string` |  |
| `mapStyles[stylename].id` | `string` |  |
| `mapStyles[stylename].label` | `string` |  |

Fields are described as follows:

| Setting | Type | Description |
| --- | --- | --- |
| `name` | `string` | name of the field |
| `type` | `string` |  |
| `format` | `string` |  |
| `analyzerType` | `string` |  |

## Visualization State

The visualization state contains the configuration of the map visualization, which includes:

- Layers (Note: documented on a separate page)
- Filters
- Joins
- Metrics
- Interaction settings
- General visualization settings

The following fields can be added to `config.visState`:

| Setting | Type | Description |
| --- | --- | --- |
| `config.visState.layers` | `array` | Configuration of layers |
| `config.visState.filters` | `array` | Configuration of filters |
| `config.visState.interactionConfig` | `object` | Configuration of interactive elements |
| `config.visState.layerBlending` | `additive`, ... | How layers are blended visually |
| `config.visState.splitMaps` | `array` | Array describing the configuration of each map when using split maps. |
| `config.visState.animationConfig` | `object` | Timeline animation configuration |
| `config.visState.animationConfig.currentTime` | `number`, `null` | Current timestamps (UNIX epoch microseconds) |
| `config.visState.animationConfig.speed` | `number` | Speed of playback |

## Layers

An array of layers can be added via the `config.visState.interactionConfig.layers` array:

| Setting | Type | Description |
| --- | --- | --- |
| `config.visState.layers` | `array` | See layer configuration. |

## Filters

| Setting | Type | Description |
| --- | --- | --- |
| `config.visState.filters` | `array` |  |

## Interaction Configuration

Contains the configuration for interactive elements on the map. The `config.visState.interactionConfig` has a number of sub objects defining various aspects of map interactivity.

## Tooltips

Enable and configure tooltips can be defined in `config.visState.interactionConfig.tooltip`:

| Setting | Type | Description |
| --- | --- | --- |
| `tooltip` | `object` |  |
| `tooltip.enabled` | `object` |  |
| `tooltip.fieldsToShow` | `object` | map of fields to show, keyed by fieldId |
| `tooltip.fieldsToShow[fieldId].name` | `string` | name of field |
| `tooltip.fieldsToShow[fieldId].format` | `null` | format of field |
| `tooltip.compareMode` | `boolean` |  |
| `tooltip.compareType` | `'absolute'` |  |

## Brushing

Enable and configure the brushing feature by adding a `config.visState.interactionConfig.brush` object:

| Setting | Type | Description |
| --- | --- | --- |
| `brush?` | `object` |  |
| `brush.enabled?` | `boolean` | Whether brushing is enabled |
| `brush.size?` | `number` | The size of the brush |

## Geocoder

Enable and configure the geocoder feature by adding a `config.visState.interactionConfig.geocoder` object:

| Setting | Type | Description |
| --- | --- | --- |
| `config.visState.geocoder` | `object` |  |
| `config.visState.geocoder.enabled` | `boolean` | Enable the geocoder control |

## Coordinate

| Setting | Type | Description |
| --- | --- | --- |
| `config.visState.coordinate` | `object` |  |
| `config.visState.coordinate.enabled` | `boolean` | Enable coordinate tooltip |

## Example Map Config

```json
{
  "version": "v1",
  "config": {
    "mapState": {
      "bearing": 0,
      "dragRotate": true,
      "latitude": 27.82040844812393,
      "longitude": 31.05221861771137,
      "pitch": 0,
      "zoom": 1.844221289168002,
      "isSplit": false,
      "mapViewMode": "MODE_GLOBE",
      "mapSplitMode": "SINGLE_MAP",
      "globe": {
        "enabled": true,
        "config": {
          "atmosphere": true,
          "azimuth": true,
          "azimuthAngle": 174,
          "basemap": true,
          "labels": false,
          "terminator": true,
          "terminatorOpacity": 0.33
        }
      }
    },
    "mapStyle": {
      "styleType": "dark",
      "topLayerGroups": {},
      "visibleLayerGroups": {
        "label": true,
        "road": true,
        "border": false,
        "building": true,
        "water": true,
        "land": true,
        "3d building": false
      },
      "threeDBuildingColor": [
        9.665468314072013,
        17.18305478057247,
        31.1442867897876
      ],
      "mapStyles": {}
    },
    "visState": {
      "filters": [],
      "interactionConfig": {
        "tooltip": {
          "fieldsToShow": {
            "f81a0c43-3712-484f-b7a9-24e826777138": [
              {
                "name": "hex",
                "format": null
              },
              {
                "name": "population",
                "format": null
              }
            ]
          },
          "compareMode": false,
          "compareType": "absolute",
          "enabled": true
        },
        "brush": {
          "size": 0.5,
          "enabled": false
        },
        "geocoder": {
          "enabled": false
        },
        "coordinate": {
          "enabled": false
        }
      },
      "layerBlending": "additive",
      "splitMaps": [],
      "animationConfig": {
        "currentTime": null,
        "speed": 1
      },
      "metrics": [],
      "geoKeys": [],
      "groupBys": [],
      "datasets": {
        "fieldDisplayNames": {
          "f81a0c43-3712-484f-b7a9-24e826777138": {}
        }
      },
      "joins": [],
      "layers": [
        {
          "id": "zyf79x7",
          "type": "hexagonId",
          "config": {
            "dataId": "f81a0c43-3712-484f-b7a9-24e826777138",
            "label": "Population - 10 km",
            "color": [130, 154, 227],
            "columns": {
              "hex_id": "hex"
            },
            "isVisible": true,
            "visConfig": {
              "opacity": 0.8,
              "colorRange": {
                "name": "Sunrise 8",
                "type": "sequential",
                "category": "Uber",
                "colors": [
                  "#194266",
                  "#355C7D",
                  "#63617F",
                  "#916681",
                  "#C06C84",
                  "#D28389",
                  "#E59A8F",
                  "#F8B195"
                ]
              },
              "coverage": 1,
              "enable3d": true,
              "sizeRange": [0, 500],
              "coverageRange": [0, 1],
              "elevationScale": 39.1
            },
            "hidden": false,
            "textLabel": [
              {
                "field": null,
                "color": [255, 255, 255],
                "size": 18,
                "offset": [0, 0],
                "anchor": "start",
                "alignment": "center"
              }
            ]
          },
          "visualChannels": {
            "colorField": {
              "name": "population",
              "type": "integer"
            },
            "colorScale": "quantile",
            "sizeField": {
              "name": "population",
              "type": "integer"
            },
            "sizeScale": "linear",
            "coverageField": null,
            "coverageScale": "linear"
          }
        }
      ]
    }
  }
}
