geonetwork-ui 2.3.0-dev.ff2a9db7 → 2.3.0
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.
- package/esm2022/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.mjs +2 -2
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.mjs +9 -7
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/read-parts.mjs +22 -7
- package/esm2022/libs/api/metadata-converter/src/lib/iso19139/write-parts.mjs +14 -3
- package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
- package/esm2022/libs/feature/dataviz/src/lib/service/data.service.mjs +14 -2
- package/esm2022/libs/feature/map/src/lib/map-context/map-context.model.mjs +1 -1
- package/esm2022/libs/feature/map/src/lib/map-context/map-context.service.mjs +30 -10
- package/esm2022/libs/feature/map/src/lib/utils/map-utils.service.mjs +7 -3
- package/esm2022/libs/feature/record/src/lib/map-view/map-view.component.mjs +14 -7
- package/esm2022/libs/feature/record/src/lib/state/mdview.facade.mjs +34 -5
- package/esm2022/libs/feature/record/src/lib/state/mdview.reducer.mjs +1 -3
- package/esm2022/libs/feature/search/src/lib/results-list/results-list.container.component.mjs +4 -4
- package/esm2022/libs/ui/elements/src/index.mjs +2 -2
- package/esm2022/libs/ui/elements/src/lib/error/error.component.mjs +30 -0
- package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +6 -7
- package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +6 -6
- package/esm2022/libs/util/app-config/src/lib/app-config.mjs +3 -1
- package/esm2022/libs/util/app-config/src/lib/fixtures.mjs +2 -1
- package/esm2022/libs/util/app-config/src/lib/model.mjs +1 -1
- package/esm2022/translations/de.json +1 -0
- package/esm2022/translations/en.json +1 -0
- package/esm2022/translations/es.json +1 -0
- package/esm2022/translations/fr.json +1 -0
- package/esm2022/translations/it.json +1 -0
- package/esm2022/translations/nl.json +1 -0
- package/esm2022/translations/pt.json +1 -0
- package/fesm2022/geonetwork-ui.mjs +391 -287
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.d.ts +2 -2
- package/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts +1 -1
- package/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts +4 -1
- package/libs/api/metadata-converter/src/lib/iso19139/read-parts.d.ts.map +1 -1
- package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts +2 -1
- package/libs/api/metadata-converter/src/lib/iso19139/write-parts.d.ts.map +1 -1
- package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +3 -3
- package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
- package/libs/feature/dataviz/src/lib/service/data.service.d.ts +2 -1
- package/libs/feature/dataviz/src/lib/service/data.service.d.ts.map +1 -1
- package/libs/feature/map/src/lib/map-context/map-context.model.d.ts +6 -0
- package/libs/feature/map/src/lib/map-context/map-context.model.d.ts.map +1 -1
- package/libs/feature/map/src/lib/map-context/map-context.service.d.ts +1 -1
- package/libs/feature/map/src/lib/map-context/map-context.service.d.ts.map +1 -1
- package/libs/feature/map/src/lib/utils/map-utils.service.d.ts.map +1 -1
- package/libs/feature/record/src/lib/map-view/map-view.component.d.ts +2 -2
- package/libs/feature/record/src/lib/map-view/map-view.component.d.ts.map +1 -1
- package/libs/feature/record/src/lib/state/mdview.facade.d.ts +5 -2
- package/libs/feature/record/src/lib/state/mdview.facade.d.ts.map +1 -1
- package/libs/feature/record/src/lib/state/mdview.reducer.d.ts.map +1 -1
- package/libs/ui/elements/src/index.d.ts +1 -1
- package/libs/ui/elements/src/index.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/error/error.component.d.ts +16 -0
- package/libs/ui/elements/src/lib/error/error.component.d.ts.map +1 -0
- package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -2
- package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
- package/libs/util/app-config/src/lib/app-config.d.ts.map +1 -1
- package/libs/util/app-config/src/lib/fixtures.d.ts.map +1 -1
- package/libs/util/app-config/src/lib/model.d.ts +1 -0
- package/libs/util/app-config/src/lib/model.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/libs/api/metadata-converter/src/lib/fixtures/generic.records.ts +9 -1
- package/src/libs/api/metadata-converter/src/lib/iso19115-3/iso19115-3.converter.ts +3 -3
- package/src/libs/api/metadata-converter/src/lib/iso19139/iso19139.converter.ts +35 -31
- package/src/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +67 -15
- package/src/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +71 -13
- package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +3 -3
- package/src/libs/common/fixtures/src/lib/records.fixtures.ts +8 -0
- package/src/libs/feature/dataviz/src/lib/service/data.service.ts +15 -1
- package/src/libs/feature/map/src/lib/map-context/map-context.model.ts +6 -0
- package/src/libs/feature/map/src/lib/map-context/map-context.service.ts +31 -9
- package/src/libs/feature/map/src/lib/utils/map-utils.service.ts +6 -2
- package/src/libs/feature/record/src/lib/map-view/map-view.component.ts +15 -8
- package/src/libs/feature/record/src/lib/state/mdview.facade.ts +40 -3
- package/src/libs/feature/record/src/lib/state/mdview.reducer.ts +0 -2
- package/src/libs/feature/search/src/lib/results-list/results-list.container.component.html +4 -4
- package/src/libs/ui/elements/src/index.ts +1 -1
- package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.html → error/error.component.html} +18 -3
- package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.ts → error/error.component.ts} +5 -4
- package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +7 -8
- package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -4
- package/src/libs/util/app-config/src/lib/app-config.ts +2 -0
- package/src/libs/util/app-config/src/lib/fixtures.ts +1 -0
- package/src/libs/util/app-config/src/lib/model.ts +1 -0
- package/translations/de.json +1 -0
- package/translations/en.json +1 -0
- package/translations/es.json +1 -0
- package/translations/fr.json +1 -0
- package/translations/it.json +1 -0
- package/translations/nl.json +1 -0
- package/translations/pt.json +1 -0
- package/translations/sk.json +1 -0
- package/esm2022/libs/ui/elements/src/lib/search-results-error/search-results-error.component.mjs +0 -29
- package/libs/ui/elements/src/lib/search-results-error/search-results-error.component.d.ts +0 -15
- package/libs/ui/elements/src/lib/search-results-error/search-results-error.component.d.ts.map +0 -1
- /package/src/libs/ui/elements/src/lib/{search-results-error/search-results-error.component.css → error/error.component.css} +0 -0
|
@@ -4,6 +4,9 @@ import {
|
|
|
4
4
|
DatasetRecord,
|
|
5
5
|
ServiceRecord,
|
|
6
6
|
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
7
|
+
import { XmlElement } from '@rgrove/parse-xml'
|
|
8
|
+
import { BaseConverter } from '../base.converter'
|
|
9
|
+
import { isEqual } from '../convert-utils'
|
|
7
10
|
import {
|
|
8
11
|
createDocument,
|
|
9
12
|
createElement,
|
|
@@ -11,32 +14,6 @@ import {
|
|
|
11
14
|
parseXmlString,
|
|
12
15
|
xmlToString,
|
|
13
16
|
} from '../xml-utils'
|
|
14
|
-
import {
|
|
15
|
-
writeAbstract,
|
|
16
|
-
writeContacts,
|
|
17
|
-
writeContactsForResource,
|
|
18
|
-
writeDistributions,
|
|
19
|
-
writeGraphicOverviews,
|
|
20
|
-
writeKeywords,
|
|
21
|
-
writeKind,
|
|
22
|
-
writeLegalConstraints,
|
|
23
|
-
writeLicenses,
|
|
24
|
-
writeLineage,
|
|
25
|
-
writeOnlineResources,
|
|
26
|
-
writeOtherConstraints,
|
|
27
|
-
writeOwnerOrganization,
|
|
28
|
-
writeRecordUpdated,
|
|
29
|
-
writeResourceCreated,
|
|
30
|
-
writeResourcePublished,
|
|
31
|
-
writeResourceUpdated,
|
|
32
|
-
writeSecurityConstraints,
|
|
33
|
-
writeSpatialRepresentation,
|
|
34
|
-
writeStatus,
|
|
35
|
-
writeTitle,
|
|
36
|
-
writeTopics,
|
|
37
|
-
writeUniqueIdentifier,
|
|
38
|
-
writeUpdateFrequency,
|
|
39
|
-
} from './write-parts'
|
|
40
17
|
import {
|
|
41
18
|
readAbstract,
|
|
42
19
|
readContacts,
|
|
@@ -59,13 +36,38 @@ import {
|
|
|
59
36
|
readSecurityConstraints,
|
|
60
37
|
readSpatialRepresentation,
|
|
61
38
|
readStatus,
|
|
39
|
+
readTemporalExtents,
|
|
62
40
|
readTitle,
|
|
63
41
|
readUniqueIdentifier,
|
|
64
42
|
readUpdateFrequency,
|
|
65
43
|
} from './read-parts'
|
|
66
|
-
import {
|
|
67
|
-
|
|
68
|
-
|
|
44
|
+
import {
|
|
45
|
+
writeAbstract,
|
|
46
|
+
writeContacts,
|
|
47
|
+
writeContactsForResource,
|
|
48
|
+
writeDistributions,
|
|
49
|
+
writeGraphicOverviews,
|
|
50
|
+
writeKeywords,
|
|
51
|
+
writeKind,
|
|
52
|
+
writeLegalConstraints,
|
|
53
|
+
writeLicenses,
|
|
54
|
+
writeLineage,
|
|
55
|
+
writeOnlineResources,
|
|
56
|
+
writeOtherConstraints,
|
|
57
|
+
writeOwnerOrganization,
|
|
58
|
+
writeRecordUpdated,
|
|
59
|
+
writeResourceCreated,
|
|
60
|
+
writeResourcePublished,
|
|
61
|
+
writeResourceUpdated,
|
|
62
|
+
writeSecurityConstraints,
|
|
63
|
+
writeSpatialRepresentation,
|
|
64
|
+
writeStatus,
|
|
65
|
+
writeTemporalExtents,
|
|
66
|
+
writeTitle,
|
|
67
|
+
writeTopics,
|
|
68
|
+
writeUniqueIdentifier,
|
|
69
|
+
writeUpdateFrequency,
|
|
70
|
+
} from './write-parts'
|
|
69
71
|
|
|
70
72
|
export class Iso19139Converter extends BaseConverter<string> {
|
|
71
73
|
protected readers: Record<
|
|
@@ -98,9 +100,9 @@ export class Iso19139Converter extends BaseConverter<string> {
|
|
|
98
100
|
lineage: readLineage,
|
|
99
101
|
distributions: readDistributions,
|
|
100
102
|
onlineResources: readOnlineResources,
|
|
103
|
+
temporalExtents: readTemporalExtents,
|
|
101
104
|
// TODO
|
|
102
105
|
spatialExtents: () => [],
|
|
103
|
-
temporalExtents: () => [],
|
|
104
106
|
extras: () => undefined,
|
|
105
107
|
landingPage: () => undefined,
|
|
106
108
|
languages: () => [],
|
|
@@ -136,9 +138,9 @@ export class Iso19139Converter extends BaseConverter<string> {
|
|
|
136
138
|
lineage: writeLineage,
|
|
137
139
|
distributions: writeDistributions,
|
|
138
140
|
onlineResources: writeOnlineResources,
|
|
141
|
+
temporalExtents: writeTemporalExtents,
|
|
139
142
|
// TODO
|
|
140
143
|
spatialExtents: () => undefined,
|
|
141
|
-
temporalExtents: () => undefined,
|
|
142
144
|
extras: () => undefined,
|
|
143
145
|
landingPage: () => undefined,
|
|
144
146
|
languages: () => undefined,
|
|
@@ -311,6 +313,8 @@ export class Iso19139Converter extends BaseConverter<string> {
|
|
|
311
313
|
fieldChanged('spatialRepresentation') &&
|
|
312
314
|
this.writers['spatialRepresentation'](record, rootEl)
|
|
313
315
|
fieldChanged('overviews') && this.writers['overviews'](record, rootEl)
|
|
316
|
+
fieldChanged('temporalExtents') &&
|
|
317
|
+
this.writers['temporalExtents'](record, rootEl)
|
|
314
318
|
fieldChanged('distributions') &&
|
|
315
319
|
this.writers['distributions'](record, rootEl)
|
|
316
320
|
fieldChanged('lineage') && this.writers['lineage'](record, rootEl)
|
|
@@ -14,18 +14,7 @@ import {
|
|
|
14
14
|
UpdateFrequency,
|
|
15
15
|
UpdateFrequencyCustom,
|
|
16
16
|
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
17
|
-
import {
|
|
18
|
-
import { getUpdateFrequencyFromFrequencyCode } from './utils/update-frequency.mapper'
|
|
19
|
-
import {
|
|
20
|
-
findChildElement,
|
|
21
|
-
findChildrenElement,
|
|
22
|
-
findNestedElement,
|
|
23
|
-
findNestedElements,
|
|
24
|
-
findParent,
|
|
25
|
-
readAttribute,
|
|
26
|
-
readText,
|
|
27
|
-
XmlElement,
|
|
28
|
-
} from '../xml-utils'
|
|
17
|
+
import { matchMimeType, matchProtocol } from '../common/distribution.mapper'
|
|
29
18
|
import {
|
|
30
19
|
ChainableFunction,
|
|
31
20
|
combine,
|
|
@@ -37,10 +26,21 @@ import {
|
|
|
37
26
|
mapArray,
|
|
38
27
|
pipe,
|
|
39
28
|
} from '../function-utils'
|
|
40
|
-
import {
|
|
41
|
-
|
|
42
|
-
|
|
29
|
+
import {
|
|
30
|
+
XmlElement,
|
|
31
|
+
findChildElement,
|
|
32
|
+
findChildrenElement,
|
|
33
|
+
findNestedElement,
|
|
34
|
+
findNestedElements,
|
|
35
|
+
findParent,
|
|
36
|
+
readAttribute,
|
|
37
|
+
readText,
|
|
38
|
+
} from '../xml-utils'
|
|
43
39
|
import { fullNameToParts } from './utils/individual-name'
|
|
40
|
+
import { getKeywordTypeFromKeywordTypeCode } from './utils/keyword.mapper'
|
|
41
|
+
import { getRoleFromRoleCode } from './utils/role.mapper'
|
|
42
|
+
import { getStatusFromStatusCode } from './utils/status.mapper'
|
|
43
|
+
import { getUpdateFrequencyFromFrequencyCode } from './utils/update-frequency.mapper'
|
|
44
44
|
|
|
45
45
|
export function extractCharacterString(): ChainableFunction<
|
|
46
46
|
XmlElement,
|
|
@@ -843,3 +843,55 @@ export function readOnlineResources(
|
|
|
843
843
|
flattenArray()
|
|
844
844
|
)(rootEl)
|
|
845
845
|
}
|
|
846
|
+
|
|
847
|
+
export function readTemporalExtents(rootEl: XmlElement) {
|
|
848
|
+
return pipe(
|
|
849
|
+
findIdentification(),
|
|
850
|
+
findNestedElements('gmd:extent', 'gmd:EX_Extent', 'gmd:temporalElement'),
|
|
851
|
+
mapArray(
|
|
852
|
+
combine(
|
|
853
|
+
findNestedElement(
|
|
854
|
+
'gmd:EX_TemporalExtent',
|
|
855
|
+
'gmd:extent',
|
|
856
|
+
'gml:TimePeriod'
|
|
857
|
+
),
|
|
858
|
+
findNestedElement(
|
|
859
|
+
'gmd:EX_TemporalExtent',
|
|
860
|
+
'gmd:extent',
|
|
861
|
+
'gml:TimeInstant'
|
|
862
|
+
)
|
|
863
|
+
)
|
|
864
|
+
),
|
|
865
|
+
mapArray(([periodEl, instantEl]) => {
|
|
866
|
+
if (periodEl) {
|
|
867
|
+
return pipe(
|
|
868
|
+
combine(
|
|
869
|
+
pipe(
|
|
870
|
+
findChildElement('gml:beginPosition', false),
|
|
871
|
+
readText(),
|
|
872
|
+
map((dateStr) => (dateStr ? new Date(dateStr) : null))
|
|
873
|
+
),
|
|
874
|
+
pipe(
|
|
875
|
+
findChildElement('gml:endPosition', false),
|
|
876
|
+
readText(),
|
|
877
|
+
map((dateStr) => (dateStr ? new Date(dateStr) : null))
|
|
878
|
+
)
|
|
879
|
+
),
|
|
880
|
+
map(([start, end]) => ({
|
|
881
|
+
start,
|
|
882
|
+
end,
|
|
883
|
+
}))
|
|
884
|
+
)(periodEl)
|
|
885
|
+
} else {
|
|
886
|
+
return pipe(
|
|
887
|
+
findChildElement('gml:timePosition', false),
|
|
888
|
+
readText(),
|
|
889
|
+
map((dateStr) => (dateStr ? new Date(dateStr) : null)),
|
|
890
|
+
map((date) => ({
|
|
891
|
+
start: date,
|
|
892
|
+
}))
|
|
893
|
+
)(instantEl)
|
|
894
|
+
}
|
|
895
|
+
})
|
|
896
|
+
)(rootEl)
|
|
897
|
+
}
|
|
@@ -15,7 +15,20 @@ import {
|
|
|
15
15
|
UpdateFrequencyCode,
|
|
16
16
|
UpdateFrequencyCustom,
|
|
17
17
|
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
18
|
+
import format from 'date-fns/format'
|
|
19
|
+
import {
|
|
20
|
+
ChainableFunction,
|
|
21
|
+
fallback,
|
|
22
|
+
filterArray,
|
|
23
|
+
getAtIndex,
|
|
24
|
+
map,
|
|
25
|
+
mapArray,
|
|
26
|
+
noop,
|
|
27
|
+
pipe,
|
|
28
|
+
tap,
|
|
29
|
+
} from '../function-utils'
|
|
18
30
|
import {
|
|
31
|
+
XmlElement,
|
|
19
32
|
addAttribute,
|
|
20
33
|
appendChildren,
|
|
21
34
|
createChild,
|
|
@@ -30,20 +43,7 @@ import {
|
|
|
30
43
|
removeChildren,
|
|
31
44
|
removeChildrenByName,
|
|
32
45
|
setTextContent,
|
|
33
|
-
XmlElement,
|
|
34
46
|
} from '../xml-utils'
|
|
35
|
-
import {
|
|
36
|
-
ChainableFunction,
|
|
37
|
-
fallback,
|
|
38
|
-
filterArray,
|
|
39
|
-
getAtIndex,
|
|
40
|
-
map,
|
|
41
|
-
mapArray,
|
|
42
|
-
noop,
|
|
43
|
-
pipe,
|
|
44
|
-
tap,
|
|
45
|
-
} from '../function-utils'
|
|
46
|
-
import format from 'date-fns/format'
|
|
47
47
|
import { readKind } from './read-parts'
|
|
48
48
|
import { namePartsToFull } from './utils/individual-name'
|
|
49
49
|
|
|
@@ -1126,3 +1126,61 @@ export function writeOnlineResources(
|
|
|
1126
1126
|
appendChildren(...record.onlineResources.map(createOnlineResource))
|
|
1127
1127
|
)(rootEl)
|
|
1128
1128
|
}
|
|
1129
|
+
|
|
1130
|
+
export function writeTemporalExtents(
|
|
1131
|
+
record: DatasetRecord,
|
|
1132
|
+
rootEl: XmlElement
|
|
1133
|
+
) {
|
|
1134
|
+
pipe(
|
|
1135
|
+
findOrCreateIdentification(),
|
|
1136
|
+
findNestedChildOrCreate('gmd:extent', 'gmd:EX_Extent'),
|
|
1137
|
+
removeChildrenByName('gmd:temporalElement'),
|
|
1138
|
+
appendChildren(
|
|
1139
|
+
...record.temporalExtents.map((extent) =>
|
|
1140
|
+
pipe(
|
|
1141
|
+
createElement('gmd:temporalElement'),
|
|
1142
|
+
createChild('gmd:EX_TemporalExtent'),
|
|
1143
|
+
appendChildren(
|
|
1144
|
+
'start' in extent && 'end' in extent
|
|
1145
|
+
? pipe(
|
|
1146
|
+
createElement('gmd:extent'),
|
|
1147
|
+
createChild('gml:TimePeriod'),
|
|
1148
|
+
appendChildren(
|
|
1149
|
+
pipe(
|
|
1150
|
+
createElement('gml:beginPosition'),
|
|
1151
|
+
pipe(
|
|
1152
|
+
extent.start
|
|
1153
|
+
? setTextContent(format(extent.start, 'yyyy-MM-dd'))
|
|
1154
|
+
: addAttribute('indeterminatePosition', 'unknown')
|
|
1155
|
+
)
|
|
1156
|
+
),
|
|
1157
|
+
pipe(
|
|
1158
|
+
createElement('gml:endPosition'),
|
|
1159
|
+
pipe(
|
|
1160
|
+
extent.end
|
|
1161
|
+
? setTextContent(format(extent.end, 'yyyy-MM-dd'))
|
|
1162
|
+
: addAttribute('indeterminatePosition', 'unknown')
|
|
1163
|
+
)
|
|
1164
|
+
)
|
|
1165
|
+
)
|
|
1166
|
+
)
|
|
1167
|
+
: pipe(
|
|
1168
|
+
createElement('gmd:extent'),
|
|
1169
|
+
createChild('gml:TimeInstant'),
|
|
1170
|
+
appendChildren(
|
|
1171
|
+
pipe(
|
|
1172
|
+
createElement('gml:timePosition'),
|
|
1173
|
+
pipe(
|
|
1174
|
+
extent.start
|
|
1175
|
+
? setTextContent(format(extent.start, 'yyyy-MM-dd'))
|
|
1176
|
+
: addAttribute('indeterminatePosition', 'unknown')
|
|
1177
|
+
)
|
|
1178
|
+
)
|
|
1179
|
+
)
|
|
1180
|
+
)
|
|
1181
|
+
)
|
|
1182
|
+
)
|
|
1183
|
+
)
|
|
1184
|
+
)
|
|
1185
|
+
)(rootEl)
|
|
1186
|
+
}
|
|
@@ -169,12 +169,12 @@ export interface DatasetSpatialExtent {
|
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
/**
|
|
172
|
-
*
|
|
172
|
+
* Period if both start and end are provided
|
|
173
|
+
* Instant if only start is provided
|
|
173
174
|
*/
|
|
174
175
|
export interface DatasetTemporalExtent {
|
|
175
|
-
start
|
|
176
|
+
start: Date
|
|
176
177
|
end?: Date
|
|
177
|
-
description?: string
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
export interface DatasetRecord extends BaseRecord {
|
|
@@ -117,6 +117,14 @@ Cette section contient des *caractères internationaux* (ainsi que des "caractè
|
|
|
117
117
|
description: 'This WFS service offers direct download capability',
|
|
118
118
|
identifierInService: 'my:featuretype',
|
|
119
119
|
},
|
|
120
|
+
{
|
|
121
|
+
type: 'service',
|
|
122
|
+
url: new URL('https://my-org.net/ogc'),
|
|
123
|
+
accessServiceProtocol: 'ogcFeatures',
|
|
124
|
+
name: 'my:featuretype',
|
|
125
|
+
description: 'This OGC service offers direct download capability',
|
|
126
|
+
identifierInService: 'my:featuretype',
|
|
127
|
+
},
|
|
120
128
|
],
|
|
121
129
|
lineage: `This record was edited manually to test the conversion processes
|
|
122
130
|
|
|
@@ -3,6 +3,7 @@ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
|
|
|
3
3
|
import {
|
|
4
4
|
OgcApiCollectionInfo,
|
|
5
5
|
OgcApiEndpoint,
|
|
6
|
+
OgcApiRecord,
|
|
6
7
|
WfsEndpoint,
|
|
7
8
|
WfsVersion,
|
|
8
9
|
} from '@camptocamp/ogc-client'
|
|
@@ -173,10 +174,23 @@ export class DataService {
|
|
|
173
174
|
}
|
|
174
175
|
|
|
175
176
|
async getDownloadUrlsFromOgcApi(url: string): Promise<OgcApiCollectionInfo> {
|
|
177
|
+
const endpoint = new OgcApiEndpoint(this.proxy.getProxiedUrl(url))
|
|
178
|
+
return await endpoint.allCollections
|
|
179
|
+
.then((collections) => {
|
|
180
|
+
return endpoint.getCollectionInfo(collections[0].name)
|
|
181
|
+
})
|
|
182
|
+
.catch((error) => {
|
|
183
|
+
throw new Error(`ogc.unreachable.unknown`)
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async getItemsFromOgcApi(url: string): Promise<OgcApiRecord> {
|
|
176
188
|
const endpoint = new OgcApiEndpoint(this.proxy.getProxiedUrl(url))
|
|
177
189
|
return await endpoint.featureCollections
|
|
178
190
|
.then((collections) => {
|
|
179
|
-
return
|
|
191
|
+
return collections.length
|
|
192
|
+
? endpoint.getCollectionItem(collections[0], '1')
|
|
193
|
+
: null
|
|
180
194
|
})
|
|
181
195
|
.catch((error) => {
|
|
182
196
|
throw new Error(`ogc.unreachable.unknown`)
|
|
@@ -20,18 +20,21 @@ export interface MapContextLayerWmsModel {
|
|
|
20
20
|
type: 'wms'
|
|
21
21
|
url: string
|
|
22
22
|
name: string
|
|
23
|
+
attributions?: string
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export interface MapContextLayerWmtsModel {
|
|
26
27
|
type: 'wmts'
|
|
27
28
|
url: string
|
|
28
29
|
name: string
|
|
30
|
+
attributions?: string
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
interface MapContextLayerWfsModel {
|
|
32
34
|
type: 'wfs'
|
|
33
35
|
url: string
|
|
34
36
|
name: string
|
|
37
|
+
attributions?: string
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
export interface MapContextLayerOgcapiModel {
|
|
@@ -39,11 +42,13 @@ export interface MapContextLayerOgcapiModel {
|
|
|
39
42
|
url: string
|
|
40
43
|
name: string
|
|
41
44
|
layerType: 'feature' | 'vectorTiles' | 'mapTiles' | 'record'
|
|
45
|
+
attributions?: string
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
interface LayerXyzModel {
|
|
45
49
|
type: 'xyz'
|
|
46
50
|
name?: string
|
|
51
|
+
attributions?: string
|
|
47
52
|
}
|
|
48
53
|
interface LayerXyzModelWithUrl extends LayerXyzModel {
|
|
49
54
|
url: string
|
|
@@ -59,6 +64,7 @@ export type MapContextLayerXyzModel =
|
|
|
59
64
|
|
|
60
65
|
interface LayerGeojson {
|
|
61
66
|
type: 'geojson'
|
|
67
|
+
attributions?: string
|
|
62
68
|
}
|
|
63
69
|
interface LayerGeojsonWithUrl extends LayerGeojson {
|
|
64
70
|
url: string
|
|
@@ -29,6 +29,8 @@ import OGCVectorTile from 'ol/source/OGCVectorTile.js'
|
|
|
29
29
|
import { MVT } from 'ol/format'
|
|
30
30
|
import VectorTileLayer from 'ol/layer/VectorTile'
|
|
31
31
|
import OGCMapTile from 'ol/source/OGCMapTile.js'
|
|
32
|
+
import ImageLayer from 'ol/layer/Image'
|
|
33
|
+
import ImageWMS from 'ol/source/ImageWMS'
|
|
32
34
|
|
|
33
35
|
export const DEFAULT_BASELAYER_CONTEXT: MapContextLayerXyzModel = {
|
|
34
36
|
type: MapContextLayerTypeEnum.XYZ,
|
|
@@ -37,6 +39,7 @@ export const DEFAULT_BASELAYER_CONTEXT: MapContextLayerXyzModel = {
|
|
|
37
39
|
`https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
|
|
38
40
|
`https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
|
|
39
41
|
],
|
|
42
|
+
attributions: `<span>© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="https://carto.com/">Carto</a></span>`,
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
export const DEFAULT_VIEW: MapContextViewModel = {
|
|
@@ -73,11 +76,13 @@ export class MapContextService {
|
|
|
73
76
|
}
|
|
74
77
|
map.setView(this.createView(mapContext.view, map))
|
|
75
78
|
map.getLayers().clear()
|
|
76
|
-
mapContext.layers.forEach((layer) =>
|
|
79
|
+
mapContext.layers.forEach((layer) =>
|
|
80
|
+
map.addLayer(this.createLayer(layer, mapConfig))
|
|
81
|
+
)
|
|
77
82
|
return map
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
createLayer(layerModel: MapContextLayerModel): Layer {
|
|
85
|
+
createLayer(layerModel: MapContextLayerModel, mapConfig?: MapConfig): Layer {
|
|
81
86
|
const { type } = layerModel
|
|
82
87
|
const style = this.styleService.styles.default
|
|
83
88
|
switch (type) {
|
|
@@ -87,12 +92,14 @@ export class MapContextService {
|
|
|
87
92
|
source: new OGCVectorTile({
|
|
88
93
|
url: layerModel.url,
|
|
89
94
|
format: new MVT(),
|
|
95
|
+
attributions: layerModel.attributions,
|
|
90
96
|
}),
|
|
91
97
|
})
|
|
92
98
|
} else if (layerModel.layerType === 'mapTiles') {
|
|
93
99
|
return new TileLayer({
|
|
94
100
|
source: new OGCMapTile({
|
|
95
101
|
url: layerModel.url,
|
|
102
|
+
attributions: layerModel.attributions,
|
|
96
103
|
}),
|
|
97
104
|
})
|
|
98
105
|
} else {
|
|
@@ -100,6 +107,7 @@ export class MapContextService {
|
|
|
100
107
|
source: new VectorSource({
|
|
101
108
|
format: new GeoJSON(),
|
|
102
109
|
url: layerModel.url,
|
|
110
|
+
attributions: layerModel.attributions,
|
|
103
111
|
}),
|
|
104
112
|
style,
|
|
105
113
|
})
|
|
@@ -109,16 +117,28 @@ export class MapContextService {
|
|
|
109
117
|
source: new XYZ({
|
|
110
118
|
url: 'url' in layerModel ? layerModel.url : undefined,
|
|
111
119
|
urls: 'urls' in layerModel ? layerModel.urls : undefined,
|
|
120
|
+
attributions: layerModel.attributions,
|
|
112
121
|
}),
|
|
113
122
|
})
|
|
114
123
|
case MapContextLayerTypeEnum.WMS:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
if (mapConfig?.DO_NOT_TILE_WMS) {
|
|
125
|
+
return new ImageLayer({
|
|
126
|
+
source: new ImageWMS({
|
|
127
|
+
url: layerModel.url,
|
|
128
|
+
params: { LAYERS: layerModel.name },
|
|
129
|
+
attributions: layerModel.attributions,
|
|
130
|
+
}),
|
|
131
|
+
})
|
|
132
|
+
} else {
|
|
133
|
+
return new TileLayer({
|
|
134
|
+
source: new TileWMS({
|
|
135
|
+
url: layerModel.url,
|
|
136
|
+
params: { LAYERS: layerModel.name, TILED: true },
|
|
137
|
+
attributions: layerModel.attributions,
|
|
138
|
+
}),
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
|
|
122
142
|
case MapContextLayerTypeEnum.WMTS: {
|
|
123
143
|
// TODO: isolate this in utils service
|
|
124
144
|
const olLayer = new TileLayer({})
|
|
@@ -141,6 +161,7 @@ export class MapContextService {
|
|
|
141
161
|
tileGrid,
|
|
142
162
|
projection: matrixSet.crs,
|
|
143
163
|
dimensions,
|
|
164
|
+
attributions: layerModel.attributions,
|
|
144
165
|
})
|
|
145
166
|
)
|
|
146
167
|
})
|
|
@@ -166,6 +187,7 @@ export class MapContextService {
|
|
|
166
187
|
})
|
|
167
188
|
},
|
|
168
189
|
strategy: bboxStrategy,
|
|
190
|
+
attributions: layerModel.attributions,
|
|
169
191
|
})
|
|
170
192
|
)
|
|
171
193
|
})
|
|
@@ -33,6 +33,7 @@ import { WmsEndpoint, WmtsEndpoint } from '@camptocamp/ogc-client'
|
|
|
33
33
|
import { LONLAT_CRS_CODES } from '../constant/projections'
|
|
34
34
|
import { fromEPSGCode, register } from 'ol/proj/proj4'
|
|
35
35
|
import proj4 from 'proj4/dist/proj4'
|
|
36
|
+
import { defaults as defaultControls } from 'ol/control/defaults'
|
|
36
37
|
|
|
37
38
|
const FEATURE_PROJECTION = 'EPSG:3857'
|
|
38
39
|
const DATA_PROJECTION = 'EPSG:4326'
|
|
@@ -47,7 +48,10 @@ export class MapUtilsService {
|
|
|
47
48
|
|
|
48
49
|
createEmptyMap(): Map {
|
|
49
50
|
return new Map({
|
|
50
|
-
controls:
|
|
51
|
+
controls: defaultControls({
|
|
52
|
+
attribution: true,
|
|
53
|
+
attributionOptions: { collapsible: false },
|
|
54
|
+
}),
|
|
51
55
|
pixelRatio: 1,
|
|
52
56
|
})
|
|
53
57
|
}
|
|
@@ -213,7 +217,7 @@ export class MapUtilsService {
|
|
|
213
217
|
}
|
|
214
218
|
|
|
215
219
|
getRecordExtent(record: Partial<CatalogRecord>): Extent {
|
|
216
|
-
if (!('spatialExtents' in record)) {
|
|
220
|
+
if (!('spatialExtents' in record) || record.spatialExtents.length === 0) {
|
|
217
221
|
return null
|
|
218
222
|
}
|
|
219
223
|
// transform an array of geojson geometries into a bbox
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
MapUtilsService,
|
|
16
16
|
} from '../../../../../../libs/feature/map/src'
|
|
17
17
|
import { getOptionalMapConfig, MapConfig } from '../../../../../../libs/util/app-config/src'
|
|
18
|
-
import { getLinkLabel
|
|
18
|
+
import { getLinkLabel } from '../../../../../../libs/util/shared/src'
|
|
19
19
|
import Feature from 'ol/Feature'
|
|
20
20
|
import { Geometry } from 'ol/geom'
|
|
21
21
|
import { StyleLike } from 'ol/style/Style'
|
|
@@ -23,10 +23,8 @@ import {
|
|
|
23
23
|
BehaviorSubject,
|
|
24
24
|
combineLatest,
|
|
25
25
|
from,
|
|
26
|
-
lastValueFrom,
|
|
27
26
|
Observable,
|
|
28
27
|
of,
|
|
29
|
-
startWith,
|
|
30
28
|
Subscription,
|
|
31
29
|
throwError,
|
|
32
30
|
withLatestFrom,
|
|
@@ -36,6 +34,7 @@ import {
|
|
|
36
34
|
distinctUntilChanged,
|
|
37
35
|
finalize,
|
|
38
36
|
map,
|
|
37
|
+
startWith,
|
|
39
38
|
switchMap,
|
|
40
39
|
tap,
|
|
41
40
|
} from 'rxjs/operators'
|
|
@@ -57,9 +56,11 @@ export class MapViewComponent implements OnInit, OnDestroy {
|
|
|
57
56
|
|
|
58
57
|
compatibleMapLinks$ = combineLatest([
|
|
59
58
|
this.mdViewFacade.mapApiLinks$,
|
|
60
|
-
this.mdViewFacade.
|
|
59
|
+
this.mdViewFacade.geoDataLinksWithGeometry$,
|
|
61
60
|
]).pipe(
|
|
62
|
-
map(([mapApiLinks,
|
|
61
|
+
map(([mapApiLinks, geoDataLinksWithGeometry]) => {
|
|
62
|
+
return [...mapApiLinks, ...geoDataLinksWithGeometry]
|
|
63
|
+
})
|
|
63
64
|
)
|
|
64
65
|
|
|
65
66
|
dropdownChoices$ = this.compatibleMapLinks$.pipe(
|
|
@@ -104,8 +105,8 @@ export class MapViewComponent implements OnInit, OnDestroy {
|
|
|
104
105
|
mapContext$ = this.currentLayers$.pipe(
|
|
105
106
|
switchMap((layers) =>
|
|
106
107
|
from(this.mapUtils.getLayerExtent(layers[0])).pipe(
|
|
107
|
-
catchError((
|
|
108
|
-
|
|
108
|
+
catchError(() => {
|
|
109
|
+
this.error = 'The layer has no extent'
|
|
109
110
|
return of(undefined)
|
|
110
111
|
}),
|
|
111
112
|
map(
|
|
@@ -117,9 +118,15 @@ export class MapViewComponent implements OnInit, OnDestroy {
|
|
|
117
118
|
},
|
|
118
119
|
} as MapContextModel)
|
|
119
120
|
),
|
|
120
|
-
tap(() =>
|
|
121
|
+
tap((res) => {
|
|
122
|
+
this.resetSelection()
|
|
123
|
+
})
|
|
121
124
|
)
|
|
122
125
|
),
|
|
126
|
+
startWith({
|
|
127
|
+
layers: [],
|
|
128
|
+
view: {},
|
|
129
|
+
} as MapContextModel),
|
|
123
130
|
withLatestFrom(this.mdViewFacade.metadata$),
|
|
124
131
|
map(([context, metadata]) => {
|
|
125
132
|
if (context.view.extent) return context
|