96 lines
2.5 KiB
JavaScript
96 lines
2.5 KiB
JavaScript
export function getMatchingPoiCategories(osmTags, categories) {
|
|
if (!Array.isArray(categories) || !osmTags) return [];
|
|
|
|
return categories.filter((category) => {
|
|
if (!Array.isArray(category.filter)) return false;
|
|
return category.filter.some((filterStr) =>
|
|
matchesFilter(osmTags, filterStr)
|
|
);
|
|
});
|
|
}
|
|
|
|
export function getMatchingPoiCategoryIds(osmTags, categories) {
|
|
return getMatchingPoiCategories(osmTags, categories).map((c) => c.id);
|
|
}
|
|
|
|
function matchesFilter(osmTags, filterStr) {
|
|
const clauses = parseOverpassClauses(filterStr);
|
|
if (clauses.length === 0) return false;
|
|
return clauses.every((clause) => matchesClause(osmTags, clause));
|
|
}
|
|
|
|
function parseOverpassClauses(filterStr) {
|
|
if (!filterStr) return [];
|
|
const matches = filterStr.match(/\[[^\]]+\]/g);
|
|
if (!matches) return [];
|
|
|
|
return matches
|
|
.map((raw) => parseClause(raw.slice(1, -1).trim()))
|
|
.filter(Boolean);
|
|
}
|
|
|
|
function parseClause(content) {
|
|
const presenceMatch = content.match(/^"([^"]+)"$/);
|
|
if (presenceMatch) {
|
|
return { type: 'presence', key: presenceMatch[1] };
|
|
}
|
|
|
|
const equalsMatch = content.match(/^"([^"]+)"\s*=\s*"([^"]*)"$/);
|
|
if (equalsMatch) {
|
|
return { type: 'equals', key: equalsMatch[1], value: equalsMatch[2] };
|
|
}
|
|
|
|
const regexMatch = content.match(/^"([^"]+)"\s*~\s*"([^"]*)"$/);
|
|
if (regexMatch) {
|
|
return {
|
|
type: 'regex',
|
|
key: regexMatch[1],
|
|
pattern: regexMatch[2],
|
|
regex: new RegExp(regexMatch[2]),
|
|
};
|
|
}
|
|
|
|
const notRegexMatch = content.match(/^"([^"]+)"\s*!~\s*"([^"]*)"$/);
|
|
if (notRegexMatch) {
|
|
return {
|
|
type: 'not-regex',
|
|
key: notRegexMatch[1],
|
|
pattern: notRegexMatch[2],
|
|
regex: new RegExp(notRegexMatch[2]),
|
|
};
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function matchesClause(osmTags, clause) {
|
|
const tagValues = getTagValues(osmTags, clause.key);
|
|
|
|
switch (clause.type) {
|
|
case 'presence':
|
|
return tagValues.length > 0;
|
|
case 'equals':
|
|
return tagValues.some((value) => value === clause.value);
|
|
case 'regex':
|
|
return tagValues.some((value) => clause.regex.test(value));
|
|
case 'not-regex':
|
|
return (
|
|
tagValues.length === 0 ||
|
|
!tagValues.some((value) => clause.regex.test(value))
|
|
);
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function getTagValues(osmTags, key) {
|
|
if (!osmTags || !key) return [];
|
|
const rawValue = osmTags[key];
|
|
if (rawValue === undefined || rawValue === null) return [];
|
|
|
|
return String(rawValue)
|
|
.split(';')
|
|
.map((value) => value.trim())
|
|
.filter(Boolean);
|
|
}
|