Openlayers前端复用Turf.js生成平头Buffer,实现如下效果:
代码如下:
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/css/ol.css" type="text/css">
<style>
.map {
height: 400px;
width: 100%;
}
body,
html,
#map {
/*:root等同html*/
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/build/ol.js"></script>
<title>OpenLayers example</title>
<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
</head>
<body>
<h2>My Map</h2>
<div id="map" class="map"></div>
<script type="text/javascript">
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
projection: 'EPSG:4326',
center: [94.45666666666666, 29.431944444444447],
zoom: 4
})
});
//实例化一个矢量图层Vector作为绘制层
var source = new ol.source.Vector({});
//创建一个图层
var vector = new ol.layer.Vector({
source: source
});
//将绘制层添加到地图容器中
map.addLayer(vector);
var select = new ol.interaction.Select({
layers: [vector]
});
select.on("select", function (e) {
var features = e.selected;
var feature = features[0];
var coord = feature.getGeometry().flatCoordinates;
alert(feature.feaindex + "坐标:" + coord)
});
map.addInteraction(select);
var gsonline0 = [
[93.94166666666668, 29.892777777777777],
[94.97500000000001, 30.098333333333333],
[96.00833333333334, 30.304166666666667],
[97.14, 30.52],
[98.19333333333334, 30.431944444444447],
[100, 30.284444444444443],
[101.52833333333334, 30.175833333333333],
[101.90333333333334, 30.80277777777778],
[102.64500000000001, 30.725277777777777],
[102.95833333333334, 30.6875],
[103.7, 30.656666666666666],
[103.94166666666668, 30.578055555555554],
[104.49, 30.616944444444446],
[105.005, 30.854444444444447],
[106.06333333333333, 31.353611111111114],
[106.17333333333333, 31.45111111111111],
[106.39666666666668, 31.636944444444445],
[106.95, 32.07944444444445],
[107.19166666666668, 32.265],
[107.65333333333334, 32.63722222222222],
[108.31333333333333, 33.34194444444445]];
var lineFeature = new ol.Feature({
geometry:new ol.geom.LineString(gsonline0)
});
lineFeature.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color:[237, 212, 0, 0.8],
width:2
}),
}))
source.addFeature(lineFeature);
let bufferGeos = flatBuffer(gsonline0, 100000);
console.log(bufferGeos);
var lbufFeature0 = new ol.Feature({
geometry:new ol.geom.Polygon([bufferGeos])
});
lbufFeature0.setStyle(new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.8)'
}),
stroke: new ol.style.Stroke({
width: 1,
color: "black"
}),
}))
source.addFeature(lbufFeature0)
function flatBuffer(coords,radius){
//定义数组
let bufferCoords = [];
if(coords.length<1) return bufferCoords;
//原始圆头buffer
let buffered = turf.buffer(turf.lineString(coords), radius, {
units: 'meters'
});
if (buffered.geometry.coordinates.length > 1) {
console.log('缓冲区半径太大')
}
//显示线原始圆头buffer
/*let fbuffered = (new ol.format.GeoJSON()).readFeature(buffered);
source.addFeature(fbuffered);
fbuffered.setStyle(new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 1)'
}),
stroke: new ol.style.Stroke({
width: 2,
color: "red"
}),
}));*/
//构建buffer为点featureCollection
let bufferedtoline = turf.polygonToLine(buffered);
//始点原始圆头buffer
let sPBuffered = turf.buffer(turf.point(coords[0]), radius, {
units: 'meters',steps:2048
});
//显示始点原始圆头buffer
/*let fSPBuffered = (new ol.format.GeoJSON()).readFeature(sPBuffered);
source.addFeature(fSPBuffered);
fSPBuffered.setStyle(new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 1)'
}),
stroke: new ol.style.Stroke({
width: 10,
color: "red"
}),
}));*/
//终点原始圆头buffer
let ePBuffered = turf.buffer(turf.point(coords[coords.length-1]), radius, {
units: 'meters',steps:2048
});
let sPHeadCoords = [];
let sPHeadCoords0 = [];
let sFlag = false;//标示,将起点的圆形头坐标分为两段
let ePHeadCoords = [];
let ePHeadCoords0 = [];
let eFlag = false;//标示,将终点的圆形头坐标分为两段
bufferedtoline.geometry.coordinates.forEach((coord) => {
bufferCoords.push(coord);
let sPoint = turf.point(coord);
//判断起点的圆形头坐标
let sPIsOnLine = turf.booleanPointInPolygon(sPoint, sPBuffered);
if (sPIsOnLine){
if(sFlag){
sPHeadCoords0.push(coord);
}
else{
sPHeadCoords.push(coord);
}
console.log('sPIsOnLine:');
console.log(coord);
}
else
{
sFlag = true;
}
//判断终点的圆形头坐标
let ePIsOnLine = turf.booleanPointInPolygon(sPoint, ePBuffered);
if (ePIsOnLine){
if(eFlag){
ePHeadCoords0.push(coord);
}
else{
ePHeadCoords.push(coord);
}
console.log('ePIsOnLine:');
console.log(coord);
}
else
{
sFlag = true;
}
//显示线原始圆头buffer上的线上的点
/*let newFeature = new ol.Feature({
geometry: new ol.geom.Point(coord)
});
//设置点的样式
newFeature.setStyle(createLabelStyle(newFeature));
//将当前要素添加到矢量数据源中
source.addFeature(newFeature);*/
});
console.log('sPHeadCoords:');
console.log(sPHeadCoords);
console.log('sPHeadCoords0:');
console.log(sPHeadCoords0);
console.log('ePHeadCoords:');
console.log(ePHeadCoords);
console.log('ePHeadCoords0:');
console.log(ePHeadCoords0);
//合并起、终点的圆形头坐标
sPHeadCoords = sPHeadCoords0.concat(sPHeadCoords.reverse());
ePHeadCoords = ePHeadCoords0.concat(ePHeadCoords.reverse());
console.log('sPHeadCoords:');
console.log(sPHeadCoords);
console.log('ePHeadCoords:');
console.log(ePHeadCoords);
//删除两端圆头
sPHeadCoords.shift();
sPHeadCoords.pop();
ePHeadCoords.shift();
ePHeadCoords.pop();
let dCoords = sPHeadCoords.concat(ePHeadCoords);//需要删除的两端圆头上的顶点
dCoords.forEach((coord) => {
let tempIndex = bufferCoords.indexOf(coord);
if(tempIndex>-1){
bufferCoords.splice(tempIndex, 1);
}
});//删除完成
//显示线切除两端圆头后的平头buffer
/*let flatBuffered = new ol.Feature({
geometry:new ol.geom.LineString(bufferCoords)
});
source.addFeature(flatBuffered);
flatBuffered.setStyle(new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 1)'
}),
stroke: new ol.style.Stroke({
width: 5,
color: "red"
}),
}));*/
return bufferCoords;
}
function createLabelStyle(feature) {
//返回一个样式
return new ol.style.Style({
//把点的样式换成ICON图标
fill: new ol.style.Fill({
//填充颜色
color: 'rgba(37,241,239,0.2)'
}),
//图形样式,主要适用于点样式
image: new ol.style.Circle({
//半径大小
radius: 7,
//填充
fill: new ol.style.Fill({
//填充颜色
color: '#e81818'
})
}),
//层
zIndex: 20
});
}
</script>
</body>
</html>