MapComplete/src/UI/Search/GeocodeResult.svelte

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

128 lines
4.3 KiB
Svelte
Raw Normal View History

2024-08-26 13:09:46 +02:00
<script lang="ts">
2024-09-11 01:46:55 +02:00
import { GeocodingUtils } from "../../Logic/Search/GeocodingProvider"
import type { GeocodeResult } from "../../Logic/Search/GeocodingProvider"
2024-08-26 13:09:46 +02:00
import { GeoOperations } from "../../Logic/GeoOperations"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import { UIEventSource } from "../../Logic/UIEventSource"
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
import { createEventDispatcher } from "svelte"
import type { SpecialVisualizationState } from "../SpecialVisualization"
import { BBox } from "../../Logic/BBox"
import ToSvelte from "../Base/ToSvelte.svelte"
import Icon from "../Map/Icon.svelte"
import TagRenderingAnswer from "../Popup/TagRendering/TagRenderingAnswer.svelte"
import ArrowUp from "@babeard/svelte-heroicons/mini/ArrowUp"
import DefaultIcon from "../Map/DefaultIcon.svelte"
2024-08-26 13:09:46 +02:00
export let entry: GeocodeResult
export let state: SpecialVisualizationState
let layer: LayerConfig
let tags: UIEventSource<Record<string, string>>
let descriptionTr: TagRenderingConfig = undefined
if (entry.feature?.properties?.id) {
layer = state.theme.getMatchingLayer(entry.feature.properties)
2024-08-26 13:09:46 +02:00
tags = state.featureProperties.getStore(entry.feature.properties.id)
2024-10-19 14:44:55 +02:00
descriptionTr = layer?.tagRenderings?.find((tr) => tr.labels.indexOf("description") >= 0)
2024-08-26 13:09:46 +02:00
}
2024-10-19 14:44:55 +02:00
let distance = state.mapProperties.location.mapD((l) =>
GeoOperations.distanceBetween([l.lon, l.lat], [entry.lon, entry.lat])
)
let bearing = state.mapProperties.location.mapD((l) =>
GeoOperations.bearing([l.lon, l.lat], [entry.lon, entry.lat])
)
2024-08-26 13:09:46 +02:00
let mapRotation = state.mapProperties.rotation
2024-10-19 14:44:55 +02:00
let inView = state.mapProperties.bounds.mapD((bounds) => bounds.contains([entry.lon, entry.lat]))
2024-08-26 13:09:46 +02:00
function select() {
if (entry.boundingbox) {
const [lat0, lat1, lon0, lon1] = entry.boundingbox
state.mapProperties.bounds.set(
new BBox([
[lon0, lat0],
[lon1, lat1],
2024-10-19 14:44:55 +02:00
]).pad(0.01)
2024-08-26 13:09:46 +02:00
)
} else {
2024-10-19 14:44:55 +02:00
state.mapProperties.flyTo(
entry.lon,
entry.lat,
GeocodingUtils.categoryToZoomLevel[entry.category] ?? 17
)
2024-08-26 13:09:46 +02:00
}
if (entry.feature?.properties?.id) {
state.selectedElement.set(entry.feature)
}
state.userRelatedState.recentlyVisitedSearch.add(entry)
state.searchState.closeIfFullscreen()
2024-08-26 13:09:46 +02:00
}
</script>
2024-10-19 14:44:55 +02:00
<button class="unstyled link-no-underline searchresult w-full" on:click={() => select()}>
<div class="flex w-full items-center gap-y-2 p-2">
2024-08-26 13:09:46 +02:00
{#if layer}
2024-10-09 00:10:56 +02:00
<div class="h-6">
<DefaultIcon {layer} properties={entry.feature.properties} clss="w-6 h-6"/>
2024-10-09 00:10:56 +02:00
</div>
2024-08-26 13:09:46 +02:00
{:else if entry.category}
2024-10-19 14:44:55 +02:00
<Icon
icon={GeocodingUtils.categoryToIcon[entry.category]}
clss="w-6 h-6 shrink-0"
color="#aaa"
/>
2024-08-26 13:09:46 +02:00
{/if}
2024-10-19 14:44:55 +02:00
<div class="flex w-full flex-col items-start pl-2">
<div class="flex w-full flex-wrap justify-between gap-x-2">
2024-08-26 13:09:46 +02:00
<b class="nowrap">
{#if layer && $tags?.id}
2024-10-19 14:44:55 +02:00
<TagRenderingAnswer
config={layer.title}
selectedElement={entry.feature}
{state}
{tags}
{layer}
/>
2024-08-26 13:09:46 +02:00
{:else}
{entry.display_name ?? entry.osm_id}
{/if}
</b>
{#if $distance > 50}
2024-10-19 14:44:55 +02:00
<div class="flex items-center gap-x-1">
2024-08-26 13:09:46 +02:00
{#if $bearing && !$inView}
2024-10-19 14:44:55 +02:00
<ArrowUp
class="h-4 w-4 shrink-0"
style={`transform: rotate(${$bearing - $mapRotation}deg)`}
/>
2024-08-26 13:09:46 +02:00
{/if}
{#if $distance}
{GeoOperations.distanceToHuman($distance)}
{/if}
</div>
{/if}
</div>
<div class="flex flex-wrap gap-x-2">
{#if descriptionTr && tags}
2024-10-19 14:44:55 +02:00
<TagRenderingAnswer
defaultSize="subtle"
noIcons={true}
config={descriptionTr}
{tags}
{state}
selectedElement={entry.feature}
{layer}
/>
2024-08-26 13:09:46 +02:00
{/if}
{#if descriptionTr && tags && entry.description}
2024-08-26 13:09:46 +02:00
{/if}
{#if entry.description}
2024-10-19 14:44:55 +02:00
<div class="subtle flex w-full justify-between">
2024-08-26 13:09:46 +02:00
{entry.description}
</div>
{/if}
</div>
</div>
</div>
</button>