如何解决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 举报,一经查实,本站将立刻删除。