Next Level Spatial Mapping was originally presented at TC26 – For those who prefer video, see https://youtu.be/EEUEhL5DT_U.
Also, the Tableau workbook used here can be downloaded at https://tinyurl.com/4b7va875
I was fortunate to collaborate with Don Wise for the presentation. He is a retired fire department executive and a 6-time Tableau ambassador. If you asked a mapping question on the Forum, Don probably answered it.
(Note: This post was transcribed from a TC practice session video – I have identified the speaker in the section header – enjoy)
1. Geospatial Mapping – Jim
Before moving into spatial mapping, it helps to distinguish it from geospatial mapping.
Geospatial mapping is the type of mapping most Tableau users already know. If your data includes a geographic field such as state, city, or ZIP code, you can drag it onto the canvas, and Tableau automatically generates the map by supplying the necessary latitude and longitude values. This is convenient, but those generated coordinates are not available for your own calculations.

Spatial mapping, by contrast, uses downloadable spatial files such as shapefiles, KML files, or GeoJSON files. These files describe geographic shapes—points, lines, multilines, polygons, and multipolygons—that can be used directly in spatial functions.
To illustrate geospatial mapping, consider a dataset of windmill locations in the United States. In that dataset, State is already recognized as a geographic field, while County begins as plain text and must be assigned a geographic role. Once County is defined correctly, Tableau can use both fields to draw the map.

After that, dragging State onto the canvas produces a map showing the states with windmill locations. Adding County refines the view further and reveals which counties contain those locations.

A simple calculation can count windmill locations and place that measure on Size, making it easier to see concentration patterns. This quickly highlights large counties in California and dense clusters across the Midwest. The same data can also be viewed as a density map to emphasize where locations are most concentrated.

We get a sense that in the Midwest, there are a lot of counties with windmill locations.
Another option is to use a filled map instead of circles. At the county level, a filled map provides a clear view of where windmill activity is distributed across the country.

With a geospatial map, there are many capabilities. You can view the data in different ways, and if it meets your needs, by all means use geospatial mapping.
2. Spatial Mapping – Jim
Now let’s focus on spatial maps.
You start by downloading data from the internet. I like to use data.gov because I can get national data, state, or local data or you could use Kaggle or just Google “Downloadable spatial data”.

When you download spatial data, it arrives as a ZIP file. Extract the contents and save them to your computer in a single file. In Tableau, you will load the KML file or SHP file, but keep the other files in the folder because Tableau needs them.
Getting the data is easy, but what are these Spatial Functions? These work much like standard calculations. In the calculation editor, Tableau includes a Spatial category that lists the available functions, and we will look at several of them this afternoon.

I like to group spatial functions into four categories. Those that convert a longitude and latitude to a shape. Others that take spatial shapes and combine them in some way to create a new geometry. – like a buffer around a point or around a line, or the intersection of two points, or maybe a border around a shape, or we could union shapes together. Some other functions just return a number, like the area of a shape or the length of a border, or others that find the distance between two points.
Finally, there are some that are rather infrequently used, but they're used to tell us if two shapes intersect or the type of shape it is.

For example, I have a shape file. And in the shape file, I've got a column for the state code. I've also got the state name. Those are text data. We're going to leave them that way. Then I've got some other data here called geometry. And geometry tells Tableau what the shape is. In my case, it's polygons or multipolygons. In yours, it could be lines or could be points or something else.

When I take that geometry and drag it to the canvas, it's going to draw a map.

Now, I'd like to take some of these shapes and combine them.
I'm using a set that includes Arizona, California, and New Mexico, and I'm going to add Nevada, and then I'm going to use that set to create another spatial geometry.

And this is just a conditional statement that says if the name of the state is in the set, then get the geometry for that.
(if [Name] in [4.1 test set 2] then [4 Geometry] end )
When I drag that to another layer on the map, I get the four states. What I'd like to do is make that into one shape. And I'm going to use a union to do that.
Union([4.1 create spatial group from set])
It's going to aggregate that data together.
Now, I'd like to put a border around it. And I'm going to use another spatial function – Outline,
OUTLINE([4.2 create union from spatial group])
I'd like to do two additional things. First, I'd like to calculate the area of that single shape using a spatial function called area. Then I also want the length of the border around that single shape. And we use the Outline to do that or the border that we created.
area([4.2 create union from spatial group],'mi')
and
length([4.3 outline from union ],'mi')
Each is in miles. You could also use kilometers or any other metric.
When we add that to the map, it looks like this.

