- add DatasetApiService wit HttpService

- Interfaces for stations and phenomena
This commit is contained in:
Arno Kaimbacher 2021-08-24 13:38:52 +02:00
parent 5740a5ddc3
commit 7857e2c5bb
13 changed files with 2495 additions and 1446 deletions

View file

@ -7,6 +7,7 @@
"babel-plugin-transform-typescript-metadata", "babel-plugin-transform-typescript-metadata",
["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose": true }], ["@babel/plugin-proposal-class-properties", { "loose": true }],
["@babel/plugin-proposal-private-property-in-object", { "loose": true }],
["@babel/plugin-proposal-private-methods", { "loose": true }] ["@babel/plugin-proposal-private-methods", { "loose": true }]
] ]
} }

View file

@ -28,8 +28,8 @@
<body> <body>
<!-- your content here... --> <!-- your content here... -->
<app-component></app-component> <app-component></app-component>
<!--
<script src="dist/polyfills.js" defer></script> --> <!-- <script src="dist/polyfills.js" defer></script> -->
<script src="dist/main.js"></script> <script src="dist/main.js"></script>
</body> </body>

View file

@ -46,6 +46,12 @@ npx @angular/cli generate component map --skip-tests
npx @angular/cli generate module map --skip-tests npx @angular/cli generate module map --skip-tests
npx @angular/cli generate service dataset-api --skip-tests
answer:
CREATE src/app/dataset-api.service.ts (139 bytes)
npx @angular/cli generate service http --skip-tests
========================================= ExtractTextPlugin ================================================== ========================================= ExtractTextPlugin ==================================================
npm install --save-dev mini-css-extract-plugin npm install --save-dev mini-css-extract-plugin
@ -115,4 +121,7 @@ npm install --save @angular/forms
Install dependencies Install dependencies
npm i @ngx-translate/http-loader #npm i @ngx-translate/http-loader
npm install --save rxjs

3656
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -52,6 +52,7 @@
"babel-plugin-transform-typescript-metadata": "^0.3.2", "babel-plugin-transform-typescript-metadata": "^0.3.2",
"core-js": "^3.16.0", "core-js": "^3.16.0",
"leaflet": "^1.7.1", "leaflet": "^1.7.1",
"rxjs": "^6.6.7",
"zone.js": "^0.11.4" "zone.js": "^0.11.4"
} }
} }

View file

