MapComplete/src/Logic/Search/LayerSearch.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

61 lines
2 KiB
TypeScript
Raw Normal View History

import SearchUtils from "./SearchUtils"
import ThemeSearch from "./ThemeSearch"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import ThemeConfig from "../../Models/ThemeConfig/ThemeConfig"
import { Utils } from "../../Utils"
2024-09-11 01:46:55 +02:00
export default class LayerSearch {
private readonly _theme: ThemeConfig
2024-09-24 17:23:44 +02:00
private readonly _layerWhitelist: Set<string>
constructor(theme: ThemeConfig) {
this._theme = theme
2024-10-19 14:44:55 +02:00
this._layerWhitelist = new Set(theme.layers.filter((l) => l.isNormal()).map((l) => l.id))
2024-09-11 01:46:55 +02:00
}
2024-10-19 14:44:55 +02:00
static scoreLayers(
query: string,
options: {
whitelist?: Set<string>
blacklist?: Set<string>
}
): Record<string, number> {
const result: Record<string, number> = {}
2024-10-19 14:44:55 +02:00
const queryParts = query
.trim()
.split(" ")
.map((q) => Utils.simplifyStringForSearch(q))
for (const id in ThemeSearch.officialThemes.layers) {
2024-09-24 17:23:44 +02:00
if (options?.whitelist && !options?.whitelist.has(id)) {
continue
}
if (options?.blacklist?.has(id)) {
continue
}
const keywords = ThemeSearch.officialThemes.layers[id]
2024-10-19 14:44:55 +02:00
result[id] = Math.min(...queryParts.map((q) => SearchUtils.scoreKeywords(q, keywords)))
}
return result
2024-09-11 01:46:55 +02:00
}
2024-09-24 18:08:01 +02:00
public search(query: string, limit: number, scoreThreshold: number = 2): LayerConfig[] {
2024-09-11 01:46:55 +02:00
if (query.length < 1) {
return []
}
const scores = LayerSearch.scoreLayers(query, { whitelist: this._layerWhitelist })
2024-10-19 14:44:55 +02:00
const asList: { layer: LayerConfig; score: number }[] = []
2024-09-11 01:46:55 +02:00
for (const layer in scores) {
asList.push({
layer: this._theme.getLayer(layer),
2024-09-24 17:23:44 +02:00
score: scores[layer],
2024-09-11 01:46:55 +02:00
})
}
asList.sort((a, b) => a.score - b.score)
return asList
2024-10-19 14:44:55 +02:00
.filter((sorted) => sorted.score < scoreThreshold)
2024-09-11 01:46:55 +02:00
.slice(0, limit)
2024-10-19 14:44:55 +02:00
.map((l) => l.layer)
2024-09-11 01:46:55 +02:00
}
}