tile-stencil
Version:
Load a MapLibre style document and parse it into Javascript functions
80 lines (73 loc) • 2.33 kB
JavaScript
export function buildFeatureFilter(filterObj) {
// filterObj is a filter definition following the 'deprecated' syntax:
// https://maplibre.org/maplibre-gl-js-docs/style-spec/other/#other-filter
if (!filterObj) return () => true;
const [type, ...vals] = filterObj;
// If this is a combined filter, the vals are themselves filter definitions
switch (type) {
case "all": {
const filters = vals.map(buildFeatureFilter); // Iteratively recursive!
return (d) => filters.every( filt => filt(d) );
}
case "any": {
const filters = vals.map(buildFeatureFilter);
return (d) => filters.some( filt => filt(d) );
}
case "none": {
const filters = vals.map(buildFeatureFilter);
return (d) => filters.every( filt => !filt(d) );
}
default:
return getSimpleFilter(filterObj);
}
}
function getSimpleFilter(filterObj) {
const [type, key, ...vals] = filterObj;
const getVal = initFeatureValGetter(key);
switch (type) {
// Existential Filters
case "has":
return d => !!getVal(d); // !! forces a Boolean return
case "!has":
return d => !getVal(d);
// Comparison Filters
case "==":
return d => getVal(d) === vals[0];
case "!=":
return d => getVal(d) !== vals[0];
case ">":
return d => getVal(d) > vals[0];
case ">=":
return d => getVal(d) >= vals[0];
case "<":
return d => getVal(d) < vals[0];
case "<=":
return d => getVal(d) <= vals[0];
// Set Membership Filters
case "in" :
return d => vals.includes( getVal(d) );
case "!in" :
return d => !vals.includes( getVal(d) );
default:
console.log("prepFilter: unknown filter type = " + filterObj[0]);
}
// No recognizable filter criteria. Return a filter that is always true
return () => true;
}
function initFeatureValGetter(key) {
switch (key) {
case "$type":
// NOTE: data includes MultiLineString, MultiPolygon, etc-NOT IN SPEC
return f => {
const t = f.geometry.type;
if (t === "MultiPoint") return "Point";
if (t === "MultiLineString") return "LineString";
if (t === "MultiPolygon") return "Polygon";
return t;
};
case "$id":
return f => f.id;
default:
return f => f.properties[key];
}
}