@ -8,19 +8,18 @@ import { MapComponent } from './map/map.component';
// HelgolandServicesConnector // HelgolandServicesConnector
// } from '@helgoland/core'; // } from '@helgoland/core';
import { HttpClientModule, HttpClient, HttpXhrBackend } from '@angular/common/http'; //for http requests import { HttpClientModule, HttpClient } from '@angular/common/http'; //for http requests
// import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
// import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { MarkerService } from './services/marker.service'; import { MarkerService } from './services/marker.service';
import { DatasetApiService } from "./services/dataset-api.service";
import { HttpService } from "./services/http.service";
// siehe https://52north.github.io/helgoland-toolbox/additional-documentation/how-tos/integrate-a-map-component.html // siehe https://52north.github.io/helgoland-toolbox/additional-documentation/how-tos/integrate-a-map-component.html
// https://52north.github.io/helgoland-toolbox/components/LocateControlComponent.html#source // https://52north.github.io/helgoland-toolbox/components/LocateControlComponent.html#source
// import { HelgolandMapControlModule, HelgolandMapSelectorModule } from '@helgoland/map';
// import { HelgolandSelectorModule } from '@helgoland/selector'; import {
// import { HelgolandDatasetlistModule } from '@helgoland/depiction'; DatasetApiInterface, ApiV3InterfaceService, SplittedDataDatasetApiInterface, DatasetApiV3Connector, HelgolandServicesConnector
import { DatasetApiInterface, ApiV3InterfaceService, SplittedDataDatasetApiInterface, DatasetApiV3Connector,HelgolandServicesConnector, DatasetApiV1ConnectorProvider, DatasetApiV2ConnectorProvider, } from '@helgoland/core';
DatasetStaConnectorProvider, DatasetApiV3ConnectorProvider } from '@helgoland/core'; import { HelgolandCoreModule } from "@helgoland/core";
import { HelgolandCoreModule, HttpService} from "@helgoland/core";
// import 'core-js'; // import 'core-js';
@ -29,33 +28,20 @@ import { HelgolandCoreModule, HttpService} from "@helgoland/core";
declarations: [AppComponent, MapComponent], declarations: [AppComponent, MapComponent],
// imports: Other modules whose exported classes are needed by component templates declared in this NgModule. // imports: Other modules whose exported classes are needed by component templates declared in this NgModule.
imports: [BrowserModule, HttpClientModule, HelgolandCoreModule], imports: [BrowserModule, HttpClientModule, HelgolandCoreModule],
// TranslateModule.forRoot({
// loader: {
// provide: TranslateLoader,
// useFactory: HttpLoaderFactory,
// deps: [HttpClient]
// }
// }),
// HelgolandSelectorModule, HelgolandMapControlModule, HelgolandMapSelectorModule, HelgolandDatasetlistModule],
providers: [ providers: [
MarkerService, MarkerService, HttpService, DatasetApiService,
// {
// provide: DatasetApiInterface,
// useClass: SplittedDataDatasetApiInterface,
// deps: [HttpXhrBackend]
// },
{ {
provide: DatasetApiInterface, provide: HelgolandServicesConnector,
useClass: SplittedDataDatasetApiInterface useClass: DatasetApiV3Connector,
deps: [HttpClient]
}, },
// {
// provide: HttpClient
// },
// {provide:'api', useValue: 'https://geomon.geologie.ac.at/52n-sos-webapp/api/' },
{
provide: HelgolandServicesConnector,
useClass: DatasetApiV3Connector,
deps: [HttpXhrBackend]
},
// DatasetApiV1ConnectorProvider,
// DatasetApiV2ConnectorProvider,
DatasetApiV3ConnectorProvider,
// DatasetStaConnectorProvider
], ],
// bootstrap: The main application view, called the root component, which hosts all other application views. // bootstrap: The main application view, called the root component, which hosts all other application views.
// Only the root NgModule should set the bootstrap property. // Only the root NgModule should set the bootstrap property.

View file

