leaflet.js+turf.js实现自由画圈功能

//声明地图函数MapCore
function MapCore(mapContainer, MapOptions) {
    this.mapContainer=mapContainer,
    this.MapOptions=MapOptions,
    this.map = null
    this.titleGaoDe=['普通地图','卫星地图']

}
/**
 * 地图类的成员方法
*/
 MapCore.prototype={
     constructor:MapCore,
    //初始化地图
    init:function() {  
        const _this=this
        if (typeof L !== 'undefined') {  
            console.log('....===', _this.mapContainer,L); 
            this.map = L.map(_this.mapContainer, {  
            zoomControl: _this.MapOptions.zoomControl, // 是否使用显示放大缩小控件  
            attributionControl: _this.MapOptions.attributionControl // 是否显示右下角的leaflet字样  
            }).setView(L.latLng(...this.MapOptions.centerPiont), this.MapOptions.zoom || 14);  //设置缩放级别及中心点
                //设置放大缩小图标位置
            if(_this.MapOptions.zoomControl && _this.MapOptions.zoomPositon){
                this.map.zoomControl.setPosition(_this.MapOptions.zoomPositon);
             }
            this.map.pm.setLang("zh");
                //初始化图层      
            this.tileLayer = L.tileLayer(this.titleGaoDe.normal).addTo(this.map);
                //地图画圈弹窗取消报错问题处理
            L.Popup.prototype._animateZoom = function (e) {
                if (!this._map) {
                   return
                 }
                 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center),
                 anchor = this._getAnchor()
                 L.DomUtil.setPosition(this._container, pos.add(anchor))
                }
                return this.map
               
            } else {  
                throw(new Error('地图初始化失败'));  
            }
              
        },
    freeDraw:function(){
           document.getElementsByClassName('leaflet-touch')[0].style.cursor ='crosshair'
            var isDrawing = false;  
            var mouseDownTime;  
            var points = []; 
            let pointsArr = []
            let lasttPoint = null
            var polyline;  
            let _this=this
            _this.map.on('mousedown', function(e) {
                if (e.originalEvent.button === 0) { // 鼠标左键
                    _this.map.dragging.disable(); 
                    isDrawing = true;  
                    mouseDownTime = Date.now();  
                    const p = {
                        lat:Number(e.latlng.lat.toFixed(8)),
                        lng:Number(e.latlng.lng.toFixed(8))
                    }
                    const p2=[Number(e.latlng.lat.toFixed(8)),Number(e.latlng.lng.toFixed(8))]
                    points = [p]; 
                    pointsArr=[p2] 
                    lasttPoint==p2
                    // firstPoint = e.latlng
                    polyline = L.polyline(points, { color: 'red' }).addTo(_this.map); 
                }
            });  
    
            _this.map.on('mousemove',async function(e) { 
                if (isDrawing) {  
                    const p = {
                        lat:Number(e.latlng.lat.toFixed(8)),
                        lng:Number(e.latlng.lng.toFixed(8))
                    }
                    const p2=[Number(e.latlng.lat.toFixed(8)),Number(e.latlng.lng.toFixed(8))]
                    // 防止重复的点
                    if(JSON.stringify(lasttPoint) !== JSON.stringify(p)){      
                        points.push(p); 
                        pointsArr.push(p2)
                        polyline.setLatLngs(points); 
                    }
                    lasttPoint = points[points.length - 1]
                }  
            });  
    
            _this.map.on('mouseup', async(e)=> {  
                _this.map.dragging.disable();
                if (isDrawing) {  
                    var now = Date.now();  
                    if (now - mouseDownTime > 500) { // 判断是否长按  
                        const line = turf.lineString(pointsArr)
                        const {intersections,starIdx,endIdx} = findSelfIntersections(line);  
                            console.log('得到',intersections,starIdx,endIdx)
                          const newPA =  pointsArr.slice(starIdx,endIdx)
                          _this.map.removeLayer(polyline);
                          L.polygon(newPA, {color: 'blue',options:0.1}).addTo(_this.map)
                    } else {  
                        // 如果不是长按,则移除临时绘制的 polyline  
                        _this.map.removeLayer(polyline);
                    }  
                    isDrawing = false;  
                    mapOff(_this.map)
                    points = []; 
                } 
                
            });  
        }
    },
//获取线段自相交点及其下标
    function findSelfIntersections(lineString) {  
        let starIdx =null
        let endIdx =null
        const coordinates = lineString.geometry.coordinates;  
        const numSegments = coordinates.length - 1;  
        const intersections = [];  
        
        // 遍历线段的每个分段,检查它是否与其他分段交叉  
        for (let i = 0; i < numSegments; i++) {  
        for (let j = i + 1; j < numSegments; j++) {  
            // 创建两个线段的Turf对象  
            const segment1 = turf.lineString([coordinates[i], coordinates[i + 1]]);  
            const segment2 = turf.lineString([coordinates[j], coordinates[j + 1]]);  
        
            // 检查两个线段是否交叉,并获取交叉点  
            const intersection = turf.lineIntersect(segment1, segment2);  
            if (intersection && intersection.features.length > 0) {  
            const { geometry: { coordinates: intCoord } } = intersection.features[0];  
            // 确保交点不是线段的端点  
            if (  
                !(intCoord[0] === coordinates[i][0] && intCoord[1] === coordinates[i][1]) &&  
                !(intCoord[0] === coordinates[i + 1][0] && intCoord[1] === coordinates[i + 1][1]) &&  
                !(intCoord[0] === coordinates[j][0] && intCoord[1] === coordinates[j][1]) &&  
                !(intCoord[0] === coordinates[j + 1][0] && intCoord[1] === coordinates[j + 1][1])  
            ) {  
                starIdx = i
                endIdx = j
                intersections.push(intCoord);  
            }  
            }  
        }  
        }  
        
        // 打印出交叉点  
        // console.log('intersections-------',intersections);
        return {
            intersections:intersections,
            starIdx:starIdx,
            endIdx:endIdx
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜雨疯行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值