Skip to content

Commit

Permalink
Merge pull request #534 from geonetwork/gml-support
Browse files Browse the repository at this point in the history
GML support when geojson not available from server
  • Loading branch information
fgravin authored Jul 19, 2023
2 parents e1f1615 + 25ceb75 commit 7babe14
Show file tree
Hide file tree
Showing 15 changed files with 1,382 additions and 38 deletions.
50 changes: 41 additions & 9 deletions libs/feature/dataviz/src/lib/service/data.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ jest.mock('@camptocamp/ogc-client', () => ({
? null
: {
name,
otherCrs: ['EPSG:4326'],
outputFormats:
name.indexOf('nojson') > -1
? ['csv', 'xls']
: ['csv', 'xls', 'json'],
? ['csv', 'xls', 'gml']
: ['csv', 'xls', 'json', 'gml'],
}
}
getFeatureTypes() {
Expand All @@ -68,6 +69,10 @@ jest.mock('@camptocamp/ogc-client', () => ({
},
]
}

getVersion(): '1.0.0' | '1.1.0' | '2.0.0' {
return '2.0.0'
}
},
}))

Expand Down Expand Up @@ -123,7 +128,7 @@ jest.mock('@geonetwork-ui/data-fetcher', () => ({
resolve(dataset)
})
),
SupportedTypes: ['csv', 'geojson', 'json', 'excel'],
SupportedTypes: ['csv', 'geojson', 'json', 'excel', 'gml'],
}))

