I recently had the task of teaching my cohort spatial calculations in Tableau. I had never used any of these calculations before, so it was a learning experience for me as well.
When people think of spatial data in Tableau, they mainly think of maps and plotting longitude and latitude. Spatial calculations allow you to further dive into analysis, allowing you to ask questions like "is this point inside this zone", "how far apart are these two locations," and "where do these two territories overlap."
Before using any of these functions, it helps to understand the three Geometry data types used.
Shape: Has to be loaded from a spatial file, an area of space, e.g., shapefile, GeoJSON, except for one exception, which I will explain.
Point: A single point in space, defined by longitude and latitude.
Line: A line connecting 2 points.
You can use this post as a cheat sheet to come back to. For each function, I provide the syntax, what it does, what type it returns, common use cases, and an example.
There are 14 spatial calculations, ranging from calculating areas and line distances to creating buffer zones. In this blog post, I will break them into 4 functional categories.
Creators (build new geometry): MAKEPOINT, MAKELINE, BUFFER, OUTLINE
Relational (compare two geometries): INTERSECTS, INTERSECTION, DIFFERENCE, SYMDIFFERENCE, UNION
Measurers (return a number): AREA, DISTANCE, LENGTH
Info/QA (return type or validity): SHAPETYPE, VALIDATE
Now lets actually take a look at the functions.
Creators:
Makepoint()
- Syntax: MAKEPOINT([Latitude], [Longitude])
- Converts decimal degrees to geometry
- Returns: Geometry (Point)
- Use Case: Convert long/ lat into spatial calculations for plotting on maps, etc
- Example: Plot customer locations → MAKEPOINT([Cust_Lat], [Cust_Lng])
Makeline()
- Syntax: MAKELINE([Origin Point], [Destination Point])
- Creates a line between two point geometries
- Returns: Geometry (line)
- Use Case: Building origin-destination visualizations, flight path, etc
- Example:
- Flight path → MAKELINE([Departure Airport], [Arrival Airport])
Buffer()
- Syntax: BUFFER([Point], distance, 'unit')
- Creates a circular Polygon around a specific point, sort of like a radius
- Units can be meters, KM, feet, miles,
- Returns: Geometry (Polygon)
- Use Case: Find all customers within 5 miles of a store, flag orders near a warehouse
- Example:
- Creating 5-mile store radius → BUFFER([Store Location], 5, 'miles')
Outline()
- Syntax: OUTLINE([Polygon Geometry])
- Extracts the boundary line of a polygon
- Returns: Geometry (line/multiline)
- Use Case: Turns filled region polygons to just their borders, useful for overlaying boundary lines on a map, measuring perimeter length with LENGTH, etc
- Examples:
- Region border → OUTLINE([County Polygon])
- Perimeter measurement → LENGTH(OUTLINE([Property]), 'meters')
Relational:
Intersects()
- Syntax: INTERSECTS([Geometry A], [Geometry B])
- Returns TRUE if two geometries overlap
- Returns: Boolean (True/False)
- Use Case: Filter rows to only those that spatially overlap another geometry. Ex: which customers are inside a sales zone, or which events occurred within a buffer.
- Examples:
- Customer in zone? → INTERSECTS([Customer Point], [Sales Zone])
- Event in buffer? → INTERSECTS([Event Pt], BUFFER([Venue], 1, 'km'))
- Parcel in floodplain? → INTERSECTS([Parcel], [Flood Zone])
Intersection()
- Syntax: INTERSECTION([Geometry A], [Geometry B])
- Returns the overlapping geometry between two shapes
- Returns: Geometry
- Use Case: Extract the two regions' areas that have in common
- Examples:
- Shared territory → INTERSECTION([Region A], [Region B])
- Flood-property overlap → INTERSECTION([Flood Zone], [Parcel])
Difference()
- Syntax: DIFFERENCE([Geometry A], [Geometry B])
- Takes in 2 Geometry shapes, Returns parts of A that do NOT overlap B
- Returns: Geometry
- Use Case: Find areas that are untouched by competitors, different zones, etc
- Examples:
- Uncovered territory → DIFFERENCE([Region], [Competitor Zone])
- Non-flood zone land → DIFFERENCE([Land Area], [Flood Plain])
Symdifference()
- Syntax: SYMDIFFERENCE([Geometry A], [Geometry B])
- Returns areas in either geometry but NOT both (non-overlapping)
- Opposite of INTERSECTION
- Returns: Geometry
- Use Case: Find what changed between two versions of a territory, or new coverage added by one network but not shared with another.
- Examples:
- Territory → SYMDIFFERENCE([Old Region], [New Region])
- Non-overlapping coverage → SYMDIFFERENCE([Network A], [Network B])
Union()
- Syntax: UNION([Geometry A], [Geometry B])
- Merges two geometries into one combined shape
- Returns: Geometry
- Use Case: Combine separate regions into one, merge two sales territories into a single district, and combine overlapping areas
- Examples:
- Merge territories → UNION([Territory East], [Territory West])
- City from neighborhoods → UNION([Neighborhood 1], [Neighborhood 2])
Measurers:
Area()
- Syntax: AREA([Geometry Field], 'unit')
- Calculates the actual area of a space (polygon)
- Units can be meters, KM, feet, miles
- Returns: Float
- Use Case: Measure territory size, calculate density, or filter zones by size threshold
- Examples:
- Territory size → AREA([Territory], 'km')
- Population density → SUM([Population]) / AREA([Region], 'km')
- Filter large zones → AREA([Zone], 'miles') > 500
Distance()
- Syntax: DISTANCE([Point A], [Point B], 'unit')
- Calculates the straight-line distance between 2 points
- Units: 'meters', 'km', 'miles', 'feet'
- Returns: Float
- Use cases: Rank customers by distance to the nearest store, proximity heat map.
- Example:
- Customer to store → DISTANCE([Customer Pt], [Store Pt], 'miles')
Length()
- Syntax: LENGTH([Line Geometry], 'unit')
- Returns the length of a line or geometry
- Units: 'meters', 'km', 'miles', 'feet'
- Returns: Float
- Use Case: Measures the length of an actual line geometry. Useful for infrastructure and logistics datasets.
- Example:
- Road segment length → LENGTH([Road Segment], 'km')
Info / QA:
Shapetype()
- Syntax: SHAPETYPE([Geometry Field])
- Returns the geometry type as a string
- Returns: String ('Point', 'LineString', 'Polygon', etc.)
- Use Case: Understand your spatial data. Confirm whether a field contains points, polygons, or lines before applying functions that expect a specific type to avoid silent errors.
- Examples:
- Check geometry type → SHAPETYPE([Location])
- Filter points only → SHAPETYPE([Geo]) == 'Point'
Validate()
- Syntax: VALIDATE([Geometry Field])
- Checks if a geometry is valid
- Returns: Boolean (True/False)
- Use Case: Spatial calculations silently fail or return NULL on corrupt/ self-intersecting geometries. Use VALIDATE to filter your dataset prior to running any spatial analysis.
- Examples:
- Filter valid rows → IF VALIDATE([Geo]) THEN [Geo] ELSE NULL END
- Check calculated field → VALIDATE(MAKEPOINT([Lat],[Lon]))
Now that you've been introduced to the 14 spatial functions, we can put them together. I’ve provided a quick quiz to test your abilities:
Quiz: Find all customers within 5 miles of a store
INTERSECTS(MAKEPOINT([Cust_Lat], [Cust_Lng]), BUFFER(MAKEPOINT([Store_Lat], [Store_Lng]), 5, 'miles'))
If you'd rather work through these visually, I put together a Google Slides Deck covering all 14 functions. It can be an easier way to see the syntax and use cases laid out side by side.
