> For the complete documentation index, see [llms.txt](https://docs.wobby.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.wobby.ai/semantic-layer/semql/geo-functions.md).

# Geo Functions

SemQL has two built-in geo functions for working with coordinates: `GEO_DISTANCE()` and `GEO_WITHIN_RADIUS()`. Both take latitude/longitude pairs and return results you can use directly in your queries.

These functions are database-agnostic — they work regardless of which database you're connected to (Snowflake, BigQuery, Redshift, etc.), because SemQL compiles them to standard trigonometry (the Haversine formula) that runs on any SQL engine.

***

## GEO\_DISTANCE

Returns the distance in **kilometers** between two geographic coordinates.

### Syntax

```sql
GEO_DISTANCE(lat1, lng1, lat2, lng2)
```

| Parameter | Type   | Description                   |
| --------- | ------ | ----------------------------- |
| `lat1`    | number | Latitude of the first point   |
| `lng1`    | number | Longitude of the first point  |
| `lat2`    | number | Latitude of the second point  |
| `lng2`    | number | Longitude of the second point |

### Examples

**Distance from a fixed point to a column value:**

```sql
SELECT
    store_name,
    city,
    GEO_DISTANCE(48.8566, 2.3522, store_lat, store_lng) AS distance_from_paris_km
FROM retail_stores
ORDER BY distance_from_paris_km ASC
```

**Filter by a calculated distance:**

```sql
SELECT
    store_name,
    GEO_DISTANCE(51.5074, -0.1278, store_lat, store_lng) AS distance_km
FROM retail_stores
WHERE GEO_DISTANCE(51.5074, -0.1278, store_lat, store_lng) <= 50
ORDER BY distance_km
```

**Distance between two columns (e.g., customer location to nearest warehouse):**

```sql
SELECT
    order_id,
    customer_name,
    GEO_DISTANCE(customer_lat, customer_lng, warehouse_lat, warehouse_lng) AS delivery_distance_km
FROM orders
JOIN customers ON orders.customer_id = customers.customer_id
JOIN warehouses ON orders.warehouse_id = warehouses.warehouse_id
ORDER BY delivery_distance_km DESC
LIMIT 20
```

***

## GEO\_WITHIN\_RADIUS

Returns `true` if a point is within a given radius of another point, `false` otherwise. Useful for filtering by proximity.

### Syntax

```sql
GEO_WITHIN_RADIUS(lat1, lng1, lat2, lng2, radius_km)
```

| Parameter   | Type   | Description                      |
| ----------- | ------ | -------------------------------- |
| `lat1`      | number | Latitude of the reference point  |
| `lng1`      | number | Longitude of the reference point |
| `lat2`      | number | Latitude of the point to test    |
| `lng2`      | number | Longitude of the point to test   |
| `radius_km` | number | Radius in kilometers             |

### Examples

**Filter stores within 25 km of a city:**

```sql
SELECT store_name, city, store_lat, store_lng
FROM retail_stores
WHERE GEO_WITHIN_RADIUS(52.3676, 4.9041, store_lat, store_lng, 25)
ORDER BY store_name
```

**Categorize records by proximity:**

```sql
SELECT
    customer_name,
    city,
    CASE
        WHEN GEO_WITHIN_RADIUS(48.8566, 2.3522, customer_lat, customer_lng, 50)
            THEN 'Within 50km of Paris'
        WHEN GEO_WITHIN_RADIUS(48.8566, 2.3522, customer_lat, customer_lng, 200)
            THEN 'Within 200km of Paris'
        ELSE 'Outside 200km'
    END AS proximity_band
FROM customers
ORDER BY proximity_band
```

**Count customers within a radius:**

```sql
SELECT
    COUNT(*) AS customer_count
FROM customers
WHERE GEO_WITHIN_RADIUS(40.7128, -74.0060, customer_lat, customer_lng, 100)
```

***

## Combining both functions

A common pattern is to show the actual distance alongside a proximity flag:

```sql
SELECT
    store_name,
    city,
    GEO_DISTANCE(50.8503, 4.3517, store_lat, store_lng) AS distance_from_brussels_km,
    GEO_WITHIN_RADIUS(50.8503, 4.3517, store_lat, store_lng, 100) AS within_100km
FROM retail_stores
ORDER BY distance_from_brussels_km
```

***

## Notes

* Coordinates must be numeric (decimal degrees). Null coordinates will cause an error.
* Distances are always in **kilometers**.
* The Haversine formula assumes a spherical Earth — it's accurate to within \~0.5% for most practical distances.
* Both functions are compiled to standard SQL math functions (`SIN`, `COS`, `ACOS`, `RADIANS`) and work on all supported database dialects.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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.wobby.ai/semantic-layer/semql/geo-functions.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.