describe('DataService', () => {
Expand Down Expand Up @@ -240,6 +245,14 @@ describe('DataService', () => {
url: 'http://local/wfs?GetFeature&FeatureType=surval_parametre_ligne&format=json',
type: MetadataLinkType.WFS,
},
{
description: 'Lieu de surveillance (ligne)',
mimeType: 'gml',
name: 'surval_parametre_ligne',
protocol: 'OGC:WFS',
url: 'http://local/wfs?GetFeature&FeatureType=surval_parametre_ligne&format=gml',
type: MetadataLinkType.WFS,
},
])
})
})
Expand Down Expand Up @@ -269,6 +282,14 @@ describe('DataService', () => {
url: 'http://local/wfs?GetFeature&FeatureType=nojson_type&format=xls',
type: MetadataLinkType.WFS,
},
{
description: 'Lieu de surveillance (ligne)',
mimeType: 'gml',
name: 'nojson_type',
protocol: 'OGC:WFS',
url: 'http://local/wfs?GetFeature&FeatureType=nojson_type&format=gml',
type: MetadataLinkType.WFS,
},
])
})
})
Expand Down Expand Up @@ -306,6 +327,14 @@ describe('DataService', () => {
url: 'http://unique-feature-type/wfs?GetFeature&FeatureType=myOnlyOne&format=json',
type: MetadataLinkType.WFS,
},
{
description: 'Lieu de surveillance (ligne)',
mimeType: 'gml',
name: '',
protocol: 'OGC:WFS',
url: 'http://unique-feature-type/wfs?GetFeature&FeatureType=myOnlyOne&format=gml',
type: MetadataLinkType.WFS,
},
])
})
})
Expand All @@ -315,8 +344,9 @@ describe('DataService', () => {
describe('WFS with GeoJSON support', () => {
it('returns an url', async () => {
const url = await service
.getGeoJsonDownloadUrlFromWfs('http://local/wfs', 'abcd')
.getDownloadUrlsFromWfs('http://local/wfs', 'abcd')
.toPromise()
.then((urls) => urls.geojson)
expect(url).toEqual(
'http://local/wfs?GetFeature&FeatureType=abcd&format=application/json'
)
Expand All @@ -326,18 +356,19 @@ describe('DataService', () => {
it('returns an observable that errors with a relevant error', async () => {
try {
await service
.getGeoJsonDownloadUrlFromWfs('http://local/wfs', 'nojsontype')
.getDownloadUrlsFromWfs('http://local/wfs', 'nojsontype')
.toPromise()
} catch (e) {
expect(e.message).toBe('wfs.geojson.notsupported')
expect(e.message).toBe('wfs.geojsongml.notsupported')
}
})
})
describe('WFS with only one feature type, no feature type name specified', () => {
it('returns one valid link using the only feature type', async () => {
const url = await service
.getGeoJsonDownloadUrlFromWfs('http://unique-feature-type/wfs', '')
.getDownloadUrlsFromWfs('http://unique-feature-type/wfs', '')
.toPromise()
.then((urls) => urls.geojson)
expect(url).toEqual(
'http://unique-feature-type/wfs?GetFeature&FeatureType=myOnlyOne&format=application/json'
)
Expand Down Expand Up @@ -501,15 +532,16 @@ describe('DataService', () => {

describe('#getGeoJsonDownloadUrlFromWfs', () => {
it('creates a WFS endpoint with a proxied url', () => {
service.getGeoJsonDownloadUrlFromWfs('http://local/wfs', 'abcd')
service.getDownloadUrlsFromWfs('http://local/wfs', 'abcd')
expect(newEndpointCall).toHaveBeenCalledWith(
'http://proxy.local/?url=http%3A%2F%2Flocal%2Fwfs'
)
})
it('returns a proxied url', async () => {
const url = await service
.getGeoJsonDownloadUrlFromWfs('http://local/wfs', 'abcd')
.getDownloadUrlsFromWfs('http://local/wfs', 'abcd')
.toPromise()
.then((urls) => urls.geojson)
expect(url).toEqual(
'http://proxy.local/?url=http%3A%2F%2Flocal%2Fwfs?GetFeature&FeatureType=abcd&format=application/json'
)
Expand Down
54 changes: 36 additions & 18 deletions libs/feature/dataviz/src/lib/service/data.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'
import { marker } from '@biesbjerg/ngx-translate-extract-marker'
import { WfsEndpoint } from '@camptocamp/ogc-client'
import { WfsEndpoint, WfsVersion } from '@camptocamp/ogc-client'
import {
BaseReader,
FetchError,
Expand All @@ -24,7 +24,7 @@ marker('wfs.unreachable.cors')
marker('wfs.unreachable.http')
marker('wfs.unreachable.unknown')
marker('wfs.featuretype.notfound')
marker('wfs.geojson.notsupported')
marker('wfs.geojsongml.notsupported')
marker('dataset.error.network')
marker('dataset.error.http')
marker('dataset.error.parse')
Expand All @@ -33,6 +33,7 @@ marker('dataset.error.unknown')
interface WfsDownloadUrls {
all: { [format: string]: string }
geojson: string
gml: { featureUrl: string; namespace: string; wfsVersion: WfsVersion }
}

@Injectable({
Expand Down Expand Up @@ -83,20 +84,23 @@ export class DataService {
outputCrs: 'EPSG:4326',
})
: null,
}
})
)
}

private getGeoJsonDownloadUrlFromWfs(
wfsUrl: string,
featureType: string
): Observable<string> {
return this.getDownloadUrlsFromWfs(wfsUrl, featureType).pipe(
map((urls) => urls.geojson),
tap((url) => {
if (url === null) {
throw new Error('wfs.geojson.notsupported')
gml:
featureType.outputFormats.find((f) =>
f.toLowerCase().includes('gml')
) &&
(featureType.defaultCrs === 'EPSG:4326' ||
featureType.otherCrs?.includes('EPSG:4326'))
? {
featureUrl: endpoint.getFeatureUrl(featureType.name, {
outputFormat: featureType.outputFormats.find((f) =>
f.toLowerCase().includes('gml')
),
outputCrs: 'EPSG:4326',
}),
namespace: featureType.name,
wfsVersion: endpoint.getVersion(),
}
: null,
}
})
)
Expand All @@ -109,6 +113,7 @@ export class DataService {
}

getDownloadLinksFromWfs(wfsLink: MetadataLink): Observable<MetadataLink[]> {
// Pour DL toutes les données
return this.getDownloadUrlsFromWfs(wfsLink.url, wfsLink.name).pipe(
map((urls) => urls.all),
map((urls) =>
Expand Down Expand Up @@ -155,8 +160,21 @@ export class DataService {
getDataset(link: MetadataLink): Observable<BaseReader> {
const linkUrl = this.proxy.getProxiedUrl(link.url)
if (link.type === MetadataLinkType.WFS) {
return this.getGeoJsonDownloadUrlFromWfs(linkUrl, link.name).pipe(
switchMap((url) => openDataset(url, 'geojson')),
return this.getDownloadUrlsFromWfs(linkUrl, link.name).pipe(
switchMap((urls) => {
if (urls.geojson) return openDataset(urls.geojson, 'geojson')
if (urls.gml)
return openDataset(urls.gml.featureUrl, 'gml', {
namespace: urls.gml.namespace,
wfsVersion: urls.gml.wfsVersion,
})
return null
}),
tap((url) => {
if (url === null) {
throw new Error('wfs.geojsongml.notsupported')
}
}),
catchError(this.interpretError)
)
} else if (link.type === MetadataLinkType.DOWNLOAD) {
Expand Down
Loading

0 comments on commit 7babe14

Please sign in to comment.