Skip to content

Instantly share code, notes, and snippets.

@rveciana
Last active January 17, 2023 00:15
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save rveciana/e0565ca3bfcebedb12bbc2d4edb9b6b3 to your computer and use it in GitHub Desktop.
Turf multiline and polygon intersection

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment