Slice a polygon with a linestring using turf.js
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Show drawn polygon area</title> | |
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> | |
<script src="https://api.mapbox.com/mapbox-gl-js/v1.10.1/mapbox-gl.js"></script> | |
<link href="https://api.mapbox.com/mapbox-gl-js/v1.10.1/mapbox-gl.css" rel="stylesheet" /> | |
<style> | |
body { margin: 0; padding: 0; } | |
#map { position: absolute; top: 0; bottom: 0; width: 100%; } | |
</style> | |
</head> | |
<body> | |
<style> | |
.calculation-box { | |
height: 75px; | |
width: 150px; | |
position: absolute; | |
bottom: 40px; | |
left: 10px; | |
background-color: rgba(255, 255, 255, 0.9); | |
padding: 15px; | |
text-align: center; | |
} | |
.controls { | |
width: 150px; | |
position: absolute;; | |
top: 10px; | |
left: 10px; | |
background-color: rgba(255, 255, 255); | |
padding: 15px; | |
} | |
p { | |
font-family: 'Open Sans'; | |
margin: 0; | |
font-size: 13px; | |
} | |
</style> | |
<script src='https://unpkg.com/@turf/turf/turf.min.js'></script> | |
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.0.9/mapbox-gl-draw.js"></script> | |
<link | |
rel="stylesheet" | |
href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.0.9/mapbox-gl-draw.css" | |
type="text/css" | |
/> | |
<div id="map"></div> | |
<div class="controls"> | |
<input type="checkbox" id="splitMode" name="splitMode" value="splitMode" onchange="toggleCheckbox(this)"> | |
<label for="splitMode"> Split mode on/off</label><br> | |
</div> | |
<div class="calculation-box"> | |
<p>Draw a polygon using the draw tools.</p> | |
<div id="calculated-area"></div> | |
</div> | |
<script> | |
let MODE = 'polygon'; | |
mapboxgl.accessToken = 'pk.eyJ1Ijoia3VhbmIiLCJhIjoidXdWUVZ2USJ9.qNKXXP6z9_fKA8qrmpOi6Q'; | |
var map = new mapboxgl.Map({ | |
container: 'map', // container id | |
style: 'mapbox://styles/mapbox/light-v9', //hosted style id | |
center: [-122.431297, 37.773972], // starting position | |
zoom: 12 // starting zoom | |
}); | |
var draw = new MapboxDraw({ | |
displayControlsDefault: false, | |
controls: { | |
polygon: true, | |
line_string: true, | |
trash: true | |
} | |
}); | |
map.addControl(draw); | |
toggleCheckbox({"checked": false}); | |
map.on('draw.create', updateArea); | |
map.on('draw.delete', updateArea); | |
map.on('draw.update', updateArea); | |
function updateArea(e) { | |
var data = draw.getAll(); | |
if (MODE == 'polygon') { | |
var answer = document.getElementById('calculated-area'); | |
if (data.features.length > 0) { | |
var area = turf.area(data); | |
// restrict to area to 2 decimal points | |
var rounded_area = Math.round(area * 100) / 100; | |
answer.innerHTML = | |
'<p><strong>' + | |
rounded_area + | |
'</strong></p><p>square meters</p>'; | |
} else { | |
answer.innerHTML = ''; | |
if (e.type !== 'draw.delete') | |
alert('Use the draw tools to draw a polygon!'); | |
} | |
} else if (MODE == 'slice') { | |
const polys = data.features.filter(ea => ea.geometry.type == 'Polygon'); | |
const lines = data.features.filter(ea => ea.geometry.type == 'LineString'); | |
// just assuming one of each for now | |
const poly = polys[0]; | |
const line = lines[0]; | |
const polyAsLine = turf.polygonToLine(poly); | |
const unionedLines = turf.union(polyAsLine, line); | |
const polygonized = turf.polygonize(unionedLines); | |
const keepFromPolygonized = polygonized["features"].filter(ea => turf.booleanPointInPolygon(turf.pointOnFeature(ea), poly)); | |
draw.deleteAll().set(turf.featureCollection(keepFromPolygonized)); | |
} | |
} | |
function toggleCheckbox(element) { | |
const drawLine = document.getElementsByClassName("mapbox-gl-draw_line")[0]; | |
const drawPolygon = document.getElementsByClassName("mapbox-gl-draw_polygon")[0]; | |
if (element.checked) { | |
MODE = 'slice'; | |
drawLine.disabled = false; | |
drawLine.style.backgroundColor = "white"; | |
drawPolygon.disabled = true; | |
drawPolygon.style.backgroundColor = "lightgrey"; | |
} else { | |
MODE = 'polygon'; | |
drawLine.disabled = true; | |
drawLine.style.backgroundColor = "lightgrey" | |
drawPolygon.disabled = false; | |
drawPolygon.style.backgroundColor = "white"; | |
} | |
} | |
function getRoot(pairingsList, i) { | |
if (pairingsList[i] === undefined) { | |
return i; | |
} else if (pairingsList[i] === i) { | |
return i; | |
} else { | |
return getRoot(pairingsList, pairingsList[i]) | |
} | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment