【问题标题】:HexagonLayer - Get aggregated data or it's value boundsHexagonLayer - 获取聚合数据或其值范围
【发布时间】:2019-01-18 10:48:18
【问题描述】:

我正在构建 mapbox 和 deck.gl 应用程序,我想在运行时根据值范围过滤一些条形

我只想显示条形图,它的聚合值在某个范围内[min,max]

所以,我的简化问题是

在地图上绘制六边形后如何获取deck.gl hexagonLayer聚合条形数据?

那么,我可以正确计算出upperPercentilelowerPercentile,它们负责图形过滤...

var { MapboxLayer, HexagonLayer } = deck;

//Create the Mapbox map
var map = new mapboxgl.Map({
    container: document.body,
    style: 'mapbox://styles/mapbox/dark-v9?optimize=true',
    center: [-1.4157, 52.2324],
    zoom: 6,
    pitch: 40.5
});

// Get Data for visual
var DATA_URL = 'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv';

//Create the deck.gl hexagon layer and style for the data
var OPTIONS = ['radius', 'coverage', 'upperPercentile'];
var COLOR_RANGE = [
    [1, 152, 189],
    [73, 227, 206],
    [216, 254, 181],
    [254, 237, 177],
    [254, 173, 84],
    [209, 55, 78]
];
var LIGHT_SETTINGS = {
    lightsPosition: [-0.144528, 49.739968, 8000, -3.807751, 54.104682, 8000],
    ambientRatio: 0.4,
    diffuseRatio: 0.6,
    specularRatio: 0.2,
    lightsStrength: [0.8, 0.0, 0.8, 0.0],
    numberOfLights: 2
};
var hexagonLayer;


  map.on('style.load', () => {

hexagonLayer = new MapboxLayer({
    type: HexagonLayer,
    id: 'heatmap',
    data: d3.csv(DATA_URL),
    radius: 1000,
    coverage: 1,
    upperPercentile: 100,
    colorRange: COLOR_RANGE,
    elevationRange: [0, 1000],
    elevationScale: 250,
    extruded: true,
    getPosition: d => [Number(d.lng), Number(d.lat)],
    lightSettings: LIGHT_SETTINGS,
    opacity: 1
});

// Add the deck.gl hex layer below labels in the Mapbox map
map.addLayer(hexagonLayer, 'waterway-label');




// I WANT TO GET MINIMUM AND MAXIMUM VALUES FOR BARS HERE

<html>

<head>
    <title>Road AccidentsIncidents</title>
        <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
        <script src="https://unpkg.com/deck.gl@^6.2.0/deckgl.min.js"></script>
        <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.js"></script>
        <link rel="stylesheet" type="text/css" href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.css">
        <script src="https://d3js.org/d3.v5.min.js"></script>
        <style type="text/css">
        #map { position:absolute; top:0; bottom:0; width:100%; }
        body {
            font-family: Helvetica, Arial, sans-serif;
            width: 100vw;
            height: 100vh;
            margin: 0;
            padding: 0
        }

        #control-panel {
            position: absolute;
            background: #fff;
            top: 0;
            left: 0;
            margin: 12px;
            padding: 20px;
            font-size: 12px;
            line-height: 1.5;
            z-index: 1;
        }

        label {
            display: inline-block;
            width: 140px;
        }
        </style>
</head>

<body>
    <div id="control-panel">
        <div>
            <label>Radius</label>
            <input id="radius" type="range" min="500" max="10000" step="500" value="1000"></input>
            <span id="radius-value"></span>
        </div>
        <div>
            <label>Coverage</label>
            <input id="coverage" type="range" min="0" max="1" step="0.1" value="1"></input>
            <span id="coverage-value"></span>
        </div>
        <div>
            <label>Upper Percentile</label>
            <input id="upperPercentile" type="range" min="90" max="100" step="1" value="100"></input>
            <span id="upperPercentile-value"></span>
        </div>
    </div>
</body>
<script type="text/javascript">
mapboxgl.accessToken = 'pk.eyJ1IjoicnNiYXVtYW5uIiwiYSI6ImNqbjdsemZybzFtc3MzcnFvNXFucXQweTEifQ.2N_6Nd1rZG-I2pyA9I1xfA';

var { MapboxLayer, HexagonLayer } = deck;

//Create the Mapbox map
var map = new mapboxgl.Map({
    container: document.body,
    style: 'mapbox://styles/mapbox/dark-v9?optimize=true',
    center: [-1.4157, 52.2324],
    zoom: 6,
    pitch: 40.5
});

// Get Data for visual
var DATA_URL = 'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv';

//Create the deck.gl hexagon layer and style for the data
var OPTIONS = ['radius', 'coverage', 'upperPercentile'];
var COLOR_RANGE = [
    [1, 152, 189],
    [73, 227, 206],
    [216, 254, 181],
    [254, 237, 177],
    [254, 173, 84],
    [209, 55, 78]
];
var LIGHT_SETTINGS = {
    lightsPosition: [-0.144528, 49.739968, 8000, -3.807751, 54.104682, 8000],
    ambientRatio: 0.4,
    diffuseRatio: 0.6,
    specularRatio: 0.2,
    lightsStrength: [0.8, 0.0, 0.8, 0.0],
    numberOfLights: 2
};

var hexagonLayer;

//Add the deck.gl Custom Layer to the map once the Mapbox map loads
map.on('style.load', () => {

    hexagonLayer = new MapboxLayer({
        type: HexagonLayer,
        id: 'heatmap',
        data: d3.csv(DATA_URL),
        radius: 1000,
        coverage: 1,
        upperPercentile: 100,
        colorRange: COLOR_RANGE,
        elevationRange: [0, 1000],
        elevationScale: 250,
        extruded: true,
        getPosition: d => [Number(d.lng), Number(d.lat)],
        lightSettings: LIGHT_SETTINGS,
        opacity: 1
    });

    // Add the deck.gl hex layer below labels in the Mapbox map
    map.addLayer(hexagonLayer, 'waterway-label');
    
    
    
    
    // I WANT TO GET MINIMUM AND MAXIMUM VALUES FOR BARS HERE
    
});

// Add sliders to change the layer's settings based on user input
OPTIONS.forEach(key => {
    document.getElementById(key).onchange = (evt) => {
        var value = Number(evt.target.value);
        document.getElementById(key + '-value').innerHTML = value;
        if (hexagonLayer) {
            hexagonLayer.setProps({
                [key]: value });
        }
    };
});
</script>

</html>

【问题讨论】:

    标签: mapbox mapbox-gl-js deck.gl


    【解决方案1】:

    getColorValue 函数将为每个具有属于该集群的点的集群调用。你可以像这样修改这个函数:

    // other props
    
    // will be called num_cluster times
    getColorValue: (points) => {
      // points that belong to a particular cluster
      // do stuff with points
      return points.length;
    },
    
    // other props
    

    最后,您可以使用onSetColorDomain 回调(想想onClusteringComplete 回调)将值填充到您的html 中。这里的另一个好处是这个函数用[min, max]调用回调,所以如果它只是为了显示一个栏,你不必计算它们。

    我已更改您的示例以显示集群数以及最小值和最大值。

    <html>
    
    <head>
        <title>Road AccidentsIncidents</title>
            <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
            <script src="https://unpkg.com/deck.gl@^6.2.0/deckgl.min.js"></script>
            <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.js"></script>
            <link rel="stylesheet" type="text/css" href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.css">
            <script src="https://d3js.org/d3.v5.min.js"></script>
            <style type="text/css">
            #map { position:absolute; top:0; bottom:0; width:100%; }
            body {
                font-family: Helvetica, Arial, sans-serif;
                width: 100vw;
                height: 100vh;
                margin: 0;
                padding: 0
            }
    
            #control-panel {
                position: absolute;
                background: #fff;
                top: 0;
                left: 0;
                margin: 12px;
                padding: 20px;
                font-size: 12px;
                line-height: 1.5;
                z-index: 1;
            }
    
            label {
                display: inline-block;
                width: 140px;
            }
            </style>
    </head>
    
    <body>
        <div id="control-panel">
            <div>
                <label>Radius</label>
                <input id="radius" type="range" min="500" max="10000" step="500" value="1000"></input>
                <span id="radius-value"></span>
            </div>
            <div>
                <label>Coverage</label>
                <input id="coverage" type="range" min="0" max="1" step="0.1" value="1"></input>
                <span id="coverage-value"></span>
            </div>
            <div>
                <label>Upper Percentile</label>
                <input id="upperPercentile" type="range" min="90" max="100" step="1" value="100"></input>
                <span id="upperPercentile-value"></span>
            </div>
            <div>
              <div style="padding: 7px 0">
                <span>Total Clusters: </span>
                <span id="total-clusters-value">Loading</span>
              </div>
              <div>
                <span>[Min, Max]: </span>
                <span id="min-max-value">Loading</span>
              </div>
            </div>
        </div>
    </body>
    <script type="text/javascript">
    mapboxgl.accessToken = 'pk.eyJ1IjoicnNiYXVtYW5uIiwiYSI6ImNqbjdsemZybzFtc3MzcnFvNXFucXQweTEifQ.2N_6Nd1rZG-I2pyA9I1xfA';
    
    var { MapboxLayer, HexagonLayer } = deck;
    
    //Create the Mapbox map
    var map = new mapboxgl.Map({
        container: document.body,
        style: 'mapbox://styles/mapbox/dark-v9?optimize=true',
        center: [-1.4157, 52.2324],
        zoom: 6,
        pitch: 40.5
    });
    
    // Get Data for visual
    var DATA_URL = 'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv';
    
    //Create the deck.gl hexagon layer and style for the data
    var OPTIONS = ['radius', 'coverage', 'upperPercentile'];
    var COLOR_RANGE = [
        [1, 152, 189],
        [73, 227, 206],
        [216, 254, 181],
        [254, 237, 177],
        [254, 173, 84],
        [209, 55, 78]
    ];
    var LIGHT_SETTINGS = {
        lightsPosition: [-0.144528, 49.739968, 8000, -3.807751, 54.104682, 8000],
        ambientRatio: 0.4,
        diffuseRatio: 0.6,
        specularRatio: 0.2,
        lightsStrength: [0.8, 0.0, 0.8, 0.0],
        numberOfLights: 2
    };
    
    var hexagonLayer;
    
    let clusters = [];
    const minMax = document.getElementById('min-max' + '-value');
    const totalClusters = document.getElementById('total-clusters' + '-value');
    
    //Add the deck.gl Custom Layer to the map once the Mapbox map loads
    map.on('style.load', () => {
    
        hexagonLayer = new MapboxLayer({
            type: HexagonLayer,
            id: 'heatmap',
            data: d3.csv(DATA_URL),
            radius: 1000,
            coverage: 1,
            upperPercentile: 100,
            colorRange: COLOR_RANGE,
            elevationRange: [0, 1000],
            elevationScale: 250,
            extruded: true,
            getPosition: d => [Number(d.lng), Number(d.lat)],
            getColorValue: points => { clusters.push(points.length); return points.length; },
            onSetColorDomain: ([min, max]) => { minMax.innerHTML = `[${min}, ${max}]`; totalClusters.innerHTML = clusters.length; },
            lightSettings: LIGHT_SETTINGS,
            opacity: 1
        });
    
        // Add the deck.gl hex layer below labels in the Mapbox map
        map.addLayer(hexagonLayer, 'waterway-label');
        
        
        
        
        // I WANT TO GET MINIMUM AND MAXIMUM VALUES FOR BARS HERE
        
    });
    
    // Add sliders to change the layer's settings based on user input
    OPTIONS.forEach(key => {
        document.getElementById(key).onchange = (evt) => {
            clusters = [];
            var value = Number(evt.target.value);
            document.getElementById(key + '-value').innerHTML = value;
            if (hexagonLayer) {
                hexagonLayer.setProps({
                    [key]: value });
            }
        };
    });
    </script>
    
    </html>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-21
      • 2018-11-28
      • 2017-09-26
      • 2021-09-15
      • 2020-05-09
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多