Skip to content

Commit 3033174

Browse files
committed
draft zoom/heat/style, restructure store actions
1 parent 6987535 commit 3033174

File tree

15 files changed

+385
-139
lines changed

15 files changed

+385
-139
lines changed

packages/clients/textLocator/TODO.md

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,8 @@
11
# TODO
22

3-
## MUSS
4-
5-
* Liste ermittelter Orte
6-
* Liste ermittelter Texte mit Ortsbezug
73
* Ortsbezüge eines Textes graphisch darstellen
8-
* Suchgeometrien: Rechtecke, Punkte
9-
* Suchgeometrien: Ortspolygone (Adresssuche?)
10-
* Kontextsuche: Filtern ermittelter Texte (???)
11-
* Relevanzbewertung von Ortsbezügen (UI nur Count?)
12-
13-
## SOLL
14-
15-
* Häufigkeit von Funden
16-
* Dataport-Geo-Design
17-
* Ortsbezüge von Texten als Ortsgebirge (?)
18-
* Zugriff auf weitere Geodaten (???)
19-
* Schreibweisen/Sprachen von Orten berücksichtigen
20-
* Historische Ortspolygone beachten
21-
* Suchgeometrien: Kreise, Vielecke
22-
* Ortssuche
23-
24-
## KANN
25-
26-
* 3D-Darstellung Ortsgebirge
27-
* Höhenlinien Ortsgebirge
28-
* Farbliche Markieren Ortsgebirge
4+
* Suchgeometrien: Ortspolygone (Ort => Alle bezüglichen Orte)
5+
* Schreibweisen/Sprachen von Orten berücksichtigen (=> Zusammenfassung in Übersicht?)
6+
* Historische Ortspolygone beachten (=> Zeitslot-Auswahl)
7+
* Ortsbezüge von Texten als Ortsgebirge (explorativ)
8+
* Mehrsprachigkeit (en/de)

