Optionally add tag to place photo
This commit is contained in:
95
app/utils/poi-category-matcher.js
Normal file
95
app/utils/poi-category-matcher.js
Normal file
@@ -0,0 +1,95 @@
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user