# Spatial Index

## Overview

Joule provides implementation of a spatial Index based on the Quad Tree data structure and algorithm. The search area is divided in to rectangle and thus the world is flattened from a sphere in to a rectangle spatial index.

This feature is provided as a service which can be embedded within custom processors and has its own DSL.

## Example & DSL attributes

The below example creates a search tree of the world as flattened rectangle.

```yaml
spatial index:
  top left coordinates: [-180f,-90f]
  width: 360
  area: 64800
  max levels: 24
  preferred max elements: 50
```

### Attributes schema

<table><thead><tr><th width="214">Attribute</th><th width="217">Description</th><th width="219">Data Type</th><th data-type="checkbox">Required</th></tr></thead><tbody><tr><td>top left coordinates</td><td>North west coordinate to create the spatial index </td><td>Float<br>Default: [-180f, -90f]</td><td>true</td></tr><tr><td>width</td><td>Width of the search area in terms of degrees</td><td><p>Integer</p><p>Default: 360</p></td><td>false</td></tr><tr><td>area</td><td>Search area</td><td><p>Integer</p><p>Default: 64800</p></td><td>false</td></tr><tr><td>max levels</td><td>Maximun number of sub spatial indexes.  Range must be within 0 to 24.</td><td><p>Integer</p><p>Default: 16</p></td><td>false</td></tr><tr><td>preferred max elements</td><td>Maximun number of elements within a bounded area.</td><td><p>Integer</p><p>Default: 500</p></td><td>false</td></tr></tbody></table>

### API Example

This example demonstrates how to query initialise the spatial index and query it thereafter within a custom processor.

{% hint style="info" %}
For further information how to use this service please [contact fractalworks](https://www.fractalworks.io/contact)
{% endhint %}

```java
private QuadTree<GeoFence> geoFenceSearchTree;

@Override
public void initialize(Properties prop) throws ProcessorException {
    super.initialize(prop);
    geoFenceSearchTree.initialise();
    
    // Other custom initialization
}

/**
* Query the geoFenceSearchTree with passed location information 
*
* @param event
* @param entityLatitude
* @param entityLongitude
*/
private GeoTrackingInfo queryGeospace(final StreamEvent event, final double entityLatitude, final double entityLongitude){
    // Perform geofence search
    Collection<GeoFence> foundGeoFences = geoFenceSearchTree.query(new Tuple<>(entityLatitude, entityLongitude));
    Object trackingKey = event.getValue(trackingEventKey);
    
    // Update stateful tracking
    GeoTrackingInfo info = state.get(trackingKey);
    
    info.setCurrentLatLng(entityLatitude, entityLongitude, event.getEventTime());
    info.setCurrentGeofenceIds(foundGeoFences);
    
    return info;        
}

/**
* Set QuadTree for processor
*
* @param geoFenceSearchTree
*/
@JsonProperty(value = "spatial index")
public void setGeoFenceSearchTree(QuadTree<GeoFence> geoFenceSearchTree) {
   this.geoFenceSearchTree = geoFenceSearchTree;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fractalworks.io/joule/components/analytics/analytic-tools/advanced-analytics/geospatial/spatial-index.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
