Skip to content

Commit 793eb5b

Browse files
committed
add adressSearch to input fields
1 parent 460227e commit 793eb5b

File tree

5 files changed

+461
-136
lines changed

5 files changed

+461
-136
lines changed

packages/clients/snowbox/src/mapConfiguration.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ export const mapConfiguration = {
263263
},
264264
},
265265
routing: {
266-
serviceUrl: 'https://geodienste.hamburg.de/web_ors/v2/directions/',
266+
serviceUrl: 'https://geodienste.hamburg.de/web_ors//v2/directions/',
267267
format: 'geojson',
268268
selectableTravelModes: [
269269
'driving-car',
@@ -280,5 +280,20 @@ export const mapConfiguration = {
280280
width: 2,
281281
},
282282
},
283+
addressSearch: {
284+
searchMethods: [
285+
{
286+
queryParameters: {
287+
searchAddress: true,
288+
searchStreets: true,
289+
searchHouseNumbers: true,
290+
},
291+
type: 'mpapi',
292+
url: 'https://geodienste.hamburg.de/HH_WFS_GAGES?service=WFS&request=GetFeature&version=2.0.0',
293+
},
294+
],
295+
minLength: 3,
296+
waitMs: 300,
297+
},
283298
},
284299
}

packages/plugins/Routing/src/components/Routing.vue

