mirror of
https://github.com/Viglino/ol-ext.git
synced 2026-01-25 17:36:21 +00:00
254 lines
6.5 KiB
HTML
254 lines
6.5 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>ol-ext: Delaunay triangulation</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
|
|
<meta name="description" content="Calculate the Delaunay triangulation of a Point vector source." />
|
|
<meta name="keywords" content="ol, openlayers tirangulation, delaunay" />
|
|
|
|
<!-- jQuery -->
|
|
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
|
|
|
|
<!-- Openlayers -->
|
|
<link rel="stylesheet" href="https://openlayers.org/en/latest/css/ol.css" />
|
|
<script type="text/javascript" src="https://openlayers.org/en/latest/build/ol.js"></script>
|
|
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
|
|
|
|
<!-- ol-ext -->
|
|
<link rel="stylesheet" href="../../dist/ol-ext.css" />
|
|
<script type="text/javascript" src="../../dist/ol-ext.js"></script>
|
|
|
|
<link rel="stylesheet" href="../style.css" />
|
|
|
|
<style>
|
|
.ol-control.ol-bar .ol-control.ol-text-button:hover {
|
|
background: #33669977;
|
|
}
|
|
.ol-control.ol-bar .ol-control.ol-text-button.ol-active {
|
|
background: #369;
|
|
}
|
|
.ol-control.ol-bar .ol-control.ol-text-button.ol-active > div,
|
|
.ol-control.ol-bar .ol-control.ol-text-button > div:hover {
|
|
color: #fff;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body >
|
|
<a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>
|
|
|
|
<a href="../../index.html">
|
|
<h1>ol-ext: Delaunay triangulation</h1>
|
|
</a>
|
|
<div class="info">
|
|
<p>
|
|
The <i>ol/source/Delaunay</i> computes a
|
|
<a href="https://en.wikipedia.org/wiki/Delaunay_triangulation">
|
|
Delaunay triangulation
|
|
</a>
|
|
of a vector source (points).
|
|
</p>
|
|
<p>
|
|
<span class="experimental">Experimental</span>
|
|
this feature is still in progress and may be buggy.
|
|
</p>
|
|
<p>
|
|
NB: the algorithm is incremental and not very efficient but it computes the triangulation directly in a <i>ol/source/Vector</i>.
|
|
<br/>
|
|
You can add/remove vertex from the point source and get the resulting triangles directly in the triangle source.
|
|
<br/>
|
|
If you're looking for you'd better see an other algorithme like
|
|
<a href="https://github.com/mapbox/delaunator#performance">
|
|
mapbox/delaunator
|
|
</a>
|
|
</p>
|
|
<p>
|
|
This is more to use with interactive processes to maintains a triangulation on state while interacting.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Map div -->
|
|
<div id="map" style="width:600px; height:400px;"></div>
|
|
|
|
<div class="options">
|
|
<input type="number" value="20" />
|
|
<button onclick="generate(Number($(this).prev().val()))">Generate!</button>
|
|
<br/>
|
|
Generated triangles
|
|
<ul class='triangles'></ul>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
|
|
function generate(nb) {
|
|
var t = new Date();
|
|
var ext = map.getView().calculateExtent(map.getSize());
|
|
for (var i=0; i<nb; ++i) {
|
|
var f = new ol.Feature(new ol.geom.Point([ext[0]+(ext[2]-ext[0])*Math.random(), ext[1]+(ext[3]-ext[1])*Math.random()]));
|
|
nodes.addFeature(f);
|
|
}
|
|
console.log('Elapsed',((new Date())-t)/1000+'s');
|
|
}
|
|
|
|
// Base layers
|
|
var stamen = new ol.layer.Tile(
|
|
{ title: "Watercolor",
|
|
baseLayer: true,
|
|
source: new ol.source.Stamen({
|
|
layer: 'watercolor'
|
|
})
|
|
});
|
|
|
|
// The map
|
|
var map = new ol.Map ({
|
|
target: 'map',
|
|
view: new ol.View ({
|
|
zoom: 4,
|
|
center: [205461, 5867916]
|
|
}),
|
|
layers: [stamen]
|
|
});
|
|
|
|
// Default style
|
|
var fill = new ol.style.Fill({
|
|
color: 'rgba(255,255,255,0.4)'
|
|
});
|
|
var stroke = new ol.style.Stroke({
|
|
color: '#3399CC',
|
|
width: 1.25
|
|
});
|
|
var style = new ol.style.Style({
|
|
image: new ol.style.RegularShape({
|
|
stroke: stroke,
|
|
points: 4,
|
|
radius: 5,
|
|
radius2: 0
|
|
}),
|
|
text: new ol.style.Text({
|
|
font: 'bold 10px sans-serif',
|
|
text:'test',
|
|
textAlign: 'left',
|
|
textBaseline: 'bottom',
|
|
offsetX: 3,
|
|
offsetY: -3
|
|
}),
|
|
fill: fill,
|
|
stroke: stroke
|
|
});
|
|
|
|
var redStyle = new ol.style.Style({
|
|
fill: new ol.style.Fill({ color: [255,0,0,.2] })
|
|
});
|
|
|
|
// Node source
|
|
var nodes = new ol.source.Vector();
|
|
var nb = 0;
|
|
nodes.on('addfeature', function(e) {
|
|
e.feature.set('id', nb++);
|
|
});
|
|
var vector = new ol.layer.Vector({
|
|
source: nodes,
|
|
style: function(f) {
|
|
style.getText().setText(String(f.get('id')||'0'));
|
|
return style;
|
|
}
|
|
});
|
|
|
|
// Delaunay source based on the node source
|
|
var delaunay = new ol.source.Delaunay({
|
|
source: nodes
|
|
});
|
|
var triangle = new ol.layer.Vector({
|
|
source: delaunay
|
|
});
|
|
|
|
// In the map
|
|
map.addLayer(triangle);
|
|
map.addLayer(vector);
|
|
|
|
// Control Bar
|
|
var bar = new ol.control.Bar({ toggleOne: true });
|
|
map.addControl(bar);
|
|
|
|
// Draw interaction to add new points
|
|
var draw = new ol.interaction.Draw({ source: nodes, type:"Point" });
|
|
bar.addControl(new ol.control.Toggle({
|
|
className: 'ol-text-button',
|
|
html: "add",
|
|
interaction: draw,
|
|
active: true
|
|
}));
|
|
|
|
// Delete
|
|
var del = new ol.interaction.Select({
|
|
layers: [vector],
|
|
hitTolerance: 5
|
|
});
|
|
del.on('select', function(e){
|
|
var f = e.selected[0];
|
|
if (f) nodes.removeFeature(f);
|
|
del.getFeatures().clear();
|
|
});
|
|
bar.addControl(new ol.control.Toggle({
|
|
className: 'ol-text-button',
|
|
html: "del",
|
|
interaction: del
|
|
}));
|
|
|
|
/*
|
|
// Draw interaction to add new points
|
|
var modify = new ol.interaction.Modify({ source: nodes });
|
|
bar.addControl(new ol.control.Toggle({
|
|
className: 'ol-text-button',
|
|
html: "mod",
|
|
interaction: modify,
|
|
}));
|
|
modify.on('modifystart', function(e){
|
|
console.log(e)
|
|
var f = modify.dragSegments_[0][0].feature;
|
|
//nodes.removeFeature(f)
|
|
});
|
|
modify.on('modifyend', function(e){
|
|
console.log(e)
|
|
var f = modify.dragSegments_[0][0].feature;
|
|
//nodes.addFeature(f);
|
|
});
|
|
*/
|
|
|
|
// Select
|
|
var select = new ol.interaction.Select();
|
|
select.setActive(false);
|
|
map.addInteraction(select);
|
|
|
|
|
|
// Show circumcircle on hover
|
|
var hover = new ol.interaction.Hover({
|
|
layers: [vector],
|
|
hitTolerance: 5
|
|
});
|
|
hover.on('enter', function(e){
|
|
select.getFeatures().clear();
|
|
if (e.layer===triangle) {
|
|
var c = e.feature.getGeometry().getCoordinates()[0];
|
|
c = delaunay.getCircumCircle(c);
|
|
if (c.radius) {
|
|
c = new ol.geom.Circle(c.center, c.radius);
|
|
var f = new ol.Feature(c);
|
|
f.setStyle(redStyle);
|
|
select.getFeatures().push(f);
|
|
}
|
|
}
|
|
});
|
|
hover.on('leave', function(e){
|
|
select.getFeatures().clear();
|
|
});
|
|
bar.addControl(new ol.control.Toggle({
|
|
className: 'ol-text-button',
|
|
html: 'circle',
|
|
interaction: hover
|
|
}));
|
|
|
|
</script>
|
|
|
|
</body>
|
|
</html> |