diff --git a/packages/geo/src/lib/import-export/import-export/import-export.component.html b/packages/geo/src/lib/import-export/import-export/import-export.component.html
index 8657764df4..68a2186ae6 100644
--- a/packages/geo/src/lib/import-export/import-export/import-export.component.html
+++ b/packages/geo/src/lib/import-export/import-export/import-export.component.html
@@ -13,10 +13,10 @@
-
diff --git a/packages/geo/src/lib/import-export/import-export/import-export.component.scss b/packages/geo/src/lib/import-export/import-export/import-export.component.scss
index 8fcdaee323..bcbc7ba3cf 100644
--- a/packages/geo/src/lib/import-export/import-export/import-export.component.scss
+++ b/packages/geo/src/lib/import-export/import-export/import-export.component.scss
@@ -2,8 +2,12 @@ mat-form-field {
width: 100%;
}
+h4 {
+ padding: 0 5px;
+}
+
.igo-form {
- padding: 5px;
+ padding: 15px 5px;
}
.igo-form-button-group {
diff --git a/packages/geo/src/lib/import-export/import-export/import-export.component.ts b/packages/geo/src/lib/import-export/import-export/import-export.component.ts
index 57c8868a8a..099b5a9c2c 100644
--- a/packages/geo/src/lib/import-export/import-export/import-export.component.ts
+++ b/packages/geo/src/lib/import-export/import-export/import-export.component.ts
@@ -1,6 +1,6 @@
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
-import { Subscription, throwError } from 'rxjs';
+import { Subscription, BehaviorSubject } from 'rxjs';
import { MessageService, LanguageService } from '@igo2/core';
@@ -29,7 +29,7 @@ export class ImportExportComponent implements OnDestroy, OnInit {
public formats = ExportFormat;
public layers: VectorLayer[];
public inputProj: string = 'EPSG:4326';
- public loading = false;
+ public loading$ = new BehaviorSubject(false);
private layers$$: Subscription;
@@ -58,26 +58,30 @@ export class ImportExportComponent implements OnDestroy, OnInit {
}
importFiles(files: File[]) {
- this.loading = true;
+ this.loading$.next(true);
for (const file of files) {
- this.importService
- .import(file, this.inputProj)
- .subscribe(
- (features: Feature[]) => this.onFileImportSuccess(file, features),
- (error: Error) => this.onFileImportError(file, error)
- );
+ this.importService.import(file, this.inputProj).subscribe(
+ (features: Feature[]) => this.onFileImportSuccess(file, features),
+ (error: Error) => this.onFileImportError(file, error),
+ () => {
+ this.loading$.next(false);
+ }
+ );
}
}
handleExportFormSubmit(data: ExportOptions) {
- this.loading = true;
+ this.loading$.next(true);
const layer = this.map.getLayerById(data.layer);
const olFeatures = layer.dataSource.ol.getFeatures();
this.exportService
.export(olFeatures, data.format, layer.title, this.map.projection)
.subscribe(
- () => { this.loading = false;},
- (error: Error) => this.onFileExportError(error)
+ () => {},
+ (error: Error) => this.onFileExportError(error),
+ () => {
+ this.loading$.next(false);
+ }
);
}
@@ -89,7 +93,6 @@ export class ImportExportComponent implements OnDestroy, OnInit {
}
private onFileImportSuccess(file: File, features: Feature[]) {
- this.loading = false;
handleFileImportSuccess(
file,
features,
@@ -100,7 +103,7 @@ export class ImportExportComponent implements OnDestroy, OnInit {
}
private onFileImportError(file: File, error: Error) {
- this.loading = false;
+ this.loading$.next(false);
handleFileImportError(
file,
error,
@@ -110,7 +113,7 @@ export class ImportExportComponent implements OnDestroy, OnInit {
}
private onFileExportError(error: Error) {
- this.loading = false;
+ this.loading$.next(false);
handleFileExportError(error, this.messageService, this.languageService);
}
}
diff --git a/packages/geo/src/lib/import-export/shared/export.service.ts b/packages/geo/src/lib/import-export/shared/export.service.ts
index bcba80ad8c..0d704220b1 100644
--- a/packages/geo/src/lib/import-export/shared/export.service.ts
+++ b/packages/geo/src/lib/import-export/shared/export.service.ts
@@ -9,13 +9,15 @@ import OlFeature from 'ol/Feature';
import { downloadContent } from './export.utils';
import { ExportFormat } from './export.type';
-import { ExportInvalidFileError, ExportNothingToExportError } from './export.errors';
+import {
+ ExportInvalidFileError,
+ ExportNothingToExportError
+} from './export.errors';
@Injectable({
providedIn: 'root'
})
export class ExportService {
-
static ogreFormats = {
GML: 'gml',
GPX: 'gpx',
@@ -39,15 +41,26 @@ export class ExportService {
projectionOut = 'EPSG:4326'
): Observable {
const exportOlFeatures = olFeatures.map((olFeature: OlFeature) => {
- const keys = olFeature.getKeys().filter((key: string) => !key.startsWith('_'));
- const properties = keys.reduce((acc: object, key: string) => {
- acc[key] = olFeature.get(key);
- return acc;
- }, {geometry: olFeature.getGeometry()});
+ const keys = olFeature
+ .getKeys()
+ .filter((key: string) => !key.startsWith('_'));
+ const properties = keys.reduce(
+ (acc: object, key: string) => {
+ acc[key] = olFeature.get(key);
+ return acc;
+ },
+ { geometry: olFeature.getGeometry() }
+ );
return new OlFeature(properties);
});
- return this.exportAsync(exportOlFeatures, format, title, projectionIn, projectionOut);
+ return this.exportAsync(
+ exportOlFeatures,
+ format,
+ title,
+ projectionIn,
+ projectionOut
+ );
}
private exportAsync(
@@ -68,15 +81,36 @@ export class ExportService {
if (ogreFormats.indexOf(format) >= 0) {
if (this.ogreUrl === undefined) {
if (ExportService.noOgreFallbacks.indexOf(format) >= 0) {
- this.exportToFile(olFeatures, observer, format, title, projectionIn, projectionOut);
+ this.exportToFile(
+ olFeatures,
+ observer,
+ format,
+ title,
+ projectionIn,
+ projectionOut
+ );
} else {
observer.error(new ExportInvalidFileError());
}
return;
}
- this.exportWithOgre(olFeatures, observer, format, title, projectionIn, projectionOut);
+ this.exportWithOgre(
+ olFeatures,
+ observer,
+ format,
+ title,
+ projectionIn,
+ projectionOut
+ );
} else {
- this.exportToFile(olFeatures, observer, format, title, projectionIn, projectionOut);
+ this.exportToFile(
+ olFeatures,
+ observer,
+ format,
+ title,
+ projectionIn,
+ projectionOut
+ );
}
};
@@ -120,9 +154,10 @@ export class ExportService {
featureNS: 'http://example.com/feature'
});
- const url = `${this.ogreUrl}/convert`;
+ const url = `${this.ogreUrl}/convertJson`;
const form = document.createElement('form');
form.setAttribute('method', 'post');
+ form.setAttribute('target', '_blank');
form.setAttribute('action', url);
const geojsonField = document.createElement('input');
@@ -132,7 +167,10 @@ export class ExportService {
form.appendChild(geojsonField);
const outputNameField = document.createElement('input');
- const outputName = format === 'Shapefile' ? `${title}.zip` : title;
+ const outputName =
+ format === 'Shapefile'
+ ? `${title}.zip`
+ : `${title}.${format.toLowerCase()}`;
outputNameField.setAttribute('type', 'hidden');
outputNameField.setAttribute('name', 'outputName');
outputNameField.setAttribute('value', outputName);
@@ -141,7 +179,7 @@ export class ExportService {
const ogreFormat = ExportService.ogreFormats[format];
const outputFormatField = document.createElement('input');
outputFormatField.setAttribute('type', 'hidden');
- outputFormatField.setAttribute('name', 'formatOutput');
+ outputFormatField.setAttribute('name', 'format');
outputFormatField.setAttribute('value', ogreFormat);
form.appendChild(outputFormatField);
@@ -153,10 +191,15 @@ export class ExportService {
}
private nothingToExport(olFeatures: OlFeature[], format: string): boolean {
- if (olFeatures.length === 0) { return true; }
+ if (olFeatures.length === 0) {
+ return true;
+ }
if (format === 'GPX') {
- const pointOrLine = olFeatures.find((olFeature) => {
- return ['Point', 'LineString'].indexOf(olFeature.getGeometry().getType()) >= 0;
+ const pointOrLine = olFeatures.find(olFeature => {
+ return (
+ ['Point', 'LineString'].indexOf(olFeature.getGeometry().getType()) >=
+ 0
+ );
});
return pointOrLine === undefined;
}
diff --git a/packages/geo/src/lib/import-export/shared/import.service.ts b/packages/geo/src/lib/import-export/shared/import.service.ts
index 0467d8c4b5..d094088f35 100644
--- a/packages/geo/src/lib/import-export/shared/import.service.ts
+++ b/packages/geo/src/lib/import-export/shared/import.service.ts
@@ -10,14 +10,18 @@ import * as olformat from 'ol/format';
import OlFeature from 'ol/Feature';
import { Feature } from '../../feature/shared/feature.interfaces';
-import { ImportInvalidFileError, ImportUnreadableFileError, ImportSizeError, ImportSRSError } from './import.errors';
+import {
+ ImportInvalidFileError,
+ ImportUnreadableFileError,
+ ImportSizeError,
+ ImportSRSError
+} from './import.errors';
import { computeLayerTitleFromFile, getFileExtension } from './import.utils';
@Injectable({
providedIn: 'root'
})
export class ImportService {
-
static allowedMimeTypes = [
'application/gml+xml',
'application/vnd.google-earth.kml+xml',
@@ -31,36 +35,47 @@ export class ImportService {
'application/x-zip'
];
- static allowedExtensions = [
- 'geojson',
- 'kml',
- 'gpx',
- 'json',
- 'gml'
- ];
+ static allowedExtensions = ['geojson', 'kml', 'gpx', 'json', 'gml'];
private ogreUrl: string;
- constructor(
- private http: HttpClient,
- private config: ConfigService
- ) {
+ constructor(private http: HttpClient, private config: ConfigService) {
this.ogreUrl = this.config.getConfig('importExport.url');
}
- import(file: File, projectionIn = 'EPSG:4326', projectionOut = 'EPSG:4326'): Observable {
+ import(
+ file: File,
+ projectionIn = 'EPSG:4326',
+ projectionOut = 'EPSG:4326'
+ ): Observable {
return this.importAsync(file, projectionIn, projectionOut);
}
- private getFileImporter(file: File): (file: File, observer: Observer, projectionIn: string, projectionOut: string) => void {
+ private getFileImporter(
+ file: File
+ ): (
+ file: File,
+ observer: Observer,
+ projectionIn: string,
+ projectionOut: string
+ ) => void {
const extension = getFileExtension(file);
const mimeType = file.type;
- const allowedMimeTypes = [...ImportService.allowedMimeTypes, ...ImportService.allowedZipMimeTypes];
+ const allowedMimeTypes = [
+ ...ImportService.allowedMimeTypes,
+ ...ImportService.allowedZipMimeTypes
+ ];
const allowedExtensions = ImportService.allowedExtensions;
- if (allowedMimeTypes.indexOf(mimeType) < 0 && allowedExtensions.indexOf(extension) < 0) {
+ if (
+ allowedMimeTypes.indexOf(mimeType) < 0 &&
+ allowedExtensions.indexOf(extension) < 0
+ ) {
return undefined;
- } else if (mimeType === 'application/json' || ['json', 'geojson', 'kml'].indexOf(extension) >= 0) {
+ } else if (
+ mimeType === 'application/json' ||
+ ['json', 'geojson', 'kml'].indexOf(extension) >= 0
+ ) {
return this.importFile;
} else if (this.ogreUrl !== undefined) {
return this.importFileWithOgre;
@@ -69,7 +84,11 @@ export class ImportService {
return undefined;
}
- private importAsync(file: File, projectionIn: string, projectionOut: string): Observable {
+ private importAsync(
+ file: File,
+ projectionIn: string,
+ projectionOut: string
+ ): Observable {
const doImport = (observer: Observer) => {
if (file.size >= 30000000) {
observer.error(new ImportSizeError());
@@ -87,7 +106,12 @@ export class ImportService {
return new Observable(doImport);
}
- private importFile(file: File, observer: Observer, projectionIn: string, projectionOut: string) {
+ private importFile(
+ file: File,
+ observer: Observer,
+ projectionIn: string,
+ projectionOut: string
+ ) {
const reader = new FileReader();
reader.onload = (event: any) => {
@@ -113,7 +137,12 @@ export class ImportService {
reader.readAsText(file, 'UTF-8');
}
- private importFileWithOgre(file: File, observer: Observer, projectionIn: string, projectionOut: string) {
+ private importFileWithOgre(
+ file: File,
+ observer: Observer,
+ projectionIn: string,
+ projectionOut: string
+ ) {
const url = `${this.ogreUrl}/convert`;
const formData = new FormData();
formData.append('upload', file);
@@ -122,39 +151,48 @@ export class ImportService {
formData.append('formatOutput', 'GEOJSON');
formData.append('skipFailures', '');
- this.http
- .post(url, formData, {headers: new HttpHeaders()})
- .subscribe(
- (response: {errors?: string[]} | object | null) => {
- if (response === null) {
- observer.error(new ImportUnreadableFileError());
- return;
- }
-
- const errors = (response as any).errors || [];
- if (errors.length > 0) {
- observer.error(new ImportUnreadableFileError());
- } else {
- const features = this.parseFeaturesFromGeoJSON(file, response, projectionOut);
- observer.next(features);
- observer.complete();
- }
- },
- (error: any) => {
- error.error.caught = true;
- const errMsg = error.error.msg;
- if (errMsg === 'No valid files found') {
- observer.error(new ImportInvalidFileError());
- } else if (errMsg.startWith("ERROR 1: Failed to process SRS definition")) {
- observer.error(new ImportSRSError());
- } else {
- observer.error(new ImportUnreadableFileError());
- }
+ this.http.post(url, formData, { headers: new HttpHeaders() }).subscribe(
+ (response: { errors?: string[] } | object | null) => {
+ if (response === null) {
+ observer.error(new ImportUnreadableFileError());
+ return;
}
- );
+
+ const errors = (response as any).errors || [];
+ if (errors.length > 0) {
+ observer.error(new ImportUnreadableFileError());
+ } else {
+ const features = this.parseFeaturesFromGeoJSON(
+ file,
+ response,
+ projectionOut
+ );
+ observer.next(features);
+ observer.complete();
+ }
+ },
+ (error: any) => {
+ error.error.caught = true;
+ const errMsg = error.error.msg || '';
+ if (errMsg === 'No valid files found') {
+ observer.error(new ImportInvalidFileError());
+ } else if (
+ errMsg.startWith('ERROR 1: Failed to process SRS definition')
+ ) {
+ observer.error(new ImportSRSError());
+ } else {
+ observer.error(new ImportUnreadableFileError());
+ }
+ }
+ );
}
- private parseFeaturesFromFile(file: File, data: string, projectionIn: string, projectionOut: string): Feature[] {
+ private parseFeaturesFromFile(
+ file: File,
+ data: string,
+ projectionIn: string,
+ projectionOut: string
+ ): Feature[] {
const extension = getFileExtension(file);
const mimeType = file.type;
@@ -172,7 +210,7 @@ export class ImportService {
case 'kml':
format = new olformat.KML();
break;
- case 'gpx':
+ case 'gpx':
format = new olformat.GPX();
break;
case 'gml':
@@ -201,7 +239,11 @@ export class ImportService {
return features;
}
- private parseFeaturesFromGeoJSON(file: File, data: object, projectionOut: string): Feature[] {
+ private parseFeaturesFromGeoJSON(
+ file: File,
+ data: object,
+ projectionOut: string
+ ): Feature[] {
const olFormat = new olformat.GeoJSON();
const olFeatures = olFormat.readFeatures(data);
const features = olFeatures.map((olFeature: OlFeature) => {