-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dev version, not usable as a main panel yet
- Loading branch information
1 parent
952875a
commit b5aa8b4
Showing
4 changed files
with
190 additions
and
38 deletions.
There are no files selected for viewing
62 changes: 61 additions & 1 deletion
62
projects/hslayers/components/wfs-filter/wfs-filter.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,61 @@ | ||
<hs-filters [rule]="rule"></hs-filters> | ||
<div class="container-fluid"> | ||
<!-- Check if there are available WFS layers --> | ||
@if (availableLayers.length > 0) { | ||
<!-- Layer selection dropdown --> | ||
<div class="row mb-3"> | ||
<div class="col-12"> | ||
<label for="layerSelect" class="form-label">Select WFS Layer:</label> | ||
<select id="layerSelect" class="form-select" [(ngModel)]="selectedLayer" | ||
(ngModelChange)="selectLayer($event)"> | ||
<option [ngValue]="null">-- Select a layer --</option> | ||
<!-- Loop through available layers --> | ||
@for (layer of availableLayers; track layer) { | ||
<option [ngValue]="layer"> | ||
{{ layer.title }} | ||
</option> | ||
} | ||
</select> | ||
</div> | ||
</div> | ||
|
||
<!-- Display filter options if a layer is selected --> | ||
@if (selectedLayer) { | ||
<div class="row"> | ||
<div class="col-12"> | ||
<div class="card"> | ||
<div class="card-body"> | ||
<h5 class="card-title">Filter for: {{ selectedLayer.title }}</h5> | ||
<!-- Filter component --> | ||
<hs-filters [rule]="rule" [selectedLayer]="selectedLayer" (change)="onChange()"></hs-filters> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
} @else { | ||
<!-- Prompt to select a layer if none is selected --> | ||
<div class="row"> | ||
<div class="col-12"> | ||
<div class="alert alert-info" role="alert"> | ||
Please select a WFS layer to apply filters. | ||
</div> | ||
</div> | ||
</div> | ||
} | ||
} @else { | ||
<!-- Display when no WFS layers are available --> | ||
<div class="row"> | ||
<div class="col-12"> | ||
<div class="text-center py-4"> | ||
<i class="icon-layers mb-3 text-muted" style="font-size: 48px;"></i> | ||
<h4>No WFS Layers Available</h4> | ||
<p class="mb-0">There are currently no WFS layers available for filtering.</p> | ||
<p>To use this feature, please add a WFS layer to the map first.</p> | ||
<!-- Button to open the Add Data panel --> | ||
<button class="btn btn-primary mt-3" (click)="openAddDataPanel()"> | ||
Add WFS Layer | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
} | ||
</div> |
145 changes: 108 additions & 37 deletions
145
projects/hslayers/components/wfs-filter/wfs-filter.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,120 @@ | ||
import * as olFormatFilter from 'ol/format/filter'; | ||
import {Component, Input, inject} from '@angular/core'; | ||
import { | ||
HsFiltersComponent, | ||
HsFiltersService, | ||
} from 'hslayers-ng/components/styler'; | ||
import {Component, Input, OnInit, inject} from '@angular/core'; | ||
import {FormsModule} from '@angular/forms'; | ||
import {HsFiltersComponent, HsFiltersService} from 'hslayers-ng/common/filters'; | ||
import {HsLayerDescriptor} from 'hslayers-ng/types'; | ||
import {HsLayerManagerService} from 'hslayers-ng/services/layer-manager'; | ||
import {HsLayoutService} from 'hslayers-ng/services/layout'; | ||
import {HsUtilsService} from 'hslayers-ng/services/utils'; | ||
import {Vector as VectorLayer} from 'ol/layer'; | ||
import {Vector as VectorSource} from 'ol/source'; | ||
import {getWfsUrl} from 'hslayers-ng/common/extensions'; | ||
|
||
@Component({ | ||
selector: 'hs-wfs-filter', | ||
templateUrl: './wfs-filter.component.html', | ||
styles: ``, | ||
standalone: true, | ||
imports: [HsFiltersComponent], | ||
imports: [HsFiltersComponent, FormsModule], | ||
}) | ||
export class HsWfsFilterComponent { | ||
@Input() rule: any; | ||
export class HsWfsFilterComponent implements OnInit { | ||
@Input() rule: any = {}; | ||
@Input() preselectedLayer: HsLayerDescriptor; | ||
|
||
hsFiltersService = inject(HsFiltersService); | ||
constructor() {} | ||
|
||
parseFilters(filters: any[]): any[] { | ||
return filters.map((filter) => { | ||
switch (filter[0]) { | ||
case '==': | ||
return olFormatFilter.equalTo(filter[1], filter[2]); | ||
case '*=': | ||
return olFormatFilter.like(filter[1], filter[2]); | ||
case '!=': | ||
return olFormatFilter.notEqualTo(filter[1], filter[2]); | ||
case '<': | ||
return olFormatFilter.lessThan(filter[1], filter[2]); | ||
case '<=': | ||
return olFormatFilter.lessThanOrEqualTo(filter[1], filter[2]); | ||
case '>': | ||
return olFormatFilter.greaterThan(filter[1], filter[2]); | ||
case '>=': | ||
return olFormatFilter.greaterThanOrEqualTo(filter[1], filter[2]); | ||
case '&&': | ||
return olFormatFilter.and(...this.parseFilters(filter.slice(1))); | ||
case '||': | ||
return olFormatFilter.or(...this.parseFilters(filter.slice(1))); | ||
case '!': | ||
return olFormatFilter.not(this.parseFilters([filter[1]])[0]); | ||
default: | ||
throw new Error('Invalid filter type'); | ||
} | ||
}); | ||
hsLayerManagerService = inject(HsLayerManagerService); | ||
hsUtilsService = inject(HsUtilsService); | ||
hsLayoutService = inject(HsLayoutService); | ||
|
||
availableLayers: HsLayerDescriptor[] = []; | ||
selectedLayer: HsLayerDescriptor | null = null; | ||
|
||
ngOnInit() { | ||
this.updateAvailableLayers(); | ||
if (this.preselectedLayer) { | ||
this.selectLayer(this.preselectedLayer); | ||
} | ||
} | ||
|
||
/** | ||
* Updates the list of available WFS layers | ||
*/ | ||
updateAvailableLayers() { | ||
this.availableLayers = this.hsLayerManagerService.data.layers.filter( | ||
(l: HsLayerDescriptor) => | ||
this.hsUtilsService.instOf(l.layer, VectorLayer) && | ||
this.hsUtilsService.instOf(l.layer.getSource(), VectorSource) && | ||
getWfsUrl(l.layer), | ||
); | ||
} | ||
|
||
/** | ||
* Selects a layer and updates the filter service | ||
* @param layer The layer to select | ||
*/ | ||
selectLayer(layer: HsLayerDescriptor | null) { | ||
this.selectedLayer = layer; | ||
this.hsFiltersService.setSelectedLayer(layer); | ||
// Reset the rule when changing layers | ||
this.rule = {}; | ||
} | ||
|
||
/** | ||
* Handles changes in the filter | ||
*/ | ||
onChange() { | ||
if (this.rule.filter) { | ||
const parsedFilter = this.parseFilter(this.rule.filter); | ||
console.log('Parsed OpenLayers filter for WFS:', parsedFilter); | ||
// You can now use this parsedFilter with OpenLayers for WFS requests | ||
} | ||
} | ||
|
||
/** | ||
* Parses the filter into OpenLayers format | ||
* @param filter The filter to parse | ||
* @returns Parsed OpenLayers filter | ||
*/ | ||
parseFilter(filter: any[]): any { | ||
if (!Array.isArray(filter)) { | ||
return null; | ||
} | ||
|
||
const [operator, ...operands] = filter; | ||
|
||
switch (operator) { | ||
case '||': | ||
return olFormatFilter.or(...operands.map((op) => this.parseFilter(op))); | ||
case '&&': | ||
return olFormatFilter.and( | ||
...operands.map((op) => this.parseFilter(op)), | ||
); | ||
case '!': | ||
return olFormatFilter.not(this.parseFilter(operands[0])); | ||
case '==': | ||
return olFormatFilter.equalTo(operands[0], operands[1]); | ||
case '*=': | ||
return olFormatFilter.like(operands[0], operands[1]); | ||
case '!=': | ||
return olFormatFilter.notEqualTo(operands[0], operands[1]); | ||
case '<': | ||
return olFormatFilter.lessThan(operands[0], operands[1]); | ||
case '<=': | ||
return olFormatFilter.lessThanOrEqualTo(operands[0], operands[1]); | ||
case '>': | ||
return olFormatFilter.greaterThan(operands[0], operands[1]); | ||
case '>=': | ||
return olFormatFilter.greaterThanOrEqualTo(operands[0], operands[1]); | ||
default: | ||
console.warn(`Unsupported operator: ${operator}`); | ||
return null; | ||
} | ||
} | ||
|
||
/** | ||
* Opens the Add Data panel | ||
*/ | ||
openAddDataPanel() { | ||
this.hsLayoutService.setMainPanel('addData'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './styler.service'; | ||
export * from './default-style'; | ||
export * from './style-part-base.component'; |
20 changes: 20 additions & 0 deletions
20
projects/hslayers/services/styler/style-part-base.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import {Component, EventEmitter, Input, Output} from '@angular/core'; | ||
|
||
@Component({ | ||
template: '<div></div>', | ||
standalone: true, | ||
}) | ||
export class HsStylerPartBaseComponent { | ||
@Output() changes = new EventEmitter<void>(); | ||
@Output() deleteFilter = new EventEmitter<void>(); | ||
|
||
@Input() warning: string; | ||
|
||
emitChange(): void { | ||
this.changes.emit(); | ||
} | ||
|
||
deleteRuleFilter(): void { | ||
this.deleteFilter.emit(); | ||
} | ||
} |