Skip to content

Commit

Permalink
Fix: sonar cloud quick fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
TIL-EBP committed Nov 27, 2024
1 parent 5a78304 commit 08924a8
Show file tree
Hide file tree
Showing 28 changed files with 3,178 additions and 3,202 deletions.
34 changes: 16 additions & 18 deletions ui/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
FROM node:22-alpine as build

WORKDIR /app
COPY . .

RUN npm install --ignore-scripts
RUN npm run build --omit=dev



FROM nginx:alpine

WORKDIR /usr/share/nginx/html
COPY --from=build /app/dist/ /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
FROM node:22-alpine AS build

WORKDIR /app
COPY . .

RUN npm install --ignore-scripts && npm run build --omit=dev


FROM nginx:alpine

WORKDIR /usr/share/nginx/html
COPY --from=build /app/dist/ /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
3 changes: 2 additions & 1 deletion ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

<head>
<meta charset="UTF-8">
<title>swissgeol</title>

<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/png" href="src/images/swissgeol_favicon_viewer_small.png">

<link href="bundle.css" rel="stylesheet">

<meta name="description" content="swissgeol.ch is the 3D subsurface viewer of the Swiss Confederation. Geoscientific information below the terrain of Switzerland can be combined with geographic information above terrain.">
<title>swissgeol</title>
<script>window.activeEnvironment="default_active_env"</script>
</head>

Expand Down
196 changes: 97 additions & 99 deletions ui/src/earthquakeVisualization/earthquakeVisualizer.js
Original file line number Diff line number Diff line change
@@ -1,99 +1,97 @@
import {
Cartographic,
Cartesian3,
CustomDataSource,
HeadingPitchRange,
Math as CMath,
BoundingSphere,
Rectangle,

} from 'cesium';
import {EARTHQUAKE_SPHERE_SIZE_COEF, getColorFromTime, parseEarthquakeData} from './helpers';
import {LayerType} from '../constants';

export default class EarthquakeVisualizer {
/**
* @param {import('cesium/Source/Widgets/Viewer/Viewer').default} viewer
* @param {Object} config
*/
constructor(viewer, config) {
this.viewer = viewer;
this.config = config;
this.earthquakeDataSource = new CustomDataSource(LayerType.earthquakes);
this.viewer.dataSources.add(this.earthquakeDataSource);
this.boundingSphere = null;
this.boundingRectangle = new Rectangle(
Number.POSITIVE_INFINITY,
Number.POSITIVE_INFINITY,
Number.NEGATIVE_INFINITY,
Number.NEGATIVE_INFINITY
);
this.maximumHeight = 0;
this.earthquakeDataSource.entities.collectionChanged.addEventListener(() => {
this.viewer.scene.requestRender();
});
}

async showEarthquakes() {
const response = await fetch(this.config.downloadUrl);
const text = await response.text();
parseEarthquakeData(text).map(data => {
const size = Number(data.Magnitude.split(' ')[0]) * EARTHQUAKE_SPHERE_SIZE_COEF;
const depthMeters = Number(data.Depthkm.split(' ')[0]) * 1000; // convert km to m
const longitude = Number(data.Longitude);
const latitude = Number(data.Latitude);
delete data.Longitude;
delete data.Latitude;
const position = Cartesian3.fromDegrees(longitude, latitude, -depthMeters);
const posCart = Cartographic.fromCartesian(position);
const altitude = this.viewer.scene.globe.getHeight(posCart) || 0;
posCart.height = posCart.height + altitude;
Cartographic.toCartesian(posCart, undefined, position);
const cameraDistance = size * 4;
const zoomHeadingPitchRange = new HeadingPitchRange(0, CMath.toRadians(25), cameraDistance);
data['Details'] = this.config.detailsUrl;
this.boundingRectangle.west = Math.min(CMath.toRadians(longitude), this.boundingRectangle.west);
this.boundingRectangle.south = Math.min(CMath.toRadians(latitude), this.boundingRectangle.south);
this.boundingRectangle.east = Math.max(CMath.toRadians(longitude), this.boundingRectangle.east);
this.boundingRectangle.north = Math.max(CMath.toRadians(latitude), this.boundingRectangle.north);
this.maximumHeight = Math.max(this.maximumHeight, depthMeters * 2);
return this.earthquakeDataSource.entities.add({
position: position,
ellipsoid: {
radii: new Cartesian3(size, size, size),
material: getColorFromTime(data.Time),
},
properties: {
...data,
propsOrder: this.config.propsOrder,
zoomHeadingPitchRange: zoomHeadingPitchRange
}
});
});
this.boundingSphere = BoundingSphere.fromRectangle3D(this.boundingRectangle);
}

/**
* @param {boolean} visible
*/
async setVisible(visible) {
const entities = this.earthquakeDataSource.entities.values;
if (entities && entities.length) {
this.earthquakeDataSource.show = visible;
} else {
if (visible) {
await this.showEarthquakes();
}
}
}

/**
* @param {number} opacity
*/
setOpacity(opacity) {
const entities = this.earthquakeDataSource.entities.values;
entities.forEach(entity => {
entity.ellipsoid.material = entity.ellipsoid.material.color.getValue().withAlpha(Number(opacity));
});
}
}
import {
Cartographic,
Cartesian3,
CustomDataSource,
HeadingPitchRange,
Math as CMath,
BoundingSphere,
Rectangle,

} from 'cesium';
import {EARTHQUAKE_SPHERE_SIZE_COEF, getColorFromTime, parseEarthquakeData} from './helpers';
import {LayerType} from '../constants';