Lines changed: 188 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,62 @@
22
<v-scroll-x-reverse-transition>
33
<v-card class="polar-routing-menu">
44
<v-card-title>{{ $t('common:plugins.routing.title') }} </v-card-title>
5-
<v-text-field
6-
v-model="startpointInput"
7-
:label="$t('common:plugins.routing.startLabel')"
8-
:hint="$t('common:plugins.routing.inputHint')"
9-
persistent-hint
10-
@input="sendSearchRequest"
11-
>
12-
</v-text-field>
13-
<v-text-field
14-
v-model="endpointInput"
15-
:label="$t('common:plugins.routing.endLabel')"
16-
>
17-
</v-text-field>
18-
<v-btn @click="resetCoordinates"
19-
>{{ $t('common:plugins.routing.resetButton') }}
5+
6+
<!-- Start Point Input with Dropdown -->
7+
<div style="position: relative">
8+
<v-text-field
9+
v-model="startpointInput"
10+
:label="$t('common:plugins.routing.startLabel')"
11+
@input="handleAddressSearch('start')"
12+
></v-text-field>
13+
<v-list
14+
v-if="startSearchResults.length && startDropdownOpen"
15+
class="dropdown"
16+
>
17+
<v-list-item
18+
v-for="(result, index) in startSearchResults"
19+
:key="index"
20+
@click="selectStart(result)"
21+
>
22+
<span>
23+
{{ result.strassenname }}
24+
<template v-if="result.hausnummer">
25+
{{ result.hausnummer }}</template
26+
>
27+
</span>
28+
</v-list-item>
29+
</v-list>
30+
</div>
31+
32+
<div style="position: relative">
33+
<v-text-field
34+
v-model="endpointInput"
35+
:label="$t('common:plugins.routing.endLabel')"
36+
@input="handleAddressSearch('end')"
37+
></v-text-field>
38+
<v-list
39+
v-if="endSearchResults.length && endDropdownOpen"
40+
class="dropdown"
41+
>
42+
<v-list-item
43+
v-for="(result, index) in endSearchResults"
44+
:key="index"
45+
@click="selectEnd(result)"
46+
>
47+
<span>
48+
{{ result.strassenname }}
49+
<template v-if="result.hausnummer">
50+
{{ result.hausnummer }}</template
51+
>
52+
</span>
53+
</v-list-item>
54+
</v-list>
55+
</div>
56+
57+
<v-btn @click="resetCoordinates">
58+
{{ $t('common:plugins.routing.resetButton') }}
2059
</v-btn>
60+
2161
<v-select
2262
v-model="selectedTravelModeItem"
2363
clearable
@@ -34,6 +74,7 @@
3474
item-value="key"
3575
item-text="translatedKey"
3676
></v-select>
77+
3778
<div>
3879
{{ $t('common:plugins.routing.avoidRoutesTitle') }}
3980
<v-layout row wrap>
@@ -48,10 +89,12 @@
4889
</v-flex>
4990
</v-layout>
5091
</div>
92+
5193
<v-btn @click="sendRequest">Send Request</v-btn>
5294
<v-btn @click="showSteps = !showSteps">
5395
{{ $t('common:plugins.routing.routeDetails') }}
5496
</v-btn>
97+
5598
<div v-if="showSteps">
5699
<v-list v-for="(step, i) in searchResponseSegments" :key="i">
57100
{{ step }}
@@ -64,58 +107,89 @@
64107
<script lang="ts">
65108
import Vue from 'vue'
66109
import { mapGetters, mapActions, mapMutations } from 'vuex'
110+
import debounce from 'lodash.debounce'
67111
68112
export default Vue.extend({
69113
name: 'RoutingPlugin',
70114
data: () => ({
71-
isOpen: false,
72-
// TODO: wieder rausnhemen, wenn es nicht funktioniert
73-
inline: null,
74115
showSteps: false,
116+
startDropdownOpen: false,
117+
endDropdownOpen: false,
75118
}),
76119
computed: {
77-
...mapGetters(['hasSmallDisplay']),
78120
...mapGetters('plugin/routing', [
79-
'renderType',
80-
'travelModeOptionsFromMapConfig',
81-
'preferenceOptionsFromMapConfig',
82121
'selectableTravelModes',
83122
'selectablePreferences',
84123
'selectableRouteTypesToAvoid',
85124
'selectedRouteTypesToAvoid',
86-
'searchResponseData',
125+
'searchResults',
87126
'start',
88127
'end',
128+
'startAddress',
129+
'endAddress',
130+
'waitMs',
89131
]),
90132
startpointInput: {
91-
get(): Coordinate {
92-
return this.start
133+
get() {
134+
return this.startAddress ? this.startAddress : this.start
93135
},
94-
set(value: Coordinate): void {
95-
this.start(value)
136+
set(value) {
137+
console.error('Setting startpointInput to:', value)
138+
this.setStart(value)
96139
},
97140
},
98141
endpointInput: {
99-
get(): Coordinate {
100-
return this.end
142+
get() {
143+
return this.endAddress ? this.endAddress : this.end
101144
},
102-
set(value: Coordinate): void {
103-
this.end(value)
145+
set(value) {
146+
this.setEnd(value)
104147
},
105148
},
149+
startSearchResults() {
150+
return this.searchResults
151+
.flatMap((result) => {
152+
const baseName = result.strassenname
153+
if (result.hausnummern && result.hausnummern.length > 0) {
154+
return result.hausnummern.map((hausnummer) => ({
155+
displayName: `${baseName} ${hausnummer}`,
156+
...result,
157+
hausnummer,
158+
}))
159+
}
160+
return [{ displayName: baseName, ...result }]
161+
})
162+
.slice(0, 20)
163+
},
164+
endSearchResults() {
165+
return this.searchResults
166+
.flatMap((result) => {
167+
const baseName = result.strassenname
168+
if (result.hausnummern && result.hausnummern.length > 0) {
169+
return result.hausnummern.map((hausnummer) => ({
170+
displayName: `${baseName} ${hausnummer}`,
171+
...result,
172+
hausnummer,
173+
}))
174+
}
175+
return [{ displayName: baseName, ...result }]
176+
})
177+
.slice(0, 20)
178+
},
179+
106180
selectedTravelModeItem: {
107-
get(): string {
181+
get() {
108182
return this.selectedTravelMode
109183
},
110-
set(value: string): void {
184+
set(value) {
111185
this.setSelectedTravelMode(value)
112186
},
113187
},
114188
selectedPreferenceItem: {
115-
get(): string {
189+
get() {
116190
return this.selectedPreference
117191
},
118-
set(value: string): void {
192+
set(value) {
119193
this.setSelectedPreference(value)
120194
},
121195
},
@@ -132,47 +206,98 @@ export default Vue.extend({
132206
}))
133207
},
134208
selectedRouteTypesToAvoidItem: {
135-
get(): string {
209+
get() {
136210
return this.selectedRouteTypesToAvoid
137211
},
138-
set(value: string): void {
212+
set(value) {
139213
this.setSelectedRouteTypesToAvoid(value)
140214
},
141215
},
142-
searchResponseSegments: {
143-
get(): object {
144-
return this.searchResponseData?.features[0].properties.segments[0].steps
145-
},
146-
},
147-
},
148-
watch: {
149-
search: function () {
150-
// TODO: prüfen, ob die Koordinaten im richtigen Format sind
151-
// TODO: Koordinaten an den Routingdienst übermitteln mit sendRequest() - zu vermeidende Routentypen mitsenden
152-
this.sendRequest()
216+
searchResponseSegments() {
217+
return this.searchResponseData?.features[0].properties.segments[0].steps
153218
},
154219
},
155220
mounted() {
156221
this.initializeTool()
157222
},
158223
methods: {
159224
...mapActions('plugin/routing', [
225+
'sendSearchRequest',
160226
'initializeTool',
161-
'resetCoordinates',
162227
'sendRequest',
163-
'sendSearchRequest',
164228
]),
165229
...mapMutations('plugin/routing', [
230+
'setStart',
231+
'setEnd',
166232
'setSelectedTravelMode',
167233
'setSelectedPreference',
168234
'setSelectedRouteTypesToAvoid',
169-
'setSearchResponseData',
235+
'setStartAddress',
236+
'setEndAddress',
170237
]),
171-
translatedRouteTypeToAvoid(myKey) {
172-
const localKey = this.selectableRouteTypesToAvoid.find(
173-
(element) => element.key === myKey
174-
).localKey
175-
return localKey
238+
debouncedSendSearchRequest: debounce(function (payload) {
239+
this.sendSearchRequest(payload)
240+
}, 300),
241+
handleAddressSearch(type) {
242+
const input = type === 'start' ? this.startpointInput : this.endpointInput
243+
244+
if (type === 'start') {
245+
this.startDropdownOpen = true
246+
this.endDropdownOpen = false
247+
} else if (type === 'end') {
248+
this.startDropdownOpen = false
249+
this.endDropdownOpen = true
250+
}
251+
252+
this.debouncedSendSearchRequest({ input, type })
253+
},
254+
toggleDropdown(type) {
255+
if (type === 'start') {
256+
this.startDropdownOpen = true
257+
this.endDropdownOpen = false
258+
} else if (type === 'end') {
259+
this.startDropdownOpen = false
260+
this.endDropdownOpen = true
261+
}
262+
},
263+
resetCoordinates() {
264+
this.setStart(null)
265+
this.setEnd(null)
266+
this.setStartAddress(null)
267+
this.setEndAddress(null)
268+
},
269+
selectStart(result) {
270+
if (result.strassenname) {
271+
this.startpointInput = result.displayName
272+
this.setStart(result.position)
273+
this.setStartAddress(result.displayName)
274+
this.startDropdownOpen = false
275+
this.$nextTick(() => {
276+
this.$store.commit('plugin/routing/setSearchResults', [])
277+
})
278+
} else {
279+
console.error('No street name available for selected result:', result)
280+
}
281+
},
282+
selectEnd(result) {
283+
if (result.strassenname) {
284+
this.endpointInput = result.displayName
285+
this.setEnd(result.position)
286+
this.setEndAddress(result.displayName)
287+
this.endDropdownOpen = false
288+
this.$nextTick(() => {
289+
this.$store.commit('plugin/routing/setSearchResults', [])
290+
})
291+
} else {
292+
console.error('No street name available for selected result:', result)
293+
}
294+
},
295+
296+
translatedRouteTypeToAvoid(key) {
297+
const routeType = this.selectableRouteTypesToAvoid.find(
298+
(type) => type.key === key
299+
)
300+
return routeType ? this.$t(routeType.localKey) : key
176301
},
177302
},
178303
})
@@ -188,4 +313,11 @@ export default Vue.extend({
188313
padding-left: 20px;
189314
padding-right: 20px;
190315
}
316+
317+
.dropdown {
318+
max-height: 300px; /* Passt die Höhe an */
319+
overflow-y: auto; /* Ermöglicht Scrollen */
320+
border: 1px solid #ccc;
321+
background-color: #fff;
322+
}
191323
</style>

0 commit comments

Comments
 (0)