Spatial functions are pretty easy to use. They work just like calculations, except you're working with spatial data.
3 Makepoint and Makeline – Don
Welcome, everybody, to San Diego again. We're going to find out where everybody arrived from, using MAKEPOINT() and MAKELINE(), two geospatial functions in Tableau.

To use MAKELINE() and MAKEPOINT() together, we need two sets of latitude and longitude. We have our ‘To’ latitude and our ‘To’ longitude, and our ‘From’ latitude and our ‘From’ longitude. And you'll notice that ‘To’ latitude and ‘To’ longitude, they're all the same values, because that represents the point for San Diego. And then for each country, we have separate latitudes and longitudes. We will use those in a function, MAKEPOINT() from latitude and from longitude, and MAKEPOINT() to latitude and to longitude, and then we combine them together in Makeline.

This could all be one calculation, but it's easier to reference backwards in case there's an issue.

And we bring that into a map, and we get these great circle arcs showing where everybody is from.

For example, we have a large number of folks from Canada and New Brunswick, only 15, 250, from Quebec. This is just fake data. I’ve placed the number of attendees on the size button and colored each country separately, so we get a nice view as to where everybody is from. So, this is a great way of showing MAKEPOINT(), MAKELINE() together. You could use turn-by-turn directions as well, if you had perhaps path, and that would give you a very ordered structure. So just remember, you can expand on this for geospatial presentations and mapping.
4 Getting GPX data from your Smartwatch – Don

Before we get started, I’d like to ask, who's got a Smartwatch? If you have a Smartwatch, it contains GPX data, and that GPX data is essentially GPS data. In Apple Health or in Android, your health records can be exported out to Tableau prep, and we can change that GPS extension from to .txt or .csv, and we then load that XML file into Tableau prep, and then we would output that into Tableau Desktop.

I want you to think about that going forward. This is a very brief Tableau prep flow example. There are 39 changes in there. And it contains a lot of information, the route and the waypoint date and time, latitude and longitude, and things like that, horizontal and vertical accuracy, and bearing. And we're going to use that going forward.

Just know that it's available on your watch. And if you need this flow, just ask us for it, and we'll get it to you.
5 Where are the best tacos in San Diego? – Don
While we're here in San Diego, we have two problems. We need to learn spatial functions, and we need to find great tacos!

I have three criteria for food. It's usually got to be good, cheap, and a lot, but if a restaurant has two out of the three, then I'm probably in. As we're here in San Diego, let's go ahead and find some tacos. I'm going to bring out a road geometry that I have brought in from the San Diego GIS portal for the County of San Diego. And I found some taco locations from San Diego magazine, San Diego's 40 best tacos from 2025.
I didn't have the ability to reverse geocode this in Tableau, but I did do it in a product called "Geocod.io," and it's free to use. I use it for small datasets, 2500 addresses or fewer. So, we now have our taco locations. I'm kind of focusing just on our particular area here near the convention center. You'll see that I've got Harbor Drive out here. It's colored differently, and then we have Convention Way. It's in a different color from the rest of the roads. That's really easy to do, simply by calculation we have
CONTAINS([Full Name], ‘Harbor’)
and that returns just a simple true or false. Same thing for the other colors.
For example, IF [Full Name] IS ‘I-5’ OR ‘San Diego freeway’ or ‘Convention Way’, then make it orange, otherwise blue, when dropped on the color button.

