Turf.js integration

Purpose

This tutorial shows you how to integrate TomTom Maps SDK for Web with Turf.js and use some of its features. Turf.js. is an open source library for geospatial analysis. With this tutorial you can:

  • Learn how to display a well-defined and limited area (in our example: Amsterdam) on the map.
  • Learn how to calculate polygon’s area in square kilometers with Turf.js.
  • Find out how to check if some points are located within or outside of the area (polygon) with Turf.js.

Prerequisites

To start using the TomTom Maps SDK for Web, you need the following:

  • API Key - If you don't have an API key visit a How to get a TomTom API key site and create one.
  • Coordinates How to find your company location coordinates?
    The simplest way for obtaining these coordinates is to go to api_explorer. First, click on Fuzzy Search and then on a Try it out button. Let's assume your company address is: ' 100 Century Center Ct 210, San Jose, CA 95112, USA'. You have to place it in a query field and clear other pre-populated fields, then scroll down and press the Execute button. Please take into account that you should not use special HTML characters (like '$','?',&','#') in address. In the response you can find section and there you can see that the very first item from the list of items matched your query. Look at the property below address fields. There you can see the data you need:
    1<position>
    2 <lat>37.36729</lat>
    3 <lon>-121.91595</lon>
    4</position>
  • Turf.js Add Turf.js to your project
    You can follow the Turf.js Getting started instructions. There are a few different ways to add the library to your project. In this tutorial, Turf.js is loaded via a script tag.
    • Add the following script tag to the
      <script src="https://npmcdn.com/@turf/turf/turf.min.js"></script>

Displaying the map

To display a map, use the following HTML5 code:

1<!DOCTYPE html>
2<html>
3 <head>
4 <meta charset="utf-8" />
5 <title>TomTom Web SDK plus TURF</title>
6 <link
7 rel="stylesheet"
8 type="text/css"
9 href="https://api.tomtom.com/maps-sdk-for-web/cdn/6.x/<version>/maps/maps.css"
10 />
11 <script src="https://api.tomtom.com/maps-sdk-for-web/cdn/6.x/<version>/maps/maps-web.min.js"></script>
12 <script src="https://api.tomtom.com/maps-sdk-for-web/cdn/6.x/<version>/services/services-web.min.js"></script>
13 <link rel="stylesheet" type="text/css" href="style.css" />
14 <script src="https://npmcdn.com/@turf/turf/turf.min.js"></script>
15 </head>
16
17 <body>
18 <div id="map"></div>
19 <script src="app.js"></script>
20 </body>
21</html>

Create file app.js with following code:

1var apiKey = "YOUR_API_KEY"
2var map = tt.map({
3 key: apiKey,
4 container: "map",
5 center: [4.899431, 52.379189],
6 zoom: 10,
7})

All javascript code should be added to this file.

Create style.css file with following code:

1body {
2 margin: 0
3}
4#map {
5 height: 100vh;
6 width: 100vw;
7}

Displaying a polygon on the map

Let's assume you offer your service only in the city area, in this example in Amsterdam. The application displays city area and its borders.

To display city boundaries, you need to retrieve a polygon from Additional Data Service . Before that you need to get geometry.id of that city by querying Fuzzy Search endpoint.

To implement this, perform the following steps:

You can find more information about the fuzzySearch method and indexes values at: Fuzzy Search.

1var SEARCH_QUERY = "Amsterdam"
2
3function findGeometry() {
4 tt.services
5 .fuzzySearch({
6 key: apiKey,
7 query: SEARCH_QUERY,
8 })
9 .then(getAdditionalData)
10}

Here is the code which executes findGeometry function:

1function getAdditionalData(fuzzySearchResults) {
2 var geometryId = fuzzySearchResults.results[0].dataSources.geometry.id
3 tt.services
4 .additionalData({
5 key: apiKey,
6 geometries: [geometryId],
7 geometriesZoom: 12,
8 })
9 .then(processAdditionalDataResponse)
10}
map.on("load", findGeometry())
  1. Create a function called findGeometry and declare a SEARCH_QUERY variable.
  2. Use the tt.services.fuzzySearch method to get the geometry.id.
    To limit indexes utilized for the search to Geographies, set the idxSet parameter to Geo.
  3. Create the getAdditionalData function. Inside call the additionalData method and obtain requested geometries. Pass them for further processing to another function called processAditionalDataResponse.
    1function getAdditionalData(fuzzySearchResults) {
    2 var geometryId = fuzzySearchResults.results[0].dataSources.geometry.id
    3 tt.services
    4 .additionalData({
    5 key: apiKey,
    6 geometries: [geometryId],
    7 geometriesZoom: 12,
    8 })
    9 .then(processAdditionalDataResponse)
    10}
  4. To display a polygon on the map, create a new GeoJSON layer using previously obtained geometryData and add it to the map. See the following code:
    1function buildLayer(id, data) {
    2 return {
    3 id: id,
    4 type: "fill",
    5 source: {
    6 type: "geojson",
    7 data: {
    8 type: "Feature",
    9 geometry: {
    10 type: "Polygon",
    11 coordinates: data,
    12 },
    13 },
    14 },
    15 layout: {},
    16 paint: {
    17 "fill-color": "#2FAAFF",
    18 "fill-opacity": 0.8,
    19 "fill-outline-color": "black",
    20 },
    21 }
    22}
    23function displayPolygonOnTheMap(additionalDataResult) {
    24 var geometryData =
    25 additionalDataResult.geometryData.features[0].geometry.coordinates[0]
    26 map.addLayer(buildLayer("fill_shape_id", geometryData))
    27 return geometryData
    28}
  5. Create the processAditionalDataResponse function and execute displayPolygonOnTheMap function inside.
    1function processAdditionalDataResponse(additionalDataResponse) {
    2 if (
    3 additionalDataResponse.additionalData &&
    4 additionalDataResponse.additionalData.length
    5 ) {
    6 var geometryData = displayPolygonOnTheMap(
    7 additionalDataResponse.additionalData[0]
    8 )
    9 }
    10}

