app.service.ts 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. import hsv2rgb from 'hsv2rgb';
  2. import {Injectable} from '@angular/core';
  3. import {Feature} from 'ol';
  4. import {Fill, Stroke, Style} from 'ol/style';
  5. import {GeoJSON} from 'ol/format';
  6. import {Vector as VectorLayer} from 'ol/layer';
  7. import {Vector as VectorSource} from 'ol/source';
  8. import {HsConfig} from 'hslayers-ng/config.service';
  9. import {HsEventBusService} from 'hslayers-ng/components/core/event-bus.service';
  10. import {HsLanguageService} from 'hslayers-ng/components/language/language.service';
  11. import {HsLayoutService} from 'hslayers-ng/components/layout/layout.service';
  12. //import {HsMapService} from 'hslayers-ng/components/map/map.service';
  13. import {HsPanelContainerService} from 'hslayers-ng/components/layout/panels/panel-container.service';
  14. import {HsSidebarService} from 'hslayers-ng/components/sidebar/sidebar.service';
  15. import {AdjusterComponent} from './adjuster/adjuster.component';
  16. import {AdjusterEventService} from './adjuster/adjuster-event.service';
  17. import {AdjusterLegendService} from './adjuster/adjuster-legend.service';
  18. import {AdjusterService} from './adjuster/adjuster.service';
  19. import {nuts} from './nuts';
  20. @Injectable({providedIn: 'root'})
  21. export class AppService {
  22. nuts2style = new Style({
  23. stroke: new Stroke({
  24. color: '#000000',
  25. width: 0.5,
  26. }),
  27. });
  28. nuts2Layer = new VectorLayer({
  29. source: nuts.nuts2Source,
  30. editor: {editable: false},
  31. visible: false,
  32. style: this.nuts2style,
  33. title: 'NUTS2 regions',
  34. });
  35. nuts3IndexLayer = new VectorLayer({
  36. source: nuts.nuts3IndexSource,
  37. editor: {editable: false},
  38. visible: true,
  39. style: (f) => this.indexStyle(f),
  40. title: 'NUTS3 regions: Rural attractiveness index',
  41. });
  42. nuts3ClustersLayer = new VectorLayer({
  43. source: nuts.nuts3ClustersSource,
  44. editor: {editable: false},
  45. visible: true,
  46. style: this.generateStyle(this.adjusterService.method),
  47. title: 'NUTS3 regions: Clusters',
  48. });
  49. pilotsColor = 'rgba(29, 148, 29, 0.2)';
  50. pilotsStyle = new Style({
  51. stroke: new Stroke({
  52. color: '#1d941d',
  53. width: 1.5,
  54. }),
  55. fill: new Fill({
  56. color: this.pilotsColor,
  57. }),
  58. });
  59. pilotRegions = new VectorLayer({
  60. source: new VectorSource({
  61. format: new GeoJSON(),
  62. url: require('./data/pilot_regions.geojson').default,
  63. }),
  64. editor: {editable: false},
  65. visible: true,
  66. style: this.pilotsStyle,
  67. title: 'Polirural Pilot Regions',
  68. });
  69. serviceUrl: string;
  70. constructor(
  71. public adjusterService: AdjusterService,
  72. public adjusterEventService: AdjusterEventService,
  73. public adjusterLegendService: AdjusterLegendService,
  74. public hsConfig: HsConfig,
  75. public hsEventBus: HsEventBusService,
  76. public hsLanguageService: HsLanguageService,
  77. public hsLayoutService: HsLayoutService,
  78. //public hsMapService: HsMapService,
  79. public hsPanelContainerService: HsPanelContainerService,
  80. public hsSidebarService: HsSidebarService
  81. ) {
  82. this.serviceUrl = this.adjusterService.serviceBaseUrl + 'georeport/';
  83. this.nuts3IndexLayer.set('popUp', {
  84. attributes: [
  85. {attribute: 'CNTR_CODE', label: 'Country'},
  86. {attribute: 'NUTS_NAME', label: 'Name'},
  87. {
  88. attribute: 'aggregate',
  89. label: 'aggregated index',
  90. displayFunction: (x) => {
  91. return `${(x * 100).toFixed(2)} %`;
  92. },
  93. },
  94. {
  95. attribute: 'NUTS_ID',
  96. label: 'Detailed report',
  97. displayFunction: (x) => {
  98. return `<a href="${this.serviceUrl}${x}" target="_blank">in a new page</a>.`;
  99. },
  100. },
  101. ],
  102. });
  103. /* For debugging only */
  104. /*this.hsEventBus.olMapLoads.subscribe((map) => {
  105. map.on('click', this.debugMe);
  106. });*/
  107. this.nuts3IndexLayer.set('editable', false);
  108. this.nuts3IndexLayer.set('queryable', false);
  109. this.nuts3IndexLayer.getSource().legend_categories = this.adjusterLegendService.createIndexLegend();
  110. this.nuts3ClustersLayer.set('popUp', {
  111. attributes: [
  112. {attribute: 'CNTR_CODE', label: 'Country'},
  113. {attribute: 'NUTS_NAME', label: 'Name'},
  114. {attribute: this.adjusterService.method, label: 'Cluster ID'},
  115. {
  116. attribute: 'NUTS_ID',
  117. label: 'Detailed report',
  118. displayFunction: (x) => {
  119. return `<a href="${this.serviceUrl}${x}" target="_blank">in a new page</a>.`;
  120. },
  121. },
  122. ],
  123. });
  124. this.nuts3ClustersLayer.set('editable', false);
  125. this.nuts3ClustersLayer.set('queryable', false);
  126. this.pilotRegions.set('popUp', {
  127. attributes: [
  128. {attribute: 'NUTS_NAME', label: 'Region name'},
  129. //TODO: Uncomment when implemented in the rural-attractiveness-service
  130. /*{
  131. attribute: 'NUTS_ID',
  132. label: 'Pilot region details',
  133. displayFunction: (x) => {
  134. return `<a href="${this.serviceUrl}${x}" target="_blank">in a new page</a>.`;
  135. },
  136. },*/
  137. ],
  138. });
  139. this.pilotRegions.getSource().legend_categories = [
  140. {
  141. color: this.pilotsColor,
  142. name: 'Polirural pilot region',
  143. },
  144. ];
  145. this.pilotRegions.set('queryable', false);
  146. this.adjusterEventService.loaded.subscribe(({success}) => {
  147. if (success) {
  148. this.adjusterLegendService.refreshColorPalette(
  149. this.adjusterService.numberOfClusters
  150. );
  151. /*this.colorPalette = this.generateRandomColorPalette(
  152. adjusterService.clusters.length
  153. );*/
  154. }
  155. });
  156. this.adjusterEventService.methodChanged.subscribe((method) => {
  157. /*TODO: prettify this
  158. this.nuts3ClustersLayer.set(
  159. 'title',
  160. `NUTS3 regions: ${method.replaceAll(/\((.+?)\)/g, '')} Clusters`
  161. );*/
  162. this.nuts3ClustersLayer.get('popUp').attributes[2].attribute = method;
  163. this.nuts3ClustersLayer.setStyle(
  164. this.generateStyle(this.adjusterService.method)
  165. );
  166. });
  167. /* The order of pushes matter! */
  168. this.hsConfig.default_layers.push(this.nuts3ClustersLayer);
  169. this.hsConfig.default_layers.push(this.nuts3IndexLayer);
  170. this.hsConfig.default_layers.push(this.nuts2Layer);
  171. this.hsConfig.default_layers.push(this.pilotRegions);
  172. /*this.hsMapService
  173. .loaded()
  174. .then((map) => this.hsMapService.repopulateLayers([]));*/
  175. this.hsEventBus.layoutLoads.subscribe(() => {
  176. this.init();
  177. });
  178. }
  179. init(): void {
  180. this.hsSidebarService.buttons.push({
  181. panel: 'adjuster',
  182. module: 'pra.adjuster',
  183. order: 0,
  184. title: () =>
  185. this.hsLanguageService.getTranslation('ADJUSTER.adjustFactors'),
  186. description: 'Adjust factors for computation',
  187. icon: 'icon-analytics-piechart',
  188. });
  189. this.hsPanelContainerService.create(AdjusterComponent, {});
  190. this.hsLayoutService.setDefaultPanel('adjuster');
  191. }
  192. /**
  193. * @description Function factory for generating style functions based on different clustering methods
  194. * @param {string} method currently selected method
  195. * @returns {function} style function
  196. */
  197. private generateStyle(method: string) {
  198. return (feature: Feature): Style => {
  199. if (isNaN(feature.get(method))) {
  200. return new Style({
  201. fill: new Fill({
  202. color: '#FFF',
  203. }),
  204. stroke: new Stroke({
  205. color: '#3399CC',
  206. width: 0.25,
  207. }),
  208. });
  209. } else {
  210. return new Style({
  211. fill: new Fill({
  212. color: this.adjusterLegendService.colorPalette[
  213. feature.get(method) - 1
  214. ],
  215. }),
  216. stroke: new Stroke({
  217. color: '#FFF',
  218. width: 0.25,
  219. }),
  220. });
  221. }
  222. };
  223. }
  224. private indexStyle = (feature) => {
  225. if (isNaN(feature.get('aggregate'))) {
  226. return [
  227. new Style({
  228. fill: new Fill({
  229. color: '#FFF',
  230. }),
  231. stroke: new Stroke({
  232. color: '#3399CC',
  233. width: 0.25,
  234. }),
  235. }),
  236. ];
  237. } else {
  238. return [
  239. new Style({
  240. fill: new Fill({
  241. color: this.adjusterLegendService.perc2color(
  242. feature.get('aggregate')
  243. ),
  244. }),
  245. stroke: new Stroke({
  246. color: '#FFFFFF',
  247. width: 0.15,
  248. }),
  249. }),
  250. ];
  251. }
  252. };
  253. private debugMe(e) {
  254. console.log(e);
  255. const feats = e.map.getFeaturesAtPixel(e.pixel);
  256. console.log(feats);
  257. }
  258. }