@ -1,24 +1,21 @@
import { Component, AfterViewInit, OnChanges, SimpleChanges, EventEmitter, Input, Output } from '@angular/core'; import { Component, AfterViewInit, OnChanges, SimpleChanges, EventEmitter, Input, Output } from '@angular/core';
import * as L from 'leaflet'; import * as L from 'leaflet';
import { MarkerService } from '../services/marker.service'; import { MarkerService } from '../services/marker.service';
import { DatasetApiInterface, DatasetApiV2Connector, SplittedDataDatasetApiInterface } from '@helgoland/core'; import { DatasetApiService } from '../services/dataset-api.service';
import { BaseMapComponent } from './base-map.component'; import { BaseMapComponent } from './base-map.component';
import { HelgolandServicesConnector } from '@helgoland/core';
// const iconRetinaUrl = 'assets/marker-icon-2x.png'; // const iconRetinaUrl = 'assets/marker-icon-2x.png';
// const iconUrl = 'assets/marker-icon.png'; // const iconUrl = 'assets/marker-icon.png';
// const shadowUrl = 'assets/marker-shadow.png'; // const shadowUrl = 'assets/marker-shadow.png';
// const iconDefault = L.icon({ // const iconDefault = L.icon({
// iconRetinaUrl, // iconRetinaUrl,
// iconUrl, // iconUrl,
// shadowUrl, // shadowUrl,
// iconSize: [25, 41], // iconSize: [25, 41],
// iconAnchor: [12, 41], // iconAnchor: [12, 41],
// popupAnchor: [1, -34], // popupAnchor: [1, -34],
// tooltipAnchor: [16, -28], // tooltipAnchor: [16, -28],
// shadowSize: [41, 41] // shadowSize: [41, 41]
// }); // });
// L.Marker.prototype.options.icon = iconDefault; // L.Marker.prototype.options.icon = iconDefault;
@ -54,11 +51,12 @@ export class MapComponent
protected oldBaseLayer: L.Control.LayersObject = {}; protected oldBaseLayer: L.Control.LayersObject = {};
protected map: L.Map; protected map: L.Map;
protected zoomControl: L.Control.Zoom; protected zoomControl: L.Control.Zoom;
protected markerFeatureGroup: L.FeatureGroup;
// constructor() { } // constructor() { }
constructor( constructor(
protected markerService: MarkerService, protected markerService: MarkerService,
protected servicesConnector: HelgolandServicesConnector) { protected datasetApiService: DatasetApiService) {
super(); super();
} }
// constructor(markerService: MarkerService) { // constructor(markerService: MarkerService) {
@ -68,7 +66,30 @@ export class MapComponent
ngAfterViewInit(): void { ngAfterViewInit(): void {
this.initMap(); this.initMap();
// this.markerService.makeCapitalMarkers(this.map); // this.markerService.makeCapitalMarkers(this.map);
this.markerService.makeCapitalCircleMarkers(this.map); // this.markerService.makeCapitalCircleMarkers(this.map);
this.datasetApiService.getStations('https://geomon.geologie.ac.at/52n-sos-webapp/api/')
.subscribe((res) => {
this.markerFeatureGroup = L.featureGroup();
if (res instanceof Array && res.length > 0) {
res.forEach((entry) => {
//const marker = this.createDefaultGeometry(entry);
// const marker = L.geoJSON(entry.geometry);
const marker = L.geoJSON(entry.geometry, {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng);
}
})
if (marker) { this.markerFeatureGroup.addLayer(marker); }
});
this.markerFeatureGroup.addTo(this.map);
// this.zoomToMarkerBounds(this.markerFeatureGroup.getBounds());
} else {
// this.onNoResultsFound.emit(true);
}
this.map.invalidateSize();
this.onContentLoadingEvent.emit(false);
});
// this.createStationGeometries(); // this.createStationGeometries();
} }
@ -87,18 +108,4 @@ export class MapComponent
// } // }
} }
protected createStationGeometries() {
this.servicesConnector.getPlatforms('https://geomon.geologie.ac.at/52n-sos-webapp/api/')
.subscribe((res) => {
if (res instanceof Array && res.length > 0) {
res.forEach((entry) => {
let test = entry;
});
}
this.onContentLoadingEvent.emit(false);
});
}
} }

View file

@ -0,0 +1,63 @@
// https://github.com/52North/helgoland-toolbox/blob/develop/libs/core/src/lib/dataset-api/dataset-impl-api-interface.service.ts
// https://github.com/52North/helgoland-toolbox/blob/495f75cadcc3e7232206db1cd5dd8bbf3a172c4b/libs/core/src/lib/abstract-services/api-interface.ts#L6
// https://github.com/52North/helgoland-toolbox/blob/495f75cadcc3e7232206db1cd5dd8bbf3a172c4b/libs/core/src/lib/api-communication/connectors/dataset-api-v3-connector/api-v3-interface.ts#L321
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Phenomenon } from '../../shared/models/phenomenon';
import { Station } from '../../shared/models/station';
import { HttpService } from './http.service';
import { HttpRequestOptions } from '../../shared/models/http-requests';
import { HttpParams } from '@angular/common/http';
// @Injectable({
// providedIn: 'root'
// })
@Injectable()
export class DatasetApiService {
// constructor() { }
constructor(
private httpClient: HttpClient,
protected httpService: HttpService,) {
}
public getPhenomena(apiUrl: string, params?, options?) {
const url = this.createRequestUrl(apiUrl, 'phenomena');
return this.requestApi<Phenomenon[]>(url, params, options);
}
public getStations(apiUrl: string, params?, options?: HttpRequestOptions): Observable<Station[]> {
const url = this.createRequestUrl(apiUrl, 'features');
return this.requestApi<Station[]>(url, params, options);
}
protected createRequestUrl(apiUrl: string, endpoint: string, id?: string) {
// TODO Check whether apiUrl ends with slash
let requestUrl = apiUrl + endpoint;
if (id) { requestUrl += '/' + id; }
return requestUrl;
}
protected requestApi<T>(
url: string, params: HttpParams = new HttpParams(), options: HttpRequestOptions = {}
): Observable<T> {
return this.httpService.client(options).get<T>(url,
{
params,
headers: this.createBasicAuthHeader(options.basicAuthToken)
}
);
}
protected createBasicAuthHeader(token: string): HttpHeaders {
const headers = new HttpHeaders();
if (token) { return headers.set('Authorization', token); }
return headers;
}
}

