Mapbox GL JS刷新层 [英] Mapbox GL JS refresh layer

查看:1114
本文介绍了Mapbox GL JS刷新层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Chroma.js来设置Mapbox等值区域的样式。我这样做是通过在变量 dataStyleProp 中存储源的一个属性 - 在这种情况下,数据是填充,属性是free,slave,白色和总数)。然后我使用 dataStyleProp 来构建Chroma.js色标。我想做的是:

I'm using Chroma.js to style a Mapbox choropleth map. I do this by storing in a variable dataStyleProp a single property of the source -- in this case the data are population and the properties are "free", "slave", "white", and "total"). Then I use dataStyleProp to build the Chroma.js color scale. What I would like to do is:


  1. 从a中选择 dataStyleProp 的值HTML页面上的单选按钮,

  2. 将该值传递给Chroma脚本,

  3. 然后刷新地图以显示新的等值线。

  1. Select the value for dataStyleProp from a radio button on the HTML page,
  2. Pass that value to the Chroma script,
  3. Then refresh the map to show the new choropleth.

我设法做了1.和2.但是不能让3.工作。我已经尝试 map.update map.resize 尝试强制刷新但不起作用。我还查看了 map.getSource(source).setData(data),但传递的数据必须是geojson和我的 dataStyleProp 是一个字符串。

I've managed to do 1. and 2. but can't get 3. to work. I've tried map.update and map.resize to try to force the refresh but neither works. I also looked at map.getSource(source).setData(data) but the data passed must be a geojson and my dataStyleProp is a string.

我考虑为每个 dataStyleProp 值创建一个新图层,但这意味着创建数百个额外的图层(每个源至少有4个不同的 dataStyleProp 值),我想尽可能避免创建所有这些额外的图层。

I considered creating a new layer for each dataStyleProp value, but that would mean creating hundreds of extra layers (each source has at least 4 different dataStyleProp values) and I'd like to avoid creating all those extra layers if possible.

如何刷新地图以显示新的 dataStyleProp 色阶?

How can I refresh the map to show the new dataStyleProp color scale?

HTML:

<div id="map"></div>
<div>
  <ul class="sidebar-list">
    <li id="dataInput"> 
      <div id="data1"></div>
      <div id="data2"></div>
      <div id="data3"></div>
      <div id="data4"></div>
      <div><button id="update">Update</button></div>
    </li>
  </ul>
</div>

JS:

mapboxgl.accessToken = "myaccesstoken";
var map = new mapboxgl.Map({
    container: "map",
    style: "mapbox://styles/mystyle",  
    center: [-100.04, 38.907],
    minZoom: 3
    });

