-
-
Save kuanb/0cd97a02ea4aefff85f20fb0475d3ec4 to your computer and use it in GitHub Desktop.
Slice a polygon with a linestring using turf.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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@5.1.6/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