Skip to content

Commit

Permalink
feat(integration): tool for vector source closest feature (#994)
Browse files Browse the repository at this point in the history
* refactor(geolocation): move from map to controller

* wip

* wip

* wip

* wip

* feat(geolocation): listener to observable conversion. Now allow the debounce the emit of the event.

* feat(integration): tool for vector source closest feature

* wip

* wip

* wip

* wip

* wip

* refactor(proximity): flip the tool order

* lint

Co-authored-by: Pierre-Étienne Lord <[email protected]>
  • Loading branch information
pelord and Pierre-Étienne Lord authored Jun 6, 2022
1 parent 3e8151e commit 5c4f0a0
Show file tree
Hide file tree
Showing 9 changed files with 427 additions and 6 deletions.
2 changes: 2 additions & 0 deletions packages/integration/src/lib/map/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export * from './advanced-map-tool';
export * from './map-proximity-tool';
export * from './map-details-tool';
export * from './map-legend';
export * from './map-tool';
export * from './map-tools';
export * from './map.state';
export * from './map-proximity.state';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './map-proximity-tool.component';
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<igo-entity-table #table class="table-compact" [store]="mapProximityState.proximityFeatureStore" [template]="tableTemplate"></igo-entity-table>
<br>
<mat-form-field *ngIf="mapProximityState.currentPositionCoordinate$ | async as coord" class="coordinates">
<textarea #textArea matInput readonly rows="1"
[placeholder]="'igo.integration.map-proximity-tool.lon' | translate"
[value]="coord[0]"></textarea>
</mat-form-field>
<mat-form-field *ngIf="mapProximityState.currentPositionCoordinate$ | async as coord2" class="coordinates2">
<textarea #textArea matInput readonly rows="1"
[placeholder]="'igo.integration.map-proximity-tool.lat' | translate"
[value]="coord2[1]"></textarea>
</mat-form-field>

<button *ngIf="(mapProximityState.currentPositionCoordinate$ | async) && (mapProximityState.currentPositionCoordinate$ | async).length" mat-icon-button
(click)="copyTextToClipboard()">
<mat-icon svgIcon="content-copy"></mat-icon>
</button>
<div class="title-container">
<mat-label class="title mat-typography">{{'igo.integration.map-proximity-tool.method' | translate}}</mat-label>
</div>
<div class="igo-input-container mat-typography">
<mat-radio-group (change)="onLocationTypeChange($event)">
<mat-radio-button [checked]="(mapProximityState.proximitylocationType$|async)==='geolocation'" value="geolocation">{{'igo.integration.map-proximity-tool.geolocation' | translate}}</mat-radio-button>
<mat-radio-button [checked]="(mapProximityState.proximitylocationType$|async)==='mapCenter'" value="mapCenter">{{'igo.integration.map-proximity-tool.mapCenter' | translate}}</mat-radio-button>
</mat-radio-group>
</div>

<div class="radius-unit">

<mat-form-field appearance="outline" class="measure-field" floatLabel="always">
<mat-label>{{'igo.integration.map-proximity-tool.radiusM' | translate}}</mat-label>
<input type="number" pattern="[0-9]*" [(ngModel)]="maxDistance" matInput placeholder="{{'igo.integration.map-proximity-tool.radiusM' | translate}}">
</mat-form-field>


</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@


.table-compact {
height: auto;
}

.table-compact ::ng-deep .mat-header-cell.mat-column-selectionCheckbox {
width: 52px;
}

textarea { resize: none; };

mat-form-field { padding: 10px 15px; };
mat-form-field.coordinates { width: 110px; };
mat-form-field.coordinates2 { width: 100px; padding: 0px 10px 0px 3px };
mat-form-field.igo-input-container { width: 60%; padding: 0px 15px; };


.radius-unit {
display: flex;
width: 90%;
margin-left: 2px;
padding: 5px;
}

.radius-field {

display: flex;
flex-flow: column nowrap;
width: 60%;
}
.title-container {
padding: 10px;
}

.title {
margin-left: 5px;
font-size: initial;
}

.mat-radio-group {
display: flex;
flex-direction: column;
padding-top: 10px;
}

.mat-radio-button {
display: inline-flex;
position: relative;
margin-left: 16px;
margin-top: 10px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { MatRadioChange } from '@angular/material/radio';
import { EntityTableComponent, EntityTableTemplate, ToolComponent } from '@igo2/common';
import { LanguageService, MessageService } from '@igo2/core';
import { Feature, IgoMap } from '@igo2/geo';
import { NumberUtils, Clipboard } from '@igo2/utils';
import { Subscription } from 'rxjs';
import { MapProximityState } from '../map-proximity.state';
import { MapState } from '../map.state';
@ToolComponent({
name: 'map-proximity',
title: 'igo.integration.tools.closestFeature',
icon: 'radius'
})

/**
* Tool to handle the advanced map tools
*/
@Component({
selector: 'igo-map-proximity-tool',
templateUrl: './map-proximity-tool.component.html',
styleUrls: ['./map-proximity-tool.component.scss']
})

export class MapProximityToolComponent implements OnInit, OnDestroy {

private subs$$: Subscription[] = [];
@ViewChild('table', { static: true }) table: EntityTableComponent;

get maxDistance() {
return this.mapProximityState.proximityRadiusValue$.value;
}
set maxDistance(value: number) {
this.mapProximityState.proximityRadiusValue$.next(value);
}

get map(): IgoMap {
return this.mapState.map;
}
public userDefinedMapCenter: boolean;
public userDefinedFollowPosition: boolean;
/**
* Table template
* @internal
*/
public tableTemplate: EntityTableTemplate = {
selection: true,
selectMany: false,
selectionCheckbox: false,
sort: true,
columns: [
{
name: 'element',
title: this.languageService.translate.instant('igo.integration.map-proximity-tool.feature'),
valueAccessor: (localFeature: Feature) => {
return localFeature.properties.element;
}
},
{
name: 'distance',
title: this.languageService.translate.instant('igo.integration.map-proximity-tool.distance'),
valueAccessor: (localFeature: Feature) => {
return `${NumberUtils.roundToNDecimal(localFeature.properties.distance, 1)}m`;
}
}
]
};

constructor(
public mapState: MapState,
public mapProximityState: MapProximityState,
private languageService: LanguageService,
private messageService: MessageService) {
}

ngOnInit(): void {
this.mapProximityState.enabled$.next(true);
this.userDefinedFollowPosition = this.map.geolocationController.followPosition === true;
this.userDefinedMapCenter = this.map.mapCenter$.value === true;

this.subs$$.push(this.mapProximityState.proximitylocationType$.subscribe(v => {
this.map.mapCenter$.next(v !== 'geolocation');
if (v === 'geolocation') {
this.map.geolocationController.followPosition = true;
} else {
this.map.geolocationController.followPosition = false;
}
}));
}

ngOnDestroy(): void {
this.mapProximityState.enabled$.next(false);
this.map.mapCenter$.next(this.userDefinedMapCenter);
this.subs$$.map(s => s.unsubscribe());
this.map.geolocationController.followPosition = this.userDefinedFollowPosition;
}

onLocationTypeChange(e: MatRadioChange) {
this.mapProximityState.proximitylocationType$.next(e.value);
}

/**
* Copy the coordinates to a clipboard
*/
copyTextToClipboard(): void {

const successful = Clipboard.copy(this.mapProximityState.currentPositionCoordinate$?.value.toString());
if (successful) {
const translate = this.languageService.translate;
const title = translate.instant(
'igo.integration.map-proximity-tool.copyTitle'
);
const msg = translate.instant('igo.integration.map-proximity-tool.copyMsg');
this.messageService.success(msg, title);
}
}
}
Loading

0 comments on commit 5c4f0a0

Please sign in to comment.