Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jahow committed Jul 24, 2024
1 parent ce94962 commit a39e2f5
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 63 deletions.
10 changes: 10 additions & 0 deletions libs/feature/map/src/lib/+state/map.actions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { createAction, props } from '@ngrx/store'
import { MapContext } from '@geospatial-sdk/core'
import type { Feature } from 'geojson'

export const setContext = createAction(
'[Map] Set Context',
props<{ context: MapContext }>()
)

export const setSelectedFeatures = createAction(
'[Map] Set Selected Features',
props<{ selectedFeatures: Feature[] }>()
)

export const clearSelectedFeatures = createAction(
'[Map] Clear Selected Features'
)
10 changes: 10 additions & 0 deletions libs/feature/map/src/lib/+state/map.facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@ import { select, Store } from '@ngrx/store'
import * as MapSelectors from './map.selectors'
import * as MapActions from './map.actions'
import { MapContext } from '@geospatial-sdk/core'
import { Feature } from 'geojson'

@Injectable()
export class MapFacade {
context$ = this.store.pipe(select(MapSelectors.getMapContext))
selectedFeatures$ = this.store.pipe(select(MapSelectors.getSelectedFeatures))

constructor(private readonly store: Store) {}

applyContext(context: MapContext) {
this.store.dispatch(MapActions.setContext({ context }))
}

selectFeatures(selectedFeatures: Feature[]) {
this.store.dispatch(MapActions.setSelectedFeatures({ selectedFeatures }))
}

clearFeatureSelection() {
this.store.dispatch(MapActions.clearSelectedFeatures())
}
}
15 changes: 15 additions & 0 deletions libs/feature/map/src/lib/+state/map.reducer.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { Action, createReducer, on } from '@ngrx/store'
import * as MapActions from './map.actions'
import { MapContext } from '@geospatial-sdk/core'
import { Feature } from 'geojson'

export const MAP_FEATURE_KEY = 'map'

export interface MapState {
context: MapContext
selectedFeatures: Feature[]
}

export interface MapPartialState {
Expand All @@ -14,6 +16,7 @@ export interface MapPartialState {

export const initialMapState: MapState = {
context: { layers: [], view: {} },
selectedFeatures: [],
}

const reducer = createReducer(
Expand All @@ -23,6 +26,18 @@ const reducer = createReducer(
...state,
context,
}
}),
on(MapActions.setSelectedFeatures, (state, { selectedFeatures }) => {
return {
...state,
selectedFeatures,
}
}),
on(MapActions.clearSelectedFeatures, (state) => {
return {
...state,
selectedFeatures: [],
}
})
)

Expand Down
5 changes: 5 additions & 0 deletions libs/feature/map/src/lib/+state/map.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ export const getMapContext = createSelector(
getMapState,
(state: MapState) => state.context
)

export const getSelectedFeatures = createSelector(
getMapState,
(state: MapState) => state.selectedFeatures
)
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
<gn-ui-map-container [context]="context$ | async"></gn-ui-map-container>
<gn-ui-map-container
[context]="context$ | async"
(featuresClicked)="handleFeaturesClicked($event)"
></gn-ui-map-container>
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ import { MapFacade } from '../+state/map.facade'
import { MapContext, MapContextLayerXyz } from '@geospatial-sdk/core'
import { MapContainerComponent } from '@geonetwork-ui/ui/map'
import { CommonModule } from '@angular/common'
import Feature from 'ol/Feature'
import GeoJSON from 'ol/format/GeoJSON'

