@vcmap/ui 5.0.0-rc.14 → 5.0.0-rc.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +33 -31
  2. package/build/build.js +9 -0
  3. package/build/buildHelpers.js +12 -10
  4. package/build/commonViteConfig.js +3 -10
  5. package/config/base.config.json +30 -24
  6. package/config/dev.config.json +13 -1
  7. package/config/www.config.json +104 -17
  8. package/dist/assets/cesium.430460.js +137226 -0
  9. package/dist/assets/cesium.js +1 -1
  10. package/dist/assets/core.5089ba.js +16024 -0
  11. package/dist/assets/core.js +1 -1
  12. package/dist/assets/index.854f8e2b.js +1 -0
  13. package/dist/assets/ol.9be53a.js +44279 -0
  14. package/dist/assets/ol.js +1 -1
  15. package/dist/assets/{ui.15ef6a.css → ui.49010a.css} +1 -1
  16. package/dist/assets/ui.49010a.js +16776 -0
  17. package/dist/assets/ui.js +1 -1
  18. package/dist/assets/vue.247c1c.js +4675 -0
  19. package/dist/assets/vue.js +5 -2
  20. package/dist/assets/{vuetify.202322.css → vuetify.735e58.css} +1 -1
  21. package/dist/assets/vuetify.735e58.js +21019 -0
  22. package/dist/assets/vuetify.js +5 -2
  23. package/dist/index.html +1 -1
  24. package/index.html +77 -0
  25. package/index.js +8 -1
  26. package/package.json +12 -10
  27. package/plugins/@vcmap/create-link/fallbackCreateLink.vue +4 -1
  28. package/plugins/@vcmap/create-link/index.js +4 -1
  29. package/plugins/@vcmap/pluginExample/exampleActions.js +45 -0
  30. package/plugins/@vcmap/pluginExample/index.js +38 -1
  31. package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +152 -98
  32. package/plugins/@vcmap/project-selector/ContextsListComponent.vue +8 -1
  33. package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +27 -1
  34. package/plugins/@vcmap/search-nominatim/LICENSE.md +14 -0
  35. package/plugins/@vcmap/search-nominatim/README.md +2 -0
  36. package/plugins/@vcmap/search-nominatim/config.json +4 -0
  37. package/plugins/@vcmap/search-nominatim/index.js +26 -0
  38. package/plugins/@vcmap/search-nominatim/nominatim.js +170 -0
  39. package/plugins/@vcmap/search-nominatim/package.json +43 -0
  40. package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +26 -0
  41. package/plugins/buttonExamples/ButtonExamples.vue +28 -1
  42. package/plugins/categoryTest/Categories.vue +16 -0
  43. package/plugins/categoryTest/Category.vue +30 -4
  44. package/plugins/example/mySuperComponent.vue +12 -1
  45. package/plugins/notifier/index.js +31 -0
  46. package/plugins/notifier/notifierTester.vue +88 -0
  47. package/plugins/package.json +2 -1
  48. package/plugins/simple-graph/SimpleGraphComponent.vue +5 -11
  49. package/plugins/test/allIconsComponent.vue +16 -0
  50. package/plugins/test/editor.vue +3 -0
  51. package/plugins/test/emptyComponent.vue +3 -0
  52. package/plugins/test/index.js +22 -0
  53. package/plugins/test/myCustomHeader.vue +9 -1
  54. package/plugins/test/testList.vue +287 -0
  55. package/plugins/test/vcsContent.vue +3 -0
  56. package/plugins/test/windowManagerExample.vue +3 -0
  57. package/plugins/wizardExample/index.js +41 -0
  58. package/plugins/wizardExample/wizardExample.vue +77 -0
  59. package/src/actions/actionHelper.js +103 -2
  60. package/src/actions/styleSelector.vue +9 -0
  61. package/src/application/VcsApp.vue +95 -17
  62. package/src/application/VcsAttributions.vue +63 -0
  63. package/src/application/VcsAttributionsFooter.vue +87 -0
  64. package/src/application/{Navbar.vue → VcsNavbar.vue} +35 -2
  65. package/src/application/VcsSettings.vue +4 -0
  66. package/src/application/attributionsHelper.js +150 -0
  67. package/src/application/vcsAppWrapper.vue +5 -1
  68. package/src/components/buttons/VcsActionButtonList.vue +8 -1
  69. package/src/components/buttons/VcsButton.vue +7 -1
  70. package/src/components/form-inputs-controls/VcsCheckbox.vue +7 -2
  71. package/src/components/form-inputs-controls/VcsColorPicker.vue +4 -0
  72. package/src/components/form-inputs-controls/VcsFormSection.vue +55 -9
  73. package/src/components/form-inputs-controls/VcsRadio.vue +7 -1
  74. package/src/components/form-inputs-controls/VcsSelect.vue +38 -2
  75. package/src/components/form-inputs-controls/VcsTextArea.vue +2 -0
  76. package/src/components/form-inputs-controls/VcsTextField.vue +16 -4
  77. package/src/components/form-inputs-controls/VcsWizard.vue +133 -0
  78. package/src/components/imageElementInjector.vue +22 -0
  79. package/src/components/lists/VcsActionList.vue +12 -1
  80. package/src/components/lists/VcsList.vue +466 -0
  81. package/src/components/lists/VcsTreeview.vue +7 -3
  82. package/src/components/lists/VcsTreeviewLeaf.vue +23 -51
  83. package/src/components/lists/VcsTreeviewSearchbar.vue +6 -23
  84. package/src/components/notification/VcsTooltip.vue +14 -9
  85. package/src/components/tables/VcsTable.vue +129 -38
  86. package/src/contentTree/LayerTree.vue +1 -1
  87. package/src/contentTree/contentTreeItem.js +13 -13
  88. package/src/contentTree/subContentTreeItem.js +1 -1
  89. package/src/contentTree/vcsObjectContentTreeItem.js +1 -1
  90. package/src/featureInfo/AddressBalloonComponent.vue +17 -1
  91. package/src/featureInfo/BalloonComponent.vue +63 -27
  92. package/src/featureInfo/balloonFeatureInfoView.js +14 -14
  93. package/src/featureInfo/balloonHelper.js +4 -0
  94. package/src/featureInfo/featureInfo.js +23 -2
  95. package/src/featureInfo/featureInfoInteraction.js +1 -1
  96. package/src/i18n/de.js +22 -0
  97. package/src/i18n/en.js +22 -0
  98. package/src/icons/+all.js +4 -0
  99. package/src/icons/WandIcon.vue +63 -0
  100. package/src/legend/legendHelper.js +18 -12
  101. package/src/legend/styleLegendItem.vue +20 -1
  102. package/src/legend/vcsLegend.vue +29 -3
  103. package/src/manager/toolbox/GroupToolboxComponent.vue +13 -1
  104. package/src/manager/toolbox/SelectToolboxComponent.vue +13 -1
  105. package/src/manager/toolbox/ToolboxManager.vue +3 -0
  106. package/src/manager/window/WindowComponent.vue +15 -2
  107. package/src/manager/window/WindowComponentHeader.vue +38 -7
  108. package/src/manager/window/WindowManager.vue +1 -0
  109. package/src/manager/window/windowManager.js +11 -1
  110. package/src/navigation/mapNavigation.vue +15 -36
  111. package/src/navigation/orientationToolsButton.vue +6 -1
  112. package/src/navigation/overviewMap.js +19 -47
  113. package/src/navigation/tiltSlider.vue +3 -0
  114. package/src/navigation/vcsCompass.vue +2 -0
  115. package/src/notifier/notifier.js +121 -0
  116. package/src/notifier/notifierComponent.vue +84 -0
  117. package/src/search/resultItem.vue +89 -0
  118. package/src/search/resultsComponent.vue +98 -0
  119. package/src/search/search.js +326 -0
  120. package/src/search/searchComponent.vue +90 -0
  121. package/src/styles/_typography.scss +3 -0
  122. package/src/styles/utils/_cursor.scss +4 -0
  123. package/src/styles/variables.scss +23 -4
  124. package/src/vcsUiApp.js +35 -1
  125. package/src/vuePlugins/vuetify.js +2 -0
  126. package/dist/assets/cesium.9489f8.js +0 -8699
  127. package/dist/assets/core.aa346a.js +0 -4
  128. package/dist/assets/index.3cd4fffa.js +0 -1
  129. package/dist/assets/ol.39651b.js +0 -439
  130. package/dist/assets/ui.15ef6a.js +0 -71
  131. package/dist/assets/vue.cbe9d8.js +0 -9
  132. package/dist/assets/vuetify.202322.js +0 -148