export default class EarthquakeVisualizer {
/**
* @param {import('cesium/Source/Widgets/Viewer/Viewer').default} viewer
* @param {Object} config
*/
constructor(viewer, config) {
this.viewer = viewer;
this.config = config;
this.earthquakeDataSource = new CustomDataSource(LayerType.earthquakes);
this.viewer.dataSources.add(this.earthquakeDataSource);
this.boundingSphere = null;
this.boundingRectangle = new Rectangle(
Number.POSITIVE_INFINITY,
Number.POSITIVE_INFINITY,
Number.NEGATIVE_INFINITY,
Number.NEGATIVE_INFINITY
);
this.maximumHeight = 0;
this.earthquakeDataSource.entities.collectionChanged.addEventListener(() => {
this.viewer.scene.requestRender();
});
}

async showEarthquakes() {
const response = await fetch(this.config.downloadUrl);
const text = await response.text();
parseEarthquakeData(text).map(data => {
const size = Number(data.Magnitude.split(' ')[0]) * EARTHQUAKE_SPHERE_SIZE_COEF;
const depthMeters = Number(data.Depthkm.split(' ')[0]) * 1000; // convert km to m
const longitude = Number(data.Longitude);
const latitude = Number(data.Latitude);
delete data.Longitude;
delete data.Latitude;
const position = Cartesian3.fromDegrees(longitude, latitude, -depthMeters);
const posCart = Cartographic.fromCartesian(position);
const altitude = this.viewer.scene.globe.getHeight(posCart) || 0;
posCart.height = posCart.height + altitude;
Cartographic.toCartesian(posCart, undefined, position);
const cameraDistance = size * 4;
const zoomHeadingPitchRange = new HeadingPitchRange(0, CMath.toRadians(25), cameraDistance);
data['Details'] = this.config.detailsUrl;
this.boundingRectangle.west = Math.min(CMath.toRadians(longitude), this.boundingRectangle.west);
this.boundingRectangle.south = Math.min(CMath.toRadians(latitude), this.boundingRectangle.south);
this.boundingRectangle.east = Math.max(CMath.toRadians(longitude), this.boundingRectangle.east);
this.boundingRectangle.north = Math.max(CMath.toRadians(latitude), this.boundingRectangle.north);
this.maximumHeight = Math.max(this.maximumHeight, depthMeters * 2);
return this.earthquakeDataSource.entities.add({
position: position,
ellipsoid: {
radii: new Cartesian3(size, size, size),
material: getColorFromTime(data.Time),
},
properties: {
...data,
propsOrder: this.config.propsOrder,
zoomHeadingPitchRange: zoomHeadingPitchRange
}
});
});
this.boundingSphere = BoundingSphere.fromRectangle3D(this.boundingRectangle);
}

/**
* @param {boolean} visible
*/
async setVisible(visible) {
const entities = this.earthquakeDataSource.entities.values;
if (entities && entities.length) {
this.earthquakeDataSource.show = visible;
} else if (visible) {
await this.showEarthquakes();
}
}

/**
* @param {number} opacity
*/
setOpacity(opacity) {
const entities = this.earthquakeDataSource.entities.values;
entities.forEach(entity => {
entity.ellipsoid.material = entity.ellipsoid.material.color.getValue().withAlpha(Number(opacity));
});
}
}
2 changes: 1 addition & 1 deletion ui/src/elements/dashboard/ngm-dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export class NgmDashboard extends LitElementI18n {
// const topic = this.topics?.find(p => p.id === value.param.topicId);
// this.selectTopicOrProject(topic);
// } else
if (value.kind === 'project') {
if (value.kind === 'project') {
removeProject();
const project = await this.apiClient.getProject(value.param.projectId);
this.selectTopicOrProject(project);
Expand Down
129 changes: 64 additions & 65 deletions ui/src/elements/ngm-layer-legend.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,64 @@
import {html, PropertyValues} from 'lit';
import {until} from 'lit/directives/until.js';
import {customElement, state} from 'lit/decorators.js';
import draggable from './draggable';
import i18next from 'i18next';
import {LitElementI18n} from '../i18n.js';

import {LayerConfig, LayerType} from '../layertree';
import {unsafeHTML} from 'lit/directives/unsafe-html.js';
import {classMap} from 'lit/directives/class-map.js';
import {dragArea} from './helperElements';

@customElement('ngm-layer-legend')
export class NgmLayerLegend extends LitElementI18n {
@state()
accessor config!: LayerConfig;

protected firstUpdated(_changedProperties: PropertyValues) {
// hidden is required to have correct window placing
this.hidden = true;
draggable(this, {
allowFrom: '.drag-handle'
});
this.hidden = false;
super.firstUpdated(_changedProperties);
}

getImageLegend() {
const legendImage = this.config.legend ? `https://api.geo.admin.ch/static/images/legends/${this.config.legend}_${i18next.language}.png` : undefined;
return html`${legendImage ? html`
<div class="ngm-legend-container">
<div>${i18next.t('dtd_legend')}</div>
<div class="ngm-legend-image"><img src="${legendImage}"></div>
</div>
` : ''}`;
}

async getWmtsLegend() {
const response = await fetch(`https://api3.geo.admin.ch/rest/services/api/MapServer/${this.config.layer}/legend?lang=${i18next.language}`);
const legendHtml = await response.text();
return html`
<div class="ngm-legend-html">
${unsafeHTML(legendHtml)}
</div>`;
}

render() {
return html`
<div class="ngm-floating-window-header drag-handle">
${i18next.t(this.config.label)}
<div class="ngm-close-icon" @click=${() => this.dispatchEvent(new CustomEvent('close'))}></div>
</div>
<div class="content-container ${classMap({'legend-html': this.config.type === LayerType.swisstopoWMTS})}">
${this.config.type === LayerType.swisstopoWMTS ? html`${until(this.getWmtsLegend(), html`
<div class="ui loader"></div>`)}` : this.getImageLegend()}
</div>
${dragArea}
`;
}

createRenderRoot() {
// no shadow dom
return this;
}
}
import {html, PropertyValues} from 'lit';
import {until} from 'lit/directives/until.js';
import {customElement, state} from 'lit/decorators.js';
import draggable from './draggable';
import i18next from 'i18next';
import {LitElementI18n} from '../i18n.js';

import {LayerConfig, LayerType} from '../layertree';
import {unsafeHTML} from 'lit/directives/unsafe-html.js';
import {classMap} from 'lit/directives/class-map.js';
import {dragArea} from './helperElements';

@customElement('ngm-layer-legend')
export class NgmLayerLegend extends LitElementI18n {
@state()
accessor config!: LayerConfig;

protected firstUpdated(_changedProperties: PropertyValues) {
// hidden is required to have correct window placing
this.hidden = true;
draggable(this, {
allowFrom: '.drag-handle'
});
this.hidden = false;
super.firstUpdated(_changedProperties);
}

getImageLegend() {
const legendImage = this.config.legend ? `https://api.geo.admin.ch/static/images/legends/${this.config.legend}_${i18next.language}.png` : undefined;
return legendImage && html`
<div class="ngm-legend-container">
<div>${i18next.t('dtd_legend')}</div>
<div class="ngm-legend-image"><img src="${legendImage}"></div>
</div>`;
}

async getWmtsLegend() {
const response = await fetch(`https://api3.geo.admin.ch/rest/services/api/MapServer/${this.config.layer}/legend?lang=${i18next.language}`);
const legendHtml = await response.text();
return html`
<div class="ngm-legend-html">
${unsafeHTML(legendHtml)}
</div>`;
}

render() {
return html`
<div class="ngm-floating-window-header drag-handle">
${i18next.t(this.config.label)}
<div class="ngm-close-icon" @click=${() => this.dispatchEvent(new CustomEvent('close'))}></div>
</div>
<div class="content-container ${classMap({'legend-html': this.config.type === LayerType.swisstopoWMTS})}">
${this.config.type === LayerType.swisstopoWMTS ? until(this.getWmtsLegend(), html`
<div class="ui loader"></div>`) : this.getImageLegend()}
</div>
${dragArea}
`;
}

createRenderRoot() {
// no shadow dom
return this;
}
}
Loading

0 comments on commit 08924a8

Please sign in to comment.