function loadAll() {
  function getStates() {
    return fetch("data/1790_state_race.json").then(function(response) {
        return response.json();
        });
    }

  getStates().then(function(response) {
    states1790race = response;
    console.log(states1790race);
    });

all = $.when(states1790race); 

all.done(function() {  

    var vtMatchProp = "GISJOIN";
    var dataMatchProp = "GISJOIN";

    map.on("load", function () {
      map.addSource("states1790", {
            type: "vector",
            url: "mapbox://statessource"  
            });

      map.addSource("1790", {
            "type": "vector",
            "url": "mapbox://countiessource"
            });

      if (document.getElementsByName("dataInput").value === undefined) {
        var dataStyleProp = "TOTAL";
        }  
    var dataInput = document.getElementsByName("dataInput");
            $("#update").on("click", function() {
                    for (var i = 0; i < dataInput.length; i++) {
                            if (dataInput[i].checked) {
                                dataStyleProp = dataInput[i].value;
                                break;
                                }
                            }
                    console.log(dataStyleProp);

                    //refresh map layer here???

                    });

    var stops = [["0", "rgba(227,227,227,0)"]];
    var numbers1790 = states1790race.map(function(val) {
            return Number(val[dataStyleProp])
            });
    //chroma quantile scale
    var limits1790 = chroma.limits(numbers1790, 'q', 9);

    //chroma color scale
    var colorScale = chroma.scale(["#ffe8c6", "#915c0e"]).mode("lch").colors(10);

    var newData1790 = states1790race.map(function(state) {
        var color = "#e3e3e3";
        for (var i = 0; i < limits1790.length; i++) {
            if (state[dataStyleProp] <= limits1790[i]) {
              color = colorScale[i];
              break;
              }
            }
        var id = state[dataMatchProp];
        return [id, color]
    });

map.addLayer({
        "id": "1790states",
        "source": "states1790",
        "source-layer": "USA-states-1790",
        "type": "fill",
        "layout": { "visibility": "visible" }, 
            "paint": {
                "fill-color": {
                    "property": vtMatchProp,
                    "type": "categorical",
                    "stops": newData1790
                    }, 
                "fill-outline-color": "white",
                "fill-opacity": 1
                } 
            });  

});

map.on("click", function(e) {

        var features = map.queryRenderedFeatures(e.point, { layers: ["1790states", "1790counties" ] });
        map.getCanvas().style.cursor = (features.length) ? "pointer": "";

        var feature = features[0];


        if (feature.properties.COUNTY == undefined) {
            for (var i = 0; i < states1790race.length; i++) {
                if (feature.properties.GISJOIN == states1790race[i].GISJOIN) {
                    total = states1790race[i].TOTAL;
                    free = states1790race[i].FREE;
                    slave = states1790race[i].SLAVE;
                    white = states1790race[i].WHITE;
                    year = states1790race[i].YEAR;
                    document.getElementById("data1").innerHTML = "<input type='radio' checked name='dataInput' value='TOTAL'> Total State Population: " + addCommas(total);
                    document.getElementById("place").innerHTML = feature.properties.STATENAM;
                    }
                } 

            } else if 

             (feature.properties.COUNTY != undefined) {
            for (var j = 0; j < counties1790race.length; j++) {
                if (feature.properties.GISJOIN == counties1790race[j].GISJOIN) {
                    total = counties1790race[j].TOTAL;
                    free = counties1790race[j].FREE;
                    slave = counties1790race[j].SLAVE;
                    white = counties1790race[j].WHITE;
                    year = counties1790race[j].YEAR;
                    document.getElementById("data1").innerHTML = "<input type='radio' checked name='dataInput' value='TOTAL'> Total County Population: " + addCommas(total);
                    document.getElementById("place").innerHTML = feature.properties.NHGISNAM + " County, " + feature.properties.STATENAM;
                    }
                } 
            }

        if (feature.properties.STATENAM != undefined) {
            var buildings = map.querySourceFeatures(e.point);
            document.getElementById("data2").innerHTML = "<input type='radio' name='dataInput' value='FREE'> Free: " + addCommas(free);
            document.getElementById("data3").innerHTML = "<input type='radio' name='dataInput' value='SLAVE'> Slave: " + addCommas(slave);
            document.getElementById("data4").innerHTML = "<input type='radio' name='dataInput' value='WHITE'> White: " + addCommas(white);
            document.getElementById("timeline").innerHTML = "Population in " + year;
            }

    });

  });

}


推荐答案

我'我有点困惑你正在尝试做什么(我不知道Chroma是什么),但看起来你正试图以某种方式动态更新Mapbox托管的矢量图块源的属性。你不能这样做。

I'm a bit confused about what you're trying to do (I don't know what Chroma is), but it looks like you are trying to somehow dynamically update properties of a vector tile source hosted on Mapbox. You can't do this.

你基本上有两个动态数据可视化选项:

You basically have two options for a dynamic data visualisation:


  1. 在浏览器中生成GeoJSON,并调用 map.setData()显示它。

  2. 保留地图数据静态,但生成一个巨大的数据驱动属性来可视化它:如果状态名称= X,则将其绘制为淡粉色。如果状态名称= Y,则将其绘制为淡蓝色等。

  1. Generate a GeoJSON in the browser, and call map.setData() to display it.
  2. Keep the map data static, but generate a huge data-driven property to visualise it: "If state name = X, draw it pale pink. If state name = Y, draw it pale blue" etc.

如果你已经拥有了瓷砖组中的所有数据和所有地理位置,那么我不清楚你的问题是什么,或者为什么你有刷新它的麻烦。只需调用 setPaintProperty 甚至 setStyle 即可更新可视化。

If you already have all the data and all the geographies in the tileset, then I'm not clear on what your problem is, or why you have trouble "refreshing" it. Just call setPaintProperty or even setStyle to update the visualisation.

这篇关于Mapbox GL JS刷新层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