You can easily add some distinction to your roadmap structure here, but just know that these are not lines. These are actually polygons, which is why Tableau is reading them as filled geometry.
So, we have our road geometry, we have our taco locations, and then separately, I wanted to create a San Diego Convention Center value, and you can do that manually as well using MAKEPOINT(). I found the latitude and longitude online, and I'm adding the spatial reference ID of 4326, which might be necessary when you build something out manually, just so that Tableau can place it properly on a map, because we're talking about geospatial, so I used MAKEPOINT() to create the San Diego Convention Center point.
MAKEPOINT(32.70569,-117.16015, 4326)
Let's go ahead and bring that in, and then I did one or one of my favorite spots. It's called Crack Taco, and then I brought it in, and then we have our Distance from Crack Taco to the Convention Center is .5 miles. And the easy way to look at that is using our DISTANCE() function. Now we have our San Diego Convention Center and our Crack Taco, and it's in miles. And just know that that's as the crow flies.
How did I get to my estimated walk time? Well, that's really simple. We have our distance divided by our speed divided by 24, and that gets us a float value, and then you format that as hours, minutes, and seconds. So, I also have my speed miles per hour as a parameter, and that could be adjustable, and we can now see that Crack Taco, right here on the harbor, is about 11 minute’s walk at three miles per hour.

So, let’s bring in some additional information here, and that would be the GPX data, or rather the GPS data that we just talked about. And as you can see, I hit not one, but I hit two spots. I hit Puesto, and Crack Taco, and I think I did that all on one day, yeah, on the 14th. So, I hit both of these spots on the same day, and I can tell you that these folks here (Crack Taco) are good, cheap, and a lot, and these folks here (Puesto), they're good, but they're not cheap, and they're not a lot. So, this is another example using GPS data, and I've parsed this down to every six seconds.
6 Bring in Elevation – Don
Speaking of walking…If I know that I generally walk about three miles per hour, and I saw this next example, I would be questioning, why am I doing 1.4 to 1.2 mph, and then on this side, 1.7, and it looks like I started on this (right) side and ended on this (left) side. There's some additional data in that, GPS data, and for additional context, we probably want to show elevation. Elevation brings us our Z axis in addition to our X and Y axes. I'm going to go ahead and close this guy down (left map), because that mountain is not that high. It's actually about anywhere from five degrees to 35 degrees, but I climbed about 700 feet in 40 minutes, so that's not too bad, but that tells me why that value looks different on one side versus the other side. Don't forget that elevation is the Z access, and it's just as important as your X and Y.

So now that we know that where the where the taco spots are, I created a spatial Taco Index using distance, estimated walk time, and rank. And don't forget that we can use rank on a map, and I would suggest that if you do use it, use Table Across. And what I did is I grabbed a bunch of Yelp ratings, Yelp reviews, and the DISTANCE() function from prior. Because I wanted the result to be spatial. And basically, loosely translated, the calculation is, the better the ratings and the more reviews and the closer to the conference, the better the spatial index. And that came with some breakpoints in the data, and I was able to create a legend.
So, we have our Legendary Tacos here. We have Conference Favorites here at the taco stand, and then Worth the Walk…that's my Crack Tacos guy. There are some others there as well. And then Late Night only. Well, read between the lines. I would probably do that if I've had a few and I've been out for a while. So, a great way of showing where things are. But I'm going to say that these folks here are probably my next spot, because the closest rank is one. Yelp rating of 4.2, Yelp reviews about 1500, and a Spatial Taco index of 3.4, compared to Lola's, which is third, and Puesto, which is fourth. So, a great way of showing not only where our folks are, but what's best, and more importantly, from a spatial standpoint, what's closest. Don't forget, folks, that we can always right-click and duplicate as a cross tab, and we get our table of data, which we can further analyze.

7 Using Viewport – Don
I'm not going to build this out for you. I will give you the instructions, but it involves two maps, and I'm going to bring in our taco locations, which are just points, and our zips, which are just polygons.

This uses the intersect function, but I will show you what that spatial parameter looks like for Viewport, and it's in a particular spot. It is a Spatial Data type in the parameter section, but it lives here under Map Viewport, and you can see that I have it selected for our taco locations, and these points are going to be the focus for the end user. We bring these two together in a dashboard, and I'm going to pretend that I'm the Crack Taco owner, and I want to know primarily where I want to maybe expand my business or do some marketing.

As we select the points, then the alternate map, then zoom in. This allows you to have a nice drill-down effect for analysis or focusing. So that's how I would use that going forward in determining which zip codes I wanted to maybe focus on from a marketing standpoint or perhaps expand my business.
Don't forget that Tableau maps now support mixed geometry, which is a great big deal for all of us, because before, we could only do either points or polygons, but not both together.
8 Using Well-Known Text – WKT – Don
And a good example of that is WKT or Well-Known Text. And this next example uses a spatial parameter, the INTERSECTS() function, the SHAPE_TYPE() function, and the AREA() function.

