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');
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

搞GIS图形的sky.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值