You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
4.2 KiB
113 lines
4.2 KiB
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
|
|
<body> |
|
<h1>Concaveman</h1> |
|
<p> |
|
An interactive demo of <a href="https://github.com/mapbox/concaveman">concaveman</a> - a Javascript module for |
|
fast 2D concave hulls. Use the sliders to visualize the effect of the two parameters, concavity and |
|
lengthThreshold. |
|
</p> |
|
<div> |
|
<label for="concavity">Concavity </label> |
|
<input type="range" oninput="updateConcavity(this.value)" id="concavity" min="0" value="2.0" max="3.2" |
|
step="0.05"> |
|
<input type="text" id="concavityText" value="2.0"> |
|
<label for="lengthThreshold"> Length Threshold</label> |
|
<input type="range" oninput="updateLengthThreshold(this.value)" id="lengthThreshold" min="0" value="0" max="100" |
|
step="1"> |
|
<input type="text" id="lengthThresholdText" value="0.0"> |
|
</div> |
|
<br> |
|
|
|
<script src="https://d3js.org/d3.v3.min.js"></script> |
|
<script src="./concaveman-bundle.js"></script> |
|
<script type="text/javascript" language="javascript" src="continent_polygons.geojson_var"></script> |
|
<script> |
|
var width = 2000, |
|
height = 2000, |
|
minx = -200, |
|
miny = -100, |
|
scale = 3; |
|
|
|
var concavity = 2.0; |
|
var lengthThreshold = 0.0; |
|
|
|
function updateConcavity(val) { |
|
concavity = val; |
|
document.getElementById('concavityText').value = val; |
|
updateConcaveHull(); |
|
}; |
|
function updateLengthThreshold(val) { |
|
lengthThreshold = val; |
|
document.getElementById('lengthThresholdText').value = val; |
|
updateConcaveHull(); |
|
}; |
|
function get_all_points(geojson) { |
|
var points = []; |
|
if (geojson.type == "Polygon") { |
|
geojson.coordinates[0].forEach(e => points.push(e)); |
|
} else if (geojson.type == "MultiPolygon") { |
|
for (let i = 0; i < geojson.coordinates.length; i++) { |
|
geojson.coordinates[i][0].forEach(e => points.push(e)); |
|
} |
|
} |
|
return points; |
|
} |
|
|
|
console.log("GEOJson: ", geojson); |
|
var points = geojson.features.map(feature => { |
|
return get_all_points(feature.geometry); |
|
}); |
|
console.log(points); |
|
|
|
var svg = d3.select("body").append("svg") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
// svg.selectAll('circle') |
|
// .data(points) |
|
// .enter() |
|
// .append('circle') |
|
// .attr("cx", function (d) { return (d[0] - minx) * scale; }) |
|
// .attr("cy", function (d) { return (d[1] - miny) * scale; }) |
|
// .attr("r", 2); |
|
|
|
function updateConcaveHull() { |
|
svg.selectAll('polygon').remove(); |
|
svg.selectAll('polygon') |
|
//.data([concaveman(points, concavity, lengthThreshold)]) |
|
.data(points.map(partpoints => { |
|
return concaveman(partpoints, concavity, lengthThreshold) |
|
})) |
|
.enter() |
|
.append('polygon') |
|
.attr('points', function (points) { |
|
data = "" |
|
for (var i = points.length; i--;) { |
|
data += [(points[i][0] - minx) * scale, (points[i][1] - miny) * scale].join(','); |
|
data += " "; |
|
} |
|
data += [(points[0][0] - minx) * scale, (points[0][1] - miny) * scale].join(','); |
|
|
|
return data |
|
}) |
|
.attr('stroke', 'black') |
|
.attr('fill', 'yellow') |
|
.attr('opacity', 0.2) |
|
.attr('stroke-width', 1); |
|
|
|
var new_geojson = geojson; |
|
for(let i=0; i<new_geojson.features.length; i++) { |
|
new_geojson.features[i].geometry.type = "MultiPolygon"; |
|
new_geojson.features[i].geometry.coordinates = [[ |
|
concaveman(points[i], concavity, lengthThreshold) |
|
]]; |
|
}; |
|
console.log("New GeoJSON: ", new_geojson); |
|
console.log(JSON.stringify(new_geojson)); |
|
}; |
|
|
|
updateConcaveHull(); |
|
</script> |
|
</body> |