diff --git a/projects/hslayers/components/add-data/vector/vector-file/vector-file.component.ts b/projects/hslayers/components/add-data/vector/vector-file/vector-file.component.ts index 85ce61098a..1ef14c55dc 100644 --- a/projects/hslayers/components/add-data/vector/vector-file/vector-file.component.ts +++ b/projects/hslayers/components/add-data/vector/vector-file/vector-file.component.ts @@ -13,7 +13,10 @@ import {Cluster} from 'ol/source'; import {GeoJSON} from 'ol/format'; import {DEFAULT_VECTOR_LOAD_TYPE} from '../../enums/load-types.const'; -import {HsAddDataCommonFileService} from 'hslayers-ng/shared/add-data'; +import { + HsAddDataCommonFileService, + HsAddDataVectorUploadService, +} from 'hslayers-ng/shared/add-data'; import {HsAddDataVectorService} from 'hslayers-ng/shared/add-data'; import {HsCommonLaymanService} from 'hslayers-ng/common/layman'; import {HsConfig} from 'hslayers-ng/config'; @@ -51,6 +54,7 @@ export class HsAddDataVectorFileComponent constructor( private hsAddDataVectorService: HsAddDataVectorService, + private hsAddDataVectorUploadService: HsAddDataVectorUploadService, public hsAddDataCommonFileService: HsAddDataCommonFileService, private hsCommonLaymanService: HsCommonLaymanService, private hsConfig: HsConfig, @@ -151,9 +155,10 @@ export class HsAddDataVectorFileComponent async updateExistingLayer(): Promise { let features = this.data.features.length > 0 ? this.data.features : []; if (this.fileType != 'geojson') { - const nonJson = await this.hsAddDataVectorService.convertUploadedData( - this.fileInput.nativeElement.files[0], - ); + const nonJson = + await this.hsAddDataVectorUploadService.convertUploadedData( + this.fileInput.nativeElement.files[0], + ); features = nonJson.features; //proper typing will get rid of this } this.hsLayerUtilsService.isLayerClustered(this.data.sourceLayer) @@ -166,7 +171,7 @@ export class HsAddDataVectorFileComponent handleFileUpload(evt: HsUploadedFiles): void { Array.from(evt.fileList).forEach(async (f) => { const uploadedData = - await this.hsAddDataVectorService.readUploadedFile(f); + await this.hsAddDataVectorUploadService.readUploadedFile(f); if (uploadedData !== undefined && !uploadedData.error) { uploadedData.url !== undefined ? (this.data.base64url = uploadedData.url) diff --git a/projects/hslayers/shared/add-data/public-api.ts b/projects/hslayers/shared/add-data/public-api.ts index 28866c607e..470c551c31 100644 --- a/projects/hslayers/shared/add-data/public-api.ts +++ b/projects/hslayers/shared/add-data/public-api.ts @@ -16,3 +16,5 @@ export * from './catalogue/micka.service'; export * from './catalogue/catalogue-map.service'; export * from './vector/vector.service'; +export * from './vector/vector-upload.service'; +export * from './vector/vector.utils.service'; diff --git a/projects/hslayers/shared/add-data/vector/vector-upload.service.ts b/projects/hslayers/shared/add-data/vector/vector-upload.service.ts new file mode 100644 index 0000000000..076ec290b0 --- /dev/null +++ b/projects/hslayers/shared/add-data/vector/vector-upload.service.ts @@ -0,0 +1,199 @@ +import {Injectable} from '@angular/core'; + +import {Feature} from 'ol'; +import {Projection, get as getProjection} from 'ol/proj'; +import {PROJECTIONS as epsg4326Aliases} from 'ol/proj/epsg4326'; + +import {HsLogService} from 'hslayers-ng/shared/log'; +import {HsMapService} from 'hslayers-ng/shared/map'; + +import {HsAddDataVectorUtilsService} from './vector.utils.service'; + +@Injectable({ + providedIn: 'root', +}) +export class HsAddDataVectorUploadService { + readUploadedFileAsText = (inputFile: any) => { + const temporaryFileReader = new FileReader(); + return new Promise((resolve, reject) => { + temporaryFileReader.onerror = () => { + temporaryFileReader.abort(); + reject(new DOMException('Problem parsing input file.')); + }; + temporaryFileReader.onload = () => { + resolve(temporaryFileReader.result); + }; + temporaryFileReader.readAsText(inputFile); + }); + }; + readUploadedFileAsURL = (inputFile: any) => { + const temporaryFileReader = new FileReader(); + return new Promise((resolve, reject) => { + temporaryFileReader.onerror = () => { + temporaryFileReader.abort(); + reject(new DOMException('Problem parsing input file.')); + }; + temporaryFileReader.onload = () => { + resolve(temporaryFileReader.result); + }; + temporaryFileReader.readAsDataURL(inputFile); + }); + }; + + constructor( + private hsLog: HsLogService, + private hsMapService: HsMapService, + private hsAddDataVectorUtilsService: HsAddDataVectorUtilsService, + ) {} + + /** + * Create a object containing data from XML dataset + * @param file - File uploaded by the user + * @param type - Data type + */ + async createVectorObjectFromXml(file: File, type: string): Promise { + try { + const uploadedContent = await this.readUploadedFileAsURL(file); + const dataUrl = uploadedContent.toString(); + const object = { + url: dataUrl, + name: file.name, + title: file.name, + type: type, + }; + return object; + } catch (e) { + this.hsLog.warn('Uploaded file is not supported!'); + return {error: 'couldNotUploadSelectedFile'}; + } + } + + /** + * Read uploaded file and extract the data as JSON object + * @param file - File uploaded by the user + * @returns JSON object with parsed data + */ + async readUploadedFile(file: File): Promise { + let uploadedData; + const fileType = this.hsAddDataVectorUtilsService.tryGuessTypeFromNameOrUrl( + file.name.toLowerCase(), + ); + switch (fileType) { + case 'kml': + uploadedData = await this.createVectorObjectFromXml(file, fileType); + break; + case 'gpx': + uploadedData = await this.convertUploadedData(file); + break; + default: + try { + const fileContents = await this.readUploadedFileAsText(file); + const fileToJSON = JSON.parse(fileContents); + if (fileToJSON !== undefined) { + fileToJSON.name = file.name.split('.')[0]; + uploadedData = await this.createVectorObjectFromJson(fileToJSON); + return uploadedData; + } + } catch (e) { + this.hsLog.warn('Uploaded file is not supported!', e); + return {error: 'couldNotUploadSelectedFile'}; + } + } + return uploadedData; + } + + /** + * Convert uploaded KML or GPX files into GeoJSON format / parse loaded GeoJSON + * @param file - Uploaded KML, GPX or GeoJSON files + */ + async convertUploadedData(file: File): Promise { + let parser; + const uploadedData: any = {}; + try { + const uploadedContent: any = await this.readUploadedFileAsText(file); + let fileType = this.hsAddDataVectorUtilsService.tryGuessTypeFromNameOrUrl( + file.name.toLowerCase(), + ); + switch (fileType) { + case 'kml': + const KML = (await import('ol/format/KML')).default; + parser = new KML(); + uploadedData.features = parser.readFeatures(uploadedContent); + break; + case 'gpx': + const GPX = (await import('ol/format/GPX')).default; + parser = new GPX(); + uploadedData.features = parser.readFeatures(uploadedContent); + fileType = 'json'; + break; + default: + } + if (uploadedData?.features?.length > 0) { + this.transformFeaturesIfNeeded( + uploadedData.features, + parser.readProjection(uploadedContent), + ); + } + uploadedData.nativeFeatures = parser.readFeatures(uploadedContent); + uploadedData.nativeSRS = parser.readProjection(uploadedContent); + uploadedData.title = file.name.split('.')[0].trim(); + uploadedData.name = uploadedData.title; + uploadedData.type = fileType; + return uploadedData; + } catch (e) { + this.hsLog.warn('Uploaded file is not supported' + e); + return {error: 'couldNotUploadSelectedFile'}; + } + } + + /** + * Read features from uploaded file as objects + * @param json - Uploaded file parsed as json object + * @returns JSON object with file name and read features + */ + async createVectorObjectFromJson(json: any): Promise { + let features: Feature[] = []; + const GeoJSON = (await import('ol/format/GeoJSON')).default; + const format = new GeoJSON(); + const projection = format.readProjection(json); + if (!projection) { + return { + error: 'ERROR.srsNotSupported', + }; + } + if (json.features?.length > 0) { + //FIXME: Type-cast shall be automatically inferred after OL >8.2 + features = format.readFeatures(json) as Feature[]; + this.transformFeaturesIfNeeded(features, projection); + } + const object = { + name: json.name, + title: json.name, + srs: this.hsAddDataVectorUtilsService.getFeaturesProjection(projection), + features: features, //Features in map crs + nativeFeatures: format.readFeatures(json), //Features in native CRS + nativeSRS: projection, + }; + return object; + } + + /** + * Transform features to other projection if needed + * @param features - Extracted features from uploaded file + * @param projection - Projection to which transform the features + */ + transformFeaturesIfNeeded(features: Feature[], projection: Projection): void { + const mapProjection = this.hsMapService.getMap().getView().getProjection(); + if (projection != mapProjection) { + projection = epsg4326Aliases + .map((proj) => proj.getCode()) + .some((code) => code === projection.getCode()) + ? getProjection('EPSG:4326') + : projection; + features.forEach((f) => + //TODO: Make it parallel using workers or some library + f.getGeometry().transform(projection, mapProjection), + ); + } + } +} diff --git a/projects/hslayers/shared/add-data/vector/vector.service.ts b/projects/hslayers/shared/add-data/vector/vector.service.ts index b64149d652..46dab4f68a 100644 --- a/projects/hslayers/shared/add-data/vector/vector.service.ts +++ b/projects/hslayers/shared/add-data/vector/vector.service.ts @@ -1,11 +1,8 @@ import {Injectable} from '@angular/core'; -import {Feature} from 'ol'; -import {GPX, GeoJSON, KML} from 'ol/format'; import {Layer, Vector as VectorLayer} from 'ol/layer'; -import {Projection, get as getProjection} from 'ol/proj'; import {Source, Vector as VectorSource} from 'ol/source'; -import {PROJECTIONS as epsg4326Aliases} from 'ol/proj/epsg4326'; +import {get as getProjection} from 'ol/proj'; import {HsAddDataCommonFileService} from '../common-file.service'; import {HsAddDataService} from '../add-data.service'; @@ -27,6 +24,7 @@ import { } from 'hslayers-ng/common/layman'; import {setDefinition} from 'hslayers-ng/common/extensions'; +import {HsAddDataVectorUtilsService} from './vector.utils.service'; import {HsVectorLayerOptions} from 'hslayers-ng/types'; import {VectorLayerDescriptor} from 'hslayers-ng/types'; import {VectorSourceDescriptor} from 'hslayers-ng/types'; @@ -35,33 +33,6 @@ import {VectorSourceDescriptor} from 'hslayers-ng/types'; providedIn: 'root', }) export class HsAddDataVectorService { - readUploadedFileAsText = (inputFile: any) => { - const temporaryFileReader = new FileReader(); - return new Promise((resolve, reject) => { - temporaryFileReader.onerror = () => { - temporaryFileReader.abort(); - reject(new DOMException('Problem parsing input file.')); - }; - temporaryFileReader.onload = () => { - resolve(temporaryFileReader.result); - }; - temporaryFileReader.readAsText(inputFile); - }); - }; - readUploadedFileAsURL = (inputFile: any) => { - const temporaryFileReader = new FileReader(); - return new Promise((resolve, reject) => { - temporaryFileReader.onerror = () => { - temporaryFileReader.abort(); - reject(new DOMException('Problem parsing input file.')); - }; - temporaryFileReader.onload = () => { - resolve(temporaryFileReader.result); - }; - temporaryFileReader.readAsDataURL(inputFile); - }); - }; - constructor( private hsAddDataCommonFileService: HsAddDataCommonFileService, private hsAddDataService: HsAddDataService, @@ -71,6 +42,7 @@ export class HsAddDataVectorService { private hsMapService: HsMapService, private hsStylerService: HsStylerService, private hsUtilsService: HsUtilsService, + private hsAddDataVectorUtilsService: HsAddDataVectorUtilsService, ) {} /** @@ -161,7 +133,7 @@ export class HsAddDataVectorService { } if (this.hsUtilsService.undefineEmptyString(type) === undefined) { - type = this.tryGuessTypeFromNameOrUrl(url); + type = this.hsAddDataVectorUtilsService.tryGuessTypeFromNameOrUrl(url); } let mapProjection; @@ -357,7 +329,9 @@ export class HsAddDataVectorService { const layerDesc: UpsertLayerObject = { title: data.title, name: getLaymanFriendlyLayerName(data.name), - crs: this.getFeaturesProjection(getProjection(data.nativeSRS)).getCode(), + crs: this.hsAddDataVectorUtilsService + .getFeaturesProjection(getProjection(data.nativeSRS)) + .getCode(), workspace: commonFileRef.endpoint.user, access_rights: data.access_rights, style, @@ -459,183 +433,4 @@ export class HsAddDataVectorService { src.un('change', this.changeListener); } } - - /** - * Tries to guess file type based on the file extension - * @param extension - Parsed file extension from uploaded file - */ - tryGuessTypeFromNameOrUrl(extension: string): string { - if (extension !== undefined) { - if (extension.toLowerCase().endsWith('kml')) { - return 'kml'; - } - if (extension.toLowerCase().endsWith('gpx')) { - return 'gpx'; - } - if ( - extension.toLowerCase().endsWith('geojson') || - extension.toLowerCase().endsWith('json') - ) { - return 'geojson'; - } - } - } - - /** - * Create a object containing data from XML dataset - * @param file - File uploaded by the user - * @param type - Data type - */ - async createVectorObjectFromXml(file: File, type: string): Promise { - try { - const uploadedContent = await this.readUploadedFileAsURL(file); - const dataUrl = uploadedContent.toString(); - const object = { - url: dataUrl, - name: file.name, - title: file.name, - type: type, - }; - return object; - } catch (e) { - this.hsLog.warn('Uploaded file is not supported!'); - return {error: 'couldNotUploadSelectedFile'}; - } - } - - /** - * Read uploaded file and extract the data as JSON object - * @param file - File uploaded by the user - * @returns JSON object with parsed data - */ - async readUploadedFile(file: File): Promise { - let uploadedData; - const fileType = this.tryGuessTypeFromNameOrUrl(file.name.toLowerCase()); - switch (fileType) { - case 'kml': - uploadedData = await this.createVectorObjectFromXml(file, fileType); - break; - case 'gpx': - uploadedData = await this.convertUploadedData(file); - break; - default: - try { - const fileContents = await this.readUploadedFileAsText(file); - const fileToJSON = JSON.parse(fileContents); - if (fileToJSON !== undefined) { - fileToJSON.name = file.name.split('.')[0]; - uploadedData = this.createVectorObjectFromJson(fileToJSON); - return uploadedData; - } - } catch (e) { - this.hsLog.warn('Uploaded file is not supported!', e); - return {error: 'couldNotUploadSelectedFile'}; - } - } - return uploadedData; - } - - /** - * Returns layman supported projection - */ - getFeaturesProjection(projection: Projection): Projection { - return epsg4326Aliases - .map((proj) => proj.getCode()) - .some((code) => code === projection.getCode()) - ? getProjection('EPSG:4326') - : this.hsLaymanService.supportedCRRList.indexOf(projection.getCode()) > -1 - ? projection - : getProjection('EPSG:4326'); - //Features in map CRS - } - - /** - * Read features from uploaded file as objects - * @param json - Uploaded file parsed as json object - * @returns JSON object with file name and read features - */ - createVectorObjectFromJson(json: any): any { - let features: Feature[] = []; - const format = new GeoJSON(); - const projection = format.readProjection(json); - if (!projection) { - return { - error: 'ERROR.srsNotSupported', - }; - } - if (json.features?.length > 0) { - //FIXME: Type-cast shall be automatically inferred after OL >8.2 - features = format.readFeatures(json) as Feature[]; - this.transformFeaturesIfNeeded(features, projection); - } - const object = { - name: json.name, - title: json.name, - srs: this.getFeaturesProjection(projection), - features: features, //Features in map crs - nativeFeatures: format.readFeatures(json), //Features in native CRS - nativeSRS: projection, - }; - return object; - } - - /** - * Transform features to other projection if needed - * @param features - Extracted features from uploaded file - * @param projection - Projection to which transform the features - */ - transformFeaturesIfNeeded(features: Feature[], projection: Projection): void { - const mapProjection = this.hsMapService.getMap().getView().getProjection(); - if (projection != mapProjection) { - projection = epsg4326Aliases - .map((proj) => proj.getCode()) - .some((code) => code === projection.getCode()) - ? getProjection('EPSG:4326') - : projection; - features.forEach((f) => - //TODO: Make it parallel using workers or some library - f.getGeometry().transform(projection, mapProjection), - ); - } - } - - /** - * Convert uploaded KML or GPX files into GeoJSON format / parse loaded GeoJSON - * @param file - Uploaded KML, GPX or GeoJSON files - */ - async convertUploadedData(file: File): Promise { - let parser; - const uploadedData: any = {}; - try { - const uploadedContent: any = await this.readUploadedFileAsText(file); - let fileType = this.tryGuessTypeFromNameOrUrl(file.name.toLowerCase()); - switch (fileType) { - case 'kml': - parser = new KML(); - uploadedData.features = parser.readFeatures(uploadedContent); - break; - case 'gpx': - parser = new GPX(); - uploadedData.features = parser.readFeatures(uploadedContent); - fileType = 'json'; - break; - default: - } - if (uploadedData?.features?.length > 0) { - this.transformFeaturesIfNeeded( - uploadedData.features, - parser.readProjection(uploadedContent), - ); - } - uploadedData.nativeFeatures = parser.readFeatures(uploadedContent); - uploadedData.nativeSRS = parser.readProjection(uploadedContent); - uploadedData.title = file.name.split('.')[0].trim(); - uploadedData.name = uploadedData.title; - uploadedData.type = fileType; - return uploadedData; - } catch (e) { - this.hsLog.warn('Uploaded file is not supported' + e); - return {error: 'couldNotUploadSelectedFile'}; - } - } } diff --git a/projects/hslayers/shared/add-data/vector/vector.utils.service.ts b/projects/hslayers/shared/add-data/vector/vector.utils.service.ts new file mode 100644 index 0000000000..806fdf7692 --- /dev/null +++ b/projects/hslayers/shared/add-data/vector/vector.utils.service.ts @@ -0,0 +1,47 @@ +import {Injectable} from '@angular/core'; + +import {Projection, get as getProjection} from 'ol/proj'; +import {PROJECTIONS as epsg4326Aliases} from 'ol/proj/epsg4326'; + +import {HsLaymanService} from 'hslayers-ng/shared/save-map'; + +@Injectable({ + providedIn: 'root', +}) +export class HsAddDataVectorUtilsService { + constructor(private hsLaymanService: HsLaymanService) {} + /** + * Tries to guess file type based on the file extension + * @param extension - Parsed file extension from uploaded file + */ + tryGuessTypeFromNameOrUrl(extension: string): string { + if (extension !== undefined) { + if (extension.toLowerCase().endsWith('kml')) { + return 'kml'; + } + if (extension.toLowerCase().endsWith('gpx')) { + return 'gpx'; + } + if ( + extension.toLowerCase().endsWith('geojson') || + extension.toLowerCase().endsWith('json') + ) { + return 'geojson'; + } + } + } + + /** + * Returns layman supported projection + */ + getFeaturesProjection(projection: Projection): Projection { + return epsg4326Aliases + .map((proj) => proj.getCode()) + .some((code) => code === projection.getCode()) + ? getProjection('EPSG:4326') + : this.hsLaymanService.supportedCRRList.indexOf(projection.getCode()) > -1 + ? projection + : getProjection('EPSG:4326'); + //Features in map CRS + } +} diff --git a/projects/hslayers/shared/layer-manager/layer-manager-copy-layer.service.ts b/projects/hslayers/shared/layer-manager/layer-manager-copy-layer.service.ts index 232d690198..a87f8898c2 100644 --- a/projects/hslayers/shared/layer-manager/layer-manager-copy-layer.service.ts +++ b/projects/hslayers/shared/layer-manager/layer-manager-copy-layer.service.ts @@ -44,10 +44,12 @@ export class HsLayerManagerCopyLayerService { if (!name || typeof name === 'number') { name = getName(currentOlLayer); } + const layerType = + await this.hsLayerManagerUtilsService.getLayerSourceType( + currentOlLayer, + ); const layerCopy = await this.hsAddDataOwsService.connectToOWS({ - type: this.hsLayerManagerUtilsService - .getLayerSourceType(currentOlLayer) - .toLowerCase(), + type: layerType.toLowerCase(), uri: url, layer: name, getOnly: true, diff --git a/projects/hslayers/shared/layer-manager/layer-manager-utils.service.ts b/projects/hslayers/shared/layer-manager/layer-manager-utils.service.ts index 3fdc14b995..6219e615a9 100644 --- a/projects/hslayers/shared/layer-manager/layer-manager-utils.service.ts +++ b/projects/hslayers/shared/layer-manager/layer-manager-utils.service.ts @@ -84,17 +84,17 @@ export class HsLayerManagerUtilsService { * Only the commonly used values are listed here, it shall be probably extended in the future. * @returns Short description of source type: 'WMS', 'XYZ', 'vector (GeoJSON)' etc. */ - getLayerSourceType(layer: Layer): string { - if (this.hsLayerUtilsService.isLayerKMLSource(layer)) { + async getLayerSourceType(layer: Layer): Promise { + if (await this.hsLayerUtilsService.isLayerKMLSource(layer)) { return `vector (KML)`; } - if (this.hsLayerUtilsService.isLayerGPXSource(layer)) { + if (await this.hsLayerUtilsService.isLayerGPXSource(layer)) { return `vector (GPX)`; } - if (this.hsLayerUtilsService.isLayerGeoJSONSource(layer)) { + if (await this.hsLayerUtilsService.isLayerGeoJSONSource(layer)) { return `vector (GeoJSON)`; } - if (this.hsLayerUtilsService.isLayerTopoJSONSource(layer)) { + if (await this.hsLayerUtilsService.isLayerTopoJSONSource(layer)) { return `vector (TopoJSON)`; } if (this.hsLayerUtilsService.isLayerVectorLayer(layer)) { diff --git a/projects/hslayers/shared/layer-manager/layer-manager.service.ts b/projects/hslayers/shared/layer-manager/layer-manager.service.ts index 5b6cfde4d1..6025e619da 100644 --- a/projects/hslayers/shared/layer-manager/layer-manager.service.ts +++ b/projects/hslayers/shared/layer-manager/layer-manager.service.ts @@ -277,7 +277,7 @@ export class HsLayerManagerService { idString() { return 'layer' + (this.coded_path || '') + (this.uid || ''); }, - type: this.hsLayerManagerUtilsService.getLayerSourceType(layer), + type: await this.hsLayerManagerUtilsService.getLayerSourceType(layer), source: this.hsLayerManagerUtilsService.getLayerSourceUrl(layer), }; this.loadingEvents(layerDescriptor); diff --git a/projects/hslayers/shared/utils/layer-utils.service.ts b/projects/hslayers/shared/utils/layer-utils.service.ts index 0684b2f56d..e95a7effa5 100644 --- a/projects/hslayers/shared/utils/layer-utils.service.ts +++ b/projects/hslayers/shared/utils/layer-utils.service.ts @@ -14,7 +14,6 @@ import { } from 'ol/source'; import {Feature, View} from 'ol'; import {default as FeatureFormat} from 'ol/format/Feature'; -import {GPX, GeoJSON, KML, TopoJSON} from 'ol/format'; import {Geometry} from 'ol/geom'; import {Image as ImageLayer, Layer, Vector as VectorLayer} from 'ol/layer'; import {METERS_PER_UNIT} from 'ol/proj'; @@ -247,7 +246,8 @@ export class HsLayerUtilsService { * @param layer - an OL vector layer * @returns true only if the GeoJSON format is explicitly specified in the source. False otherwise. */ - isLayerGeoJSONSource(layer: Layer): boolean { + async isLayerGeoJSONSource(layer: Layer): Promise { + const GeoJSON = (await import('ol/format/GeoJSON')).default; if (this.HsUtilsService.instOf(this.getLayerSourceFormat(layer), GeoJSON)) { return true; } @@ -259,7 +259,8 @@ export class HsLayerUtilsService { * @param layer - an OL vector layer * @returns true only if the TopoJSON format is explicitly specified in the source. False otherwise. */ - isLayerTopoJSONSource(layer: Layer): boolean { + async isLayerTopoJSONSource(layer: Layer): Promise { + const TopoJSON = (await import('ol/format/TopoJSON')).default; if ( this.HsUtilsService.instOf(this.getLayerSourceFormat(layer), TopoJSON) ) { @@ -273,7 +274,8 @@ export class HsLayerUtilsService { * @param layer - an OL vector layer * @returns true only if the KML format is explicitly specified in the source. False otherwise. */ - isLayerKMLSource(layer: Layer): boolean { + async isLayerKMLSource(layer: Layer): Promise { + const KML = (await import('ol/format/KML')).default; if (this.HsUtilsService.instOf(this.getLayerSourceFormat(layer), KML)) { return true; } @@ -285,7 +287,8 @@ export class HsLayerUtilsService { * @param layer - an OL vector layer * @returns true only if the GPX format is explicitly specified in the source. False otherwise. */ - isLayerGPXSource(layer: Layer): boolean { + async isLayerGPXSource(layer: Layer): Promise { + const GPX = await import('ol/format/GPX'); if (this.HsUtilsService.instOf(this.getLayerSourceFormat(layer), GPX)) { return true; }