I found online a Well-Known text visualizer. All the links will be in the workbook. And this is basically just a polygon. And I've included a point as well. And you can see that Tableau is showing the function that the shape type is mixed. The area is 242.6 miles. And here's the point right here. And this is the polygon.

What it looks like is this. Again, the data type is spatial, but the geometry on this particular section is showing both points and polygons, and it allows you to then display various dimensions, depending upon what area you're trying to select. I want the end user to be focused on a particular section of data involving these points and polygons. And the reason that Tableau is not showing us these other points for Taco locations is that I'm using the intersects function as a true false Boolean result in filtering down to just true.
INTERSECTS([Taco Locations],[Viewport (Zips & Tacos)])
Here we have Little Italy, and we have East Village. And Little Italy does not have any taco locations. And we have Lola 55, in the polygon here, and then the Gaslamp Quarter, we have none. And then downtown San Diego, we have three. So, a great way of creating focus is just using Well-Known Text.
9 Overlapping Spatial Shapes Using Spatial Parameters – Don
I'm going to do a little bit more of an involved example. Schools, liquor licenses, cannabis licenses, using DISTANCE(), INTERSECTS(), estimated walk time, and a parameter action.

It involves three completely separate sets of data. And something was interesting about this, in the way to make this work with the intersect function on three different levels.
We have our schools in orange, and we have our cannabis licenses in green, and we have our liquor licenses in blue, and I'm using extensive use of color. And you'll notice here that I've selected Hollywood Senior High in Los Angeles, and that's a selected point. What that looks like, again (displaying parameter settings), is spatial, and we leverage that in our Buffer function, and we have our selected point and our buffer radius and feet, which is also a parameter, and we have a parameter action (displaying parameter action settings), so we are focusing on the selected point, and the source field is our schools.

When we go from this central point of Hollywood Senior High to say this guy, the buffer moves dynamically and then updates accordingly. In this particular section, we have 44 liquor licenses, and we have three cannabis licenses.
The key to using three separate sets of data, and we're not intersecting this information in a join, nothing formal like a physical join or a relationship. We're simply using the intersect function three different times to create this type of view. And what's key about this is that each of these fields is named the same, so that's why you'll see, for example, [Points 3] and [Points 2], and [Points], and these can easily be renamed if necessary, so that there's better distinction.
MAKEPOINT([Points Latitude], [Points Longitude])
But this is a great way of bringing in multiple sets of information and creating some dynamics in a map. And we're going to go ahead and give you all the data sources and references in this workbook. And just a final reminder, don't forget that, now in Tableau Prep in 2026.1, supports many spatial calculations such as MAKEPOINT(), MAKELINE(), BUFFER(), DISTANCE(), and so on. You can do all of this ahead of using it in Tableau Desktop, save yourself some time and energy, and create some efficiency in Desktop.
And with that, I'm going to turn things back over to Jim, who's going to show you some very cool buildout of x, y plots going forward. And Jim, I'm going to turn it right back to you.
10 X-Y Plotting – Jim
This afternoon, we're going to get to see IronViz. I hope everybody's going to go to see it. It's one of my favorite events.
They're going to do some really cool stuff, and you're going to be sitting there, just like I'm going to be sitting and saying, " How did they do that? Well, I'm going to show you one of their secrets. They're using x y plots on maps.

Remember when you were in school and you learned to first make plots. You drew a horizontal line, and you call that your X axis. You put a vertical line, and you call that the Y axis. And then you put points x and y locations and connected those points with a line. Well, we're going to do the same sort of thing here in the X and Y location.

