rveciana - using-turf-to-measure-how-far-a-line-travels-through-a-polygon-in-modern-turf-js

Using Turf to measure how far a line travels through a polygon in modern turf.js

Open raw page in new tab

Example to ilustrate this question at gis.stackoverflow.

The solution is using a combination of lineIntersect and lineSlice. The first one gives the points where the line and the polygon intersect. The second takes the part of the polyline btween the two points.

If the result is more complex (i.e. the resulting intersection is a polyline), the algorithm should be repeated for each part in the polygon.

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>A simple map</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet.js" integrity="sha512-tAGcCfR4Sc5ZP5ZoVz0quoZDYX5aCtEm/eu1KhSLj2c9eFrylXZknQYmxUssFaVJKvvc0dJQixhGjG2yXWiV9Q==" crossorigin=""></script>
<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
<style>
  body { margin:0; padding:0; }
  #map { position:absolute; top:0; bottom:0; width:100%; }
  p.distance-container {
  	position: absolute;
    z-index: 10;
    font-size: 2em;
    margin: 1em;
    right: 0em;
    width: 8em;
    background-color: #fff;
    padding: 0.5em;
  }
</style>
</head>
<body>


<div id='map'>
	<p class='distance-container'>The line travels through the polygon for <span id="distance"></span> miles.</p>
</div>
<script>

var map = L.map('map').setView([51.505, -0.09], 13);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

var poly = {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              51.17431640625,
              47.025206001585396
            ],
            [
              45.17578125,
              43.13306116240612
            ],
            [
              54.5361328125,
              41.85319643776675
            ],
            [
              51.17431640625,
              47.025206001585396
            ]
          ]
        ]
      }
    }
var line = {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [
            42.78076171875,
            46.01222384063236
          ],
          [
            49.78076171875,
            43.01222384063236
          ],
          [
            50.78076171875,
            44.51222384063236
          ],
          [
            56.865234375,
            44.26093725039923
          ]
        ]
      }
    }

var polyStyle = {
    "color": "#ff7800",
    "weight": 5,
    "opacity": 0.65
};

var polyLayer = L.geoJSON(poly, {
    style: polyStyle
}).addTo(map);

var lineStyle = {
    "color": "#ff7800",
    "weight": 5,
    "opacity": 0.65
};

var lineLayer = L.geoJSON(line, {
    style: lineStyle
}).addTo(map);

map.fitBounds(lineLayer.getBounds());

let intersectionPoints = turf.lineIntersect(line, poly);
let intersectionPointsArray = intersectionPoints.features.map(d => {return d.geometry.coordinates});
L.geoJSON(intersectionPoints).addTo(map);



let intersection = turf.lineSlice(turf.point(intersectionPointsArray[0]), turf.point(intersectionPointsArray[1]), line);

L.geoJSON(intersection).addTo(map);

</script>


</body>
</html>