Mapboxgl 实现弧线功能

更多精彩内容尽在 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加VX:digital_twin123

image.png
代码如下:

const mapCenter = [-0.5, 51.8];

// please use your own token!
const map = new mapboxgl.Map({
    
    
    container: 'map',
    style: 'mapbox://styles/mapbox/light-v11',
    center: [-10, 25],
    zoom: 2,
    maxZoom: 5
});

map.on('load', () => {
    
    
    map.setLight({
    
    
        intensity: 0
    });
    const points = turf.randomPoint(50, {
    
    
        bbox: [-100, 0, 100, 80]
    });
    const mergedArray = [];
    turf.featureEach(points, function (currentFeature, featureIndex) {
    
    
        const arcLine = generateLine([mapCenter, currentFeature.geometry.coordinates]);
        mergedArray.push(arcLine);
    });
    const flat = mergedArray.flat();
    const arcCollection = turf.featureCollection([]);
    arcCollection.features = flat;
    addLine(arcCollection);
});

function generateLine(coords) {
    
    
    const options = {
    
    
        units: 'miles'
    };
    const buffer = 10; // line width
    const line = turf.lineString(coords); // generate line with coords
    const length = turf.length(line, options); // line length
    const arcQuality = 4; // lower = more points to generate along arc and higher arcs
    const points = length / arcQuality; // number of points based on length and quality value
    const segment = length / points; // segment length based on number of points

    const pointArray = []; // empty array to hold each point
    const curve = 4; // value that determines when curve ends
    let heightVal = 1; // init height
    const maxHeight = points * points; // higher arcs based on distance/number of points

    for (let i = 0; i < points; i++) {
    
    
        const along = turf.along(line, segment * i, options);
        const maxSegment = maxHeight / points;
        const alongCoords = along.geometry.coordinates;
        const newVal = (points / 2) - i;
        if (i < (points / 2)) {
    
    
            const sq = (newVal * newVal) / (points / curve);
            heightVal = maxHeight - (maxSegment * sq);
        } else {
    
    
            const val = (points / 2) + (newVal - (points / 2));
            const sq = (val * val) / (points / curve);
            heightVal = maxHeight - (maxSegment * sq);
        }
        const circOptions = {
    
    
            steps: 10,
            units: 'miles',
            properties: {
    
    
                'heightVal': heightVal
            }
        };
        const circle = turf.circle([alongCoords[0], alongCoords[1]], buffer, circOptions);
        pointArray.push(circle);
    }
    return pointArray;
}

function addLine(arcs) {
    
    
    map.addSource('arcs', {
    
    
        'type': 'geojson',
        'data': arcs
    });

    map.addLayer({
    
    
        'id': 'arcLayer',
        'type': 'fill-extrusion',
        'source': 'arcs',
        'paint': {
    
    
            'fill-extrusion-color': [
                'interpolate',
                ['linear'],
                ['get', 'heightVal'],
                0,
                '#f768a1',
                200000,
                '#c51b8a',
                400000,
                '#7a0177'
            ],
            'fill-extrusion-opacity': 1,
            // 'fill-extrusion-base': 0,
            'fill-extrusion-base': [
                'case',
                ['<', ['get', 'heightVal'], 8000],
                8000,
                ['-', ['*', ['get', 'heightVal'], 1.5], 8000]
            ],
            'fill-extrusion-height': ['*', ['get', 'heightVal'], 1.5]
        }
    }, 'road-label-simple');
}

猜你喜欢

转载自blog.csdn.net/u013929284/article/details/140625925