@@ -1,37 +1,19 @@
1
1
  <template>
2
2
  <v-form v-model="isValid">
3
3
  <VcsFormSection
4
- title="VcsFormSection"
5
- :title-actions="[
6
- {
7
- name: 'denseSelection',
8
- title: 'change row height',
9
- icon: dense ? 'mdi-arrow-split-horizontal' : 'mdi-arrow-collapse-vertical',
10
- callback: () => this.dense = !this.dense
11
- },
12
- { name: 'noIcon', title: 'another action without icon', callback: () => {} },
13
- {
14
- name: 'help',
15
- title: helpExample,
16
- icon: 'mdi-help-circle',
17
- callback: () => {},
18
- },
19
- {
20
- name: 'toggleSection',
21
- title: 'toggle section',
22
- icon: showSection ? '$vcsMinus' : '$vcsPlus',
23
- callback: () => this.showSection = !this.showSection
24
- },
25
- {
26
- name: 'toggleIcon',
27
- title: 'toggle switch example',
28
- icon: showSection ? 'mdi-toggle-switch' : 'mdi-toggle-switch-off',
29
- active: showSection,
30
- callback: () => this.showSection = !this.showSection
31
- },
32
- { name: 'alert', icon: 'mdi-message-text', callback: alertAction },
33
- ]"
4
+ heading="VcsFormSection Select & Text Inputs"
5
+ :header-actions="actions"
34
6
  >