I'm going from 0% to 100% in the x direction, in the y direction, and I'm going to drop in the daily sales from the superstore data. And we're going to convert that X dimension from zero degrees longitude to 180 degrees longitude, using those percentages and zero degrees latitude to 90 degrees latitude in the y direction.
(Note: At TC, I was reminded that the linear distance between latitudes above 60 degrees gets compressed due to the curvature of the earth. I have added a correction in this final version by simply multiplying the x – y locations by .1 making the map range 0-18 degrees longitude and 0-9 degrees latitude- well out of the range where distances get compressed)
Let's take a look at how that's done. We're going to start by determining the length of the x-axis, and that's nothing more than the total number of days in our data set, which is the maximum order date minus the minimum order date.
{max([Order Date])}-{min([Order Date])}
That's going to give us the length of the X axis.
The distance to any point on that axis for a data point is the order date for that data point minus the minimum order date.
[Order Date]-{min([Order Date])}
We're going to calculate that as a percent of the total. Here's our increment to any point divided by the length of the axis times 180 degrees longitude.
.1* ((avg([6.2 date increment to any point])
/avg([6.1 date range max]) ) *180)
Note the .1 multiplication correction factor
Okay, and then we're going to do the same thing in the y direction, except we're going to use sales. This is an LOD for the sales at any point.
{ FIXED [Order Date]: sum([Sales])}
The sales range, or the axis range for sales, is the maximum minus the minimum, and we're going to calculate that percentage as the sales at any point over the range of the sales times the 90 degrees of longitude.
{max([6.4 sales lod at day level])}
.1*((sum([6.4 sales lod at day level])
/sum([6.5 sales range based on lod ]) ) *90)
Note the .1 multiplication correction factor
And then we're just going to use Makepoint as Don used.
MAKEPOINT([6.6 percent of sales range ],
[6.3 Percent order date in range])
We're going to use Makepoint to plot the points, then we're going to connect them together, and that's what our plot looks like.

But it doesn't really look like that. What it really looks like is this, and it's sitting on a map of the world, and zero longitude, zero latitude is a point right around here. And all I've done is I've come back into Maps and take a look at the background layers on maps. And I've changed the washout to 100% so that you don't see it, and now we've got an x, y plot of longitude and latitude.

If we can do that for one chart on the map, we can do it for many charts using map layers.

I'm going to add two more charts. First, we're going to take that line chart and push it to the top of the frame, and then we're going to add in the lower left-hand corner a scatter plot of sales and profit by subcategory. Then we're also going to add a bar chart now to move our line chart to the top of the screen, all we're going to do is we're going to change our percent of sales calculation to start at 50 degrees longitude and use that 40% above 50 degrees longitude based on the percentage of the daily sales versus the sales access to get to get to the top of the screen.
.1*(45+( (sum([7.53 sales lod at day level])/
sum([7.54 sales range based on lod ]) ) *40))

Now I want to come back in and add this scatter plot.

We're going to hide this other chart for just a second, and all we're going to do is we're going to calculate our sales range to determine the length of the sales axis, and it's just the maximum sales by subcategory minus the minimum. And we're going to do the same for profit, maximum profit minus the minimum profit, and then the percent of.
{ FIXED :MAX( {FIXED [Sub-Category]:sum([Sales])} )}
– { FIXED :min( {FIXED [Sub-Category]:sum([Sales])} )}
{ FIXED :MAX( {FIXED [Sub-Category]:sum([Profit])} )}
– { FIXED :min( {FIXED [Sub-Category]:sum([Profit])} )}
For our sales vertically is going to be the sales at any point divided by the length of our axis times 35 degrees of latitude. I'm going to leave a little gap at the top of that so that I've got some white space. And then, in terms of longitude, we're only going to go over half the screen, or 90 degrees, not the 180 degrees.
.1*(( (sum({ FIXED [Sub-Category]:sum([Sales])})
/sum([7.30 sales range for scatter – sub cat level ]) ) *35))
.1*( 10 + ( (sum({ FIXED [Sub-Category]:sum([Profit])})/
sum([7.31 profit range for scatter – sub cat level ]) ) *80))
We're going to use the left half of that. And I want it to start at 10 degrees longitude and go out to a total of 90 degrees. And that's, once again, it's just the profit at any point divided by the range. And then we use make point, and we can plot the points.

Now we can do the same thing for our bar chart. I'm not going to go through the math on this. We're going to give you this workbook, and you can reverse engineer it, and we can add it back to our line chart. And you can see we got three charts on the same page, but in reality.

And you know, what we've really got is that it's on a map of the world, and all I've done is hide the map of the world in the background.

That's what Don and I wanted to share with you today. These are the links for the workbook and for the video. We recorded this video earlier, then used AI to transcribe the recording – please see the video and download the workbook.
