geonetwork-ui 2.10.3-dev.4154db07d → 2.11.0-dev.0559cfd9d

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 (128) hide show
  1. package/fesm2022/geonetwork-ui.mjs +2983 -2095
  2. package/fesm2022/geonetwork-ui.mjs.map +1 -1
  3. package/index.d.ts +408 -180
  4. package/index.d.ts.map +1 -1
  5. package/package.json +10 -8
  6. package/src/libs/api/metadata-converter/src/lib/dcat-ap/dcat-ap.converter.ts +2 -0
  7. package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +5 -5
  8. package/src/libs/api/metadata-converter/src/lib/fixtures/mel.records.dataset+featurecatalog.ts +395 -0
  9. package/src/libs/api/metadata-converter/src/lib/fixtures/metawal.records.ts +5 -5
  10. package/src/libs/api/metadata-converter/src/lib/gn4/gn4.field.mapper.ts +78 -21
  11. package/src/libs/api/metadata-converter/src/lib/gn4/types/elasticsearch.model.ts +13 -1
  12. package/src/libs/api/metadata-converter/src/lib/gn4/types/metadata.model.ts +19 -0
  13. package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +17 -6
  14. package/src/libs/api/metadata-converter/src/lib/iso19115-3/read-parts.ts +110 -0
  15. package/src/libs/api/metadata-converter/src/lib/iso19115-3/write-parts.ts +133 -2
  16. package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +9 -0
  17. package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +11 -6
  18. package/src/libs/api/metadata-converter/src/lib/iso19139/utils/association-type.mapper.ts +12 -0
  19. package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +2 -2
  20. package/src/libs/api/repository/src/lib/gn4/elasticsearch/elasticsearch.service.ts +157 -38
  21. package/src/libs/api/repository/src/lib/gn4/gn4-repository.ts +45 -50
  22. package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +54 -20
  23. package/src/libs/common/domain/src/lib/model/search/aggregation.model.ts +2 -0
  24. package/src/libs/common/domain/src/lib/model/search/filter.model.ts +24 -2
  25. package/src/libs/common/domain/src/lib/model/search/sort-by.model.ts +1 -5
  26. package/src/libs/common/domain/src/lib/repository/records-repository.interface.ts +3 -3
  27. package/src/libs/common/fixtures/src/lib/records.fixtures.ts +42 -62
  28. package/src/libs/feature/dataviz/src/lib/chart-view/chart-view.component.ts +3 -2
  29. package/src/libs/feature/dataviz/src/lib/geo-table-view/geo-table-view.component.ts +2 -1
  30. package/src/libs/feature/dataviz/src/lib/service/data.service.ts +54 -41
  31. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-associated-records/form-field-associated-records.component.html +33 -0
  32. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-associated-records/form-field-associated-records.component.ts +94 -0
  33. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field-temporal-extents/form-field-temporal-extents.component.html +16 -12
  34. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.html +6 -0
  35. package/src/libs/feature/editor/src/lib/components/record-form/form-field/form-field.component.ts +6 -0
  36. package/src/libs/feature/editor/src/lib/fields.config.ts +5 -0
  37. package/src/libs/feature/map/src/index.ts +0 -2
  38. package/src/libs/feature/map/src/lib/add-layer-from-file/add-layer-from-file.component.html +1 -0
  39. package/src/libs/feature/map/src/lib/feature-map.module.ts +1 -8
  40. package/src/libs/feature/notifications/src/lib/notifications.service.ts +6 -4
  41. package/src/libs/feature/notify-reuse/src/lib/notify-reuse-form/notify-reuse-form.component.ts +8 -3
  42. package/src/libs/feature/record/src/lib/state/mdview.actions.ts +4 -8
  43. package/src/libs/feature/record/src/lib/state/mdview.effects.ts +10 -17
  44. package/src/libs/feature/record/src/lib/state/mdview.facade.ts +2 -4
  45. package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +4 -9
  46. package/src/libs/feature/record/src/lib/state/mdview.selectors.ts +2 -7
  47. package/src/libs/feature/router/src/lib/default/router.service.ts +1 -1
  48. package/src/libs/feature/router/src/lib/default/state/query-params.utils.ts +1 -1
  49. package/src/libs/feature/search/src/index.ts +2 -0
  50. package/src/libs/feature/search/src/lib/filter-dropdown/filter-dropdown.component.html +18 -4
  51. package/src/libs/feature/search/src/lib/filter-dropdown/filter-dropdown.component.ts +80 -19
  52. package/src/libs/feature/search/src/lib/geocoding/geocoding.service.ts +105 -0
  53. package/src/libs/feature/search/src/lib/location-search/location-search.component.html +18 -0
  54. package/src/libs/feature/search/src/lib/location-search/location-search.component.ts +114 -0
  55. package/src/libs/feature/search/src/lib/search-filters-summary-item/search-filters-summary-item.component.ts +19 -8
  56. package/src/libs/feature/search/src/lib/sort-by/sort-by.component.ts +1 -1
  57. package/src/libs/feature/search/src/lib/state/reducer.ts +1 -4
  58. package/src/libs/feature/search/src/lib/utils/service/fields.service.ts +64 -4
  59. package/src/libs/feature/search/src/lib/utils/service/fields.ts +92 -9
  60. package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.html +6 -7
  61. package/src/libs/ui/dataviz/src/lib/data-table/data-table.component.ts +31 -19
  62. package/src/libs/ui/dataviz/src/lib/data-table/data-table.fixtures.ts +2 -2
  63. package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.html +3 -3
  64. package/src/libs/ui/elements/src/lib/record-feature-catalog/feature-catalog-list/feature-catalog-list.component.ts +2 -2
  65. package/src/libs/ui/elements/src/lib/service-capabilities/service-capabilities.component.ts +2 -1
  66. package/src/libs/ui/inputs/src/index.ts +2 -0
  67. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.css +0 -4
  68. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.html +12 -3
  69. package/src/libs/ui/inputs/src/lib/autocomplete/autocomplete.component.ts +11 -3
  70. package/src/libs/ui/inputs/src/lib/date-adapter.providers.ts +30 -0
  71. package/src/libs/ui/inputs/src/lib/date-picker/date-picker.component.ts +3 -24
  72. package/src/libs/ui/inputs/src/lib/date-range-dropdown/date-range-dropdown.component.css +37 -3
  73. package/src/libs/ui/inputs/src/lib/date-range-dropdown/date-range-dropdown.component.html +135 -16
  74. package/src/libs/ui/inputs/src/lib/date-range-dropdown/date-range-dropdown.component.ts +166 -29
  75. package/src/libs/ui/inputs/src/lib/date-range-picker/date-range-picker.component.ts +3 -7
  76. package/src/libs/ui/inputs/src/lib/drag-and-drop-file-input/drag-and-drop-file-input.component.css +1 -0
  77. package/src/libs/ui/inputs/src/lib/drag-and-drop-file-input/drag-and-drop-file-input.component.html +20 -7
  78. package/src/libs/ui/inputs/src/lib/drag-and-drop-file-input/drag-and-drop-file-input.component.ts +46 -5
  79. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.html +7 -4
  80. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.component.ts +12 -9
  81. package/src/libs/ui/inputs/src/lib/dropdown-multiselect/dropdown-multiselect.model.ts +2 -2
  82. package/src/libs/ui/inputs/src/lib/search-feature-catalog/search-feature-catalog.component.ts +2 -1
  83. package/src/libs/ui/inputs/src/lib/spatial-extent-dropdown/spatial-extent-dropdown.component.css +0 -0
  84. package/src/libs/ui/inputs/src/lib/spatial-extent-dropdown/spatial-extent-dropdown.component.html +117 -0
  85. package/src/libs/ui/inputs/src/lib/spatial-extent-dropdown/spatial-extent-dropdown.component.ts +244 -0
  86. package/src/libs/ui/layout/src/lib/block-list/block-list.component.css +1 -0
  87. package/src/libs/util/app-config/src/lib/app-config.ts +37 -0
  88. package/src/libs/util/app-config/src/lib/fixtures.ts +37 -1
  89. package/src/libs/util/app-config/src/lib/model.ts +25 -1
  90. package/src/libs/util/data-fetcher/src/lib/data-fetcher.ts +19 -22
  91. package/src/libs/util/data-fetcher/src/lib/engine/duckdb.ts +185 -0
  92. package/src/libs/util/data-fetcher/src/lib/engine/results.ts +63 -0
  93. package/src/libs/util/data-fetcher/src/lib/{sql-utils.ts → engine/sql-utils.ts} +28 -13
  94. package/src/libs/util/data-fetcher/src/lib/model.ts +2 -1
  95. package/src/libs/util/data-fetcher/src/lib/readers/base-file.ts +53 -38
  96. package/src/libs/util/data-fetcher/src/lib/readers/base.ts +11 -0
  97. package/src/libs/util/data-fetcher/src/lib/readers/csv.ts +9 -47
  98. package/src/libs/util/data-fetcher/src/lib/readers/excel.ts +27 -27
  99. package/src/libs/util/data-fetcher/src/lib/readers/geojson.ts +5 -24
  100. package/src/libs/util/data-fetcher/src/lib/readers/gml.ts +5 -49
  101. package/src/libs/util/data-fetcher/src/lib/readers/json.ts +5 -23
  102. package/src/libs/util/data-fetcher/src/lib/readers/wfs.ts +184 -128
  103. package/src/libs/util/data-fetcher/src/lib/utils.ts +0 -143
  104. package/src/libs/util/shared/src/index.ts +1 -0
  105. package/src/libs/util/shared/src/lib/autofocus.directive.ts +26 -0
  106. package/src/libs/util/shared/src/lib/gn-ui-version.ts +1 -1
  107. package/src/libs/util/shared/src/lib/links/link-utils.ts +19 -10
  108. package/src/libs/util/shared/src/lib/services/date.service.ts +3 -3
  109. package/src/libs/util/shared/src/lib/utils/file.ts +15 -0
  110. package/src/libs/util/shared/src/lib/utils/geojson.ts +24 -0
  111. package/src/libs/util/shared/src/lib/utils/index.ts +1 -0
  112. package/tailwind.base.css +5 -0
  113. package/translations/de.json +38 -5
  114. package/translations/en.json +37 -4
  115. package/translations/es.json +35 -2
  116. package/translations/fr.json +42 -9
  117. package/translations/it.json +36 -3
  118. package/translations/nl.json +35 -2
  119. package/translations/pt.json +35 -2
  120. package/translations/sk.json +36 -3
  121. package/src/libs/feature/map/src/lib/geocoding/geocoding.component.html +0 -41
  122. package/src/libs/feature/map/src/lib/geocoding/geocoding.component.ts +0 -112
  123. package/src/libs/feature/map/src/lib/geocoding.service.ts +0 -57
  124. package/src/libs/feature/map/src/lib/style/index.ts +0 -2
  125. package/src/libs/feature/map/src/lib/style/map-style.fixtures.ts +0 -47
  126. package/src/libs/feature/map/src/lib/style/map-style.service.ts +0 -108
  127. package/src/libs/util/data-fetcher/src/lib/readers/base-cache.ts +0 -14
  128. /package/src/libs/feature/{map/src/lib/geocoding/geocoding.component.css → editor/src/lib/components/record-form/form-field/form-field-associated-records/form-field-associated-records.component.css} +0 -0
