rveciana - turf-multiline-and-polygon-intersection

Turf multiline and polygon intersection

Open raw page in new tab

The previous example showed how to intersect a line with a polygon, but the situations can be more complicated, as shown in this example.

The solution is using the lineSplit function for each part of the multilinestring and selecting the ones that fit the needs. The first part can be inside or outside the polygon, depending on the first point. Detecting this, is easy to get only the needed parts.

<!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'>
</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": [
          [
            [
              50,
              47
            ],
            [
              45,
              43
            ],
            [
              50,
              46
            ],
            [
              55,
              43
            ],
            [
              50,
              47
            ]
          ]
        ]
      }
    }
  


var line = {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "MultiLineString",
        "coordinates": [
        [[
            44,
            46.5
          ],
          [
            56,
            46.5
          ]],
         [[
            44,
            46.8
          ],
          [
            50,
            46.8
          ]],
          [[
            50,
            46.3
          ],
          [
            56,
            46.3
          ]],
          [[
            44,
            44.5
          ],
          [
            56,
            44.5
          ]],
          [[
            48,
            45
          ],
          [
            56,
            45
          ]],
          [[
            44,
            45.5
          ],
          [
            51.5,
            45.5
          ]],
          [[
            46.4,
            44
          ],
          [
            53.7,
            44
          ]]
        ]
      }
    }

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());

line.geometry.coordinates.forEach(part => {
  let split = turf.lineSplit(turf.lineString(part), poly);
  let oddPair;
  if(turf.booleanPointInPolygon(turf.point(part[0]), poly)){
    oddPair = 0;
  } else {
    oddPair = 1;
  }
  split.features.forEach((splitedPart, i) => {
    if((i + oddPair)%2 === 0) {
      L.geoJSON(splitedPart.geometry).addTo(map);
    }
  });


 

});


</script>


</body>
</html>