export const DEFAULT_BASELAYER_CONTEXT: MapContextLayerXyz = {
type: 'xyz',
urls: [
`https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
`https://b.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
`https://c.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
],
url: `https://{a-c}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`,
attributions: `<span>© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="https://carto.com/">Carto</a></span>`,
}

Expand All @@ -37,4 +35,13 @@ export class MapStateContainerComponent {
)

constructor(private mapFacade: MapFacade) {}

handleFeaturesClicked(features: Feature[]) {
if (!features.length) {
this.mapFacade.clearFeatureSelection()
return
}
const geojsonFeatures = new GeoJSON().writeFeaturesObject(features).features
this.mapFacade.selectFeatures(geojsonFeatures)
}
}
6 changes: 5 additions & 1 deletion libs/feature/record/src/lib/feature-record.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { NgModule } from '@angular/core'
import { CommonModule } from '@angular/common'
import { FeatureDetailComponent } from '@geonetwork-ui/ui/map'
import {
FeatureDetailComponent,
MapContainerComponent,
} from '@geonetwork-ui/ui/map'
import { StoreModule } from '@ngrx/store'
import { EffectsModule } from '@ngrx/effects'
import { UiLayoutModule } from '@geonetwork-ui/ui/layout'
Expand Down Expand Up @@ -57,6 +60,7 @@ import { DataViewShareComponent } from './data-view-share/data-view-share.compon
PopupAlertComponent,
FeatureDetailComponent,
MapStateContainerComponent,
MapContainerComponent,
],
providers: [MdViewFacade],
exports: [
Expand Down
5 changes: 4 additions & 1 deletion libs/feature/record/src/lib/map-view/map-view.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
<div
class="relative w-full h-full bg-white border border-gray-300 rounded-lg overflow-hidden"
>
<gn-ui-map-state-container></gn-ui-map-state-container>
<gn-ui-map-container
[context]="mapContext$ | async"
(featuresClicked)="onMapFeatureSelect($event)"
></gn-ui-map-container>
<div
class="top-[1em] right-[1em] p-3 bg-white absolute overflow-y-auto overflow-x-hidden max-h-72 w-56"
[class.hidden]="!selection"
Expand Down
108 changes: 53 additions & 55 deletions libs/feature/record/src/lib/map-view/map-view.component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
OnDestroy,
OnInit,
ViewChild,
} from '@angular/core'
import { MapStyleService, MapUtilsService } from '@geonetwork-ui/feature/map'
import { getOptionalMapConfig, MapConfig } from '@geonetwork-ui/util/app-config'
Expand All @@ -14,33 +14,38 @@ import { StyleLike } from 'ol/style/Style'
import {
BehaviorSubject,
combineLatest,
from,
Observable,
of,
Subscription,
startWith,
throwError,
withLatestFrom,
} from 'rxjs'
import {
catchError,
distinctUntilChanged,
finalize,
map,
switchMap,
tap,
} from 'rxjs/operators'
import { MdViewFacade } from '../state/mdview.facade'
import { DataService } from '@geonetwork-ui/feature/dataviz'
import { DatasetDistribution } from '@geonetwork-ui/common/domain/model/record'
import { MapContextLayer } from '@geospatial-sdk/core'
import { MapContext, MapContextLayer } from '@geospatial-sdk/core'
import { MapContainerComponent } from '@geonetwork-ui/ui/map'

@Component({
selector: 'gn-ui-map-view',
templateUrl: './map-view.component.html',
styleUrls: ['./map-view.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MapViewComponent implements OnInit, OnDestroy {
export class MapViewComponent implements AfterViewInit {
@ViewChild(MapContainerComponent) mapContainer: MapContainerComponent

mapConfig: MapConfig = getOptionalMapConfig()
selection: Feature<Geometry>
private subscription = new Subscription()
private selectionStyle: StyleLike

compatibleMapLinks$ = combineLatest([
Expand Down Expand Up @@ -91,44 +96,44 @@ export class MapViewComponent implements OnInit, OnDestroy {
})
)

// mapContext$ = this.currentLayers$.pipe(
// switchMap((layers) =>
// from(this.mapUtils.getLayerExtent(layers[0])).pipe(
// catchError(() => {
// this.error = 'The layer has no extent'
// return of(undefined)
// }),
// map(
// (extent) =>
// ({
// layers,
// view: {
// extent,
// },
// } as MapContext)
// ),
// tap((res) => {
// this.resetSelection()
// })
// )
// ),
// startWith({
// layers: [],
// view: {},
// } as MapContext),
// withLatestFrom(this.mdViewFacade.metadata$),
// map(([context, metadata]) => {
// if (context.view.extent) return context
// const extent = this.mapUtils.getRecordExtent(metadata)
// return {
// ...context,
// view: {
// ...context.view,
// extent,
// },
// }
// })
// )
mapContext$ = this.currentLayers$.pipe(
switchMap((layers) =>
from(this.mapUtils.getLayerExtent(layers[0])).pipe(
catchError(() => {
this.error = 'The layer has no extent'
return of(undefined)
}),
map(
(extent) =>
({
layers,
view: {
extent,
},
} as MapContext)
),
tap((res) => {
this.resetSelection()
})
)
),
startWith({
layers: [],
view: {},
} as MapContext),
withLatestFrom(this.mdViewFacade.metadata$),
map(([context, metadata]) => {
if (context.view.extent) return context
const extent = this.mapUtils.getRecordExtent(metadata)
return {
...context,
view: {
...context.view,
extent,
},
}
})
)

constructor(
private mdViewFacade: MdViewFacade,
Expand All @@ -138,18 +143,11 @@ export class MapViewComponent implements OnInit, OnDestroy {
private styleService: MapStyleService
) {}

ngOnDestroy(): void {
this.subscription.unsubscribe()
}

ngOnInit(): void {
this.mapUtils.prioritizePageScroll(this.mapManager.map.getInteractions())
this.selectionStyle = this.styleService.styles.defaultHL
this.subscription.add(
this.featureInfo.features$.subscribe((features) => {
this.onMapFeatureSelect(features)
})
ngAfterViewInit(): void {
this.mapUtils.prioritizePageScroll(
this.mapContainer.openlayersMap.getInteractions()
)
this.selectionStyle = this.styleService.styles.defaultHL
}

onMapFeatureSelect(features: Feature<Geometry>[]): void {
Expand Down

0 comments on commit a39e2f5

Please sign in to comment.