7
+ <template #help>
8
+ <ol>
9
+ <li>{{ $t('pluginExample.help1') }}:</li>
10
+ <span>{{ $t('pluginExample.help1desc') }}</span>
11
+ <li>{{ $t('pluginExample.help2') }}:</li>
12
+ <span>{{ $t('pluginExample.help2desc') }}</span>
13
+ <li>{{ $t('pluginExample.help3') }}:</li>
14
+ <span>{{ $t('pluginExample.help3desc') }}</span>
15
+ </ol>
16
+ </template>
35
17
  <template #default v-if="showSection">
36
18
  <v-container class="pa-2">
37
19
  <v-row
@@ -107,6 +89,74 @@
107
89
  />
108
90
  </v-col>
109
91
  </v-row>
92
+ <v-row
93
+ :dense="dense"
94
+ no-gutters
95
+ align="center"
96
+ >
97
+ <v-col>
98
+ <VcsLabel html-for="emailInput" :dense="dense">
99
+ Email
100
+ </VcsLabel>
101
+ </v-col>
102
+ <v-col>
103
+ <VcsTextField
104
+ id="emailInput"
105
+ :dense="dense"
106
+ type="email"
107
+ :rules="[isValidEmail]"
108
+ v-model="state.email"
109
+ />
110
+ </v-col>
111
+ </v-row>
112
+ <v-row
113
+ :dense="dense"
114
+ no-gutters
115
+ align="center"
116
+ >
117
+ <v-col>
118
+ <VcsLabel html-for="prependedInput" :dense="dense">
119
+ String With Icon
120
+ </VcsLabel>
121
+ </v-col>
122
+ <v-col>
123
+ <VcsTextField
124
+ id="prependedInput"
125
+ :dense="dense"
126
+ prepend-icon="mdi-map-marker"
127
+ v-model="state.prependedInput"
128
+ />
129
+ </v-col>
130
+ </v-row>
131
+ <v-row
132
+ :dense="dense"
133
+ no-gutters
134
+ align="center"
135
+ >
136
+ <v-col>
137
+ <VcsLabel html-for="fileInput" :dense="dense">
138
+ Email
139
+ </VcsLabel>
140
+ </v-col>
141
+ <v-col>
142
+ <VcsTextField
143
+ id="fileInput"
144
+ :dense="dense"
145
+ type="file"
146
+ multiple
147
+ v-model="state.files"
148
+ />
149
+ </v-col>
150
+ </v-row>
151
+ </v-container>
152
+ </template>
153
+ </VcsFormSection>
154
+ <VcsFormSection
155
+ heading="VcsFormSection Number Inputs"
156
+ help-text="pluginExample.help"
157
+ >
158
+ <template #default>
159
+ <v-container>
110
160
  <v-row
