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

Remove Bounding Box From Vertex #1866

Open
wants to merge 5 commits into
base: test
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
abstracts bounding box calculation, notifies user when bbox is used
  • Loading branch information
kim committed Feb 3, 2024
commit f89a9825e88505f1bdcaa22abb1b2383a4fb6b38
1 change: 1 addition & 0 deletions src/app/models/asf-api.model.ts
Original file line number Diff line number Diff line change
@@ -39,6 +39,7 @@ export enum PolygonRepairTypes {
CLOSE = 'CLOSE',
REVERSE = 'REVERSE',
WRAP = 'WRAP',
BBOX = 'BBOX'
}

export enum PolygonErrorTypes {
2 changes: 1 addition & 1 deletion src/app/services/map/map.service.ts
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ export class MapService {
tap(isDrawing => this.map.getViewport().style.cursor = isDrawing ? 'crosshair' : 'default')
);

private mapView: views.MapView;
private mapView: views.MapView = views.equatorial();
private map: Map;
private scaleLine: ScaleLine;

75 changes: 70 additions & 5 deletions src/app/services/polygon-validation.service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Injectable } from '@angular/core';

import { of } from 'rxjs';
import { filter, map, switchMap, catchError } from 'rxjs/operators';
import { filter, map, switchMap, catchError, withLatestFrom } from 'rxjs/operators';

import { MapService } from './map/map.service';
import { AsfApiService } from './asf-api.service';
import { WktService } from './wkt.service';

import * as models from '@models';
import { NotificationService } from './notification.service';
import { Feature } from 'ol';
import { Geometry, Polygon } from 'ol/geom';
import { DrawService } from './map/draw.service';

