Mapboxgl 分图层聚合

(1)使用场景:当聚合点位于多个要素的边界的时候,聚合点会根据距离进行聚合,忽略自身的属性,无法达到我们想要的效果。

   

(2)效果:采用的一种方式是 将聚合点按照不同面要素分为多个要素图层加载。

(3)代码:

HTML、CSS:

<head>
    <meta charset="UTF-8" />
    <title>Mapboxgl 分图层聚合</title>
    <style>
        html,
        body,
        #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
    <link rel="stylesheet" href="../lib/js/geoglobe/mapbox-gl.css" type="text/css" />
    <script type="text/javascript" src="../lib/js/geoglobe/mapbox-gl.js"></script>
    <script type="text/javascript" src="../lib/js/turf/turf_new.min.js"></script>
    <script type="text/javascript" src="../lib/js/interpolation/kriging_noModule.js"></script>

    <!-- 行政区划数据 -->
    <script src="./data/noName.js"></script>
    <!-- 随机点数据 -->
    <script src="./data/randomPoint.js"></script>

    <body>
        <div id="map"></div>
        <script src="./js/mapboxCluster.js"></script>
    </body>
</head>

JS:


let map; // 地图实例
const colorStops = {
    stops: [
        [0, '#ffffcc'],
        [1, '#a1dab4'],
        [2, '#41b6c4'],
        [3, '#2c7fb8'],
        [4, '#ffffcc'],
        [5, '#253494'],
        [6, '#fed976'],
        [7, '#feb24c'],
        [8, '#fd8d3c'],
        [9, '#f03b20'],
        [10, '#bd0026'],
        [11, '#253494'],
        [12, '#ffffcc'],
    ],
    property: 'FID',
};
// 地图初始化
function init() {
    map = new mapboxgl.Map({
        container: 'map',
        style: {
            version: 8,
            sources: {
                cartodb: {
                    tiles: ['http://b.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png'],
                    tileSize: 256,
                    type: 'raster',
                },
            },
            layers: [
                {
                    id: 'cartodb',
                    type: 'raster',
                    source: 'cartodb',
                },
            ],
            glyphs: '../../lib/pbf/{fontstack}/{range}.pbf', //  地图字体文件
        },
        center: [114.44515001943142, 30.649477958235423],
        zoom: 8.3,
        pitch: 0,
    });
    // 地图加载
    map.on('load', () => {
        addStateLayer();
    });
}

// 聚合图层加载
function addClusterLayer(id, featureData) {
    map.addSource('clusters' + id, {
        type: 'geojson',
        data: featureData,
        cluster: true,
        clusterRadius: 50,
    });

    // 聚合图层
    map.addLayer({
        id: 'clusters' + id,
        type: 'circle',
        source: 'clusters' + id,
        filter: ['has', 'point_count'],
        paint: {
            'circle-color': ['step', ['get', 'point_count'], '#51bbd6', 4, '#f1f075', 7, '#f28cb1'],
            'circle-radius': ['step', ['get', 'point_count'], 20, 4, 30, 7, 40],
        },
    });

    // 聚合图层上的文字注记
    map.addLayer({
        id: 'cluster-count' + id,
        type: 'symbol',
        source: 'clusters' + id,
        filter: ['has', 'point_count'],
        layout: {
            'text-field': '{point_count_abbreviated}',
            'text-font': ['Open Sans Regular', 'Arial Unicode MS Regular'],
            'text-size': 12,
        },
    });

    // 单点图层
    map.addLayer({
        id: 'unclustered-point' + id,
        type: 'circle',
        source: 'clusters' + id,
        filter: ['!', ['has', 'point_count']],
        paint: {
            'circle-color': '#11b4da',
            'circle-radius': 4,
            'circle-stroke-width': 1,
            'circle-stroke-color': '#fff',
        },
    });
}

// 添加边界图层
function addStateLayer() {
    let noNameFeatures = [];
    noName.features.forEach((element) => {
        noNameFeatures.push({
            type: 'Feature',
            properties: element.attributes,
            geometry: {
                type: 'Polygon',
                coordinates: element.geometry.rings,
            },
        });
    });
    map.addSource('noName', {
        type: 'geojson',
        data: {
            type: 'FeatureCollection',
            features: noNameFeatures,
        },
    });
    map.addLayer({
        id: 'noName',
        source: 'noName',
        type: 'fill',
        paint: {
            'fill-color': colorStops,
            'fill-opacity': 0.5,
            'fill-outline-color': 'black',
        },
    });

    // 判断 每个面要素中的点要素 
    var ptsWithin = [];
    noNameFeatures.forEach((item) => {
        ptsWithin.push(turf.pointsWithinPolygon(randomPoints, item)); //  使用turf.js库
    });
    // console.log(ptsWithin); // 查看 处理后的点要素

    // 每组点要素分别添加聚合图层
    ptsWithin.forEach((item, index) => {
        addClusterLayer(index, item);
    });
}

init();

(4)可能存在的问题:1,图层过多的时候可能不方便管理;2,图层存在叠加,一定程度会导致用户误解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值