Openlayers前端复用Turf.js生成平头Buffer

23 篇文章 0 订阅
7 篇文章 0 订阅
该示例展示了如何在OpenLayers中结合Turf.js库生成平头Buffer效果。代码创建了一个矢量图层,并在地图上绘制了一条线,然后通过Turf.js的buffer方法生成缓冲区,再处理掉两端的圆形头部,最终得到平头的Buffer区域。此外,代码还实现了选择线段时显示坐标的功能。
摘要由CSDN通过智能技术生成

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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值