111
161
  :dense="dense"
112
162
  no-gutters
@@ -199,58 +249,14 @@
199
249
  />
200
250
  </v-col>
201
251
  </v-row>
202
- <v-row
203
- :dense="dense"
204
- no-gutters
205
- align="center"
206
- >
207
- <v-col cols="1" class="px-1">
208
- <VcsLabel html-for="textInput" :dense="dense" class="text-caption">
209
- 1
210
- </VcsLabel>
211
- </v-col>
212
- <v-col>
213
- <VcsSelect
214
- :items="['A', 'B', 'C']"
215
- :dense="dense"
216
- />
217
- </v-col>
218
- <v-col>
219
- <VcsSelect
220
- :items="['A', 'B', 'C']"
221
- :dense="dense"
222
- multiple
223
- />
224
- </v-col>
225
- <v-col>
226
- <VcsTextField
227
- id="textInput"
228
- clearable
229
- :dense="dense"
230
- v-model="state.conditionalInput"
231
- />
232
- </v-col>
233
- </v-row>
234
- <v-row
235
- :dense="dense"
236
- no-gutters
237
- align="center"
238
- >
239
- <v-col>
240
- <VcsLabel html-for="emailInput" :dense="dense">
241
- Email
242
- </VcsLabel>
243
- </v-col>
244
- <v-col>
245
- <VcsTextField
246
- id="emailInput"
247
- :dense="dense"
248
- type="email"
249
- :rules="[isValidEmail]"
250
- v-model="state.email"
251
- />
252
- </v-col>
253
- </v-row>
252
+ </v-container>
253
+ </template>
254
+ </VcsFormSection>
255
+ <VcsFormSection
256
+ heading="VcsFormSection Radio & Checkbox"
257
+ >
258
+ <template #default>
259
+ <v-container>
254
260
  <v-row
255
261
  :dense="dense"
256
262
  no-gutters
@@ -296,6 +302,54 @@
296
302
  </v-container>
297
303
  </template>
298
304
  </vcsformsection>
305
+ <VcsFormSection
306
+ heading="VcsFormSection Mixed Inputs"
307
+ >
308
+ <template #default>
309
+ <v-container>
310
+ <v-row
311
+ :dense="dense"
312
+ align="center"
313
+ >
314
+ <v-col cols="1">
315
+ <VcsLabel html-for="textInput" :dense="dense" class="text-caption">
316
+ 1
317
+ </VcsLabel>
318
+ </v-col>
319
+ <v-col cols="3">
320
+ <VcsSelect
321
+ :items="[
322
+ {value: 'one', i18n: 'pluginExample.numbers.one'},
323
+ {value: 'two', i18n: 'pluginExample.numbers.two'},
324
+ {value: 'three', i18n: 'pluginExample.numbers.three'}]"
325
+ :item-text="item => item.i18n"
326
+ :dense="dense"
327
+ />
328
+ </v-col>
329
+ <v-col cols="3">
330
+ <VcsSelect
331
+ :items="[
332
+ {value: 'Anna', fullName: 'Annabella'},
333
+ {value: 'Bella', fullName: 'Belladonna'},
334
+ {value: 'Claudi', fullName: 'Claudine'}]"
335
+ :item-text="item => item.fullName"
336
+ :dense="dense"
337
+ multiple
338
+ v-model="state.selectedMultiple"
339
+ />
340
+ </v-col>
341
+ <v-col cols="5">
342
+ <VcsTextField
343
+ id="textInput"
344
+ clearable
345
+ :dense="dense"
346
+ v-model="state.conditionalInput"
347
+ />
348
+ </v-col>
349
+ </v-row>
350
+ </v-container>
351
+ </template>
352
+ </VcsFormSection>
299
353
  <VcsButton
300
354
  @click="logState(state)"
301
355
  :disabled="!isValid"
@@ -325,6 +379,7 @@
325
379
  VcsFormSection,
326
380
  VcsLabel,
327
381
  } from '@vcmap/ui';
382
+ import { VCol, VContainer, VForm, VRow } from 'vuetify/lib';
328
383
  import { isValidText, conditionalTest, isValidEmail } from './validation.js';
329
384
 
