> ## Documentation Index
> Fetch the complete documentation index at: https://calcs.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# GIS Widget

> Guide to implementing GIS widgets for geographic data queries and mapping functionality

The GIS Widget provides geographic information system capabilities, allowing templates to query location-based data such as wind speeds, elevations, and regional parameters based on latitude and longitude coordinates.

## Related Documentation

<CardGroup cols={2}>
  <Card title="GIS Solvers" icon="map" href="/calcs_builder/solvers/gis_solvers">
    Learn about GIS solvers for advanced geographic data processing
  </Card>

  <Card title="Remote Widget Integration" icon="globe">
    GIS widgets often integrate with remote solvers for complex geographic calculations
  </Card>
</CardGroup>

## Widget Types

The GIS widget supports four different types of geographic queries:

| Type          | Description                                                                    | Output                                       |
| ------------- | ------------------------------------------------------------------------------ | -------------------------------------------- |
| **region**    | Query regions with defined borders, returns values based on polygon boundaries | `value` (scalar or unit)                     |
| **raycast**   | Draw rays from a point to detect intersections with boundaries                 | `distances` (flat array of numbers)          |
| **contour**   | Query interpolated values from contour maps                                    | `value` (interpolated scalar or unit)        |
| **elevation** | Get elevation data from external APIs                                          | `elevation` (elevation number at coordinate) |

## Region Type

This widget queries a region map (Multi-polygon GIS geometry) where each region has an assigned value. The output is not interpolated between regions.

### Configuration

<ResponseField name="type" type="string" required>
  Set to "region" for regional boundary queries
</ResponseField>

<ResponseField name="dataset" type="string" required>
  Name of the GIS dataset to query (e.g., "no\_base\_wind\_speed")
</ResponseField>

<ResponseField name="displayValue" type="function" required>
  Function defining what is displayed above the map: `f(o) = o.value`
</ResponseField>

<ResponseField name="latitude" type="number" required>
  Latitude coordinate, often using `projectDefault("latitude", fallback)`
</ResponseField>

<ResponseField name="longitude" type="number" required>
  Longitude coordinate, often using `projectDefault("longitude", fallback)`
</ResponseField>

### Example Implementation

```json theme={null}
{
  "type": "sheetTemplateWidgets",
  "attributes": {
    "type": "gis",
    "label": "Base Wind Velocity",
    "referenceId": "baseWindVelocityMap",
    "equation": [
      {
        "result": "{
          \"type\": \"region\", 
          \"dataset\": \"no_base_wind_speed\", 
          \"displayValue\": f(o) = o.value,
          \"latitude\": projectDefault(\"latitude\", 59.91323), 
          \"longitude\": projectDefault(\"longitude\", 10.73978) 
        }",
        "condition": "annex == \"NS\""
      }
    ],
    "showInSummary": true
  }
}
```

### Accessing Region Data

Extract the value from the GIS widget in a equation widget:

```json theme={null}
{
  "type": "computed",
  "units2": "m/s",  
  "equation": [
    {
      "result": "baseWindVelocityMap.value",
      "condition": "@default"
    }
  ]
}
```

<Info>
  **Unit Handling:** The GIS layer can return either a `number` (requiring unit assignment in the equation widget) or a `unit` (already with units assigned).
</Info>

## Raycast Type

Raycast draws lines from a single point outwards to detect intersections with boundaries. This is used for calculating distances to coastlines, elevation profiles, and similar applications.

### Configuration

<ResponseField name="type" type="string" required>
  Set to "raycast" for ray-based boundary detection
</ResponseField>

<ResponseField name="dataset" type="string" required>
  Dataset containing boundary information (e.g., "eu\_coastline")
</ResponseField>

<ResponseField name="maxDistance" type="number" required>
  Maximum distance for rays in meters
</ResponseField>

<ResponseField name="numRays" type="number" required>
  Number of equally-spaced rays to cast
</ResponseField>

<ResponseField name="latitude" type="number" required>
  Origin latitude coordinate
</ResponseField>

<ResponseField name="longitude" type="number" required>
  Origin longitude coordinate
</ResponseField>

### Example Implementation

```json theme={null}
{
  "type": "gis",
  "referenceId": "distanceUpwindMap",
  "equation": [
    {
      "result": "{      
        \"type\": \"raycast\",
        \"dataset\": \"eu_coastline\",
        \"maxDistance\": 100000,
        \"numRays\": 12,
        \"latitude\": projectDefault(\"latitude\", 51.50003),
        \"longitude\": projectDefault(\"longitude\", -0.12458)
      }",
      "condition": "@default"
    }
  ]
}
```

