微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Mapbox - 过滤器相互覆盖

如何解决Mapbox - 过滤器相互覆盖

我正在根据此示例创建地图: https://labs.mapbox.com/education/impact-tools/finder-with-filters/

在他们的示例中,他们有两个下拉过滤器和一个复选框过滤器。我想要三个复选框过滤器。我创建了三个复选框过滤器,它们本身似乎运行良好。问题是过滤器似乎按照点击的顺序相互覆盖。在他们的示例中,过滤器似乎协同工作,所以当我更改过滤器类型时,我无法弄清楚为什么它不再起作用。

这是我的项目的代码https://codepen.io/flyinginsect2/pen/eYdyqxZ

以下是与过滤相关的代码片段:

const config = {
    style: "mapBox://styles/mapBox/light-v10",accesstoken: "pk.eyJ1IjoibGF1cmFqZWFudGhvcm5lIiwiYSI6ImNraXl5M29oMDEyMjgzM3BhNTh1MGc1NjkifQ.g4IAFIrXPpl3ricw3f_Onw",CSV: "https://docs.google.com/spreadsheets/d/106xm254us29hAUEtR7mTo0hwbDJv8dhyQs9rxY601Oc/gviz/tq?tqx=out:csv&sheet=Attributes",center: [-104.339,46.869],zoom: 2,title: "ENVIROLocity Mapper",description: "Environmental Networking,Volunteering,Internship,and R.... Opportunities",sideBarInfo: ["Org_name","CityState"],popupInfo: ["Org_name"],filters: [
        {
            type: "checkBox",title: "Sector: ",columnHeader: "Sector",listItems: ["Local Government","Nonprofit"]
        },{
            type: "checkBox",title: "Industry: ",columnHeader: "Industry_type",listItems: ["Conservation","Policy"]
        },title: "Internships: ",columnHeader: "internships_YN",listItems: ["Yes"]
        }
    ]

};

const selectFilters = [];
const checkBoxFilters = [];

function createFilterObject(filterSettings) {
    filterSettings.forEach(function (filter) {
        if (filter.type === 'checkBox') {
            columnHeader = filter.columnHeader;
            listItems = filter.listItems;

            const keyvalues = {};
            Object.assign(keyvalues,{ header: columnHeader,value: listItems });
            checkBoxFilters.push(keyvalues);
        }
        if (filter.type === 'dropdown') {
            columnHeader = filter.columnHeader;
            listItems = filter.listItems;

            const keyvalues = {};

            Object.assign(keyvalues,value: listItems });
            selectFilters.push(keyvalues);
        }
    });
}

function applyFilters() {
    const filterForm = document.getElementById('filters');

    filterForm.addEventListener('change',function () {
        const filterOptionHTML = this.getElementsByClassName('filter-option');
        const filterOption = [].slice.call(filterOptionHTML);

        const geojSelectFilters = [];
        const geojCheckBoxFilters = [];
        filteredFeatures = [];
        filteredGeojson.features = [];

        filterOption.forEach(function (filter) {
            if (filter.type === 'checkBox' && filter.checked) {
                checkBoxFilters.forEach(function (objs) {
                    Object.entries(objs).forEach(function ([key,value]) {
                        if (value.includes(filter.value)) {
                            const geojFilter = [objs.header,filter.value];
                            geojCheckBoxFilters.push(geojFilter);
                        }
                    });
                });
            }
            if (filter.type === 'select-one' && filter.value) {
                selectFilters.forEach(function (objs) {
                    Object.entries(objs).forEach(function ([key,filter.value];
                            geojSelectFilters.push(geojFilter);
                        }
                    });
                });
            }
        });

        if (geojCheckBoxFilters.length === 0 && geojSelectFilters.length === 0) {
            geojsonData.features.forEach(function (feature) {
                filteredGeojson.features.push(feature);
            });
        } else if (geojCheckBoxFilters.length > 0) {
            geojCheckBoxFilters.forEach(function (filter) {
                geojsonData.features.forEach(function (feature) {
                    if (feature.properties[filter[0]].includes(filter[1])) {
                        if (
                            filteredGeojson.features.filter(
                                (f) => f.properties.id === feature.properties.id
                            ).length === 0
                        ) {
                            filteredGeojson.features.push(feature);
                        }
                    }
                });
            });
            if (geojSelectFilters.length > 0) {
                const removeIds = [];
                filteredGeojson.features.forEach(function (feature) {
                    let selected = true;
                    geojSelectFilters.forEach(function (filter) {
                        if (
                            feature.properties[filter[0]].indexOf(filter[1]) < 0 &&
                            selected === true
                        ) {
                            selected = false;
                            removeIds.push(feature.properties.id);
                        } else if (selected === false) {
                            removeIds.push(feature.properties.id);
                        }
                    });
                });
                removeIds.forEach(function (id) {
                    const idx = filteredGeojson.features.findindex(
                        (f) => f.properties.id === id
                    );
                    filteredGeojson.features.splice(idx,1);
                });
            }
        } else {
            geojsonData.features.forEach(function (feature) {
                let selected = true;
                geojSelectFilters.forEach(function (filter) {
                    if (
                        !feature.properties[filter[0]].includes(filter[1]) &&
                        selected === true
                    ) {
                        selected = false;
                    }
                });
                if (
                    selected === true &&
                    filteredGeojson.features.filter(
                        (f) => f.properties.id === feature.properties.id
                    ).length === 0
                ) {
                    filteredGeojson.features.push(feature);
                }
            });
        }

        map.getSource('locationData').setData(filteredGeojson);
        buildLocationList(filteredGeojson);
    });
}

function filters(filterSettings) {
    filterSettings.forEach(function (filter) {
        if (filter.type === 'checkBox') {
            buildCheckBox(filter.title,filter.listItems);
        } else if (filter.type === 'dropdown') {
            buildDropDownList(filter.title,filter.listItems);
        }
    });
}

function removeFilters() {
    let input = document.getElementsByTagName('input');
    let select = document.getElementsByTagName('select');
    let selectOption = [].slice.call(select);
    let checkBoxOption = [].slice.call(input);
    filteredGeojson.features = [];
    checkBoxOption.forEach(function (checkBox) {
        if (checkBox.type == 'checkBox' && checkBox.checked == true) {
            checkBox.checked = false;
        }
    });

    selectOption.forEach(function (option) {
        option.selectedindex = 0;
    });

    map.getSource('locationData').setData(geojsonData);
    buildLocationList(geojsonData);
}

function removeFiltersButton() {
    const removeFilter = document.getElementById('removeFilters');
    removeFilter.addEventListener('click',function () {
        removeFilters();
    });
}

createFilterObject(config.filters);
applyFilters();
filters(config.filters);
removeFiltersButton();

我阅读了有关组合过滤器的 MapBox 文档,但我不知道如何使用它。 https://docs.mapbox.com/mapbox-gl-js/style-spec/other/#other-filter

我知道还有许多其他 Stack Exchange 帖子可以解决多个条件的过滤问题,但我找不到似乎解决这个特定问题的帖子。

解决方法

问题在于 "Local Government" 的值空间

如果您查看生成的 HTML,您会在 id 中看到一个空格,这是无效的 HTML

<input class="px12 filter-option" type="checkbox" id="Local Government" value="Local Government">

只需在构建 HTML id 属性时删除空格

input.setAttribute('id',listItems[i].replace(/\s/g,''));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。