app.service.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import * as hsv2rgb from 'hsv2rgb';
  2. import {Feature} from 'ol';
  3. import {Fill, Stroke, Style} from 'ol/style';
  4. import {Injectable} from '@angular/core';
  5. import {Vector as VectorLayer} from 'ol/layer';
  6. import {HsConfig} from 'hslayers-ng/config.service';
  7. import {HsLayoutService} from 'hslayers-ng/components/layout/layout.service';
  8. import {HsMapService} from 'hslayers-ng/components/map/map.service';
  9. import {HsPanelContainerService} from 'hslayers-ng/components/layout/panels/panel-container.service';
  10. import {HsSidebarService} from 'hslayers-ng/components/sidebar/sidebar.service';
  11. import {AdjusterComponent} from './adjuster/adjuster.component';
  12. import {AdjusterEventService} from './adjuster/adjuster-event.service';
  13. import {AdjusterService} from './adjuster/adjuster.service';
  14. import {nuts} from './nuts';
  15. @Injectable({providedIn: 'root'})
  16. export class AppService {
  17. // https://colorbrewer2.org/?type=qualitative&scheme=Paired&n=12
  18. colorPalette = [
  19. '#a6cee3',
  20. '#1f78b4',
  21. '#b2df8a',
  22. '#33a02c',
  23. '#fb9a99',
  24. '#e31a1c',
  25. '#fdbf6f',
  26. '#ff7f00',
  27. '#cab2d6',
  28. '#6a3d9a',
  29. '#ffff99',
  30. '#b15928',
  31. ];
  32. nuts2style = new Style({
  33. stroke: new Stroke({
  34. color: '#000000',
  35. width: 0.5,
  36. }),
  37. });
  38. nuts2Layer = new VectorLayer({
  39. source: nuts.nuts2Source,
  40. editor: {editable: false},
  41. visible: false,
  42. style: this.nuts2style,
  43. title: 'NUTS2 regions',
  44. });
  45. nuts3style = (feature: Feature): Style => {
  46. if (isNaN(feature.get(this.method))) {
  47. return [
  48. new Style({
  49. fill: new Fill({
  50. color: '#FFF',
  51. }),
  52. stroke: new Stroke({
  53. color: '#3399CC',
  54. width: 0.25,
  55. }),
  56. }),
  57. ];
  58. } else {
  59. return [
  60. new Style({
  61. fill: new Fill({
  62. color: this.colorPalette[feature.get(this.method) - 1],
  63. }),
  64. stroke: new Stroke({
  65. color: '#FFF',
  66. width: 0.25,
  67. }),
  68. }),
  69. ];
  70. }
  71. };
  72. nuts3Layer = new VectorLayer({
  73. source: nuts.nuts3Source,
  74. editor: {editable: false},
  75. visible: true,
  76. style: this.nuts3style,
  77. title: 'NUTS3 regions',
  78. });
  79. method: string;
  80. serviceUrl: string;
  81. constructor(
  82. private adjusterService: AdjusterService,
  83. private adjusterEventService: AdjusterEventService,
  84. private hsConfig: HsConfig,
  85. private hsLayoutService: HsLayoutService,
  86. private hsMapService: HsMapService,
  87. private hsSidebarService: HsSidebarService,
  88. private hsPanelContainerService: HsPanelContainerService
  89. ) {
  90. this.method = this.adjusterService.method;
  91. this.serviceUrl = this.adjusterService.serviceBaseUrl + 'georeport/';
  92. this.nuts3Layer.set('popUp', {
  93. attributes: [
  94. {attribute: 'CNTR_CODE', label: 'Country'},
  95. {attribute: 'NUTS_NAME', label: 'Name'},
  96. {attribute: this.method, label: 'Cluster ID'},
  97. {
  98. attribute: 'NUTS_ID',
  99. label: 'Detailed report',
  100. displayFunction: (x) => {
  101. return `<a href="${this.serviceUrl}${x}" target="_blank">in a new page</a>.`;
  102. },
  103. },
  104. ],
  105. });
  106. this.adjusterEventService.clustersLoaded.subscribe(() => {
  107. this.colorPalette = this.generateRandomColorPalette(
  108. adjusterService.clusters.length
  109. );
  110. });
  111. /* The order of pushes matter! */
  112. this.hsConfig.default_layers.push(this.nuts3Layer);
  113. this.hsConfig.default_layers.push(this.nuts2Layer);
  114. /*this.hsMapService
  115. .loaded()
  116. .then((map) => this.hsMapService.repopulateLayers([]));*/
  117. this.init();
  118. }
  119. init(): void {
  120. this.hsSidebarService.buttons.push({
  121. panel: 'adjuster',
  122. module: 'pra.adjuster',
  123. order: 0,
  124. title: 'Adjust factors',
  125. description: 'Adjust factors for computation',
  126. icon: 'icon-analytics-piechart',
  127. });
  128. this.hsPanelContainerService.create(AdjusterComponent, {});
  129. this.hsLayoutService.setDefaultPanel('adjuster');
  130. //this.hsLayoutService.sidebarRight = false;
  131. }
  132. /**
  133. * https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
  134. * @private
  135. * @description Only generates random colors if the current palette does not provide enough colors for all the clusters
  136. * @param {number} colorCount Number of colors to randomly generate
  137. * @returns {Array<Array<Number>>} Array of RGB colors
  138. */
  139. private generateRandomColorPalette(colorCount: number) {
  140. const palette = this.colorPalette;
  141. const goldenRatioConjugate = 0.618033988749895;
  142. let i = palette.length;
  143. while (i < colorCount) {
  144. let h = Math.random();
  145. h += goldenRatioConjugate;
  146. h %= 1;
  147. h *= 360;
  148. palette.push(hsv2rgb(h, 0.5, 0.95));
  149. i++;
  150. }
  151. return palette;
  152. //return `rgba(${r}, ${g}, ${b}, 0.7)`;
  153. }
  154. }