forked from MapComplete/MapComplete
chore: automated housekeeping...
This commit is contained in:
parent
c9ce29f206
commit
40e894df8b
294 changed files with 14209 additions and 4192 deletions
|
@ -7,14 +7,14 @@ import { ImmutableStore, Store, Stores } from "../UIEventSource"
|
|||
import OpenStreetMapIdSearch from "./OpenStreetMapIdSearch"
|
||||
|
||||
type IntermediateResult = {
|
||||
feature: Feature,
|
||||
feature: Feature
|
||||
/**
|
||||
* Lon, lat
|
||||
*/
|
||||
center: [number, number],
|
||||
levehnsteinD: number,
|
||||
physicalDistance: number,
|
||||
searchTerms: string[],
|
||||
center: [number, number]
|
||||
levehnsteinD: number
|
||||
physicalDistance: number
|
||||
searchTerms: string[]
|
||||
description: string
|
||||
}
|
||||
export default class LocalElementSearch implements GeocodingProvider {
|
||||
|
@ -24,37 +24,50 @@ export default class LocalElementSearch implements GeocodingProvider {
|
|||
constructor(state: ThemeViewState, limit: number) {
|
||||
this._state = state
|
||||
this._limit = limit
|
||||
|
||||
}
|
||||
|
||||
async search(query: string, options?: GeocodingOptions): Promise<SearchResult[]> {
|
||||
return this.searchEntries(query, options, false).data
|
||||
}
|
||||
|
||||
private getPartialResult(query: string, candidateId: string | undefined, matchStart: boolean, centerpoint: [number, number], features: Feature[]): IntermediateResult[] {
|
||||
const results: IntermediateResult [] = []
|
||||
private getPartialResult(
|
||||
query: string,
|
||||
candidateId: string | undefined,
|
||||
matchStart: boolean,
|
||||
centerpoint: [number, number],
|
||||
features: Feature[]
|
||||
): IntermediateResult[] {
|
||||
const results: IntermediateResult[] = []
|
||||
|
||||
for (const feature of features) {
|
||||
const props = feature.properties
|
||||
const searchTerms: string[] = Utils.NoNull([props.name, props.alt_name, props.local_name,
|
||||
(props["addr:street"] && props["addr:number"]) ?
|
||||
props["addr:street"] + props["addr:number"] : undefined])
|
||||
const searchTerms: string[] = Utils.NoNull([
|
||||
props.name,
|
||||
props.alt_name,
|
||||
props.local_name,
|
||||
props["addr:street"] && props["addr:number"]
|
||||
? props["addr:street"] + props["addr:number"]
|
||||
: undefined,
|
||||
])
|
||||
|
||||
let levehnsteinD: number
|
||||
if (candidateId === props.id) {
|
||||
levehnsteinD = 0
|
||||
} else {
|
||||
levehnsteinD = Math.min(...searchTerms.flatMap(entry => entry.split(/ /)).map(entry => {
|
||||
let simplified = Utils.simplifyStringForSearch(entry)
|
||||
if (matchStart) {
|
||||
simplified = simplified.slice(0, query.length)
|
||||
}
|
||||
return Utils.levenshteinDistance(query, simplified)
|
||||
}))
|
||||
levehnsteinD = Math.min(
|
||||
...searchTerms
|
||||
.flatMap((entry) => entry.split(/ /))
|
||||
.map((entry) => {
|
||||
let simplified = Utils.simplifyStringForSearch(entry)
|
||||
if (matchStart) {
|
||||
simplified = simplified.slice(0, query.length)
|
||||
}
|
||||
return Utils.levenshteinDistance(query, simplified)
|
||||
})
|
||||
)
|
||||
}
|
||||
const center = GeoOperations.centerpointCoordinates(feature)
|
||||
if ((levehnsteinD / query.length) <= 0.3) {
|
||||
|
||||
if (levehnsteinD / query.length <= 0.3) {
|
||||
let description = ""
|
||||
if (feature.properties["addr:street"]) {
|
||||
description += "" + feature.properties["addr:street"]
|
||||
|
@ -75,7 +88,11 @@ export default class LocalElementSearch implements GeocodingProvider {
|
|||
return results
|
||||
}
|
||||
|
||||
searchEntries(query: string, options?: GeocodingOptions, matchStart?: boolean): Store<SearchResult[]> {
|
||||
searchEntries(
|
||||
query: string,
|
||||
options?: GeocodingOptions,
|
||||
matchStart?: boolean
|
||||
): Store<SearchResult[]> {
|
||||
if (query.length < 3) {
|
||||
return new ImmutableStore([])
|
||||
}
|
||||
|
@ -88,17 +105,26 @@ export default class LocalElementSearch implements GeocodingProvider {
|
|||
const partials: Store<IntermediateResult[]>[] = []
|
||||
|
||||
for (const [_, geoIndexedStore] of properties) {
|
||||
const partialResult = geoIndexedStore.features.map(features => this.getPartialResult(query, candidateId, matchStart, centerPoint, features))
|
||||
const partialResult = geoIndexedStore.features.map((features) =>
|
||||
this.getPartialResult(query, candidateId, matchStart, centerPoint, features)
|
||||
)
|
||||
partials.push(partialResult)
|
||||
}
|
||||
|
||||
const listed: Store<IntermediateResult[]> = Stores.concat(partials).map(l => l.flatMap(x => x))
|
||||
return listed.mapD(results => {
|
||||
results.sort((a, b) => (a.physicalDistance + a.levehnsteinD * 25) - (b.physicalDistance + b.levehnsteinD * 25))
|
||||
const listed: Store<IntermediateResult[]> = Stores.concat(partials).map((l) =>
|
||||
l.flatMap((x) => x)
|
||||
)
|
||||
return listed.mapD((results) => {
|
||||
results.sort(
|
||||
(a, b) =>
|
||||
a.physicalDistance +
|
||||
a.levehnsteinD * 25 -
|
||||
(b.physicalDistance + b.levehnsteinD * 25)
|
||||
)
|
||||
if (this._limit) {
|
||||
results = results.slice(0, this._limit)
|
||||
}
|
||||
return results.map(entry => {
|
||||
return results.map((entry) => {
|
||||
const [osm_type, osm_id] = entry.feature.properties.id.split("/")
|
||||
return <SearchResult>{
|
||||
lon: entry.center[0],
|
||||
|
@ -113,12 +139,9 @@ export default class LocalElementSearch implements GeocodingProvider {
|
|||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
suggest(query: string, options?: GeocodingOptions): Store<SearchResult[]> {
|
||||
return this.searchEntries(query, options, true)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue