Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix] : Handle non geospatial ogc services #889

Merged
merged 10 commits into from
Jun 6, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class MdViewFacadeMock {
mapApiLinks$ = new BehaviorSubject([])
dataLinks$ = new BehaviorSubject([])
geoDataLinks$ = new BehaviorSubject([])
geoDataLinksWithGeometry$ = new BehaviorSubject([])
downloadLinks$ = new BehaviorSubject([])
apiLinks$ = new BehaviorSubject([])
otherLinks$ = new BehaviorSubject([])
Expand Down Expand Up @@ -377,6 +378,7 @@ describe('RecordMetadataComponent', () => {
})
describe('when a GEODATA link present', () => {
beforeEach(() => {
facade.geoDataLinksWithGeometry$.next(['link'])
facade.geoDataLinks$.next(['link'])
fixture.detectChanges()
mapTab = fixture.debugElement.queryAll(By.css('mat-tab'))[0]
Expand All @@ -399,7 +401,7 @@ describe('RecordMetadataComponent', () => {
beforeEach(() => {
facade.mapApiLinks$.next(['link'])
facade.dataLinks$.next(null)
facade.geoDataLinks$.next(null)
facade.geoDataLinksWithGeometry$.next(null)
fixture.detectChanges()
tableTab = fixture.debugElement.queryAll(By.css('mat-tab'))[1]
chartTab = fixture.debugElement.queryAll(By.css('mat-tab'))[2]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SourcesService } from '@geonetwork-ui/feature/catalog'
import { SearchService } from '@geonetwork-ui/feature/search'
import { ErrorType } from '@geonetwork-ui/ui/elements'
import { BehaviorSubject, combineLatest } from 'rxjs'
import { filter, map, mergeMap } from 'rxjs/operators'
import { filter, map, mergeMap, startWith } from 'rxjs/operators'
import { OrganizationsServiceInterface } from '@geonetwork-ui/common/domain/organizations.service.interface'
import {
Keyword,
Expand All @@ -22,12 +22,12 @@ export class RecordMetadataComponent {

displayMap$ = combineLatest([
this.metadataViewFacade.mapApiLinks$,
this.metadataViewFacade.geoDataLinks$,
this.metadataViewFacade.geoDataLinksWithGeometry$,
cmoinier marked this conversation as resolved.
Show resolved Hide resolved
]).pipe(
map(
([mapLinks, geoDataLinks]) =>
mapLinks?.length > 0 || geoDataLinks?.length > 0
)
map(([mapApiLinks, geoDataLinksWithGeometry]) => {
return mapApiLinks?.length > 0 || geoDataLinksWithGeometry?.length > 0
}),
startWith(false)
)

displayData$ = combineLatest([
Expand Down
8 changes: 8 additions & 0 deletions libs/common/fixtures/src/lib/records.fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ Cette section contient des *caractères internationaux* (ainsi que des "caractè
description: 'This WFS service offers direct download capability',
identifierInService: 'my:featuretype',
},
{
type: 'service',
url: new URL('https://my-org.net/ogc'),
accessServiceProtocol: 'ogcFeatures',
name: 'my:featuretype',
description: 'This OGC service offers direct download capability',
identifierInService: 'my:featuretype',
},
],
lineage: `This record was edited manually to test the conversion processes

Expand Down
27 changes: 27 additions & 0 deletions libs/feature/dataviz/src/lib/service/data.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ jest.mock('@camptocamp/ogc-client', () => ({
})
}
allCollections = Promise.resolve([{ name: 'collection1' }])
featureCollections =
this.url.indexOf('error.http') > -1
? Promise.reject(new Error())
: Promise.resolve(['collection1', 'collection2'])
getCollectionItem(collection, id) {
return Promise.resolve('item1')
}
},
}))

Expand Down Expand Up @@ -700,5 +707,25 @@ describe('DataService', () => {
)
})
})
describe('#getItemsFromOgcApi', () => {
describe('calling getItemsFromOgcApi() with a valid URL', () => {
it('returns the first collection item when collections array is not empty', async () => {
const item = await service.getItemsFromOgcApi(
'https://my.ogc.api/features'
)
expect(item).toBe('item1')
})
})

describe('calling getItemsFromOgcApi() with an erroneous URL', () => {
it('throws an error', async () => {
try {
await service.getItemsFromOgcApi('http://error.http/ogcapi')
} catch (e) {
expect(e.message).toBe('ogc.unreachable.unknown')
}
})
})
})
})
})
14 changes: 14 additions & 0 deletions libs/feature/dataviz/src/lib/service/data.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
import {
OgcApiCollectionInfo,
OgcApiEndpoint,
OgcApiRecord,
WfsEndpoint,
WfsVersion,
} from '@camptocamp/ogc-client'
Expand Down Expand Up @@ -183,6 +184,19 @@ export class DataService {
})
}

async getItemsFromOgcApi(url: string): Promise<OgcApiRecord> {
const endpoint = new OgcApiEndpoint(this.proxy.getProxiedUrl(url))
return await endpoint.featureCollections
.then((collections) => {
return collections.length
? endpoint.getCollectionItem(collections[0], '1')
: null
})
.catch((error) => {
throw new Error(`ogc.unreachable.unknown`)
})
}

getDownloadLinksFromEsriRest(
esriRestLink: DatasetServiceDistribution
): DatasetDistribution[] {
Expand Down
10 changes: 10 additions & 0 deletions libs/feature/map/src/lib/utils/map-utils.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,16 @@ describe('MapUtilsService', () => {
})
})

describe('getRecordExtent', () => {
it('should return null if spatialExtents is not present or is an empty array', () => {
const record1: Partial<CatalogRecord> = {}
const record2: Partial<CatalogRecord> = { spatialExtents: [] }

expect(service.getRecordExtent(record1)).toBeNull()
expect(service.getRecordExtent(record2)).toBeNull()
})
})

describe('#prioritizePageScroll', () => {
const interactions = defaults()
let dragRotate
Expand Down
2 changes: 1 addition & 1 deletion libs/feature/map/src/lib/utils/map-utils.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export class MapUtilsService {
}

getRecordExtent(record: Partial<CatalogRecord>): Extent {
if (!('spatialExtents' in record)) {
if (!('spatialExtents' in record) || record.spatialExtents.length === 0) {
return null
}
// transform an array of geojson geometries into a bbox
Expand Down
30 changes: 15 additions & 15 deletions libs/feature/record/src/lib/map-view/map-view.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jest.mock('@geonetwork-ui/util/app-config', () => ({

class MdViewFacadeMock {
mapApiLinks$ = new Subject()
geoDataLinks$ = new Subject()
geoDataLinksWithGeometry$ = new Subject()
metadata$ = of({ title: 'abcd' })
}

Expand Down Expand Up @@ -272,7 +272,7 @@ describe('MapViewComponent', () => {
describe('with no link compatible with MAP_API or GEODATA usage', () => {
beforeEach(fakeAsync(() => {
mdViewFacade.mapApiLinks$.next([])
mdViewFacade.geoDataLinks$.next([])
mdViewFacade.geoDataLinksWithGeometry$.next([])
tick()
fixture.detectChanges()
}))
Expand Down Expand Up @@ -317,7 +317,7 @@ describe('MapViewComponent', () => {
accessServiceProtocol: 'wms',
},
])
mdViewFacade.geoDataLinks$.next([])
mdViewFacade.geoDataLinksWithGeometry$.next([])
tick()
fixture.detectChanges()
}))
Expand Down Expand Up @@ -365,7 +365,7 @@ describe('MapViewComponent', () => {
accessServiceProtocol: 'wms',
},
])
mdViewFacade.geoDataLinks$.next([
mdViewFacade.geoDataLinksWithGeometry$.next([
{
url: new URL('http://abcd.com/wfs'),
name: 'featuretype',
Expand Down Expand Up @@ -419,7 +419,7 @@ describe('MapViewComponent', () => {
describe('with a link using WFS protocol', () => {
beforeEach(fakeAsync(() => {
mdViewFacade.mapApiLinks$.next([])
mdViewFacade.geoDataLinks$.next([
mdViewFacade.geoDataLinksWithGeometry$.next([
{
url: new URL('http://abcd.com/wfs'),
name: 'featuretype',
Expand Down Expand Up @@ -453,7 +453,7 @@ describe('MapViewComponent', () => {
accessServiceProtocol: 'wmts',
},
])
mdViewFacade.geoDataLinks$.next([])
mdViewFacade.geoDataLinksWithGeometry$.next([])
tick(200)
fixture.detectChanges()
}))
Expand All @@ -474,7 +474,7 @@ describe('MapViewComponent', () => {
describe('with a link using ESRI:REST protocol', () => {
beforeEach(fakeAsync(() => {
mdViewFacade.mapApiLinks$.next([])
mdViewFacade.geoDataLinks$.next([
mdViewFacade.geoDataLinksWithGeometry$.next([
{
name: 'mes_hdf',
url: new URL(
Expand Down Expand Up @@ -503,7 +503,7 @@ describe('MapViewComponent', () => {
describe('with a link using OGC API protocol', () => {
beforeEach(fakeAsync(() => {
mdViewFacade.mapApiLinks$.next([])
mdViewFacade.geoDataLinks$.next([
mdViewFacade.geoDataLinksWithGeometry$.next([
{
name: 'ogc layer',
url: new URL('http://abcd.com/data/ogcapi'),
Expand All @@ -530,7 +530,7 @@ describe('MapViewComponent', () => {
describe('with a link using WFS which returns an error', () => {
beforeEach(() => {
mdViewFacade.mapApiLinks$.next([])
mdViewFacade.geoDataLinks$.next([
mdViewFacade.geoDataLinksWithGeometry$.next([
{
url: new URL('http://abcd.com/wfs/error'),
name: 'featuretype',
Expand All @@ -548,7 +548,7 @@ describe('MapViewComponent', () => {
describe('during download', () => {
beforeEach(fakeAsync(() => {
mdViewFacade.mapApiLinks$.next([])
mdViewFacade.geoDataLinks$.next([
mdViewFacade.geoDataLinksWithGeometry$.next([
{
url: new URL('http://abcd.com/data.geojson'),
name: 'data.geojson',
Expand All @@ -571,7 +571,7 @@ describe('MapViewComponent', () => {
describe('after download', () => {
beforeEach(fakeAsync(() => {
mdViewFacade.mapApiLinks$.next([])
mdViewFacade.geoDataLinks$.next([
mdViewFacade.geoDataLinksWithGeometry$.next([
{
url: new URL('http://abcd.com/data.geojson'),
name: 'data.geojson',
Expand Down Expand Up @@ -605,7 +605,7 @@ describe('MapViewComponent', () => {
describe('when receiving several metadata records', () => {
beforeEach(fakeAsync(() => {
mdViewFacade.mapApiLinks$.next([])
mdViewFacade.geoDataLinks$.next([
mdViewFacade.geoDataLinksWithGeometry$.next([
{
url: new URL('http://abcd.com/data.geojson'),
name: 'data.geojson',
Expand All @@ -620,7 +620,7 @@ describe('MapViewComponent', () => {
accessServiceProtocol: 'wms',
},
])
mdViewFacade.geoDataLinks$.next([])
mdViewFacade.geoDataLinksWithGeometry$.next([])
tick()
fixture.detectChanges()
}))
Expand Down Expand Up @@ -671,7 +671,7 @@ describe('MapViewComponent', () => {
accessServiceProtocol: 'wms',
},
])
mdViewFacade.geoDataLinks$.next([])
mdViewFacade.geoDataLinksWithGeometry$.next([])
dropdownComponent.selectValue.emit(1)
tick()
fixture.detectChanges()
Expand Down Expand Up @@ -856,7 +856,7 @@ describe('MapViewComponent', () => {
describe('changing the map context', () => {
beforeEach(() => {
jest.spyOn(component, 'resetSelection')
mdViewFacade.geoDataLinks$.next([])
mdViewFacade.geoDataLinksWithGeometry$.next([])
mdViewFacade.mapApiLinks$.next([])
})
it('resets selection', () => {
Expand Down
10 changes: 6 additions & 4 deletions libs/feature/record/src/lib/map-view/map-view.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ export class MapViewComponent implements OnInit, OnDestroy {

compatibleMapLinks$ = combineLatest([
this.mdViewFacade.mapApiLinks$,
this.mdViewFacade.geoDataLinks$,
this.mdViewFacade.geoDataLinksWithGeometry$,
]).pipe(
map(([mapApiLinks, geoDataLinks]) => [...mapApiLinks, ...geoDataLinks])
map(([mapApiLinks, geoDataLinksWithGeometry]) => {
return [...mapApiLinks, ...geoDataLinksWithGeometry]
})
)

dropdownChoices$ = this.compatibleMapLinks$.pipe(
Expand Down Expand Up @@ -102,8 +104,8 @@ export class MapViewComponent implements OnInit, OnDestroy {
mapContext$ = this.currentLayers$.pipe(
switchMap((layers) =>
from(this.mapUtils.getLayerExtent(layers[0])).pipe(
catchError((error) => {
console.warn(error) // FIXME: report this to the user somehow
catchError(() => {
this.error = 'The layer has no extent'
return of(undefined)
}),
map(
Expand Down
Loading
Loading