Add search previews on the map

This commit is contained in:
Pieter Vander Vennet 2024-08-23 02:16:24 +02:00
parent 1c46a65c84
commit 4f52483a98
19 changed files with 315 additions and 87 deletions

View file

@ -0,0 +1,41 @@
import { GeoCodeResult } from "./GeocodingProvider"
import { Store } from "../UIEventSource"
import { FeatureSource } from "../FeatureSource/FeatureSource"
import { Feature, Geometry } from "geojson"
export default class GeocodingFeatureSource implements FeatureSource {
public features: Store<Feature<Geometry, Record<string, string>>[]>
constructor(provider: Store<GeoCodeResult[]>) {
this.features = provider.mapD(geocoded => {
const features: Feature[] = []
for (const gc of geocoded) {
if (gc.lat === undefined || gc.lon === undefined) {
continue
}
features.push({
type: "Feature",
properties: {
id: "search_result_" + gc.osm_type + "/" + gc.osm_id,
category: gc.category,
description: gc.description,
display_name: gc.display_name,
osm_id: gc.osm_type + "/" + gc.osm_id,
osm_key: gc.feature?.properties?.osm_key,
osm_value: gc.feature?.properties?.osm_value
},
geometry: {
type: "Point",
coordinates: [gc.lon, gc.lat]
}
})
}
return features
})
}
}

View file

@ -2,8 +2,10 @@ import { BBox } from "../BBox"
import { Feature, Geometry } from "geojson"
import { DefaultPinIcon } from "../../Models/Constants"
import { Store } from "../UIEventSource"
export type GeocodingCategory = "coordinate" | "city" | "house" | "street" | "locality" | "country" | "train_station" | "county" | "airport"
import * as search from "../../assets/generated/layers/search.json"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson"
export type GeocodingCategory = "coordinate" | "city" | "house" | "street" | "locality" | "country" | "train_station" | "county" | "airport" | "shop"
export type GeoCodeResult = {
/**
@ -66,6 +68,8 @@ export interface ReverseGeocodingProvider {
export class GeocodingUtils {
public static searchLayer= new LayerConfig(<LayerConfigJson> search, "search")
public static categoryToZoomLevel: Record<GeocodingCategory, number> = {
city: 12,
county: 10,
@ -75,7 +79,8 @@ export class GeocodingUtils {
locality: 14,
street: 15,
train_station: 14,
airport: 13
airport: 13,
shop:16
}
@ -89,7 +94,8 @@ export class GeocodingUtils {
street: "globe_alt",
train_station: "train",
county: "building_office_2",
airport: "airport"
airport: "airport",
shop: "building_storefront"
}

View file

@ -95,6 +95,9 @@ export default class PhotonSearch implements GeocodingProvider, ReverseGeocoding
private getCategory(entry: Feature) {
const p = entry.properties
if(p.osm_key === "shop"){
return "shop"
}
if (p.osm_value === "train_station" || p.osm_key === "railway") {
return "train_station"
}

View file

@ -12,10 +12,41 @@ export class RecentSearch {
public readonly seenThisSession: Store<GeoCodeResult[]>
constructor(state: { layout: LayoutConfig, osmConnection: OsmConnection, selectedElement: Store<Feature> }) {
// const prefs = state.osmConnection.preferencesHandler.GetLongPreference("previous-searches")
const prefs = state.osmConnection.preferencesHandler.GetLongPreference("previous-searches")
prefs.addCallbackAndRunD(prev => console.trace("Previous searches are:", prev))
prefs.set(null)
this._seenThisSession = new UIEventSource<GeoCodeResult[]>([])//UIEventSource.asObject<GeoCodeResult[]>(prefs, [])
this.seenThisSession = this._seenThisSession
prefs.addCallbackAndRunD(prefs => {
if(prefs === ""){
return
}
const simpleArr = <GeoCodeResult[]> JSON.parse(prefs)
if(simpleArr.length > 0){
this._seenThisSession.set(simpleArr)
return true
}
})
this.seenThisSession.stabilized(2500).addCallbackAndRunD(seen => {
const results= []
for (let i = 0; i < Math.min(3, seen.length); i++) {
const gc = seen[i]
const simple = {
category: gc.category,
description: gc.description,
display_name: gc.display_name,
lat: gc.lat, lon: gc.lon,
osm_id: gc.osm_id,
osm_type: gc.osm_type
}
results.push(simple)
}
console.log("Setting", results)
prefs.setData(JSON.stringify(results))
})
state.selectedElement.addCallbackAndRunD(selected => {
@ -23,6 +54,10 @@ export class RecentSearch {
if(!osm_id){
return
}
console.log("Selected element is", selected)
if(["node","way","relation"].indexOf(osm_type) < 0){
return
}
const [lon, lat] = GeoOperations.centerpointCoordinates(selected)
const entry = <GeoCodeResult>{
feature: selected,
@ -46,6 +81,7 @@ export class RecentSearch {
seenIds.add(id)
}
}
console.log(">>>",arr)
this._seenThisSession.set(arr)
}
}