Skip to content

Commit

Permalink
Layer control enhancements (#142)
Browse files Browse the repository at this point in the history
* fix: show button for settings if layer has action; closes #135

* fix: Show layer expand icon only when the layer has some things to expand

* refactor: move style switcher into settings tab

* feat: Allow dynamic components for layer.description

* feat: Allow dynamic components for layer.description - set input

* feat: adjust types to allow Dynamic components for layer description

* fix: Do not change the layer object binding in layerentry

* refactor: add example for layer.description as component

* feat: use inputs.description if possible to generate abstract from dynamic component

* fix: Show layer expand icon if filtertype not Baselayers

* fix: remove right border on tabsbody for layers inside a group

* fix: Do not change the group object binding in

* fix: toggle group tabs and show all settings

* feat: Allow Dynamic components for Group description

* feat: Allow legend on LayerGroup #138

* refactor: add example legend and description components for group

* fix: style for group tabsbody and actions button position

* refactor: set input on layer IDynamicComponent - no object change needed after c6c437e
  • Loading branch information
boeckMt authored Sep 19, 2022
1 parent 8a4d9e0 commit ef628fc
Show file tree
Hide file tree
Showing 25 changed files with 412 additions and 95 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
### Features
* **@dlr-eoc/layer-control:**
- Allow legend on LayerGroup like on the layer - if one legend fits for all layers.
- Allow Dynamic components for Group description to display specific formatted descriptions.
- Allow Dynamic components for Layer description to display specific formatted descriptions (keep in mind that this breaks @dlr-eoc/services-ogc `generateResourceFromLayer` for this layer!!! - If you pass inputs.description to `IDynamicComponent` it will try to take this).


### Bug Fixes
* **@dlr-eoc/core-ui:**
- Fix style: remove right border on tabsbody for layers inside a group.

* **@dlr-eoc/layer-control:**
- Do not change the group object binding in `layerentry-group` when creating a dynamic component from the group.
- Do not change the layer object binding in `layerentry` when creating a dynamic component from the layer.
- For Baselayers also show button to switch to the settings tab if layer has action [Issue #135](https://github.com/dlr-eoc/ukis-frontend-libraries/issues/135).
- Show layer expand icon for 'Baselayers' only when the layer has some things to expand (`legendImg`, `description`, `action`, `actions` or `styles` as array to show a style switch).
* **@dlr-eoc/services-map-state:**
- Add missing time value in function `setMapState` on state initialization [issue 133](https://github.com/dlr-eoc/ukis-frontend-libraries/issues/133).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@
}

.layergroup {
.body {
.tabsbody {
border-right: none;
.layer{
.body {
.tabsbody {
border-right: none;
}
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions projects/demo-auth/src/styles/_ukis-layer-nav.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@
}

.layergroup {
.body {
.tabsbody {
border-right: none;
.layer{
.body {
.tabsbody {
border-right: none;
}
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion projects/demo-maps/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ import { RasterFeatureInfoComponent } from './components/raster-feature-info/ras
import { Popup2Component } from './components/popup2/popup2.component';
import { RouteExampleOwcLayersComponent } from './route-components/route-example-owc-layers/route-example-owc-layers.component';
import { BookmarksComponent } from './route-components/bookmarks/bookmarks.component';
import { ExampleLayerDescriptionComponent } from './components/example-layer-description/example-layer-description.component';
import { ExampleGroupLegendComponent } from './components/example-group-legend/example-group-legend.component';

@NgModule({
declarations: [
Expand Down Expand Up @@ -69,7 +71,9 @@ import { BookmarksComponent } from './route-components/bookmarks/bookmarks.compo
RasterFeatureInfoComponent,
Popup2Component,
RouteExampleOwcLayersComponent,
BookmarksComponent
BookmarksComponent,
ExampleLayerDescriptionComponent,
ExampleGroupLegendComponent
],
imports: [
BrowserModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="wrapper">
<!-- title="Show full Image" target="_blank" -->
<img [src]="legendImages[0].url" class="stacked" width="256" height="256" />
<img [src]="legendImages[1].url" usemap="#legendmap" />


<map name="legendmap">
<area shape="rect" coords="0,0,256,128" alt="top" title="Show full Image overlay" [href]="legendImages[0].url" target="_blank">
<area shape="rect" coords="0,128,256,256" alt="below" title="Show full Image base" [href]="legendImages[1].url" target="_blank">
</map>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.wrapper {
position: relative;

.stacked {
position: absolute;
pointer-events: none;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ExampleGroupLegendComponent } from './example-group-legend.component';

describe('ExampleGroupLegendComponent', () => {
let component: ExampleGroupLegendComponent;
let fixture: ComponentFixture<ExampleGroupLegendComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ExampleGroupLegendComponent ]
})
.compileComponents();

fixture = TestBed.createComponent(ExampleGroupLegendComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Component, Input, OnInit } from '@angular/core';
import { LayerGroup } from '@dlr-eoc/services-layers';

@Component({
selector: 'app-example-group-legend',
templateUrl: './example-group-legend.component.html',
styleUrls: ['./example-group-legend.component.scss']
})
export class ExampleGroupLegendComponent implements OnInit {
@Input() group: LayerGroup;
legendImages = [];
constructor() { }

ngOnInit(): void {
this.legendImages = this.group.layers.filter(l => l.legendImg && typeof l.legendImg === 'string').map(i => { return { url: i.legendImg } }).reverse();
}

}
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
import { Component, OnInit, Input, Output, EventEmitter, Inject } from '@angular/core';
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';

@Component({
selector: 'app-example-layer-action',
templateUrl: './example-layer-action.component.html',
styleUrls: ['./example-layer-action.component.scss']
})
export class ExampleLayerActionComponent {
export class ExampleLayerActionComponent implements OnInit {
@Input() layer;

private privValue = 1;
@Input() set value(value: number) {
this.privValue = value;
if (this.layer.custom_layer) {
this.layer.custom_layer.setRadius(value);
if (this.privValue !== value) {
this.privValue = value;

if (this.layer?.custom_layer) {
this.layer.custom_layer.setRadius(value);
}
}
}
get value() {
return this.privValue;
}

@Output() valueChange = new EventEmitter<number>();

constructor() { }

ngOnInit(): void {
this.layer.custom_layer.setRadius(this.value);
}

changeValue(event) {
const value = parseInt(event.target.value, 10);
this.value = value;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div class="custom-description">
{{this.description}}.
<p>
This description was styled with a dynamic component as the layer.description.
</p>

<p>
Keep in mind that this breaks @dlr-eoc/services-ogc generateResourceFromLayer() for this layer when exporting a
<b>IOwsContext</b>.
</p>

</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.custom-description {
word-break: normal;
color: #0072a3;

p {
word-break: normal;
color: rgb(255, 165, 46);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ExampleLayerDescriptionComponent } from './example-layer-description.component';

describe('ExampleLayerDescriptionComponent', () => {
let component: ExampleLayerDescriptionComponent;
let fixture: ComponentFixture<ExampleLayerDescriptionComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ExampleLayerDescriptionComponent ]
})
.compileComponents();

fixture = TestBed.createComponent(ExampleLayerDescriptionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Component, Input, OnInit } from '@angular/core';

@Component({
selector: 'app-example-layer-description',
templateUrl: './example-layer-description.component.html',
styleUrls: ['./example-layer-description.component.scss']
})
export class ExampleLayerDescriptionComponent implements OnInit {
@Input() layer;
@Input() description;
constructor() { }

ngOnInit(): void {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ export class RouteMap4Component implements OnInit, AfterViewInit {
setInput() {
const layer = this.layersSvc.getLayerById('heatmap_layer') as CustomLayer;
this.inputValue.value = 40;
layer.action.inputs = this.inputValue;
/** change object ref to trigger input change */
layer.action = Object.assign({}, layer.action);
layer.action.inputs.value = this.inputValue.value;
}

addLayers() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import olFill from 'ol/style/Fill';
import olCircleStyle from 'ol/style/Circle';
import olStroke from 'ol/style/Stroke';
import { WmsService } from '@dlr-eoc/services-ogc';
import { ExampleLayerDescriptionComponent } from '../../components/example-layer-description/example-layer-description.component';
import { ExampleGroupLegendComponent } from '../../components/example-group-legend/example-group-legend.component';

@Component({
selector: 'app-route-map',
Expand Down Expand Up @@ -93,7 +95,10 @@ export class RouteMapComponent implements OnInit {
}
},
visible: false,
description: 'eoc:world_relief_bw as web map tile service',
description: {
component: ExampleLayerDescriptionComponent,
inputs: { description: 'eoc:world_relief_bw as web map tile service' }
},
attribution: 'Relief: <a src="https://www.dlr.de/eoc">DLR/EOC</>',
legendImg: ''
});
Expand Down Expand Up @@ -148,8 +153,7 @@ export class RouteMapComponent implements OnInit {
// maxZoom: 8,
description: 'TDM90_DEM maxZoom: 8',
attribution: ' | TDM90 Data ©: <a href="http://www.dlr.de" target="_blank">DLR</a> licensed for <a rel="license" target="_blank" href="https://geoservice.dlr.de/resources/licenses/tdm90/License_for_the_Utilization_of_90m_DEM_for_Scientific_Use.pdf">scientific use</a>',
legendImg: '',
expanded: true,
legendImg: 'https://tiles.geoservice.dlr.de/service/wmts?layer=TDM90_DEM&style=default&tilematrixset=EPSG%3A3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix=EPSG%3A3857%3A4&TileCol=8&TileRow=5',
cssClass: 'custom-layer'
});

Expand Down Expand Up @@ -430,6 +434,7 @@ export class RouteMapComponent implements OnInit {
const eocBaseoverlay = new EocBaseoverlayTile();

const eocLiteoverlay = new EocLiteoverlayTile();
eocLiteoverlay.legendImg = 'https://tiles.geoservice.dlr.de/service/wmts?layer=eoc%3Aliteoverlay&style=_empty&tilematrixset=EPSG%3A3857&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix=EPSG%3A3857%3A4&TileCol=8&TileRow=5';

const OsmLayer = new OsmTileLayer();
/** add a Group of layers */
Expand All @@ -440,13 +445,20 @@ export class RouteMapComponent implements OnInit {
name: 'Test Group',
layers: [OsmLayer, eocBasemap, eocBaseoverlay],
description: 'this is a group with OsmLayer, eocBasemap, eocBaseoverlay',
expanded: true,
actions: [{ title: 'download', icon: 'download-cloud', action: (group) => { console.log(group); } }]
});

const groupLayer2 = new LayerGroup({
id: 'group_2',
name: 'Test Group 2',
expanded: true,
description: {
component: ExampleLayerDescriptionComponent,
inputs: { description: `A LayerGroup with a hidden vectorLayer2.` }
},
legendImg: {
component: ExampleGroupLegendComponent,
},
cssClass: 'custom-layer-group',
layers: [TDM90DEMLayer, vectorLayer2, eocLiteoverlay]
});
Expand Down
8 changes: 5 additions & 3 deletions projects/demo-maps/src/styles/_ukis-layer-nav.scss
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@
}

.layergroup {
.body {
.tabsbody {
border-right: none;
.layer{
.body {
.tabsbody {
border-right: none;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,36 +35,59 @@
<div *ngIf="group.expanded" class="body">
<!-- tools: zoomTo, remove, open all Tabs -->
<div class="tools">
<clr-icon *ngFor="let item of group.actions" [attr.shape]="item.icon" class="iconButton"
(click)="item.action(group)" [title]="item.title">
</clr-icon>

<clr-icon *ngIf="group.action" shape="cog" class="iconButton" [ngClass]="{'is-solid':showAction}"
(click)="showAction = !showAction" title="{{!showAction?'Show settings': 'Hide settings'}}"></clr-icon>
<clr-icon *ngIf="group.action" shape="cog" class="iconButton" [ngClass]="{'is-solid':activeTabs.settings}"
(click)="switchTab('settings')" title="{{!activeTabs.settings?'Show settings': 'Hide settings'}}"></clr-icon>
<clr-icon *ngIf="group.legendImg" title="{{!activeTabs.legend?'Show Legend': 'Hide Legend'}}" shape="image"
class="iconButton" [ngClass]="{'is-solid': activeTabs.legend}" (click)="switchTab('legend')"></clr-icon>
<clr-icon *ngIf="group.description" shape="info-standard" class="iconButton"
[ngClass]="{'is-solid': activeTabs.description}" (click)="switchTab('description')"
title="{{!activeTabs.description?'Show Info': 'Hide Info'}}"></clr-icon>

<clr-icon *ngIf="group.description" shape="info-standard" class="iconButton" [ngClass]="{'is-solid':showInfo}"
(click)="showInfo = !showInfo" title="{{!showInfo?'Show Info': 'Hide Info'}}"></clr-icon>
<clr-icon shape="details" class="iconButton" [ngClass]="{'is-solid':openAllLayersProperties}"
(click)="showHideAllDetails()"
title="{{!openAllLayersProperties?'Show all layers details': 'Hide all layers details'}}"></clr-icon>

<clr-icon *ngFor="let item of group.actions" [attr.shape]="item.icon" class="iconButton"
(click)="item.action(group)" [title]="item.title">
</clr-icon>

<span></span>
<clr-icon *ngIf="canZoomToGroup" shape="zoom-in" class="iconButton" (click)="zoomTo(group)" title="Zoom to group">
</clr-icon>
<clr-icon *ngIf="group.removable" shape="trash" class="iconButton" (click)="removeLayerGroup(group)"
title="Remove group"></clr-icon>
</div>

<div class="info" *ngIf="showInfo">
<span [innerHTML]="group.description"></span>
<!-- show Description -->
<div *ngIf="group.description && activeTabs.description" class="tabsbody">

<ng-container *ngIf="checkIsComponentItem(group,'description'); else descriptionText">
<ukis-dynamic-component [(dynamicComponent)]="dynamicComponents.description"></ukis-dynamic-component>
</ng-container>

<ng-template #descriptionText>
<span [innerHTML]="group.description"></span>
</ng-template>
</div>
<div *ngIf="group.action && showAction" class="tabsbody">

<!-- show group action -->
<div *ngIf="group.action && activeTabs.settings" class="tabsbody">
<ng-container *ngIf="checkIsComponentItem(group, 'action');">
<ukis-dynamic-component [(dynamicComponent)]="group.action">
</ukis-dynamic-component>
</ng-container>
</div>

<!-- show Legend -->
<div *ngIf="group.legendImg && activeTabs.legend" class="tabsbody">
<ng-container *ngIf="checkIsComponentItem(group,'legendImg'); else imageUrl">
<ukis-dynamic-component [(dynamicComponent)]="dynamicComponents.legendImg"></ukis-dynamic-component>
</ng-container>

<ng-template #imageUrl>
<a [href]="group.legendImg" target="_blank" title="Show full Image"><img [src]="group.legendImg" /></a>
</ng-template>
</div>

<!-- (cdkDropListSorted)="sort($event)" -->
<div cdkDropList (cdkDropListDropped)="drop($event)"
Expand Down
Loading

0 comments on commit ef628fc

Please sign in to comment.