import hsv2rgb from 'hsv2rgb'; import {Injectable} from '@angular/core'; import {Feature} from 'ol'; import {Fill, Stroke, Style} from 'ol/style'; import {GeoJSON} from 'ol/format'; import {Vector as VectorLayer} from 'ol/layer'; import {Vector as VectorSource} from 'ol/source'; import {HsConfig} from 'hslayers-ng/config.service'; import {HsEventBusService} from 'hslayers-ng/components/core/event-bus.service'; import {HsLanguageService} from 'hslayers-ng/components/language/language.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 {AdjusterLegendService} from './adjuster/adjuster-legend.service'; import {AdjusterService} from './adjuster/adjuster.service'; import {nuts} from './nuts'; @Injectable({providedIn: 'root'}) export class AppService { 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', }); nuts3IndexLayer = new VectorLayer({ source: nuts.nuts3IndexSource, editor: {editable: false}, visible: true, style: (f) => this.indexStyle(f), title: 'NUTS3 regions: Rural attractiveness index', }); nuts3ClustersLayer = new VectorLayer({ source: nuts.nuts3ClustersSource, editor: {editable: false}, visible: true, style: this.generateStyle(this.adjusterService.method), title: 'NUTS3 regions: Clusters', }); pilotsColor = 'rgba(29, 148, 29, 0.2)'; pilotsStyle = new Style({ stroke: new Stroke({ color: '#1d941d', width: 1.5, }), fill: new Fill({ color: this.pilotsColor, }), }); pilotRegions = new VectorLayer({ source: new VectorSource({ format: new GeoJSON(), url: require('./data/pilot_regions.geojson').default, }), editor: {editable: false}, visible: true, style: this.pilotsStyle, title: 'Polirural Pilot Regions', }); serviceUrl: string; constructor( public adjusterService: AdjusterService, public adjusterEventService: AdjusterEventService, public adjusterLegendService: AdjusterLegendService, public hsConfig: HsConfig, public hsEventBus: HsEventBusService, public hsLanguageService: HsLanguageService, public hsLayoutService: HsLayoutService, //public hsMapService: HsMapService, public hsPanelContainerService: HsPanelContainerService, public hsSidebarService: HsSidebarService ) { this.serviceUrl = this.adjusterService.serviceBaseUrl + 'georeport/'; this.nuts3IndexLayer.set('popUp', { attributes: [ {attribute: 'CNTR_CODE', label: 'Country'}, {attribute: 'NUTS_NAME', label: 'Name'}, { attribute: 'aggregate', label: 'aggregated index', displayFunction: (x) => { return `${(x * 100).toFixed(2)} %`; }, }, { attribute: 'NUTS_ID', label: 'Detailed report', displayFunction: (x) => { return `in a new page.`; }, }, ], }); /* For debugging only */ /*this.hsEventBus.olMapLoads.subscribe((map) => { map.on('click', this.debugMe); });*/ this.nuts3IndexLayer.set('editable', false); this.nuts3IndexLayer.set('queryable', false); this.nuts3IndexLayer.getSource().legend_categories = this.adjusterLegendService.createIndexLegend(); this.nuts3ClustersLayer.set('popUp', { attributes: [ {attribute: 'CNTR_CODE', label: 'Country'}, {attribute: 'NUTS_NAME', label: 'Name'}, {attribute: this.adjusterService.method, label: 'Cluster ID'}, { attribute: 'NUTS_ID', label: 'Detailed report', displayFunction: (x) => { return `in a new page.`; }, }, ], }); this.nuts3ClustersLayer.set('editable', false); this.nuts3ClustersLayer.set('queryable', false); this.pilotRegions.set('popUp', { attributes: [ {attribute: 'NUTS_NAME', label: 'Region name'}, //TODO: Uncomment when implemented in the rural-attractiveness-service /*{ attribute: 'NUTS_ID', label: 'Pilot region details', displayFunction: (x) => { return `in a new page.`; }, },*/ ], }); this.pilotRegions.getSource().legend_categories = [ { color: this.pilotsColor, name: 'Polirural pilot region', }, ]; this.pilotRegions.set('queryable', false); this.adjusterEventService.loaded.subscribe(({success}) => { if (success) { this.adjusterLegendService.refreshColorPalette( this.adjusterService.numberOfClusters ); /*this.colorPalette = this.generateRandomColorPalette( adjusterService.clusters.length );*/ } }); this.adjusterEventService.methodChanged.subscribe((method) => { /*TODO: prettify this this.nuts3ClustersLayer.set( 'title', `NUTS3 regions: ${method.replaceAll(/\((.+?)\)/g, '')} Clusters` );*/ this.nuts3ClustersLayer.get('popUp').attributes[2].attribute = method; this.nuts3ClustersLayer.setStyle( this.generateStyle(this.adjusterService.method) ); }); /* The order of pushes matter! */ this.hsConfig.default_layers.push(this.nuts3ClustersLayer); this.hsConfig.default_layers.push(this.nuts3IndexLayer); this.hsConfig.default_layers.push(this.nuts2Layer); this.hsConfig.default_layers.push(this.pilotRegions); /*this.hsMapService .loaded() .then((map) => this.hsMapService.repopulateLayers([]));*/ this.hsEventBus.layoutLoads.subscribe(() => { this.init(); }); } init(): void { this.hsSidebarService.buttons.push({ panel: 'adjuster', module: 'pra.adjuster', order: 0, title: () => this.hsLanguageService.getTranslation('ADJUSTER.adjustFactors'), description: 'Adjust factors for computation', icon: 'icon-analytics-piechart', }); this.hsPanelContainerService.create(AdjusterComponent, {}); this.hsLayoutService.setDefaultPanel('adjuster'); } /** * @description Function factory for generating style functions based on different clustering methods * @param {string} method currently selected method * @returns {function} style function */ private generateStyle(method: string) { return (feature: Feature): Style => { if (isNaN(feature.get(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.adjusterLegendService.colorPalette[ feature.get(method) - 1 ], }), stroke: new Stroke({ color: '#FFF', width: 0.25, }), }); } }; } private indexStyle = (feature) => { if (isNaN(feature.get('aggregate'))) { 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.adjusterLegendService.perc2color( feature.get('aggregate') ), }), stroke: new Stroke({ color: '#FFFFFF', width: 0.15, }), }), ]; } }; private debugMe(e) { console.log(e); const feats = e.map.getFeaturesAtPixel(e.pixel); console.log(feats); } }