packages/clients/textLocator/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"devDependencies": {
2222
"@polar/core": "^1.4.1",
2323
"@polar/lib-custom-types": "^1.4.1",
24+
"@polar/lib-tooltip": "^1.0.0",
2425
"@polar/plugin-address-search": "^1.2.1",
2526
"@polar/plugin-attributions": "^1.2.1",
2627
"@polar/plugin-draw": "1.1.0",

packages/clients/textLocator/src/plugins/GeometrySearch/components/GeometrySearch.vue

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,8 @@
5252
v-if="treeViewItems.length"
5353
dense
5454
hoverable
55-
activatable
5655
color="info"
5756
:items="treeViewItems"
58-
@update:active="changeActiveData"
5957
>
6058
<template #label="{ item }">
6159
<v-badge
@@ -68,6 +66,48 @@
6866
{{ item.name }}
6967
</v-badge>
7068
</template>
69+
<template #append="{ item }">
70+
<v-tooltip v-if="item.type === 'toponym' || item.children" left>
71+
<template #activator="{ on, attrs }">
72+
<!-- on single feature "Auf Fund zoomen", no heatmap -->
73+
<v-btn
74+
:aria-label="$t('plugins.geometrySearch.tooltip.highlight')"
75+
color="secondary"
76+
icon
77+
fab
78+
x-small
79+
dark
80+
v-bind="attrs"
81+
v-on="on"
82+
@click="changeActiveData(item)"
83+
@keypress="changeActiveData(item)"
84+
>
85+
<v-icon>fa-map-location-dot</v-icon>
86+
</v-btn>
87+
</template>
88+
<!-- TODO fix font -->
89+
<span>{{ $t('plugins.geometrySearch.tooltip.highlight') }}</span>
90+
</v-tooltip>
91+
<v-tooltip v-if="item.type === 'toponym'" left>
92+
<template #activator="{ on, attrs }">
93+
<v-btn
94+
:aria-label="$t('plugins.geometrySearch.tooltip.focusSearch')"
95+
color="secondary"
96+
icon
97+
fab
98+
x-small
99+
dark
100+
v-bind="attrs"
101+
v-on="on"
102+
@click="fullSearchOnToponym(item)"
103+
@keypress="fullSearchOnToponym(item)"
104+
>
105+
<v-icon>fa-magnifying-glass-arrow-right</v-icon>
106+
</v-btn>
107+
</template>
108+
<span>{{ $t('plugins.geometrySearch.tooltip.focusSearch') }}</span>
109+
</v-tooltip>
110+
</template>
71111
</v-treeview>
72112
<v-card-text v-else>
73113
{{ $t('common:plugins.geometrySearch.results.none') }}
@@ -112,7 +152,10 @@ export default Vue.extend({
112152
},
113153
methods: {
114154
...mapActions('plugin/draw', ['setDrawMode']),
115-
...mapActions('plugin/geometrySearch', ['changeActiveData']),
155+
...mapActions('plugin/geometrySearch', [
156+
'changeActiveData',
157+
'fullSearchOnToponym',
158+
]),
116159
...mapMutations('plugin/geometrySearch', ['setByCategory']),
117160
},
118161
})
@@ -149,6 +192,7 @@ export default Vue.extend({
149192
}
150193
151194
.text-locator-result-badge {
195+
cursor: pointer;
152196
max-width: 500px;
153197
width: 500px;
154198
white-space: normal;

packages/clients/textLocator/src/plugins/GeometrySearch/language.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ const language: LanguageOption[] = [
2323
Common: 'Neue Zeichnungen verwerfen vorangehende Ergebnisse.',
2424
},
2525
},
26+
tooltip: {
27+
title: 'Orte',
28+
highlight: 'Auf Funde zoomen und nach Relevanz färben',
29+
focusSearch: 'Neue Suche nach allen Geometrien zu dieser Geometrie',
30+
},
2631
results: {
2732
title: 'Funde',
2833
byLocation: 'Ort',
@@ -53,6 +58,11 @@ const language: LanguageOption[] = [
5358
Common: 'New drawings discard previous results.',
5459
},
5560
},
61+
tooltip: {
62+
title: 'Locations',
63+
highlight: 'Zoom to findings and colour by relevance',
64+
focusSearch: 'New search for all geometries to this geometry',
65+
},
5666
results: {
5767
title: 'Findings',
5868
byLocation: 'Place',
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { PolarActionHandler, PolarStore } from '@polar/lib-custom-types'
2+
import debounce from 'lodash.debounce'
3+
import { Feature } from 'ol'
4+
import VectorSource, { VectorSourceEvent } from 'ol/source/Vector'
5+
import { GeometrySearchGetters, GeometrySearchState } from '../../types'
6+
7+
let debouncedSearchGeometry: PolarActionHandler<
8+
GeometrySearchState,
9+
GeometrySearchGetters
10+
>
11+
12+
export function setupDrawReaction(
13+
this: PolarStore<GeometrySearchState, GeometrySearchGetters>,
14+
{ rootGetters, dispatch }
15+
) {
16+
// features added multiple times; avoid overly requesting
17+
debouncedSearchGeometry = debounce(
18+
(feature) => dispatch('searchGeometry', feature),
19+
20
20+
).bind(this)
21+
22+
// only keep a single feature in the draw tool
23+
const drawSource = rootGetters['plugin/draw/drawSource'] as VectorSource
24+
let lastFeature: Feature | undefined
25+
drawSource.on(['addfeature'], function (event) {
26+
const nextFeature = (event as VectorSourceEvent).feature
27+
if (nextFeature && lastFeature !== nextFeature) {
28+
lastFeature = nextFeature
29+
drawSource.clear()
30+
drawSource.addFeature(nextFeature)
31+
// @ts-expect-error | The function is bound and hence already has context.
32+
debouncedSearchGeometry(nextFeature)
33+
}
34+
})
35+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { Tooltip, getTooltip } from '@polar/lib-tooltip'
2+
import { Feature, Overlay } from 'ol'
3+
import { vectorLayer } from '../../utils/vectorDisplay'
4+
5+
export function setupTooltip({ rootGetters: { map } }) {
6+
let element: Tooltip['element'], unregister: Tooltip['unregister']
7+
const overlay = new Overlay({
8+
positioning: 'bottom-center',
9+
offset: [0, -5],
10+
})
11+
map.addOverlay(overlay)
12+
map.on('pointermove', ({ pixel, dragging, originalEvent }) => {
13+
if (dragging || ['touch', 'pen'].includes(originalEvent.pointerType)) {
14+
return
15+
}
16+
let hasFeatureAtPixel = false
17+
const localeKeys: [string, string][] = [
18+
['h2', 'plugins.geometrySearch.tooltip.title'],
19+
]
20+
// TODO do not list every name separately,
21+
map.forEachFeatureAtPixel(
22+
pixel,
23+
(feature) => {
24+
if (!(feature instanceof Feature)) {
25+
return false
26+
}
27+
if (!hasFeatureAtPixel) {
28+
hasFeatureAtPixel = true
29+
overlay.setPosition(map.getCoordinateFromPixel(pixel))
30+
}
31+
localeKeys.push([
32+
'ul',
33+
feature
34+
.get('names')
35+
.map((name) => `<li>${name.Name}</li>`)
36+
.join(''),
37+
])
38+
},
39+
{
40+
layerFilter: (layer) => layer === vectorLayer,
41+
}
42+
)
43+
if (!hasFeatureAtPixel) {
44+
overlay.setPosition(undefined)
45+
} else {
46+
unregister?.()
47+
;({ element, unregister } = getTooltip({ localeKeys }))
48+
overlay.setElement(element)
49+
return true
50+
}
51+
})
52+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { PolarStore } from '@polar/lib-custom-types'
2+
import { GeometrySearchGetters, GeometrySearchState } from '../../types'
3+
import { searchLiteratureByToponym } from '../../../../utils/literatureByToponym'
4+
5+
export function setupWatchers(
6+
this: PolarStore<GeometrySearchState, GeometrySearchGetters>,
7+
{ commit, dispatch, rootGetters }
8+
) {
9+
// load titleLocationFrequency on each featureCollection update
10+
this.watch(
11+
() => rootGetters['plugin/geometrySearch/featureCollection'],
12+
async (featureCollection) => {
13+
if (!featureCollection.features.length) {
14+
dispatch(
15+
'plugin/toast/addToast',
16+
{
17+
type: 'info',
18+
text: 'textLocator.info.noGeometriesFound',
19+
timeout: 10000,
20+
},
21+
{ root: true }
22+
)
23+
commit('setTitleLocationFrequency', {})
24+
return
25+
}
26+
const names: string[] = featureCollection.features
27+
.map((feature) => feature.properties?.names?.map((name) => name.Name))
28+
.flat(1)
29+
.filter((x) => x)
30+
const titleLocationFrequency = await searchLiteratureByToponym(
31+
rootGetters.configuration.textLocatorBackendUrl,
32+
names
33+
)
34+
commit('setTitleLocationFrequency', titleLocationFrequency)
35+
if (Object.keys(titleLocationFrequency).length) {
36+
dispatch('plugin/iconMenu/openMenuById', 'geometrySearch', {
37+
root: true,
38+
})
39+
} else {
40+
dispatch(
41+
'plugin/toast/addToast',
42+
{
43+
type: 'info',
44+
text: 'textLocator.info.noLiteratureFound',
45+
timeout: 10000,
46+
},
47+
{ root: true }
48+
)
49+
}
50+
dispatch('changeActiveData', null)
51+
}
52+
)
53+
}

0 commit comments

Comments
 (0)