@@ -0,0 +1,395 @@
1
+ import { DatasetRecord } from '../../../../../../libs/common/domain/src/lib/model/record'
2
+
3
+ export const MEL_FEATURECATALOG_DATASET_RECORD: DatasetRecord = {
4
+ uniqueIdentifier: '1f7c8d9f-3363-4512-ad3a-064fb6b851bc',
5
+ kind: 'dataset',
6
+ otherLanguages: [],
7
+ defaultLanguage: 'fr',
8
+ recordCreated: new Date('2025-11-04T15:47:22Z'),
9
+ recordUpdated: new Date('2026-10-05T08:40:46.464848Z'),
10
+ resourceCreated: new Date('2023-10-27T00:00:00'),
11
+ resourcePublished: new Date('2025-11-04'),
12
+ title: 'Schéma cyclable 2035 - liaisons - Plan de mobilité',
13
+ abstract:
14
+ 'L\'action n°35 du Plan de Mobilité de la Métropole Européenne de Lille présente le schéma cyclable métropolitain à horizon 2035. \n\nLa donnée proposée ici décrit la déclinaison en trois niveaux hiérarchiques des axes du schéma cyclable : \n- **le réseau Vélo+** pour la desserte des grandes destinations métropolitaines, \n- **le réseau intercommunal métropolitain** pour la desserte des pôles générateurs principaux, \n- **le réseau cyclable de proximité** qui assure la diffusion fine et permet de faire le lien avec les générateurs de trafic et les cœurs de quartiers. \n \n### Détail\nLes entités disposant du code INSEE "0000" sont situées en-dehors du périmètre MEL.\n \n### Donnée associée à consulter : \n*Schéma cyclable 2035 - points durs - Plan de mobilité - MEL - 2023-2035*\n \n### Contexte\nLe schéma directeur cyclable métropolitain 2035 s’ancre sur le schéma Métropole Cyclable 2020. Il en propose une vision renforcée. Il est le fruit d’une réflexion territorialisée dont l’objectif est de proposer un réseau intercommunal adapté à la géographie des territoires et aux pratiques cyclables qui ne sont pas les même en ville et à la campagne. \n\n- En milieu rural, les liaisons proposées permettront de relier les bourgs et les villages tout en organisant le rabattement vers les stations de transport collectif majeures : gares et terminus métro. Elles permettront d’accéder aux grands ensembles scolaires et zones d’emploi. Elles porteront également les déplacements longues distances vers les zones urbaines denses. \n- En zone urbaine, les liaisons inscrites au réseau intercommunal porteront les déplacements intercommunaux et inter-quartiers. Ce réseau s’articule avec le réseau de transport collectif urbain et s’appuie sur la hiérarchisation des voies. \n\n - Il permettra de desservir la totalité des communes de la Métropole Européenne de Lille. \n - Il assurera aussi une desserte directe de 90 % de la population, 94 % des emplois et 93 % des effectifs scolaires projetés à horizon 2035.\n\n### Le Schéma Directeur Cyclable Métropolitain\nLe schéma directeur cyclable métropolitain 2035 s’appuie en premier lieu sur un diagnostic complet ayant permis de mettre en lumière de nouveaux enjeux sur le territoire, notamment en regard des développements projetés et des évolutions comportementales à l’œuvre. \n \nCe nouveau schéma directeur est aussi et surtout le fruit d’une concertation avec les communes de la Métropole Européenne de Lille et d’une collaboration technique active de l’association droit au vélo. Il a été construit en interface avec les territoires limitrophes. \n \nSa compatibilité avec les nouvelles lignes de transports en site propre et le schéma cible des véloroutes et voies vertes a été considérée.',
15
+ ownerOrganization: {
16
+ name: 'Métropole Européenne de Lille',
17
+ translations: {},
18
+ },
19
+ contacts: [
20
+ {
21
+ email: 'opendata@lillemetropole.fr',
22
+ address: '2, boulevard des Cités Unies, Lille, 59040',
23
+ organization: {
24
+ name: 'Métropole Européenne de Lille',
25
+ translations: {},
26
+ },
27
+ role: 'point_of_contact',
28
+ },
29
+ ],
30
+ contactsForResource: [
31
+ {
32
+ email: 'opendata@lillemetropole.fr',
33
+ address: '2, boulevard des Cités Unies, Lille, 59040',
34
+ organization: {
35
+ name: 'Métropole Européenne de Lille',
36
+ translations: {},
37
+ },
38
+ role: 'originator',
39
+ },
40
+ {
41
+ email: 'opendata@lillemetropole.fr',
42
+ address: '2, boulevard des Cités Unies, Lille, 59040',
43
+ organization: {
44
+ name: 'Métropole Européenne de Lille',
45
+ translations: {},
46
+ },
47
+ role: 'distributor',
48
+ },
49
+ {
50
+ email: 'datamobilite@lillemetropole.fr, mfontaine@lillemetropole.fr',
51
+ address: '2, boulevard des Cités Unies, Lille, 59040',
52
+ organization: {
53
+ name: 'Métropole Européenne de Lille',
54
+ translations: {},
55
+ },
56
+ role: 'point_of_contact',
57
+ },
58
+ ],
59
+ keywords: [
60
+ {
61
+ thesaurus: {
62
+ id: 'geonetwork.thesaurus.local.place.mel',
63
+ name: 'Territoires MEL',
64
+ url: new URL(
65
+ 'https://data.lillemetropole.fr/geonetwork/srv/api/registries/vocabularies/local.place.mel'
66
+ ),
67
+ },
68
+ label: 'Métropole Européenne de Lille',
69
+ type: 'place',
70
+ translations: {},
71
+ },
72
+ {
73
+ thesaurus: {
74
+ id: 'geonetwork.thesaurus.external.theme.httpinspireeceuropaeutheme-theme',
75
+ name: 'GEMET - INSPIRE themes, version 1.0',
76
+ url: new URL(
77
+ 'http://localhost:8080/geonetwork/srv/api/registries/vocabularies/external.theme.httpinspireeceuropaeutheme-theme'
78
+ ),
79
+ },
80
+ label: '',
81
+ type: 'theme',
82
+ translations: {},
83
+ },
84
+ {
85
+ thesaurus: {
86
+ id: 'geonetwork.thesaurus.external.theme.gemet',
87
+ name: 'GEMET',
88
+ url: new URL(
89
+ 'https://data.lillemetropole.fr/geonetwork/srv/api/registries/vocabularies/external.theme.gemet'
90
+ ),
91
+ },
92
+ label: '',
93
+ type: 'theme',
94
+ translations: {},
95
+ },
96
+ {
97
+ thesaurus: {
98
+ id: 'geonetwork.thesaurus.external.theme.thesaurus_mot_cle_thematique_categories',
99
+ name: 'Catégories',
100
+ url: new URL(
101
+ 'https://data.lillemetropole.fr/geonetwork/srv/api/registries/vocabularies/external.theme.thesaurus_mot_cle_thematique_categories'
102
+ ),
103
+ },
104
+ label: 'Mobilité, transports, déplacement',
105
+ type: 'theme',
106
+ translations: {},
107
+ },
108
+ {
109
+ thesaurus: {
110
+ id: 'geonetwork.thesaurus.external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement',
111
+ name: 'Mobilité, Transports, Déplacement',
112
+ url: new URL(
113
+ 'https://data.lillemetropole.fr/geonetwork/srv/api/registries/vocabularies/external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement'
114
+ ),
115
+ },
116
+ label: 'Pistes cyclables',
117
+ type: 'theme',
118
+ translations: {},
119
+ },
120
+ {
121
+ thesaurus: {
122
+ id: 'geonetwork.thesaurus.external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement',
123
+ name: 'Mobilité, Transports, Déplacement',
124
+ url: new URL(
125
+ 'https://data.lillemetropole.fr/geonetwork/srv/api/registries/vocabularies/external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement'
126
+ ),
127
+ },
128
+ label: 'Schéma cyclable',
129
+ type: 'theme',
130
+ translations: {},
131
+ },
132
+ {
133
+ thesaurus: {
134
+ id: 'geonetwork.thesaurus.external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement',
135
+ name: 'Mobilité, Transports, Déplacement',
136
+ url: new URL(
137
+ 'https://data.lillemetropole.fr/geonetwork/srv/api/registries/vocabularies/external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement'
138
+ ),
139
+ },
140
+ label: 'Vélos',
141
+ type: 'theme',
142
+ translations: {},
143
+ },
144
+ {
145
+ thesaurus: {
146
+ id: 'geonetwork.thesaurus.external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement',
147
+ name: 'Mobilité, Transports, Déplacement',
148
+ url: new URL(
149
+ 'https://data.lillemetropole.fr/geonetwork/srv/api/registries/vocabularies/external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement'
150
+ ),
151
+ },
152
+ label: 'Plan de mobilité',
153
+ type: 'theme',
154
+ translations: {},
155
+ },
156
+ {
157
+ thesaurus: {
158
+ id: 'geonetwork.thesaurus.external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement',
159
+ name: 'Mobilité, Transports, Déplacement',
160
+ url: new URL(
161
+ 'https://data.lillemetropole.fr/geonetwork/srv/api/registries/vocabularies/external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement'
162
+ ),
163
+ },
164
+ label: 'Cyclisme',
165
+ type: 'theme',
166
+ translations: {},
167
+ },
168
+ {
169
+ thesaurus: {
170
+ id: 'geonetwork.thesaurus.external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement',
171
+ name: 'Mobilité, Transports, Déplacement',
172
+ url: new URL(
173
+ 'https://data.lillemetropole.fr/geonetwork/srv/api/registries/vocabularies/external.theme.thesaurus_mot_cle_thematique_mobilite_transports_deplacement'
174
+ ),
175
+ },
176
+ label: 'Cyclable',
177
+ type: 'theme',
178
+ translations: {},
179
+ },
180
+ ],
181
+ topics: ['transportation'],
182
+ licenses: [],
183
+ legalConstraints: [
184
+ {
185
+ text: 'Licence Ouverte v2.0 (Etalab)',
186
+ translations: {},
187
+ },
188
+ {
189
+ text: 'Utilisation libre sous réserve de mentionner la source (a minima le nom du producteur) et la date de sa dernière mise à jour',
190
+ translations: {},
191
+ },
192
+ ],
193
+ securityConstraints: [],
194
+ otherConstraints: [],
195
+ overviews: [],
196
+ spatialExtents: [
197
+ {
198
+ bbox: [
199
+ 2.78913293567365, 50.4997300394295, 3.272498092970729, 50.7945765614518,
200
+ ],
201
+ translations: {},
202
+ },
203
+ ],
204
+ onlineResources: [
205
+ {
206
+ type: 'service',
207
+ url: new URL(
208
+ 'https://data.lillemetropole.fr/geoserver/ogc/features/v1/collections/mel_mobilite_et_transport:sc_schema_cyclable_pm35_2023/items'
209
+ ),
210
+ accessServiceProtocol: 'ogcFeatures',
211
+ identifierInService: 'Schéma cyclable 2035 - liaisons - Plan de mobilité',
212
+ name: 'Schéma cyclable 2035 - liaisons - Plan de mobilité',
213
+ description: 'Schéma cyclable 2035 - liaisons - Plan de mobilité',
214
+ translations: {},
215
+ },
216
+ {
217
+ type: 'service',
218
+ url: new URL('https://data.lillemetropole.fr/geoserver/ows'),
219
+ accessServiceProtocol: 'wfs',
220
+ identifierInService:
221
+ 'mel_mobilite_et_transport:sc_schema_cyclable_pm35_2023',
222
+ name: 'mel_mobilite_et_transport:sc_schema_cyclable_pm35_2023',
223
+ description: 'Schéma cyclable 2035 - liaisons - Plan de mobilité',
224
+ translations: {},
225
+ },
226
+ {
227
+ type: 'service',
228
+ url: new URL('https://data.lillemetropole.fr/geoserver/ows'),
229
+ accessServiceProtocol: 'wms',
230
+ identifierInService:
231
+ 'mel_mobilite_et_transport:sc_schema_cyclable_pm35_2023',
232
+ name: 'mel_mobilite_et_transport:sc_schema_cyclable_pm35_2023',
233
+ description: 'Schéma cyclable 2035 - liaisons - Plan de mobilité',
234
+ translations: {},
235
+ },
236
+ {
237
+ type: 'link',
238
+ url: new URL(
239
+ 'https://plandemobilite2035.lillemetropole.fr/schema-cyclable/'
240
+ ),
241
+ name: 'Documentation',
242
+ description: 'Lien vers la carte dynamique « schéma cyclable »',
243
+ translations: {},
244
+ },
245
+ ],
246
+ translations: {},
247
+ landingPage: new URL(
248
+ 'https://data.lillemetropole.fr/catalogue/dataset/1f7c8d9f-3363-4512-ad3a-064fb6b851bc'
249
+ ),
250
+ status: 'completed',
251
+ lineage: null,
252
+ sourceRecords: [],
253
+ associatedRecords: [],
254
+ temporalExtents: [
255
+ {
256
+ start: new Date('2023-10-27'),
257
+ end: new Date('2035-12-31'),
258
+ },
259
+ ],
260
+ updateFrequency: 'notPlanned',
261
+ featureTypeDescriptions: [
262
+ {
263
+ name: 'schéma cyclable - liaisons',
264
+ description: 'Liaisons du schéma directeur cyclable de la MEL',
265
+ attributes: [
266
+ {
267
+ name: 'objectid',
268
+ description: "Identifiant de l'objet (clé primaire)",
269
+ type: 'numeric(38)',
270
+ code: 'OBJECTID',
271
+ },
272
+ {
273
+ name: 'code_insee',
274
+ description: 'Code INSEE de la commune',
275
+ type: 'varchar(8)',
276
+ code: 'CODE_INSEE',
277
+ },
278
+ {
279
+ name: 'velo_plus',
280
+ description:
281
+ "Permet de savoir si l'objet décrit un tronçon faisant parti du réseau vélo + : Oui - le tronçon fait partie intégrante du réseau vélo+ /Non - le tronçon ne fait pas partie du réseau vélo+ /Option - le tronçon pourrait éventuellement faire partie du réseau réseau vélo+ / Variante - le tronçon pourrait être utilisé en lieu et place d'un autre pour répondre à un trajet équivalent",
282
+ type: 'varchar(256)',
283
+ },
284
+ {
285
+ name: 'r_ppal',
286
+ description:
287
+ "Permet de savoir si l'objet décrit un tronçon faisant parti du réseau Intercommunal : Oui - le tronçon fait partie intégrante du réseau intercommunal / Non - le tronçon ne fait pas partie du réseau intercommunal / Option : le tronçon pourrait éventuellement faire partie du réseau intercommunal / Variante : le tronçon pourrait être utilisé en lieu et place d'un autre pour répondre à un trajet équivalent",
288
+ type: 'varchar(256)',
289
+ },
290
+ {
291
+ name: 'r_scdr',
292
+ description:
293
+ "Permet de savoir si l'objet décrit un tronçon faisant parti du réseau de proximité : Oui - le tronçon fait partie intégrante du réseau cyclable de proximité / Non - le tronçon ne fait pas partie du réseau cyclable de proximité",
294
+ type: 'varchar(256)',
295
+ },
296
+ {
297
+ name: 'test_niveau_difficulte',
298
+ description:
299
+ '[Données pour tester valeurs de liste]: Donne une note de difficulté (1-5) du tronçon.',
300
+ type: 'varchar(256)',
301
+ values: [
302
+ { value: '1', label: 'Très facile' },
303
+ { value: '2', label: 'Facile' },
304
+ { value: '3', label: 'Moyen' },
305
+ { value: '4', label: 'Difficile' },
306
+ { value: '5', label: 'Très difficile' },
307
+ ],
308
+ },
309
+ {
310
+ name: 'geom',
311
+ description: 'Géométrie de type ligne simple',
312
+ type: 'geometry',
313
+ },
314
+ ],
315
+ },
316
+ ],
317
+ }
318
+
319
+ export const MEL_FEATURECATALOG_DATASET_RECORD_EDITED: DatasetRecord = {
320
+ ...MEL_FEATURECATALOG_DATASET_RECORD,
321
+ featureTypeDescriptions: [
322
+ {
323
+ name: 'schéma cyclable - liaisons',
324
+ description: 'Liaisons du schéma directeur cyclable 2035 de la MEL',
325
+ attributes: [
326
+ {
327
+ name: 'objectid',
328
+ description: "Identifiant de l'objet (clé primaire)",
329
+ type: 'numeric(38)',
330
+ code: 'OBJECTID',
331
+ },
332
+ {
333
+ name: 'code_insee',
334
+ description: 'Code INSEE de la commune',
335
+ type: 'varchar(8)',
336
+ },
337
+ {
338
+ name: 'velo_plus',
339
+ description:
340
+ 'Appartenance au réseau vélo+ : Oui / Non / Option / Variante',
341
+ type: 'varchar(256)',
342
+ },
343
+ {
344
+ name: 'r_ppal',
345
+ description:
346
+ "Permet de savoir si l'objet décrit un tronçon faisant parti du réseau Intercommunal : Oui - le tronçon fait partie intégrante du réseau intercommunal / Non - le tronçon ne fait pas partie du réseau intercommunal / Option : le tronçon pourrait éventuellement faire partie du réseau intercommunal / Variante : le tronçon pourrait être utilisé en lieu et place d'un autre pour répondre à un trajet équivalent",
347
+ type: 'varchar(256)',
348
+ },
349
+ {
350
+ name: 'test_niveau_difficulte',
351
+ description:
352
+ '[Données pour tester valeurs de liste]: Donne une note de difficulté (1-5) du tronçon.',
353
+ type: 'varchar(256)',
354
+ values: [
355
+ {
356
+ value: '1',
357
+ label: 'Très facile',
358
+ },
359
+ {
360
+ value: '2',
361
+ label: 'Facile',
362
+ },
363
+ {
364
+ value: '3',
365
+ label: 'Moyen',
366
+ },
367
+ {
368
+ value: '4',
369
+ label: 'Difficile',
370
+ },
371
+ {
372
+ value: '5',
373
+ label: 'Très difficile',
374
+ },
375
+ {
376
+ value: '6',
377
+ label: 'Extrême',
378
+ },
379
+ ],
380
+ },
381
+ {
382
+ name: 'geom',
383
+ description: 'Géométrie de type ligne simple',
384
+ type: 'geometry',
385
+ },
386
+ {
387
+ name: 'longueur',
388
+ description: 'Longueur du tronçon en mètres',
389
+ type: 'numeric',
390
+ code: 'LONGUEUR',
391
+ },
392
+ ],
393
+ },
394
+ ],
395
+ }
@@ -422,23 +422,23 @@ Depuis, ce sont les Districts routiers qui assurent la tenue à jour de ces info
422
422
  sourceRecords: [],