Calculate and display the polygon area with Turf.js

To calculate the area of your polygon, use the Turf.js area method.

  1. Create the function called calculateTurfArea.
    • Pass geometryData as an argument, as previously defined in the getGeometry function.
    • According to Turf.js, this method returns the area of the polygon in square meters.
    • Convert it to square kilometers to make it more readable. See the following code:
    1function calculateTurfArea(geometryData) {
    2 var turfPolygon = turf.polygon(geometryData)
    3 var areaInMeters = turf.area(turfPolygon)
    4 var areaInKilometers = turf.round(
    5 turf.convertArea(areaInMeters, "meters", "kilometers"),
    6 2
    7 )
    8}
  2. To display the polygon area information, create a polygon-info-box HTML element inside the div with 'id' map.
    1<div id="polygon-info-box">
    2 <label>Area of the polygon:</label>
    3 <div>
    4 <span id="area-info"> - </span><span>km<sup>2</sup></span>
    5 </div>
    6</div>
  3. In the calculateTurfArea function created before, set the content of areaInfo element to areaInKilometers value by using an innerText property.
    1function calculateTurfArea(geometryData) {
    2 var turfPolygon = turf.polygon(geometryData)
    3 var areaInMeters = turf.area(turfPolygon)
    4 var areaInKilometers = turf.round(
    5 turf.convertArea(areaInMeters, "meters", "kilometers"),
    6 2
    7 )
    8 var areaInfo = document.getElementById("area-info")
    9 areaInfo.innerText = areaInKilometers
    10}
  4. Add styling to your polygon-info-box element in style.css file:
    1#polygon-info-box {
    2 font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
    3 position: fixed;
    4 top: 10px;
    5 right: 10px;
    6 padding: 10px;
    7 margin: 10px;
    8 z-index: 1100;
    9 background-color: white;
    10 box-shadow: rgba(0, 0, 0, 0.45) 2px 2px 2px 0px;
    11}
    12#polygon-info-box label {
    13 font-size: 1.3em;
    14 font-weight: bold;
    15 line-height: 2;
    16}
    17#polygon-info-box span {
    18 font-size: 1.2em;
    19}
    20#polygon-info-box {
    21 text-align: right;
    22}
  5. Add the calculateTurfArea function execution inside of the processAdditionalDataResponse function:
    1function processAdditionalDataResponse(additionalDataResponse) {
    2 if (
    3 additionalDataResponse.additionalData &&
    4 additionalDataResponse.additionalData.length
    5 ) {
    6 var geometryData = displayPolygonOnTheMap(
    7 additionalDataResponse.additionalData[0]
    8 )
    9 calculateTurfArea(geometryData)
    10 }
    11}

Finding points located within a polygon using Turf.js

  1. Define the markerCoordinates array with points, some of them from the inside and some from the outside of the polygon:
    1var markerCoordinates = [
    2 [4.899431, 52.379189],
    3 [4.8255823, 52.3734312],
    4 [4.7483138, 52.4022803],
    5 [4.797049, 52.435065],
    6 [4.885911, 52.320235],
    7]
  2. Now, create a drawPointsInsideAndOutsideOfPolygon function and use a pointsWithinPolygon method from the turf library:
    1function drawPointsInsideAndOutsideOfPolygon(geometryData) {
    2 var customInsidePolygonMarkerIcon = "img/inside_marker.png"
    3 var customOutsideMarkerIcon = "img/outside_marker.png"
    4 var turfPolygon = turf.polygon(geometryData)
    5 var points = turf.points(markerCoordinates)
    6 var pointsWithinPolygon = turf.pointsWithinPolygon(points, turfPolygon)
    7 markerCoordinates.forEach(function (markerCoordinate) {
    8 const markerElement = document.createElement("div")
    9 markerElement.innerHTML = createMarkerElementInnerHTML(
    10 customOutsideMarkerIcon
    11 )
    12 pointsWithinPolygon.features.forEach(function (pointWithinPolygon) {
    13 if (
    14 markerCoordinate[0] === pointWithinPolygon.geometry.coordinates[0] &&
    15 markerCoordinate[1] === pointWithinPolygon.geometry.coordinates[1]
    16 ) {
    17 markerElement.innerHTML = createMarkerElementInnerHTML(
    18 customInsidePolygonMarkerIcon
    19 )
    20 }
    21 })
    22 var marker = new tt.Marker({ element: markerElement }).setLngLat(
    23 markerCoordinate
    24 )
    25 marker.addTo(map)
    26 })
    27}
  3. Execute the drawPointsInsideAndOutsideOfPolygon function inside of the processAdditionalDataResponse function:
    1function processAdditionalDataResponse(additionalDataResponse) {
    2 if (
    3 additionalDataResponse.additionalData &&
    4 additionalDataResponse.additionalData.length
    5 ) {
    6 var geometryData = displayPolygonOnTheMap(
    7 additionalDataResponse.additionalData[0]
    8 )
    9 calculateTurfArea(geometryData)
    10 drawPointsInsideAndOutsideOfPolygon(geometryData)
    11 }
    12}

See the result!

Summary

From this tutorial you learned:

  • How to show a polygon on a map.
  • How to calculate and show its area using Turf.js.
  • How to show points located within and outside of a polygon using Turf.js.

You can find source code here: GitHub.