app.service.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. import {Injectable} from '@angular/core';
  2. import proj4 from 'proj4';
  3. import {GeoJSON} from 'ol/format';
  4. import {OSM, TileWMS, Vector as VectorSource} from 'ol/source';
  5. import {Tile, Vector as VectorLayer} from 'ol/layer';
  6. import {bbox as bboxStrategy} from 'ol/loadingstrategy';
  7. import {get as getProjection, transform} from 'ol/proj';
  8. import {register} from 'ol/proj/proj4';
  9. import {transformExtent} from 'ol/proj';
  10. import {
  11. HsConfig,
  12. HsEventBusService,
  13. HsLanguageService,
  14. HsLayerManagerService,
  15. HsLayoutService,
  16. HsMapService,
  17. HsPanelContainerService,
  18. HsQueryVectorService,
  19. HsSidebarService,
  20. getTitle,
  21. } from 'hslayers-ng';
  22. import {FcCalculatorService} from './calculator/calculator.service';
  23. import {imageWmsTLayer} from './calculator/image-wms-t-layer';
  24. proj4.defs(
  25. 'EPSG:3045',
  26. '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'
  27. );
  28. proj4.defs(
  29. 'EPSG:5514',
  30. '+proj=krovak +lat_0=49.5 +lon_0=24.83333333333333 +alpha=30.28813972222222 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +towgs84=542.5,89.2,456.9,5.517,2.275,5.516,6.96 +units=m +no_defs'
  31. );
  32. register(proj4);
  33. @Injectable({providedIn: 'root'})
  34. export class AppService {
  35. sjtskProjection = getProjection('EPSG:5514');
  36. constructor(
  37. public calcService: FcCalculatorService,
  38. public hsConfig: HsConfig,
  39. public hsEventBus: HsEventBusService,
  40. public hsLanguageService: HsLanguageService,
  41. public hsLayerManagerService: HsLayerManagerService,
  42. public hsLayoutService: HsLayoutService,
  43. public hsPanelContainerService: HsPanelContainerService,
  44. public hsSidebarService: HsSidebarService,
  45. private hsMapService: HsMapService,
  46. private hsQueryVectorService: HsQueryVectorService
  47. ) {}
  48. init(): void {
  49. /* Define the polygon's style using SLD */
  50. const fieldSld = `<?xml version="1.0" encoding="ISO-8859-1"?>
  51. <StyledLayerDescriptor version="1.0.0"
  52. xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
  53. xmlns="http://www.opengis.net/sld"
  54. xmlns:ogc="http://www.opengis.net/ogc"
  55. xmlns:xlink="http://www.w3.org/1999/xlink"
  56. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  57. <NamedLayer>
  58. <Name>Simple point with stroke</Name>
  59. <UserStyle>
  60. <Title>Default</Title>
  61. <FeatureTypeStyle>
  62. <Rule>
  63. <PolygonSymbolizer>
  64. <Fill>
  65. <CssParameter name="fill">#ffffff</CssParameter>
  66. <CssParameter name="fill-opacity">0.7</CssParameter>
  67. </Fill>
  68. <Stroke>
  69. <CssParameter name="stroke">#33cccc</CssParameter>
  70. <CssParameter name="stroke-opacity">1</CssParameter>
  71. <CssParameter name="stroke-width">2.0</CssParameter>
  72. </Stroke>
  73. </PolygonSymbolizer>
  74. </Rule>
  75. </FeatureTypeStyle>
  76. </UserStyle>
  77. </NamedLayer>
  78. </StyledLayerDescriptor>
  79. `;
  80. const lpisSource = new VectorSource({
  81. format: new GeoJSON({
  82. dataProjection: 'EPSG:5514',
  83. featureProjection: this.hsMapService.getCurrentProj('default'),
  84. }),
  85. url: (extent) => {
  86. if (extent == undefined) {
  87. extent = this.hsMapService.getMapExtent('default');
  88. }
  89. const cur_proj = this.hsMapService.getCurrentProj('default');
  90. extent = transformExtent(extent, cur_proj, 'EPSG:5514');
  91. const kulturaKod = 1; // Doesn't seem to work
  92. const proxyPath = window.location.hostname.includes('localhost')
  93. ? 'http://localhost:8085/'
  94. : '/proxy/';
  95. return (
  96. proxyPath +
  97. 'https://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/foodie/lpis.map' +
  98. '&service=WFS' +
  99. '&VERSION=1.1.0' +
  100. '&REQUEST=GetFeature' +
  101. '&TYPENAME=lpis_borders' +
  102. '&COUNT=100' +
  103. '&outputformat=geojson' +
  104. '&SRSNAME=EPSG:5514' +
  105. `&BBOX=${extent ? extent.join(',') : ''}`
  106. // + `FILTER=&<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:PropertyIsEqualTo><ogc:PropertyName>kultura</ogc:PropertyName><ogc:Literal>${kulturaKod}</ogc:Literal></ogc:PropertyIsEqualTo></ogc:Filter>`
  107. );
  108. //%3Cgml:Box%3E%3Cgml:coordinates%3E${
  109. //extent.join(',')
  110. //}%3C/gml:coordinates%3E%3C/gml:Box%3E%3C/ogc:Filter%3E`;
  111. },
  112. strategy: bboxStrategy,
  113. });
  114. lpisSource.on(
  115. 'featuresloadstart',
  116. () => (this.calcService.lpisLoading = true)
  117. );
  118. lpisSource.on(
  119. 'featuresloadend',
  120. () => (this.calcService.lpisLoading = false)
  121. );
  122. lpisSource.on('featuresloaderror', (evt) => {
  123. this.calcService.lpisLoading = false;
  124. console.warn('error when loading LPIS layer');
  125. console.log(evt);
  126. });
  127. /*const waterThematicLayers = [
  128. new Tile({
  129. properties: {
  130. title:
  131. 'Vodní útvary povrchových vod karegorie "řeka" včetně silně ovlivněných vodních útvarů a umělých vodních útvarů: 2. plánovací cyklus',
  132. //queryCapabilities: false,
  133. },
  134. source: new TileWMS({
  135. url: 'https://heis.vuv.cz/data/webmap/wms.dll?SERVICE=WMS&VERSION=1.3.0&MU=CS&',
  136. params: {
  137. LAYERS: 'isvs_upovr',
  138. INFO_FORMAT: 'text/html',
  139. STYLES: 'inspire_common:DEFAULT',
  140. FORMAT: 'image/png',
  141. },
  142. crossOrigin: 'anonymous',
  143. }),
  144. }),
  145. new Tile({
  146. properties: {
  147. title:
  148. 'Vodní útvary povrchových vod karegorie "jezero" včetně silně ovlivněných vodních útvarů a umělých vodních útvarů: 2. plánovací cyklus',
  149. //queryCapabilities: false,
  150. },
  151. source: new TileWMS({
  152. url: 'https://heis.vuv.cz/data/webmap/wms.dll?SERVICE=WMS&VERSION=1.3.0&MU=CS&',
  153. params: {
  154. LAYERS: 'isvs_upovj',
  155. INFO_FORMAT: 'text/html',
  156. STYLES: 'inspire_common:DEFAULT',
  157. FORMAT: 'image/png',
  158. },
  159. crossOrigin: 'anonymous',
  160. }),
  161. }),
  162. new Tile({
  163. properties: {
  164. title: 'OPVZ - vodárenské nádrže',
  165. //queryCapabilities: false,
  166. },
  167. source: new TileWMS({
  168. url: 'https://eagri.cz/public/app/wms/public_zp.fcgi?language=eng&',
  169. params: {
  170. LAYERS: 'OPVZ_OPVN',
  171. STYLES: 'default',
  172. FORMAT: 'image/png; mode=8bit',
  173. VERSION: '1.3.0',
  174. },
  175. crossOrigin: 'anonymous',
  176. }),
  177. }),
  178. new Tile({
  179. properties: {
  180. title: 'OPVZ - podzemní nebo povrchové',
  181. //queryCapabilities: false,
  182. },
  183. source: new TileWMS({
  184. url: 'https://eagri.cz/public/app/wms/public_zp.fcgi?language=eng&',
  185. params: {
  186. LAYERS: 'VODSTVO_BUFF_25M',
  187. STYLES: 'default',
  188. FORMAT: 'image/png; mode=8bit',
  189. VERSION: '1.3.0',
  190. },
  191. crossOrigin: 'anonymous',
  192. }),
  193. }),
  194. new Tile({
  195. properties: {
  196. title: 'OPVZ - podzemní nebo povrchové',
  197. //queryCapabilities: false,
  198. },
  199. source: new TileWMS({
  200. url: 'https://eagri.cz/public/app/wms/public_zp.fcgi?language=eng&',
  201. params: {
  202. LAYERS: 'OPVZ_PODZ_POVRCH',
  203. STYLES: 'default',
  204. FORMAT: 'image/png; mode=8bit',
  205. VERSION: '1.3.0',
  206. },
  207. crossOrigin: 'anonymous',
  208. }),
  209. }),
  210. ];*/
  211. /* Define and update the HsConfig configuration object */
  212. const translationOverrides = this.hsConfig.get().translationOverrides ?? {};
  213. const mergedTranslationOverrides = {
  214. ...translationOverrides,
  215. ...{
  216. 'cs': {
  217. 'CALCULATOR': {
  218. 'blurNone': 'žádné',
  219. 'getDates': 'VYBRAT DATUM',
  220. 'getZones': 'ZÍSKAT ZÓNY',
  221. 'errorLoading': 'Chyba při načítání dat',
  222. 'errorLoadingDates':
  223. 'Nebylo možné načíst seznam možných dat ze serveru. Zkuste to prosím později.',
  224. 'errorLoadingZones':
  225. 'Nebylo možné načíst zóny pole ze serveru. Pravděpodobně z důvodu přílišné oblačnosti snímku. Zkuste jiný datum.',
  226. 'loading': 'Načítám',
  227. 'panelHeader': 'Výpočet indexů pole',
  228. 'selectBlur': 'Vyhlazení hran zón',
  229. 'selectDate': 'Chci datum',
  230. 'selectField':
  231. 'Vyberte pole kliknutím do mapy. Více polí můžete vybrat podržením klávesy SHIFT.',
  232. 'selectMore': 'Více polí můžete vybrat podržením klávesy SHIFT',
  233. 'selectedField': 'Vybráno pole',
  234. 'selectedFields': 'Vybrána pole',
  235. 'selectFieldAndIndex': 'Nejprve vyberte index a pole v mapě',
  236. 'selectIndex': 'Vypočítat index',
  237. 'selectIndexHint': 'Vyberte z dostupných indexů',
  238. 'selectQuantiles': 'Počet kvantilů',
  239. 'zoomIn': 'Pro výběr pole je potřeba mapu přiblížit.',
  240. },
  241. },
  242. 'en': {
  243. 'CALCULATOR': {
  244. 'blurNone': 'none',
  245. 'getDates': 'GET DATES',
  246. 'getZones': 'GET ZONES',
  247. 'errorLoading': 'Error loading data',
  248. 'errorLoadingDates':
  249. 'It was not possible to load available dates from the server. Please, try again later.',
  250. 'errorLoadingZones':
  251. 'It was not possible to load field zones from the server. This is probably due to the high cloudiness of the source image. Try another date.',
  252. 'loading': 'Loading',
  253. 'panelHeader': 'Field calculation',
  254. 'selectBlur': 'Smoothing zone edges',
  255. 'selectDate': 'I want a date',
  256. 'selectField':
  257. 'Select a field by clicking in the map. You can select more fields by press and holding the SHIFT key.',
  258. 'selectMore':
  259. 'You can select more fields by press and holding the SHIFT key',
  260. 'selectedField': 'Selected field',
  261. 'selectedFields': 'Selected fields',
  262. 'selectFieldAndIndex':
  263. 'Select an index and a field in the map to continue',
  264. 'selectIndex': 'Calculate index',
  265. 'selectIndexHint': 'Select one of the available indices',
  266. 'selectQuantiles': 'Quantiles count',
  267. 'zoomIn': 'In order to select the field, you must zoom in the map.',
  268. },
  269. 'PANEL_HEADER': {'CALCULATOR': 'Field calculation'},
  270. },
  271. },
  272. };
  273. this.hsConfig.update(
  274. {
  275. datasources: [
  276. /* You need to set up Layman in order to use it. See https://github.com/LayerManager/layman */
  277. /*{
  278. title: 'Layman',
  279. url: 'http://localhost:8087',
  280. user: 'anonymous',
  281. type: 'layman',
  282. liferayProtocol: 'https',
  283. },*/
  284. {
  285. title: 'Micka',
  286. url: 'https://www.agrihub.cz/micka/csw',
  287. language: 'eng',
  288. type: 'micka',
  289. },
  290. ],
  291. /* Use hslayers-server if you need to proxify your requests to other services. See https://www.npmjs.com/package/hslayers-server */
  292. proxyPrefix: window.location.hostname.includes('localhost')
  293. ? `${window.location.protocol}//${window.location.hostname}:8085/`
  294. : '/proxy/',
  295. useProxy: true,
  296. panelsEnabled: {
  297. composition_browser: true,
  298. info: false,
  299. saveMap: false,
  300. legend: false,
  301. tripPlanner: false,
  302. },
  303. componentsEnabled: {
  304. basemapGallery: true,
  305. },
  306. //assetsPath: 'assets',
  307. symbolizerIcons: [
  308. {name: 'beach', url: '/assets/icons/beach17.svg'},
  309. {name: 'bicycles', url: '/assets/icons/bicycles.svg'},
  310. {name: 'coffee-shop', url: '/assets/icons/coffee-shop1.svg'},
  311. {name: 'mountain', url: '/assets/icons/mountain42.svg'},
  312. {name: 'warning', url: '/assets/icons/warning.svg'},
  313. ],
  314. popUpDisplay: 'hover',
  315. translationOverrides: mergedTranslationOverrides,
  316. },
  317. 'default'
  318. );
  319. this.hsLanguageService.setLanguage('en');
  320. this.hsLayoutService.setDefaultPanel('calculator');
  321. for (const layer of [
  322. new Tile({
  323. properties: {
  324. title: 'Ortofoto ČÚZK',
  325. base: true,
  326. removable: false,
  327. thumbnail: 'https://www.agrihub.sk/hsl-ng/img/orto.jpg',
  328. },
  329. source: new TileWMS({
  330. url: 'https://geoportal.cuzk.cz/WMS_ORTOFOTO_PUB/WMService.aspx',
  331. params: {
  332. LAYERS: 'GR_ORTFOTORGB',
  333. },
  334. attributions: [
  335. '© <a href="geoportal.cuzk.cz" target="_blank">ČÚZK</a>',
  336. ],
  337. }),
  338. visible: false,
  339. }),
  340. /* Thematic layers */
  341. imageWmsTLayer,
  342. new VectorLayer({
  343. properties: {
  344. title: 'LPIS (WFS)',
  345. synchronize: false,
  346. cluster: false,
  347. queryable: true,
  348. inlineLegend: true,
  349. editor: {
  350. editable: false,
  351. },
  352. sld: fieldSld,
  353. popUp: {
  354. attributes: [
  355. 'id_dpb',
  356. 'id_uz',
  357. 'nkod_dpb',
  358. 'kultura',
  359. 'svazitost',
  360. 'vymeram',
  361. ],
  362. },
  363. //path: 'User generated',
  364. },
  365. minZoom: this.calcService.MIN_LPIS_VISIBLE_ZOOM,
  366. opacity: 0.7,
  367. source: lpisSource,
  368. }),
  369. new Tile({
  370. properties: {
  371. title: 'LPIS (WMS)',
  372. queryCapabilities: false,
  373. },
  374. maxZoom: this.calcService.MIN_LPIS_VISIBLE_ZOOM,
  375. source: new TileWMS({
  376. url: 'https://gis.lesprojekt.cz/cgi-bin/mapserv?map=/home/dima/maps/foodie/lpis.map',
  377. params: {
  378. LAYERS: 'lpis_borders', //'lpis_cultures'
  379. INFO_FORMAT: undefined,
  380. FORMAT: 'image/png; mode=8bit',
  381. },
  382. crossOrigin: 'anonymous',
  383. }),
  384. }),
  385. ]) {
  386. this.hsMapService
  387. .getLayersArray()
  388. .filter((l) => getTitle(l) == getTitle(layer))
  389. .map((l) => this.hsMapService.getMap().removeLayer(l));
  390. this.hsMapService.addLayer(layer, 'default');
  391. }
  392. }
  393. }