423
423
  associatedRecords: [
424
424
  {
425
- uuid: 'b1882436-3016-421e-9dfd-0326cca998f2',
425
+ uniqueIdentifier: 'b1882436-3016-421e-9dfd-0326cca998f2',
426
426
  associationType: 'crossReference',
427
427
  },
428
428
  {
429
- uuid: 'b1741571-bbda-4732-a807-cbc36b64d54f',
429
+ uniqueIdentifier: 'b1741571-bbda-4732-a807-cbc36b64d54f',
430
430
  associationType: 'crossReference',
431
431
  },
432
432
  {
433
- uuid: 'bdcb789c-4b02-4c0c-863a-98dac4ed0240',
433
+ uniqueIdentifier: 'bdcb789c-4b02-4c0c-863a-98dac4ed0240',
434
434
  associationType: 'crossReference',
435
435
  },
436
436
  {
437
- uuid: 'c0112b86-a6e3-4df3-9da1-2927376076f4',
437
+ uniqueIdentifier: 'c0112b86-a6e3-4df3-9da1-2927376076f4',
438
438
  associationType: 'partOfSeamlessDatabase',
439
439
  },
440
440
  {
441
- uuid: '7451e2bd-22e8-4a74-a999-01c58b630369',
441
+ uniqueIdentifier: '7451e2bd-22e8-4a74-a999-01c58b630369',
442
442
  associationType: 'largerWorkCitation',
443
443
  },
444
444
  ],
