Skip to content

Commit

Permalink
fix(query): Properly remove features from query
Browse files Browse the repository at this point in the history
A silent issue was causing incorrect features being removed
from the feature query list

+ (re)define types
  • Loading branch information
jmacura committed Nov 26, 2024
1 parent 41b4030 commit 91beb2b
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 64 deletions.
27 changes: 21 additions & 6 deletions projects/hslayers/components/draw/draw-edit/draw-edit.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {NgClass} from '@angular/common';
import * as polygonClipping from 'polygon-clipping';
import polygonSplitter from 'polygon-splitter';
import {Feature} from 'ol';
import {Polygon} from 'ol/geom';
import {LineString, Polygon, SimpleGeometry} from 'ol/geom';
import {Vector} from 'ol/source';
import {Vector as VectorLayer} from 'ol/layer';

Expand All @@ -21,6 +21,12 @@ import {HsQueryVectorService} from 'hslayers-ng/services/query';
import {HsToastService} from 'hslayers-ng/common/toast';
import {defaultStyle} from 'hslayers-ng/services/styler';

declare type HsModifyOperations =
| 'difference'
| 'split'
| 'intersection'
| 'union';

@Component({
selector: 'hs-draw-edit',
templateUrl: './draw-edit.component.html',
Expand Down Expand Up @@ -277,15 +283,22 @@ export class HsDrawEditComponent implements OnDestroy, OnInit {
/**
* Modify firstly selected features with the output of polygonClipping
*/
setCoordinatesToFirstFeature(coords): void {
this.features[0].feature.getGeometry().setCoordinates(coords[0], 'XY');
setCoordinatesToFirstFeature(coords: any[]): void {
(this.features[0].feature.getGeometry() as SimpleGeometry).setCoordinates(
coords[0],
'XY',
);
}

get features() {
return this.HsQueryBaseService.features;
}

modify(type): void | boolean {
/**
* A wrapper for any modification of the selected polygons. Calls intersection(), split(), difference() or union() based on the type param.
* @param type - Type of modification.
*/
modify(type: HsModifyOperations): void {
const features = [];
const editCoords = [];

Expand All @@ -304,8 +317,10 @@ export class HsDrawEditComponent implements OnDestroy, OnInit {
if (type === 'split') {
const splittingLine =
this.features.length > 1
? this.features[1].feature
: this.editLayer.getSource().getFeatures()[0];
? (this.features[1].feature as Feature<LineString>)
: (this.editLayer
.getSource()
.getFeatures()[0] as Feature<LineString>);

newGeom = polygonSplitter(
{
Expand Down
24 changes: 4 additions & 20 deletions projects/hslayers/components/query/query-wms.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,6 @@ export class HsQueryWmsService {
});
}

/**
* Update feature list
* @param updated - Feature list has been updated
* @param group -
*/
updateFeatureList(
updated: boolean,
group: {
layer?: string;
name?: any;
attributes?: any[];
},
): void {
if (updated) {
this.hsQueryBaseService.set(group, 'features');
}
}

/**
* Request information about clicked WMS layer coordinates
* @param url - Request URL
Expand Down Expand Up @@ -188,7 +170,7 @@ export class HsQueryWmsService {
};
}),
};
this.updateFeatureList(true, group);
this.hsQueryBaseService.setFeatures(group);
}
}

Expand Down Expand Up @@ -238,7 +220,9 @@ export class HsQueryWmsService {
};
}),
};
this.updateFeatureList(updated, group);
if (updated) {
this.hsQueryBaseService.setFeatures(group);
}
});
}

Expand Down
14 changes: 10 additions & 4 deletions projects/hslayers/components/query/query.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,16 @@ export class HsQueryComponent extends HsPanelBaseComponent implements OnInit {
this.hsQueryVectorService.featureRemovals
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((feature) => {
this.hsQueryBaseService.features.splice(
this.hsQueryBaseService.features.indexOf(feature),
1,
);
const featureIdxInQuery = this.hsQueryBaseService.features
.map((fDescription) => fDescription.feature)
.filter((f) => f)
.indexOf(feature);
if (featureIdxInQuery < 0) {
// should not happen as the hsQueryBaseService.features array can't be manipulated from other place in the GUI,
// but it could be done programmatically
return;
}
this.hsQueryBaseService.features.splice(featureIdxInQuery, 1);
});
this.hsMapService.loaded().then((map) => {
map.addOverlay(this.popup);
Expand Down
56 changes: 33 additions & 23 deletions projects/hslayers/services/query/query-base.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,39 @@ import {Circle as CircleStyle, Fill, Stroke, Style} from 'ol/style';
import {Coordinate, createStringXY, toStringHDMS} from 'ol/coordinate';
import {Feature, Map} from 'ol';
import {FeatureLike} from 'ol/Feature';
import {Geometry, Point} from 'ol/geom';
import {Point} from 'ol/geom';
import {Select} from 'ol/interaction';
import {Vector} from 'ol/source';
import {Vector as VectorLayer} from 'ol/layer';
import {transform} from 'ol/proj';

import {HsConfig} from 'hslayers-ng/config';
import {HsEventBusService} from 'hslayers-ng/services/event-bus';
import {HsFeatureDescription} from './query-vector.service';
import {HsLanguageService} from 'hslayers-ng/services/language';
import {HsLayoutService} from 'hslayers-ng/services/layout';
import {HsMapService} from 'hslayers-ng/services/map';
import {HsSaveMapService} from 'hslayers-ng/services/save-map';
import {HsUtilsService} from 'hslayers-ng/services/utils';

declare type HsCoordinateDescription = {
name: string;
mapProjCoordinate: Coordinate;
epsg4326Coordinate: Coordinate;
projections: {name: string; value: any}[];
};

@Injectable({
providedIn: 'root',
})
export class HsQueryBaseService {
attributes = [];
features = [];
features: HsFeatureDescription[] = [];
featureInfoHtmls = [];
customFeatures = [];
coordinates = [];
selectedProj;
queryLayer;
queryLayer: VectorLayer;
featureLayersUnderMouse = [];
dataCleared = true;
invisiblePopup;
Expand Down Expand Up @@ -105,7 +113,7 @@ export class HsQueryBaseService {
}
this.dataCleared = false;
this.currentQuery = (Math.random() + 1).toString(36).substring(7);
this.set(this.getCoordinate(evt.coordinate), 'coordinates', true);
this.setCoordinates(this.getCoordinate(evt.coordinate));
this.last_coordinate_clicked = evt.coordinate; //It is used in some examples and apps
this.selectedProj = this.coordinates[0].projections[0];
this.getFeatureInfoStarted.next(evt);
Expand Down Expand Up @@ -181,12 +189,7 @@ export class HsQueryBaseService {
* @param coordinate - Coordinates from map single click interaction
* @returns Object with coordinates in multiple projections
*/
getCoordinate(coordinate: Coordinate): {
name: string;
mapProjCoordinate: Coordinate;
epsg4326Coordinate: Coordinate;
projections: {name: string; value: any}[];
} {
getCoordinate(coordinate: Coordinate): HsCoordinateDescription {
this.queryPoint.setCoordinates(coordinate, 'XY');
const epsg4326Coordinate = transform(
coordinate,
Expand Down Expand Up @@ -288,20 +291,27 @@ export class HsQueryBaseService {
return defaultStyle;
}

set(data: any, type: string, overwrite?: boolean): void {
if (type) {
if (overwrite) {
this[type].length = 0;
}
if (Array.isArray(data)) {
this[type] = this[type].concat(data);
} else {
this[type].push(data);
}
this.hsEventBusService.queryDataUpdated.next(this);
} else if (console) {
console.log('Query.BaseService.setData type not passed');
/**
* Sets latest coordinates as current descriptor
* @param coords - Description of coordinates in HsCoordinateDescription format
*/
setCoordinates(coords: HsCoordinateDescription): void {
this.coordinates.length = 0;
this.coordinates.push(coords);
this.hsEventBusService.queryDataUpdated.next(this);
}

/**
* Sets latest features as current descriptor
* @param features - Either a description of features in HsFeatureDescription format or an array of these descriptions
*/
setFeatures(features: HsFeatureDescription[] | HsFeatureDescription): void {
if (Array.isArray(features)) {
this.features = this.features.concat(features);
} else {
this.features.push(features);
}
this.hsEventBusService.queryDataUpdated.next(this);
}

clear(type?: string): void {
Expand Down
21 changes: 10 additions & 11 deletions projects/hslayers/services/query/query-vector.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {Subject, debounceTime} from 'rxjs';
import * as extent from 'ol/extent';
import {Cluster, Vector as VectorSource} from 'ol/source';
import {Coordinate} from 'ol/coordinate';
import {Feature, Map} from 'ol';
import {FeatureLike} from 'ol/Feature';
import {Feature} from 'ol';
import {GeoJSON, WKT} from 'ol/format';
import {Geometry, LineString, Polygon} from 'ol/geom';
import {Select} from 'ol/interaction';
Expand All @@ -33,16 +32,16 @@ type AttributeValuePair = {
sanitizedValue?;
};

type FeatureDescription = {
export type HsFeatureDescription = {
layer: string;
name: string;
attributes: any[];
stats: {
stats?: {
name: string;
value: any;
}[];
hstemplate: any;
feature: any;
hstemplate?: any;
feature?: Feature;
};

@Injectable({
Expand Down Expand Up @@ -162,13 +161,13 @@ export class HsQueryVectorService {
createFeatureAttributeList(): void {
this.hsQueryBaseService.attributes.length = 0;
const features = this.selector.getFeatures().getArray();
let featureDescriptions = [];
let featureDescriptions: HsFeatureDescription[] = [];
for (const feature of features) {
featureDescriptions = featureDescriptions.concat(
this.getFeatureAttributes(feature),
);
}
this.hsQueryBaseService.set(featureDescriptions, 'features');
this.hsQueryBaseService.setFeatures(featureDescriptions);
this.hsQueryBaseService.getFeatureInfoCollected.next();
}

Expand Down Expand Up @@ -304,9 +303,9 @@ export class HsQueryVectorService {
* @param feature - Selected feature from map
* @returns Feature attributes
*/
getFeatureAttributes(feature: Feature<Geometry>): FeatureDescription[] {
getFeatureAttributes(feature: Feature<Geometry>): HsFeatureDescription[] {
const attributes = [];
let tmp: FeatureDescription[] = [];
let tmp: HsFeatureDescription[] = [];
const hstemplate = feature.get('hstemplate')
? feature.get('hstemplate')
: null;
Expand Down Expand Up @@ -341,7 +340,7 @@ export class HsQueryVectorService {
}
}
if (!getFeatures(feature)) {
const featureDescription: FeatureDescription = {
const featureDescription: HsFeatureDescription = {
layer: this.getFeatureLayerName(feature),
name: 'Feature',
attributes: attributes,
Expand Down

0 comments on commit 91beb2b

Please sign in to comment.