Introduction to Turf.js

Welcome to Turf!

Turf.js is a JavaScript library for spatial analysis. It helps you analyze, aggregate, and transform data in order to visualize it in new ways and answer advanced questions about it. In this guide, we’ll take a look at how Turf.js works, what it can do, and some examples of it in action.

Spatial analysis

Turf.js is a library for spatial analysis: a large family of tasks like ‘calculating area and distance’ and ‘joining points to polygons’ that enable people to see new facets of their data. Spatial analysis is used in every industry: to find the nearest coffee shop, calculate travel time, and show regional statistics for utility usage. It’s also a huge part of GIS, where many problems are solved with spatial analysis.

The map below is a classic example of spatial analysis, created by physician John Snow during the 1854 cholera outbreak in London. Snow plotted cholera cases in the Soho area of London around Broad Street and noticed a cluster around the water pump. This led to improved sanitation facilities and also the discovery that cholera infection was water-borne rather than airborne.

John Snow Cholera Map

Today, spatial analysis is used in epidemiology, biology, statistics, economics, commerce and business, urban planning, geology, oil and gas, and in many other industries. With Turf.js, we can now bring these analyses to the browser and show results quickly and seamlessly.

Data in Turf.js

Almost every function in Turf.js takes GeoJSON data as its input and returns GeoJSON data as its output. GeoJSON is a popular format for storing features that make up map overlays.

Let’s take a look at some of the most common Turf.js functions in action to see how they’re used.

Turf-buffer in action

One of the most common functions is turf-buffer, which takes a GeoJSON feature of any type and returns a buffer zone of a specified distance around it as a Polygon feature.

var nullIsland = {
  type: 'Feature',
  geometry: {
    type: 'Point',
    coordinates: [0, 0]
  },
  properties: {
    name: 'Null Island'
  }
};

var oneMileOut = turf.buffer(nullIsland, 1, 'miles');

A one-mile buffer around Null Island

The magic of turf-inside

Some functions return numbers, arrays, or boolean (true/false) values, depending on their context. For example, turf-inside takes a Point feature and a Polygon feature and returns true if the point is inside the polygon.

var nullIsland = {
  type: 'Feature',
  geometry: {
    type: 'Point',
    coordinates: [0, 0]
  },
  properties: {
    name: 'Null Island'
  }
};

var oneMileOut = turf.buffer(nullIsland, 1, 'miles');
var isInside = turf.inside(nullIsland, oneMileOut); // returns true

nullIsland is inside oneMileBuffer, so isInside evaluates to true.

Super math with turf-area

For an example of a function that returns a number, let’s figure out the area of our one-mile buffer around Null Island with turf-area.

var nullIsland = {
  type: 'Feature',
  geometry: {
    type: 'Point',
    coordinates: [0, 0]
  },
  properties: {
    name: 'Null Island'
  }
};

var oneMileOut = turf.buffer(nullIsland, 1, 'miles');
var bufferArea = turf.area(oneMileOut); // returns 8113504.835073045

The area of oneMileOut is returned in square meters, so bufferArea evaluates to 8113504.835073045.

To read about the return values for each of the functions, check out the full Turf.js documentation.

GeoJSON constructors

Turf.js also has some functions that allow you to create GeoJSON Features and FeatureCollections quickly. This saves you the trouble of typing lots of curly braces and commas (where typos can often occur). An important note: these constructors are exactly the same as using regular GeoJSON primitives, and you do not need to convert your GeoJSON to these constructors to use Turf.js functions.

Turf.js GeoJSON constructors include:

var point = turf.point([0, 0], { name: 'point' });
var line = turf.linestring([[0, 0], [1, 1]], { name: 'line' });
var polygon = turf.polygon([[
  [0, 0],
  [1, 1],
  [1, 0],
  [0, 0]
]]);
var fc = turf.featurecollection([
  turf.polygon([[
    [0, 0],
    [1, 1],
    [1, 0],
    [0, 0]
  ]]),
  turf.polygon([[
    [1, 1],
    [2, 2],
    [2, 1],
    [1, 1]
  ]])
]);

Creating a GeoJSON Feature or FeatureCollection with the Turf.js constructors is no different than creating them with the traditional GeoJSON format, and all turf functions that take GeoJSON as parameters can also take the Turf.js constructors as parameters.

Common functions

We just showed you turf-buffer, turf-inside, and turf-area. Now let’s meet the rest of the family!

With Turf, you can do almost any kind of spatial analysis operation that you can think of. The functions are organized into groups to make them easier to find, although some are more widely-used than others.

  • Aggregation methods can run statistical operations on a set of points within a set of polygons. Want to compare average size of elementary schools across counties in Massachusetts? You can do that with turf-average!

  • Measurement methods can measure distances, create features, and calculate sizes. With measurement methods, you can figure out not only the exact center point of the city of Austin (with turf-centroid, but you can also measure the distance between that point and city hall (with turf-distance.

  • Transformation methods can solve spatial problems. If you want to buy a house that is both within one mile of a park and one mile of a bus stop, you can figure out where those areas overlap with turf-intersect, a transformation method.

  • Data methods can filter data by certain properties or create data for testing. For example, you can use turf-filter to toggle 311 calls by call-type.

  • Interpolation methods can estimate or average data and visualize the result. An example of this is creating contour lines (or isobands) from a set of points containing elevation information with turf-isobands.

  • Join methods can determine spatial relationships between features. If you want to know which burglaries happened in a specific neighborhood, you can use a join method like turf-within to figure it out.

  • Finally, classification methods can (yup, you guessed it) classify data into discrete groups. If you want to change the “color” property of a series of features from individual colors to simply “blue” or “not blue,” you can use the turf-reclass method.

Using Turf

As a JavaScript library, you can add Turf to your webpage the same way you add Mapbox.js: in the <head> of your document. You can use the CDN (the URL displayed below), or you can download the Turf library and source it locally.

<script src='https://api.mapbox.com/mapbox.js/plugins/turf/v2.0.2/turf.min.js'></script>

When you add Turf.js to your site, it exposes a global variable turf from which you can run any of the turf functions. (For those who are familiar, the Mapbox.js equivalent of this variable is L).

For example, let’s say we have a GeoJSON LineString feature named dc and we want to know its length in miles.

var dc = {
  type: 'Feature',
  properties: {},
  geometry: {
    type: 'LineString',
    coordinates: [
      [-77.031669, 38.878605],
      [-77.029609, 38.881946],
      [-77.020339, 38.884084],
      [-77.025661, 38.885821],
      [-77.021884, 38.889563],
      [-77.019824, 38.892368]
    ]
  }
};

To find out the length, we can use the turf-line-distance function:

var length = turf.lineDistance(dc, 'miles');

Now the variable length contains the length of route in miles.

// length === 1.6389817168470033

You can see another example of this function in action on the turf-line-distance documentation page.

Start building!

Ready for more? We recommend you move onto our next Turf.js guide, where we will dive into using Turf.js with Mapbox.js to solve real-world problems. There are also examples in the documentation on the Turf website!

Additional questions? Ask our support team or learn more about How Mapbox Works.