import * as hsv2rgb from 'hsv2rgb'; import {Feature} from 'ol'; import {Fill, Stroke, Style} from 'ol/style'; import {Injectable} from '@angular/core'; import {Vector as VectorLayer} from 'ol/layer'; import {HsConfig} from 'hslayers-ng/config.service'; import {HsLayoutService} from 'hslayers-ng/components/layout/layout.service'; import {HsMapService} from 'hslayers-ng/components/map/map.service'; import {HsPanelContainerService} from 'hslayers-ng/components/layout/panels/panel-container.service'; import {HsSidebarService} from 'hslayers-ng/components/sidebar/sidebar.service'; import {AdjusterComponent} from './adjuster/adjuster.component'; import {AdjusterEventService} from './adjuster/adjuster-event.service'; import {AdjusterService} from './adjuster/adjuster.service'; import {nuts} from './nuts'; @Injectable({providedIn: 'root'}) export class AppService { // https://colorbrewer2.org/?type=qualitative&scheme=Paired&n=12 colorPalette = [ '#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928', ]; nuts2style = new Style({ stroke: new Stroke({ color: '#000000', width: 0.5, }), }); nuts2Layer = new VectorLayer({ source: nuts.nuts2Source, editor: {editable: false}, visible: false, style: this.nuts2style, title: 'NUTS2 regions', }); nuts3style = (feature: Feature): Style => { if (isNaN(feature.get(this.method))) { return [ new Style({ fill: new Fill({ color: '#FFF', }), stroke: new Stroke({ color: '#3399CC', width: 0.25, }), }), ]; } else { return [ new Style({ fill: new Fill({ color: this.colorPalette[feature.get(this.method) - 1], }), stroke: new Stroke({ color: '#FFF', width: 0.25, }), }), ]; } }; nuts3Layer = new VectorLayer({ source: nuts.nuts3Source, editor: {editable: false}, visible: true, style: this.nuts3style, title: 'NUTS3 regions', }); method: string; serviceUrl: string; constructor( private adjusterService: AdjusterService, private adjusterEventService: AdjusterEventService, private hsConfig: HsConfig, private hsLayoutService: HsLayoutService, private hsMapService: HsMapService, private hsSidebarService: HsSidebarService, private hsPanelContainerService: HsPanelContainerService ) { this.method = this.adjusterService.method; this.serviceUrl = this.adjusterService.serviceBaseUrl + 'georeport/'; this.nuts3Layer.set('popUp', { attributes: [ {attribute: 'CNTR_CODE', label: 'Country'}, {attribute: 'NUTS_NAME', label: 'Name'}, {attribute: this.method, label: 'Cluster ID'}, { attribute: 'NUTS_ID', label: 'Detailed report', displayFunction: (x) => { return `in a new page.`; }, }, ], }); this.adjusterEventService.clustersLoaded.subscribe(() => { this.colorPalette = this.generateRandomColorPalette( adjusterService.clusters.length ); }); /* The order of pushes matter! */ this.hsConfig.default_layers.push(this.nuts3Layer); this.hsConfig.default_layers.push(this.nuts2Layer); /*this.hsMapService .loaded() .then((map) => this.hsMapService.repopulateLayers([]));*/ this.init(); } init(): void { this.hsSidebarService.buttons.push({ panel: 'adjuster', module: 'pra.adjuster', order: 0, title: 'Adjust factors', description: 'Adjust factors for computation', icon: 'icon-analytics-piechart', }); this.hsPanelContainerService.create(AdjusterComponent, {}); this.hsLayoutService.setDefaultPanel('adjuster'); //this.hsLayoutService.sidebarRight = false; } /** * https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/ * @private * @description Only generates random colors if the current palette does not provide enough colors for all the clusters * @param {number} colorCount Number of colors to randomly generate * @returns {Array>} Array of RGB colors */ private generateRandomColorPalette(colorCount: number) { const palette = this.colorPalette; const goldenRatioConjugate = 0.618033988749895; let i = palette.length; while (i < colorCount) { let h = Math.random(); h += goldenRatioConjugate; h %= 1; h *= 360; palette.push(hsv2rgb(h, 0.5, 0.95)); i++; } return palette; //return `rgba(${r}, ${g}, ${b}, 0.7)`; } }