330
385
  export default {
@@ -338,11 +393,23 @@
338
393
  VcsFormattedNumber,
339
394
  VcsFormSection,
340
395
  VcsLabel,
396
+ VForm,
397
+ VRow,
398
+ VCol,
399
+ VContainer,
341
400
  },
342
401
  props: {
343
- windowId: {
344
- type: String,
345
- default: '',
402
+ actions: {
403
+ type: Array,
404
+ required: true,
405
+ },
406
+ dense: {
407
+ type: Object,
408
+ required: true,
409
+ },
410
+ showSection: {
411
+ type: Object,
412
+ required: true,
346
413
  },
347
414
  },
348
415
  setup() {
@@ -351,17 +418,7 @@
351
418
  const newUpdate = ref(true);
352
419
  watch(plugin.state, () => { newUpdate.value = true; });
353
420
 
354
- const helpExample = [
355
- 'Please select an option.',
356
- 'If Option A is chosen, input of ConditionalInput must be \'test\'.',
357
- 'InitialTextInput stays in loading state as long as the initial text is not changed.',
358
- 'VcsFormattedNumber rounds the NumberInput to one decimal digit.',
359
- ].join('\n');
360
-
361
421
  return {
362
- showSection: ref(true),
363
- dense: ref(true),
364
- helpExample,
365
422
  // no object-destruction of reactive objects! or use toRef()
366
423
  state: plugin.state,
367
424
  // do not put the whole config here, since it would become reactive
@@ -377,9 +434,6 @@
377
434
  console.log(plugin.getSerializedState());
378
435
  newUpdate.value = false;
379
436
  },
380
- alertAction() {
381
- alert('alert');
382
- },
383
437
  };
384
438
  },
385
439
  };
@@ -33,10 +33,17 @@
33
33
 
34
34
  <script>
35
35
  import { VcsTooltip } from '@vcmap/ui';
36
+ import { VChip, VContainer, VIcon, VList } from 'vuetify/lib';
36
37
 
