app.service.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import hsv2rgb from 'hsv2rgb';
  2. import {Feature} from 'ol';
  3. import {Fill, Stroke, Style} from 'ol/style';
  4. import {Geometry} from 'ol/geom';
  5. import {Injectable} from '@angular/core';
  6. import {TopoJSON} from 'ol/format';
  7. import {Vector as VectorLayer} from 'ol/layer';
  8. import {Vector as VectorSource} from 'ol/source';
  9. import {HsConfig} from 'hslayers-ng';
  10. import {HsEventBusService} from 'hslayers-ng';
  11. import {HsLanguageService} from 'hslayers-ng';
  12. import {HsLayerManagerService} from 'hslayers-ng';
  13. import {HsLayoutService} from 'hslayers-ng';
  14. import {HsPanelContainerService} from 'hslayers-ng';
  15. import {HsSidebarService} from 'hslayers-ng';
  16. import {AdjusterComponent} from './adjuster/adjuster.component';
  17. import {AdjusterEventService} from './adjuster/adjuster-event.service';
  18. import {AdjusterLegendService} from './adjuster/adjuster-legend.service';
  19. import {AdjusterService} from './adjuster/adjuster.service';
  20. import {AppConfig, krajeLayer, masLayer, obceIndexLayer, okresyLayer} from './app.config';
  21. @Injectable({providedIn: 'root'})
  22. export class AppService {
  23. constructor(
  24. public adjusterService: AdjusterService,
  25. public adjusterEventService: AdjusterEventService,
  26. public adjusterLegendService: AdjusterLegendService,
  27. public hsConfig: HsConfig,
  28. public hsEventBus: HsEventBusService,
  29. public hsLanguageService: HsLanguageService,
  30. public hsLayerManagerService: HsLayerManagerService,
  31. public hsLayoutService: HsLayoutService,
  32. public hsPanelContainerService: HsPanelContainerService,
  33. public hsSidebarService: HsSidebarService
  34. ) {
  35. this.hsSidebarService.buttons.push({
  36. panel: 'adjuster',
  37. module: 'pra.adjuster',
  38. order: 0,
  39. title: () =>
  40. this.hsLanguageService.getTranslation('ADJUSTER.adjustFactors'),
  41. description: 'Adjust factors for computation',
  42. icon: 'icon-analytics-piechart',
  43. });
  44. this.hsPanelContainerService.create(AdjusterComponent, {});
  45. this.prepareLayers();
  46. this.adjusterEventService.loaded.subscribe(({success}) => {
  47. if (success) {
  48. this.adjusterLegendService.refreshColorPalette(
  49. this.adjusterService.numberOfClusters
  50. );
  51. }
  52. });
  53. this.hsEventBus.layoutLoads.subscribe(() => {
  54. this.init();
  55. });
  56. this.hsEventBus.olMapLoads.subscribe(() => {
  57. this.ensureLayerIsLoaded(obceIndexLayer);
  58. for (const method of this.adjusterService.methods) {
  59. this.ensureLayerIsLoaded(method.layer);
  60. }
  61. });
  62. }
  63. init(): void {
  64. this.hsLanguageService.setLanguage('cs');
  65. this.hsLayoutService.setDefaultPanel('adjuster');
  66. }
  67. /**
  68. * Create separate layer fo each clustering method and add it to default_layers
  69. */
  70. prepareLayers(): void {
  71. for (const method of this.adjusterService.methods) {
  72. method.layer = new VectorLayer({
  73. properties: {
  74. editor: {editable: false},
  75. autoLegend: false,
  76. title: `Obce ČR: ${method.name.replace(/\((.+?)\)/g, '')} clusters`,
  77. attributions: ['CC-BY ČÚZK, 2021'],
  78. popUp: {
  79. attributes: [
  80. {
  81. attribute: method.codename,
  82. label: 'ID shluku',
  83. },
  84. ],
  85. },
  86. },
  87. source: new VectorSource({
  88. format: new TopoJSON({dataProjection: 'EPSG:5514'}),
  89. url: require('./data/obce_cr_20210310_5p_5514.topojson').default,
  90. overlaps: false,
  91. }),
  92. visible: true,
  93. style: this.generateStyle(method.codename),
  94. });
  95. method.layer
  96. .getSource()
  97. .on('featuresloadend', () =>
  98. this.adjusterEventService.layerReady.next({name: method.codename})
  99. );
  100. AppConfig.default_layers.push(method.layer as any);
  101. }
  102. // obceIndexLayer, okresyLayer and krajeLayer must be pushed in this order
  103. // so they will display in correct order
  104. AppConfig.default_layers.push(obceIndexLayer as any);
  105. obceIndexLayer
  106. .getSource()
  107. .on('featuresloadend', () =>
  108. this.adjusterEventService.layerReady.next({name: 'index'})
  109. );
  110. (obceIndexLayer.getSource() as any).legend_categories = this.adjusterLegendService.createIndexLegend();
  111. AppConfig.default_layers.push(masLayer as any);
  112. AppConfig.default_layers.push(okresyLayer as any);
  113. AppConfig.default_layers.push(krajeLayer as any);
  114. this.hsConfig.update(AppConfig);
  115. }
  116. /**
  117. * Layer must be turned visible so it is loaded into the map.
  118. * This method ensures that layers critical for further computations
  119. * are for at least a moment turned visible and thus loaded properly.
  120. * @param {VectorLayer} layer One of layers used to calculate index or clusters
  121. */
  122. ensureLayerIsLoaded(layer: VectorLayer<VectorSource<Geometry>>): void {
  123. const layerVisible = layer.getVisible();
  124. if (!layerVisible) {
  125. layer.setVisible(true);
  126. setTimeout(() => layer.setVisible(false), 10);
  127. }
  128. }
  129. /**
  130. * @description Function factory for generating style functions based on different clustering methods
  131. * @param {string} method selected method
  132. * @returns {function} style function
  133. */
  134. private generateStyle(method: string) {
  135. return (feature: Feature<Geometry>): Style => {
  136. if (isNaN(feature.get(method))) {
  137. return new Style({
  138. fill: new Fill({
  139. color: '#FFF',
  140. }),
  141. stroke: new Stroke({
  142. color: '#3399CC',
  143. width: 0.25,
  144. }),
  145. });
  146. } else {
  147. return new Style({
  148. fill: new Fill({
  149. color: this.adjusterLegendService.colorPalette[
  150. feature.get(method) - 1
  151. ],
  152. }),
  153. stroke: new Stroke({
  154. color: '#FFF',
  155. width: 0.25,
  156. }),
  157. });
  158. }
  159. };
  160. }
  161. }