@@ -15,17 +15,20 @@ import {
15
15
  } from './atomic-operations'
16
16
  import { MetadataUrlService } from './metadata-url.service'
17
17
  import { inject, Injectable } from '@angular/core'
18
+ import { getAssociationTypeFromCode } from '../iso19139/utils/association-type.mapper'
18
19
  import { getStatusFromStatusCode } from '../iso19139/utils/status.mapper'
19
20
  import { getUpdateFrequencyFromFrequencyCode } from '../iso19139/utils/update-frequency.mapper'
20
21
  import {
22
+ AssociatedRecord,
21
23
  CatalogRecord,
22
24
  Constraint,
25
+ DatasetFeatureType,
23
26
  DatasetSpatialExtent,
24
27
  OnlineResource,
25
28
  OnlineResourceType,
26
29
  } from '../../../../../../libs/common/domain/src/lib/model/record'
27
30
  import { matchProtocol } from '../common/distribution.mapper'
28
- import { Thesaurus } from './types'
31
+ import { FeatureType, Thesaurus } from './types'
29
32
  import {
30
33
  getResourceType,
31
34
  getReusePresentationForm,
@@ -310,33 +313,25 @@ export class Gn4FieldMapper {
310
313
  },
311
314
  output
312
315
  ),
313
- featureTypes: (output, source) =>
314
- this.addExtra(
315
- {
316
- featureTypes: selectField(source, 'featureTypes'),
317
- },
318
- output
319
- ),
316
+ featureTypes: (output, source) => {
317
+ const featureTypes = getAsArray(selectField(source, 'featureTypes'))
318
+ if (!featureTypes.length) return output
319
+ return {
320
+ ...output,
321
+ featureTypeDescriptions: this.featureTypesField(featureTypes),
322
+ }
323
+ },
320
324
  related: (output, source) => {
325
+ const related = <SourceWithUnknownProps>selectField(source, 'related')
321
326
  const fcatSource = selectField(
322
- getFirstValue(
323
- selectField(
324
- <SourceWithUnknownProps>selectField(source, 'related'),
325
- 'fcats'
326
- )
327
- ) ?? {},
327
+ getFirstValue(selectField(related, 'fcats')) ?? {},
328
328
  '_source'
329
329
  )
330
330
  const featureCatalogIdentifier: string = selectField(
331
331
  <SourceWithUnknownProps>fcatSource,
332
332
  'uuid'
333
333
  )
334
- const sourceOfLinks = getAsArray(
335
- selectField(
336
- <SourceWithUnknownProps>selectField(source, 'related'),
337
- 'hassources'
338
- )
339
- )
334
+ const sourceOfLinks = getAsArray(selectField(related, 'hassources'))
340
335
  const sourceOfIdentifiers: string[] = sourceOfLinks
341
336
  .filter((link) => link['origin'] === 'catalog')
342
337
  .map((link) => {
@@ -345,13 +340,50 @@ export class Gn4FieldMapper {
345
340
  'uuid'
346
341
  )
347
342
  })
348
- const extraValues: Record<string, string | string[]> = {}
343
+ const siblingLinks = getAsArray(selectField(related, 'siblings'))
344
+ const siblings: AssociatedRecord[] = siblingLinks
345
+ .filter((link) => link['origin'] === 'catalog')
346
+ .map((link) => ({
347
+ uniqueIdentifier: selectField<string>(
348
+ selectField(<SourceWithUnknownProps>link, '_source'),
349
+ 'uuid'
350
+ ),
351
+ associationType: getAssociationTypeFromCode(
352
+ selectField<string>(
353
+ selectField(<SourceWithUnknownProps>link, 'properties'),
354
+ 'associationType'
355
+ )
356
+ ),
357
+ }))
358
+ const associatedLinks = getAsArray(selectField(related, 'associated'))
359
+ const associatedIdentifiers: string[] = associatedLinks
360
+ .filter((link) => link['origin'] === 'catalog')
361
+ .map((link) => {
362
+ return selectField<string>(
363
+ selectField(<SourceWithUnknownProps>link, '_source'),
364
+ 'uuid'
365
+ )
366
+ })
367
+ .filter(
368
+ (uuid) =>
369
+ !siblings.some((sibling) => sibling.uniqueIdentifier === uuid)
370
+ )
371
+ const extraValues: Record<
372
+ string,
373
+ string | string[] | AssociatedRecord[]
374
+ > = {}
349
375
  if (featureCatalogIdentifier) {
350
376
  extraValues.featureCatalogIdentifier = featureCatalogIdentifier
351
377
  }
352
378
  if (sourceOfIdentifiers && sourceOfIdentifiers.length > 0) {
353
379
  extraValues.sourceOfIdentifiers = sourceOfIdentifiers
354
380
  }
381
+ if (associatedIdentifiers && associatedIdentifiers.length > 0) {
382
+ extraValues.associatedIdentifiers = associatedIdentifiers
383
+ }
384
+ if (siblings && siblings.length > 0) {
385
+ extraValues.siblings = siblings
386
+ }
355
387
  return Object.keys(extraValues).length > 0
356
388
  ? this.addExtra(extraValues, output)
357
389
  : output
@@ -488,6 +520,31 @@ export class Gn4FieldMapper {
488
520
 
489
521
  private genericField = (output) => output
490
522
 
523
+ private featureTypesField = (
524
+ featureTypes: FeatureType[]
525
+ ): Array<DatasetFeatureType> =>
526
+ featureTypes.map((featureType) => ({
527
+ name: featureType.typeName ?? '',
528
+ ...(featureType.definition && {
529
+ description: featureType.definition,
530
+ }),
531
+ attributes: getAsArray(featureType.attributeTable ?? []).map((attr) => {
532
+ const values = (attr.values ?? [])
533
+ .filter((value) => value.code || value.label)
534
+ .map((value) => ({
535
+ value: value.code || '',
536
+ ...(value.label && { label: value.label }),
537
+ }))
538
+ return {
539
+ name: attr.name ?? '',
540
+ ...(attr.definition && { description: attr.definition }),
541
+ ...(attr.code && { code: attr.code }),
542
+ ...(attr.type && { type: attr.type }),
543
+ ...(values.length > 0 && { values }),
544
+ }
545
+ }),
546
+ }))
547
+
491
548
  private constraintField = (
492
549
  type: 'license' | 'legal' | 'security' | 'other',
493
550
  output: Partial<CatalogRecord>,
@@ -2,7 +2,19 @@ export type SortOrder = 'asc' | 'desc'
2
2
  interface SortParam {
3
3
  [key: string]: SortOrder
4
4
  }
5
- export type SortParams = string | SortParam | (string | SortParam)[]
5
+ type EsFieldSort = {
6
+ order: SortOrder
7
+ mode?: 'max' | 'min'
8
+ missing?: '_last'
9
+ nested?: {
10
+ path: string
11
+ }
12
+ }
13
+ export type SortParams =
14
+ | string
15
+ | SortParam
16
+ | { [property: string]: EsFieldSort }
17
+ | (string | SortParam | { [property: string]: EsFieldSort })[]
6
18
 
7
19
  export interface EsRequestAggTerm {
8
20
  field?: string
@@ -79,6 +79,24 @@ export interface Link {
79
79
  group?: number
80
80
  }
81
81
 
82
+ interface FeatureTypeAttribute {
83
+ name: string
84
+ code: string
85
+ link: string
86
+ definition: string
87
+ type: string
88
+ values?: Array<{ code?: string; label?: string; description?: string }>
89
+ }
90
+
91
+ export interface FeatureType {
92
+ typeName: string
93
+ definition: string
94
+ code: string
95
+ aliases: string
96
+ isAbstract: string
97
+ attributeTable: FeatureTypeAttribute[]
98
+ }
99
+
82
100
  export type MetadataObject = Partial<{
83
101
  MD_ConstraintsUseLimitationObject: MultilingualField[]
84
102
  MD_LegalConstraintsOtherConstraintsObject: MultilingualField[]
@@ -109,6 +127,7 @@ export type MetadataObject = Partial<{
109
127
  extentDescriptionObject: MultilingualField[]
110
128
  extra: string
111
129
  featureOfRecord: string
130
+ featureTypes: FeatureType[]
112
131
  feedbackCount: string
113
132
  geom: Geometry | Geometry[]
114
133
  groupOwner: string
@@ -4,6 +4,7 @@ import { Iso19139Converter } from '../iso19139'
4
4
  import { renameElements } from '../xml-utils'
5
5
  import {
6
6
  readAssociatedRecords,
7
+ readFeatureTypeDescriptions,
7
8
  readContacts,
8
9
  readContactsForResource,
9
10
  readDefaultLanguage,
@@ -22,6 +23,7 @@ import {
22
23
  } from './read-parts'
23
24
  import {
24
25
  writeAssociatedRecords,
26
+ writeFeatureTypeDescriptions,
25
27
  writeContacts,
26
28
  writeContactsForResource,
27
29
  writeDefaultLanguage,
@@ -59,6 +61,7 @@ export class Iso191153Converter extends Iso19139Converter {
59
61
  this.readers['lineage'] = readLineage
60
62
  this.readers['sourceRecords'] = readSourceRecords
61
63
  this.readers['associatedRecords'] = readAssociatedRecords
64
+ this.readers['featureTypeDescriptions'] = readFeatureTypeDescriptions
62
65
  this.readers['onlineResources'] = readOnlineResources
63
66
  this.readers['defaultLanguage'] = readDefaultLanguage
64
67
  this.readers['otherLanguages'] = readOtherLanguages
@@ -80,6 +83,7 @@ export class Iso191153Converter extends Iso19139Converter {
80
83
  this.writers['lineage'] = writeLineage
81
84
  this.writers['sourceRecords'] = writeSourceRecords
82
85
  this.writers['associatedRecords'] = writeAssociatedRecords
86
+ this.writers['featureTypeDescriptions'] = writeFeatureTypeDescriptions
83
87
  this.writers['onlineResources'] = writeOnlineResources
84
88
  this.writers['status'] = writeStatus
85
89
  this.writers['spatialRepresentation'] = writeSpatialRepresentation
@@ -187,12 +191,19 @@ export class Iso191153Converter extends Iso19139Converter {
187
191
  record: CatalogRecord,
188
192
  reference?: string
189
193
  ): Promise<string> {
190
- let result = await super.writeRecord(record, reference)
191
- // fix gco namespace definition (changes between iso19139 and iso19115-3
192
- result = result.replace(
193
- '"http://www.isotc211.org/2005/gco"',
194
- '"http://standards.iso.org/iso/19115/-3/gco/1.0"'
194
+ const result = await super.writeRecord(record, reference)
195
+ // fix the gco and gfc namespace definitions (they change between iso19139 and iso19115-3);
196
+ // only on the root element, where they are declared, so that nested declarations stay untouched
197
+ return result.replace(/<mdb:MD_Metadata[^>]*>/, (rootTag) =>
198
+ rootTag
199
+ .replace(
200
+ '"http://www.isotc211.org/2005/gco"',
201
+ '"http://standards.iso.org/iso/19115/-3/gco/1.0"'
202
+ )
203
+ .replace(
204
+ '"http://www.isotc211.org/2005/gfc"',
205
+ '"http://standards.iso.org/iso/19110/gfc/1.1"'
206
+ )
195
207
  )
196
- return result
197
208
  }
198
209
  }