@Injectable({
providedIn: 'root'
@@ -22,6 +25,7 @@ export class PolygonValidationService {
private asfApiService: AsfApiService,
private wktService: WktService,
private notificationService: NotificationService,
private drawService: DrawService,
) { }

public validate(): void {
@@ -33,9 +37,19 @@ export class PolygonValidationService {
return skip;
}),
filter(p => !!p || this.polygons.has(p)),
switchMap(polygon => this.asfApiService.validate(polygon).pipe(
catchError(_ => of(null))
)),
// filter(([_, polygon]) => ),
map(([wkt, _]) => wkt),
withLatestFrom(this.drawService.polygon$),
switchMap(([wkt, polygon]) => {
const bbox = this.getRectangleBbox(polygon, this.mapService.epsg())
if (bbox.length > 0) {
return of({ wkt: { unwrapped: wkt }, repairs: [{ type: models.PolygonRepairTypes.BBOX, report: "The provided rectangle's bounding box will be used instead of the wkt" }] })
}
return this.asfApiService.validate(wkt).pipe(
catchError(_ => of(null))
);

}),
filter(resp => !!resp),
map(resp => {
const error = this.getErrorFrom(resp);
@@ -83,7 +97,7 @@ export class PolygonValidationService {
return resp.wkt.unwrapped;
}

const { report, type } = resp.repairs.pop();
const { report, type } = resp.repairs.pop();

if (type !== models.PolygonRepairTypes.WRAP && type !== models.PolygonRepairTypes.REVERSE) {
this.notificationService.info(
@@ -100,4 +114,55 @@ export class PolygonValidationService {

this.mapService.setDrawFeature(features);
}

public isRectangle(feature: Feature<Geometry>): boolean {
const geom = feature?.getGeometry()
if (geom instanceof Polygon) {
let points = (geom as Polygon).getCoordinates() ?? []
const extent = (geom as Polygon).getExtent()
for (const point of points[0][0]) {
if (!extent.includes(point)) {
return false;
}
}
return !!points && points[0].length === 5
}
return false;
}

public getRectangleBbox(feature: Feature<Geometry>, epsg: string): number[] {
// Attempts to get the bounding box of a rectangular polygon
if (this.isRectangle(feature)) {
const clonedFeature = this.cloneFeature(feature.clone());
const rectangle = clonedFeature.getGeometry() as Polygon;
return this.getBbox(rectangle, epsg);
}
return [];
}

private cloneFeature(feature: Feature<Geometry>): Feature<Geometry> {
const clonedFeature = feature.clone();
const clonedProperties = JSON.parse(JSON.stringify(feature.getProperties()));
clonedProperties.geometry = clonedFeature.getGeometry();
clonedFeature.setProperties(clonedProperties, true);
return clonedFeature;
}

private getBbox(rectangle: Polygon, epsg: string) {
rectangle.transform(epsg, 'EPSG:4326');
const outerHull = rectangle.getLinearRing(0).getCoordinates().slice(0, 4);
return this.wrapBbox([...outerHull[0], ...outerHull[2]]);
}

private wrapBbox(bbox: number[]): number[] {
return bbox.map(value => {
if (value > 180) {
value = value % 360 - 360;
}
if (value < -180) {
value = value % 360 + 360;
}
return value;
});
}
}
42 changes: 8 additions & 34 deletions src/app/services/search-params.service.ts
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ import { RangeService } from './range.service';

import * as models from '@models';
import { DrawService } from './map/draw.service';
import { Polygon } from 'ol/geom';
import { PolygonValidationService } from './polygon-validation.service';
@Injectable({
providedIn: 'root'
})
@@ -26,7 +26,8 @@ export class SearchParamsService {
private store$: Store<AppState>,
private mapService: MapService,
private rangeService: RangeService,
private drawService: DrawService
private drawService: DrawService,
private polygonValidationService: PolygonValidationService
) { }


@@ -63,7 +64,7 @@ export class SearchParamsService {
withLatestFrom(this.store$.select(filterStore.getSelectedDatasetId)),
map(([useCalibrationData, dataset]) =>
dataset === models.opera_s1.id && useCalibrationData ?
({dataset: models.opera_s1.calibrationDatasets}) : ({}))
({ dataset: models.opera_s1.calibrationDatasets }) : ({}))
)

private groupID$ = this.store$.select(filterStore.getGroupID).pipe(
@@ -79,38 +80,11 @@ export class SearchParamsService {
).pipe(
map(([polygon, shouldOmitGeoRegion, asdf]) => shouldOmitGeoRegion ? null : { polygon: polygon, thing: asdf }),
map(polygon => {

let feature = polygon.thing;


const geom = feature?.getGeometry()
if (geom instanceof Polygon) {
let points = (geom as Polygon).getCoordinates()
if (points && points[0].length === 5) {
const clonedFeature = feature.clone();
const clonedProperties = JSON.parse(JSON.stringify(feature.getProperties()));
clonedProperties.geometry = clonedFeature.getGeometry();
clonedFeature.setProperties(clonedProperties, true);
feature = clonedFeature;
const rectangle = feature.getGeometry() as Polygon;
rectangle.transform(this.mapService.epsg(), 'EPSG:4326');
const outerHull = rectangle.getCoordinates()[0].slice(0, 4);
let extent = [...outerHull[0], ...outerHull[2]];
if (JSON.stringify(rectangle.getExtent()) === JSON.stringify(extent)) {
extent = extent.map(value => {
if (value > 180) {
value = value % 360 - 360;
}
if (value < -180) {
value = value % 360 + 360;
}
return value;
});
return { bbox: extent.join(',') };
}
const bbox = this.polygonValidationService.getRectangleBbox(feature, this.mapService.epsg());
if (bbox.length > 0) {
return { bbox: bbox.join(',') };
}
}


return { intersectsWith: polygon.polygon };
})
@@ -288,7 +262,7 @@ export class SearchParamsService {
);

public getOnDemandSearchParams = combineLatest([
this.store$.select(hyp3Store.getOnDemandUserId)
this.store$.select(hyp3Store.getOnDemandUserId)
]).pipe(
map(([userID]) => {
return {