View file

@ -0,0 +1,45 @@
// https://github.com/52North/helgoland-toolbox/blob/495f75cadcc3e7232206db1cd5dd8bbf3a172c4b/libs/core/src/lib/dataset-api/http.service.ts#L37
import { Injectable } from '@angular/core';
import { HttpClient, HttpEvent, HttpHandler, HttpRequest } from '@angular/common/http';
import { Inject, InjectionToken, Optional } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpRequestOptions } from '../../shared/models/http-requests';
export const HTTP_SERVICE_INTERCEPTORS = new InjectionToken<HttpServiceInterceptor>('HTTP_SERVICE_INTERCEPTORS');
export interface HttpServiceHandler {
handle(req: HttpRequest<any>, options: Partial<HttpRequestOptions>): Observable<HttpEvent<any>>;
}
export interface HttpServiceInterceptor {
intercept(req: HttpRequest<any>, options: Partial<HttpRequestOptions>, next: HttpServiceHandler): Observable<HttpEvent<any>>;
}
@Injectable()
export class HttpService {
private handler: HttpServiceHandler;
constructor(
protected httpHandler: HttpHandler,
@Optional() @Inject(HTTP_SERVICE_INTERCEPTORS) interceptors: HttpServiceInterceptor[] | null
) {
let handler: HttpServiceHandler = {
handle: (req, options) => httpHandler.handle(req)
};
if (interceptors) {
handler = interceptors.reduceRight((next, interceptor) => ({
handle: (req, options) => interceptor.intercept(req, options, next)
}), handler);
}
this.handler = handler;
}
public client(options: HttpRequestOptions = {}): HttpClient {
return new HttpClient({
handle: (req) => this.handler.handle(req, options)
});
}
}

View file

@ -9,7 +9,7 @@ import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { AppModule } from './app/app.module'; import { AppModule } from './app/app.module';
import { environment } from './environments/environment'; import { environment } from './environments/environment.prod';
if (environment.production) { if (environment.production) {
enableProdMode(); enableProdMode();

View file

@ -0,0 +1,5 @@
export interface HttpRequestOptions {
forceUpdate?: boolean;
basicAuthToken?: string;
expirationAtMs?: number;
}

View file

@ -0,0 +1,4 @@
export interface Phenomenon {
id: string;
label: string;
}

View file

@ -0,0 +1,34 @@
export class Station {
public id: string;
public label: string;
public geometry: GeoJSON.GeometryObject;
public properties: StationProperties;
}
export interface StationProperties {
id: string;
label: string;
// timeseries: TimeseriesCollection | Timeseries;
}
// export class TimeseriesCollection {
// [key: string]: ParameterConstellation;
// }
class Timeseries {
public id: string;
public label: string;
public url: string;
public uom: string;
public internalId: string;
public firstValue;
public lastValue;
public referenceValues;
public station: Station;
public parameters;
public statusIntervals?;
public hasData = false;
public renderingHints;
}