37
38
  export default {
38
39
  name: 'ContextsListComponent',
39
- components: { VcsTooltip },
40
+ components: {
41
+ VcsTooltip,
42
+ VContainer,
43
+ VList,
44
+ VChip,
45
+ VIcon,
46
+ },
40
47
  props: {
41
48
  contexts: {
42
49
  type: Array,
@@ -47,11 +47,37 @@
47
47
  </template>
48
48
  <script>
49
49
  import { inject } from 'vue';
50
+ import {
51
+ VList,
52
+ VContainer,
53
+ VCard,
54
+ VIcon,
55
+ VListItem,
56
+ VListItemContent,
57
+ VListItemTitle,
58
+ VListItemSubtitle,
59
+ VListItemAction,
60
+ VAvatar,
61
+ VDivider,
62
+ } from 'vuetify/lib';
50
63
  import ContextsListComponent from './ContextsListComponent.vue';
51
64
 
52
65
  export default {
53
66
  name: 'ProjectSelector',
54
- components: { ContextsListComponent },
67
+ components: {
68
+ ContextsListComponent,
69
+ VList,
70
+ VContainer,
71
+ VCard,
72
+ VIcon,
73
+ VListItem,
74
+ VListItemContent,
75
+ VListItemTitle,
76
+ VListItemSubtitle,
77
+ VListItemAction,
78
+ VAvatar,
79
+ VDivider,
80
+ },
55
81
  setup() {
56
82
  const app = inject('vcsApp');
57
83
  const plugin = app.plugins.getByKey('@vcmap/project-selector');
@@ -0,0 +1,14 @@
1
+
2
+ Copyright 2022 support@vc.systems
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
5
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation
6
+ the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
7
+ and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
12
+ THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
13
+ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
14
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,2 @@
1
+ # @vcmap/search-nominatim
2
+ describe your plugin
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "@vcmap/search-nominatim",
3
+
4
+ }
@@ -0,0 +1,26 @@
1
+ import { version, name } from './package.json';
2
+ import Nominatim from './nominatim.js';
3
+
4
+
5
+ /**
6
+ * @param {NominatimSearchOptions} config - the configuration of this plugin instance, passed in from the app.
7
+ * @returns {import("@vcmap/ui/src/vcsUiApp").VcsPlugin<T>}
8
+ * @template {Object} T
9
+ * @template {Object} S
10
+ */
11
+ export default function SearchNominatim(config) {
12
+ return {
13
+ _instance: null,
14
+ _app: null,
15
+ get name() { return name; },
16
+ get version() { return version; },
17
+ /**
18
+ * @param {import("@vcmap/ui").VcsUiApp} vcsUiApp
19
+ */
20
+ initialize(vcsUiApp) {
21
+ this._instance = new Nominatim(config);
22
+ this._app = vcsUiApp;
23
+ vcsUiApp.search.add(this._instance, name);
24
+ },
25
+ };
26
+ }
@@ -0,0 +1,170 @@
1
+ import { Extent, parseGeoJSON, wgs84Projection } from '@vcmap/core';
2
+ import { AddressBalloonFeatureInfoView, featureInfoViewSymbol } from '@vcmap/ui';
3
+
4
+ /**
5
+ *
6
+ * @param {Object} item - response item from the search request
7
+ * @returns {ResultItem}
8
+ */
9
+ function createResultItem(item) {
10
+ const data = parseGeoJSON(item.geojson);
11
+ const feature = data.features[0];
12
+ feature.setProperties(item.address);
13
+ const title = item.display_name;
14
+ feature[featureInfoViewSymbol] = new AddressBalloonFeatureInfoView({
15
+ type: 'AddressBalloonFeatureInfoView',
16
+ name: 'NominatimSearchBalloon',
17
+ balloonSubtitle: '',
18
+ addressName: 'building',
19
+ street: 'road',
20
+ number: 'house_number',
21
+ city: 'city',
22
+ zip: 'postcode',
23
+ country: 'country',
24
+ });
25
+
26
+ return {
27
+ title,
28
+ feature,
29
+ };
30
+ }
31
+
32
+ /**
33
+ * @typedef {Object} NominatimSearchOptions
34
+ * @property {string} [name="Nominatim"]
35
+ * @property {string} [url="https://nominatim.openstreetmap.org/search"]
36
+ * @property {string|undefined} city
37
+ * @property {string|undefined} state
38
+ * @property {string|undefined} [countrycode="de"]
39
+ * @property {import("@vcmap/core").Extent.Options|undefined} extent
40
+ * @property {number|undefined} [limit=20]
41
+ * @api
42
+ */
43
+
44
+ /**
45
+ * @class
46
+ * @implements {SearchImpl}
47
+ */
48
+ class Nominatim {
49
+ /**
50
+ * @returns {NominatimSearchOptions}
51
+ */
52
+ static getDefaultOptions() {
53
+ return {
54
+ name: 'Nominatim',
55
+ url: 'https://nominatim.openstreetmap.org/search',
56
+ city: undefined,
57
+ state: undefined,
58
+ countrycode: 'de',
59
+ extent: undefined,
60
+ limit: 20,
61
+ };
62
+ }
63
+
64
+ /**
65
+ * @param {NominatimSearchOptions} options
66
+ */
67
+ constructor(options) {
68
+ /**
69
+ * @type {NominatimSearchOptions}
70
+ */
71
+ const defaultOptions = Nominatim.getDefaultOptions();
72
+
73
+ /** @type {string|null} */
74
+ this.name = options.name ?? defaultOptions.name;
75
+
76
+ /** @type {string|Object} */
77
+ this.url = options.url ?? defaultOptions.url;
78
+
79
+ /** @type {string|null} */
80
+ this.city = options.city ?? null;
81
+
82
+ /** @type {string|null} */
83
+ this.state = options.state ?? null;
84
+
85
+ /** @type {string} */
86
+ this.countrycode = options.countrycode ?? defaultOptions.countrycode;
87
+
88
+ /** @type {import("@vcmap/core").Extent|null} */
89
+ this.extent = options.extent ? new Extent(options.extent) : null;
90
+
91
+ /** @type {number} */
92
+ this.limit = options.limit ?? defaultOptions.limit;
93
+ /**
94
+ * @type {AbortController}
95
+ * @private
96
+ */
97
+ this._controller = new AbortController();
98
+ }
99
+
100
+ /**
101
+ * @param {string} q - search value
102
+ * @returns {Array<ResultItem>}
103
+ */
104
+ async search(q) {
105
+ const params = {
106
+ q,
107
+ countrycodes: this.countrycode,
108
+ format: 'json',
109
+ polygon_geojson: 1,
110
+ addressdetails: 1,
111
+ limit: this.limit,
112
+ };
113
+
114
+ if (this.city) {
115
+ params.q += `,${this.city}`;
116
+ }
117
+
118
+ if (this.state) {
119
+ params.q += `,${this.state}`;
120
+ }
121
+
122
+ if (this.extent) {
123
+ params.viewbox = this.extent.getCoordinatesInProjection(wgs84Projection).join(',');
124
+ params.bounded = 1;
125
+ }
126
+
127
+ const url = new URL(this.url);
128
+ url.search = new URLSearchParams(params).toString();
129
+
130
+ const { signal } = this._controller.signal;
131
+ const response = await fetch(url, { signal });
132
+ const results = await response.json();
133
+ return results.map(createResultItem);
134
+ }
135
+
136
+ abort() {
137
+ this._controller.abort();
138
+ }
139
+
140
+ toJSON() {
141
+ /**
142
+ * @type {NominatimSearchOptions}
143
+ */
144
+ const defaultOptions = Nominatim.getDefaultOptions();
145
+ const config = {};
146
+
147
+ if (this.url !== defaultOptions.url) {
148
+ config.url = this.url;
149
+ }
150
+ if (this.city !== defaultOptions.city) {
151
+ config.city = this.city;
152
+ }
153
+ if (this.state !== defaultOptions.state) {
154
+ config.state = this.state;
155
+ }
156
+ if (this.countrycode !== defaultOptions.countrycode) {
157
+ config.countrycode = this.countrycode;
158
+ }
159
+ if (this.extent && this.extent !== defaultOptions.extent) {
160
+ config.extent = this.extent.toJSON();
161
+ }
162
+ if (this.limit !== defaultOptions.limit) {
163
+ config.limit = this.limit;
164
+ }
165
+
166
+ return config;
167
+ }
168
+ }
169
+
170
+ export default Nominatim;
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@vcmap/search-nominatim",
3
+ "version": "1.0.0",
4
+ "description": "A search plugin for OSM Nominatim",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "prepublishOnly": "vcmplugin build",
8
+ "build": "vcmplugin build",
9
+ "pack": "vcmplugin pack",
10
+ "start": "vcmplugin serve",
11
+ "preview": "vcmplugin preview",
12
+ "buildStagingApp": "vcmplugin buildStagingApp",
13
+ "lint": "eslint \"{src,tests}/**/*.{js,vue}\""
14
+ },
15
+ "author": "support@vc.systems",
16
+ "license": "MIT",
17
+ "dependencies": {},
18
+ "peerDependencies": {
19
+ "@vcmap/core": "^5.0.0-rc.20"
20
+ },
21
+ "keywords": [
22
+ "vcmap",
23
+ "plugin"
24
+ ],
25
+ "files": [
26
+ "src/",
27
+ "dist/",
28
+ "plugin-assets/",
29
+ "LICENSE.md",
30
+ "README.md"
31
+ ],
32
+ "exports": {
33
+ ".": "./src/index.js",
34
+ "./dist": "./dist/index.js"
35
+ },
36
+ "eslintIgnore": [
37
+ "node_modules"
38
+ ],
39
+ "eslintConfig": {
40
+ "root": true,
41
+ "extends": "@vcsuite/eslint-config/vue"
42
+ }
43
+ }
@@ -65,9 +65,35 @@
65
65
  </template>
66
66
  <script>
67
67
  import { inject } from 'vue';
68
+ import {
69
+ VCard,
70
+ VCardText,
71
+ VChip,
72
+ VListItem,
73
+ VListItemContent,
74
+ VListItemTitle,
75
+ VListItemAction,
76
+ VAvatar,
77
+ VIcon,
78
+ VDivider,
79
+ VSwitch,
80
+ } from 'vuetify/lib';
68
81
 
69
82
  export default {
70
83
  name: 'ThemeChanger',
84
+ components: {
85
+ VCard,
86
+ VCardText,
87
+ VChip,
88
+ VListItem,
89
+ VListItemContent,
90
+ VListItemTitle,
91
+ VListItemAction,
92
+ VAvatar,
93
+ VIcon,
94
+ VDivider,
95
+ VSwitch,
96
+ },
71
97
  setup() {
72
98
  const app = inject('vcsApp');
73
99
  const plugin = app.plugins.getByKey('@vcmap/theme-changer');