### Accessing Raycast Data

Extract specific ray distances:

```json theme={null}
{
  "equation": [
    {
      "result": "vectorSubset(distanceUpwindMap.distances, rowIndex()+1)",
      "condition": "@default"
    }
  ]
}
```

<Note>
  The gisSignificantOrography remote widget solver is independent of this widget but typically shares the same latitude, longitude, and numRays parameters.
</Note>

## Contour Type

Queries interpolated values from contour maps. Values are interpolated between contours when possible.

### Configuration

<ResponseField name="type" type="string" required>
  Set to "contour" for contour map queries
</ResponseField>

<ResponseField name="dataset" type="string" required>
  Name of the contour dataset (e.g., "gb\_base\_wind\_speed")
</ResponseField>

<ResponseField name="unit" type="string">
  Optional unit specification if dataset doesn't include units
</ResponseField>

<ResponseField name="latitude" type="number" required>
  Query latitude coordinate
</ResponseField>

<ResponseField name="longitude" type="number" required>
  Query longitude coordinate
</ResponseField>

### Example Implementation

```json theme={null}
{
  "type": "sheetTemplateWidgets",
  "attributes": {
    "type": "gis",
    "label": "Base Wind Velocity",
    "referenceId": "baseWindVelocityMap",
    "equation": [
      {
        "result": "{
          \"type\": \"contour\", 
          \"dataset\": \"gb_base_wind_speed\", 
          \"unit\": \"m/s\",
          \"latitude\": projectDefault(\"latitude\", 51.50003), 
          \"longitude\": projectDefault(\"longitude\", -0.12458) 
        }",
        "condition": "annex == \"BS\""
      }
    ],
    "showInSummary": true
  }
}
```

<Warning>
  When contour data is complex, interpolation may not occur. Refer to GIS solver SQL query documentation for details on interpolation behavior.
</Warning>

## Elevation Type

Queries elevation data at specific coordinates using external APIs (MapTiler). This provides single-point elevation sampling.

### Configuration

<ResponseField name="type" type="string" required>
  Set to "elevation" for elevation queries
</ResponseField>

<ResponseField name="latitude" type="number" required>
  Query latitude coordinate
</ResponseField>

<ResponseField name="longitude" type="number" required>
  Query longitude coordinate
</ResponseField>

### Example Implementation

```json theme={null}
{
  "type": "sheetTemplateWidgets",
  "attributes": {
    "type": "gis",
    "label": "Elevation",
    "referenceId": "elevationMap",
    "visibleIf": null,
    "equation": [
      {
        "result": "{
          \"type\": \"elevation\",  
          \"latitude\": projectDefault(\"latitude\", 51.50003), 
          \"longitude\": projectDefault(\"longitude\", -0.12458)  
        }",
        "condition": "@default"
      }
    ],
    "showInSummary": true
  }
}
```

### Accessing Elevation Data

Reference the elevation value:

```json theme={null}
{
  "equation": [
    {
      "result": "elevationMap.elevation",
      "condition": "@default"
    }
  ]
}
```

## Best Practices

### Coordinate Handling

* Always use `projectDefault()` for latitude and longitude to provide fallback values
* Ensure coordinates are in decimal degrees format
* Consider user input validation for coordinate ranges

### Performance Optimization

* Cache GIS queries when possible by avoiding frequent coordinate changes
* Use appropriate `maxDistance` and `numRays` values for raycast operations
* Consider the complexity of datasets when choosing between region and contour types

### Error Handling

* Provide meaningful fallback values in `projectDefault()` calls
* Test GIS widgets with various global locations
* Handle cases where GIS services may be unavailable

### Integration with Other Systems

* GIS widgets often work in conjunction with remote solvers
* Consider the relationship between GIS data and calculation requirements
* Document the source and accuracy of GIS datasets used

## Examples in Production

| Template               | Location                       | Usage                    |
| ---------------------- | ------------------------------ | ------------------------ |
| MAFIBracketFreestander | Norway (Skansen 28, 2670 Otta) | Wind velocity regions    |
| MAFIBracketFreestander | UK (London)                    | Contour maps and raycast |

<Info>
  For advanced GIS solver integration and complex geographic calculations, refer to the GIS Solvers documentation and Remote Widget implementation guides.
</Info>
