components/info-popup/info-popup.component.ts
Angular Material card for feature properties that have been clicked on the map.
Slides up from bottom left.
selector | app-info-popup |
imports |
MatCard
MatCardHeader
MatCardTitle
MatCardContent
MatDivider
RouterLink
MatCardFooter
MatButton
DatePipe
MatListModule
|
templateUrl | ./info-popup.component.html |
styleUrl | ./info-popup.component.scss |
Properties |
Methods |
|
constructor(service: AppService)
|
||||||
Parameters :
|
close |
close()
|
Close the popup card and reset layers.
Returns :
void
|
earthquakeDepth |
earthquakeDepth()
|
Returns :
string
|
earthquakeLocation |
earthquakeLocation()
|
Returns :
string
|
Private getMfdParameters | ||||||||||||||||
getMfdParameters(model: NshmId, infoPopupData: InfoPopupData, treesUsage: SourceLogicTreesUsage)
|
||||||||||||||||
Returns the MFD parameters for URL.
Parameters :
Returns :
MfdQuery
|
Private getSourceType | ||||||||
getSourceType(infoPopupData: InfoPopupData)
|
||||||||
Returns the feature type display.
Parameters :
Returns :
string
|
earthquakeInfoPopupData |
Default value : this.service.earthquakeInfoPopupData
|
earthquakeProperties |
Default value : computed(
() => this.earthquakeInfoPopupData().feature.properties,
)
|
infoPopupData |
Default value : this.service.infoPopupData
|
Info data for popup |
Keys |
Default value : Object.keys
|
sourceType |
Default value : computed(() => this.getSourceType(this.infoPopupData()))
|
Source type display |
import {animate, style, transition, trigger} from '@angular/animations';
import {DatePipe} from '@angular/common';
import {Component, computed} from '@angular/core';
import {MatButton} from '@angular/material/button';
import {
MatCard,
MatCardContent,
MatCardFooter,
MatCardHeader,
MatCardTitle,
} from '@angular/material/card';
import {MatDivider} from '@angular/material/divider';
import {MatListModule} from '@angular/material/list';
import {RouterLink} from '@angular/router';
import {FeatureType} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/features-service';
import {SourceLogicTreesUsage} from '@ghsc/nshmp-utils-ts/libs/nshmp-haz/www/source-logic-trees-service';
import {
SourceType,
TectonicSettings,
TreeInfo,
} from '@ghsc/nshmp-utils-ts/libs/nshmp-lib/model';
import {NshmId} from '@ghsc/nshmp-utils-ts/libs/nshmp-lib/nshm';
import {MfdQuery} from '../../../mfd/services/app.service';
import {InfoPopupData} from '../../models/state.model';
import {AppService} from '../../services/app.service';
/**
* Angular Material card for feature properties that have been clicked on the map.
*
* Slides up from bottom left.
*/
@Component({
animations: [
trigger('slideUpDown', [
transition(':enter', [
style({transform: 'translateY(100%)'}),
animate('200ms ease-in', style({transform: 'translateY(0%)'})),
]),
transition(':leave', [
animate('200ms ease-in', style({transform: 'translateY(100%)'})),
]),
]),
],
imports: [
MatCard,
MatCardHeader,
MatCardTitle,
MatCardContent,
MatDivider,
RouterLink,
MatCardFooter,
MatButton,
DatePipe,
MatListModule,
],
selector: 'app-info-popup',
styleUrl: './info-popup.component.scss',
templateUrl: './info-popup.component.html',
})
export class InfoPopupComponent {
/** Info data for popup */
infoPopupData = this.service.infoPopupData;
earthquakeInfoPopupData = this.service.earthquakeInfoPopupData;
/**
* Query parameters for MFD link.
*/
mfdParameters = computed(() =>
this.getMfdParameters(
this.service.formGroup.getRawValue().model,
this.infoPopupData(),
this.service.treesUsageResponse(),
),
);
/** Feature properties */
properties = computed(() => {
const entries: [string, unknown][] = Object.entries(
this.infoPopupData()?.feature.properties,
);
return entries.map(([key, value]) => ({key, value}));
});
earthquakeProperties = computed(
() => this.earthquakeInfoPopupData().feature.properties,
);
Keys = Object.keys;
/** Source type display */
sourceType = computed(() => this.getSourceType(this.infoPopupData()));
constructor(private service: AppService) {}
/**
* Close the popup card and reset layers.
*/
close() {
this.service.resetLayers();
this.service.updateState({
earthquakeInfoPopupData:
this.service.initialState().earthquakeInfoPopupData,
infoPopupData: this.service.initialState().infoPopupData,
});
}
earthquakeDepth(): string {
return this.earthquakeInfoPopupData()?.feature.geometry.coordinates[2].toFixed(
1,
);
}
earthquakeLocation(): string {
const [longitude, latitude] =
this.earthquakeInfoPopupData().feature.geometry.coordinates;
const latStr = [
Math.abs(latitude).toFixed(3),
'°',
latitude < 0 ? 'S' : 'N',
].join('');
const lonStr = [
Math.abs(longitude).toFixed(3),
'°',
longitude < 0 ? 'W' : 'E',
].join('');
return `${lonStr}, ${latStr}`;
}
/**
* Returns the MFD parameters for URL.
*
* @param infoPopupData The info popup data
* @param treesUsage The tree usage
*/
private getMfdParameters(
model: NshmId,
infoPopupData: InfoPopupData,
treesUsage: SourceLogicTreesUsage,
): MfdQuery {
if (infoPopupData.feature === null || infoPopupData.featureType === null) {
return null;
}
let treeInfo: TreeInfo = null;
let setting: TectonicSettings = null;
let sourceType: SourceType = null;
treesUsage.response.trees.forEach(tree => {
tree.data.forEach(group => {
group.data.forEach(data => {
if (data.name === infoPopupData.feature.properties.name) {
setting = tree.setting;
sourceType = group.type;
treeInfo = data;
}
});
});
});
const query: MfdQuery = {
cumulative: false.toString(),
model,
setting,
sourceTree: treeInfo?.id.toString(),
sourceType,
weightedMfds: false.toString(),
};
return query;
}
/**
* Returns the feature type display.
*
* @param infoPopupData The info popup data
*/
private getSourceType(infoPopupData: InfoPopupData): string {
if (infoPopupData.featureType === null) {
return;
}
const {featureType} = infoPopupData;
let display = featureType.toString();
switch (featureType) {
case FeatureType.DECOLLEMENT:
display = 'Décollement Sections';
break;
case FeatureType.FAULT:
display = 'Fault Sections';
break;
case FeatureType.INTERFACE:
display = 'Interface Sections';
break;
case FeatureType.ZONE:
display = 'Zone Sources';
break;
}
return display;
}
}
<div class="leaflet-feature-popup">
@if (infoPopupData()?.feature && infoPopupData()) {
<mat-card [@slideUpDown]>
<mat-card-header>
<mat-card-title> Feature Properties </mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-divider />
<div class="card-content">
<table>
<tbody>
@if (mfdParameters()?.sourceTree) {
<tr>
<th>
<a
routerLink="/source/mfd"
[queryParams]="mfdParameters()"
queryParamsHandling="merge"
target="_blank"
>Show MFD</a
>
</th>
</tr>
}
<tr>
<th>id</th>
<td>{{ infoPopupData().feature.id }}</td>
</tr>
<tr>
<th>Source Type</th>
<td>{{ sourceType() }}</td>
</tr>
@for (item of properties(); track item) {
@if (item.key !== 'mfd-tree' && item.key !== 'rate-map') {
<tr>
<th>{{ item.key }}</th>
<td>{{ item.value }}</td>
</tr>
}
}
</tbody>
</table>
</div>
<mat-divider />
</mat-card-content>
<mat-card-footer align="end">
<button mat-raised-button color="primary" (click)="close()">
Close
</button>
</mat-card-footer>
</mat-card>
}
@if (earthquakeInfoPopupData()?.feature && earthquakeInfoPopupData()) {
<mat-card [@slideUpDown]>
<mat-card-header>
<mat-card-title>
<a [href]="earthquakeProperties().url" target="_blank">
{{ earthquakeProperties().title }}
</a>
</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-divider />
@if (earthquakeProperties(); as props) {
<div class="card-content">
<table class="earthquake-properties">
@if (props.time) {
<tr>
<th>Time</th>
<td>
{{ earthquakeProperties().time | date: 'long' }}
</td>
</tr>
}
@if (props.mag) {
<tr>
<th>Magnitude</th>
<td>{{ earthquakeProperties().mag }}</td>
</tr>
}
@if (earthquakeInfoPopupData().feature.geometry.coordinates) {
<tr>
<th>Location</th>
<td>{{ earthquakeLocation() }}</td>
</tr>
<tr>
<th>Depth</th>
<td>{{ earthquakeDepth() }} km</td>
</tr>
}
</table>
</div>
}
<mat-divider />
</mat-card-content>
<mat-card-footer align="end">
<button mat-raised-button color="primary" (click)="close()">
Close
</button>
</mat-card-footer>
</mat-card>
}
</div>