add styling improvements; add geojson export for as zip file;
This commit is contained in:
Generated
+1412
-1037
File diff suppressed because it is too large
Load Diff
+20
-17
@@ -11,42 +11,45 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^7.2.15",
|
"@angular/animations": "^7.2.16",
|
||||||
"@angular/cdk": "^7.3.7",
|
"@angular/cdk": "^7.3.7",
|
||||||
"@angular/common": "^7.2.15",
|
"@angular/common": "^7.2.16",
|
||||||
"@angular/compiler": "^7.2.15",
|
"@angular/compiler": "^7.2.16",
|
||||||
"@angular/core": "^7.2.15",
|
"@angular/core": "^7.2.16",
|
||||||
"@angular/forms": "^7.2.15",
|
"@angular/forms": "^7.2.16",
|
||||||
"@angular/material": "^7.3.7",
|
"@angular/material": "^7.3.7",
|
||||||
"@angular/platform-browser": "^7.2.15",
|
"@angular/platform-browser": "^7.2.16",
|
||||||
"@angular/platform-browser-dynamic": "^7.2.15",
|
"@angular/platform-browser-dynamic": "^7.2.16",
|
||||||
"@angular/router": "^7.2.15",
|
"@angular/router": "^7.2.16",
|
||||||
|
"@types/jszip": "^3.1.7",
|
||||||
"@types/openlayers": "^4.6.17",
|
"@types/openlayers": "^4.6.17",
|
||||||
"core-js": "^2.5.4",
|
"core-js": "^2.6.11",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
|
"jszip": "^3.2.2",
|
||||||
"ngx-color-picker": "^7.5.0",
|
"ngx-color-picker": "^7.5.0",
|
||||||
"ol": "^5.3.2",
|
"ol": "^5.3.3",
|
||||||
"rxjs": "~6.3.3",
|
"rxjs": "~6.3.3",
|
||||||
"tslib": "^1.9.0",
|
"stream": "0.0.2",
|
||||||
|
"tslib": "^1.10.0",
|
||||||
"zone.js": "~0.8.26"
|
"zone.js": "~0.8.26"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^0.13.9",
|
"@angular-devkit/build-angular": "^0.13.0",
|
||||||
"@angular/cli": "^7.3.9",
|
"@angular/cli": "^7.3.9",
|
||||||
"@angular/compiler-cli": "^7.2.15",
|
"@angular/compiler-cli": "^7.2.16",
|
||||||
"@angular/language-service": "^7.2.15",
|
"@angular/language-service": "^7.2.16",
|
||||||
"@types/jasmine": "~2.8.8",
|
"@types/jasmine": "~2.8.8",
|
||||||
"@types/jasminewd2": "~2.0.3",
|
"@types/jasminewd2": "^2.0.8",
|
||||||
"@types/node": "~8.9.4",
|
"@types/node": "~8.9.4",
|
||||||
"codelyzer": "~4.5.0",
|
"codelyzer": "~4.5.0",
|
||||||
"jasmine-core": "~2.99.1",
|
"jasmine-core": "~2.99.1",
|
||||||
"jasmine-spec-reporter": "~4.2.1",
|
"jasmine-spec-reporter": "~4.2.1",
|
||||||
"karma": "~4.0.0",
|
"karma": "~4.0.0",
|
||||||
"karma-chrome-launcher": "~2.2.0",
|
"karma-chrome-launcher": "~2.2.0",
|
||||||
"karma-coverage-istanbul-reporter": "~2.0.1",
|
"karma-coverage-istanbul-reporter": "^2.0.6",
|
||||||
"karma-jasmine": "~1.1.2",
|
"karma-jasmine": "~1.1.2",
|
||||||
"karma-jasmine-html-reporter": "^0.2.2",
|
"karma-jasmine-html-reporter": "^0.2.2",
|
||||||
"protractor": "~5.4.0",
|
"protractor": "^5.4.3",
|
||||||
"ts-node": "~7.0.0",
|
"ts-node": "~7.0.0",
|
||||||
"tslint": "~5.11.0",
|
"tslint": "~5.11.0",
|
||||||
"typescript": "~3.2.2"
|
"typescript": "~3.2.2"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {Component, Inject} from '@angular/core';
|
import {Component, Inject} from '@angular/core';
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material";
|
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material';
|
||||||
import {ValidationErrors} from "@angular/forms";
|
import {ValidationErrors} from '@angular/forms';
|
||||||
import {RawLayer} from "../models/RawLayer";
|
import {RawLayer} from '../models/RawLayer';
|
||||||
import {Utils} from "../misc/Utils";
|
import {Utils} from '../misc/Utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Add description
|
* TODO: Add description
|
||||||
@@ -24,10 +24,11 @@ export class AddLayerComponent {
|
|||||||
layerName: '',
|
layerName: '',
|
||||||
layerData: null,
|
layerData: null,
|
||||||
color: '#4fadc2'
|
color: '#4fadc2'
|
||||||
}
|
};
|
||||||
|
|
||||||
public uploadError: ValidationErrors = null;
|
public uploadError: ValidationErrors = null;
|
||||||
public uploadIsDirty: boolean = false;
|
public uploadIsDirty: boolean = false;
|
||||||
public editMode : boolean = false;
|
public editMode: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<AddLayerComponent>,
|
public dialogRef: MatDialogRef<AddLayerComponent>,
|
||||||
@@ -37,7 +38,7 @@ export class AddLayerComponent {
|
|||||||
this.formData.layerName = data.name;
|
this.formData.layerName = data.name;
|
||||||
this.formData.layerData = data.data;
|
this.formData.layerData = data.data;
|
||||||
const colorRgb = data.getDefaultColor();
|
const colorRgb = data.getDefaultColor();
|
||||||
this.formData.color = Utils.rgbToHex(colorRgb[0],colorRgb[1],colorRgb[2]);
|
this.formData.color = Utils.rgbToHex(colorRgb[0], colorRgb[1], colorRgb[2]);
|
||||||
this.editMode = true;
|
this.editMode = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,7 +64,7 @@ export class AddLayerComponent {
|
|||||||
} else {
|
} else {
|
||||||
this.uploadError = {
|
this.uploadError = {
|
||||||
invalidFileType: true
|
invalidFileType: true
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileReader = new FileReader();
|
const fileReader = new FileReader();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div *ngIf="curFeature">
|
<div *ngIf="curFeature" class="property-list">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h4>Custom Properties</h4>
|
<h4>Custom Properties</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
.property-name {
|
.property-name {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.property-value {
|
.property-value {
|
||||||
margin: 0 0 0 6px;
|
margin: 0 0 0 6px;
|
||||||
}
|
}
|
||||||
@@ -26,3 +27,4 @@
|
|||||||
.button-container {
|
.button-container {
|
||||||
margin-top: 3rem;
|
margin-top: 3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- layer property area-->
|
<!-- layer property area-->
|
||||||
<div>
|
<div class="property-list-area">
|
||||||
<mat-card>
|
<mat-card>
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<mat-card-title>Layer Properties</mat-card-title>
|
<mat-card-title>Layer Properties</mat-card-title>
|
||||||
@@ -38,7 +38,8 @@
|
|||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<div cdkDropList class="layer-list" (cdkDropListDropped)="drop($event)">
|
<div cdkDropList class="layer-list" (cdkDropListDropped)="drop($event)">
|
||||||
<div class="list-entry" *ngFor="let layer of customLayerCollection.getArray();let i = index" cdkDrag>
|
<div class="list-entry" *ngFor="let layer of customLayerCollection.getArray();let i = index" cdkDrag>
|
||||||
<h4>{{layer.get('name') }}</h4>
|
<h4 class="title">{{layer.get('name') }}</h4>
|
||||||
|
<div class="layer-controls">
|
||||||
<i class="material-icons" (click)="centerLayerOnMap(layer)">
|
<i class="material-icons" (click)="centerLayerOnMap(layer)">
|
||||||
center_focus_strong
|
center_focus_strong
|
||||||
</i>
|
</i>
|
||||||
@@ -53,9 +54,11 @@
|
|||||||
</i>
|
</i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
<mat-card-actions>
|
<mat-card-actions>
|
||||||
<button mat-button (click)="saveLayers()">Speichern</button>
|
<button mat-button (click)="exportLayerForApp()">Export für App</button>
|
||||||
|
<button mat-button (click)="exportLayerAsGeoJson()">Export als GeoJSON</button>
|
||||||
</mat-card-actions>
|
</mat-card-actions>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.layer-control-area {
|
.layer-control-area {
|
||||||
|
max-width:25vw;
|
||||||
|
|
||||||
.layer-list {
|
.layer-list {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
border: solid 1px #ccc;
|
border: solid 1px #ccc;
|
||||||
@@ -49,18 +51,31 @@
|
|||||||
|
|
||||||
|
|
||||||
.list-entry {
|
.list-entry {
|
||||||
padding: 20px 10px;
|
padding: 10px;
|
||||||
border-bottom: solid 1px #ccc;
|
border-bottom: solid 1px #ccc;
|
||||||
color: rgba(0, 0, 0, 0.87);
|
color: rgba(0, 0, 0, 0.87);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: flex-start;
|
||||||
justify-content: space-between;
|
justify-content: center;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
cursor: move;
|
cursor: move;
|
||||||
background: white;
|
background: white;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 10px 0px 10px 0;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layer-controls {
|
||||||
|
|
||||||
|
> * {
|
||||||
|
margin-right: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
@@ -71,6 +86,10 @@
|
|||||||
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.property-list-area {
|
||||||
|
max-width: 25vw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cdk-drag-preview {
|
.cdk-drag-preview {
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ import Stroke from 'ol/style/Stroke';
|
|||||||
import Fill from 'ol/style/Fill';
|
import Fill from 'ol/style/Fill';
|
||||||
import {FeatureManagerComponent} from '../feature-management/feature-manager/feature-manager.component';
|
import {FeatureManagerComponent} from '../feature-management/feature-manager/feature-manager.component';
|
||||||
import {saveAs} from 'file-saver';
|
import {saveAs} from 'file-saver';
|
||||||
|
import {Config} from '../misc/Config';
|
||||||
|
import * as JSZip from 'jszip';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: add description
|
* TODO: add description
|
||||||
@@ -30,10 +32,6 @@ import {saveAs} from 'file-saver';
|
|||||||
* - The design und ux of the whole application has to be improved
|
* - The design und ux of the whole application has to be improved
|
||||||
* - Add bunch edit to ease coloring of the features
|
* - Add bunch edit to ease coloring of the features
|
||||||
* - add possibility to filter for features to color them easier (or add some kind of custom query language)
|
* - add possibility to filter for features to color them easier (or add some kind of custom query language)
|
||||||
* - add software versions number to geo json
|
|
||||||
* - how about the import of an previous exported file?
|
|
||||||
* -> Would work, but the export has to be improved: Single Layer export as geojson or multi geojson export,
|
|
||||||
* currently just the rawLawers are exported.
|
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-map',
|
selector: 'app-map',
|
||||||
@@ -309,9 +307,9 @@ export class MapComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO add description (currently it is not completely clear what this function is going to do)
|
* Export all Layers in one file for app usage
|
||||||
*/
|
*/
|
||||||
public saveLayers(): void {
|
public exportLayerForApp(): void {
|
||||||
const rawLayers = [];
|
const rawLayers = [];
|
||||||
this.customLayerCollection.forEach(layer => rawLayers.push(RawLayer.fromVectorLayer(layer)));
|
this.customLayerCollection.forEach(layer => rawLayers.push(RawLayer.fromVectorLayer(layer)));
|
||||||
|
|
||||||
@@ -323,9 +321,32 @@ export class MapComponent implements OnInit {
|
|||||||
data: JSON.parse(rawLayer.data)
|
data: JSON.parse(rawLayer.data)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const blob = new Blob([JSON.stringify(processedRawLayers)], {type: 'application/geo+json;charset=utf-8'});
|
const blob = new Blob([JSON.stringify(processedRawLayers)], {type: 'application/json;charset=utf-8'});
|
||||||
// TODO use dynamic name
|
saveAs(blob, `app_export_${new Date().toISOString()}.json`);
|
||||||
saveAs(blob, 'lm_layer.geojson');
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exports all layer as single geoJson files in a zip for later processing
|
||||||
|
*/
|
||||||
|
public exportLayerAsGeoJson(): void {
|
||||||
|
const zipArchive = new JSZip();
|
||||||
|
const rawLayers = [];
|
||||||
|
this.customLayerCollection.forEach(layer => rawLayers.push(RawLayer.fromVectorLayer(layer)));
|
||||||
|
|
||||||
|
// create a zip archive
|
||||||
|
rawLayers.forEach(rawLayer => {
|
||||||
|
// process raw layer with JSON.stringify(JSON.parse(...)) to avoid escaping in data property e. g. {\"type\": \"aaa\"...
|
||||||
|
// the geo json string in data property comes like this from openlayer function GeoJSON().writeFeatures
|
||||||
|
const fileContent = new Blob([JSON.stringify(JSON.parse(rawLayer.data))], {type: 'application/geo+json;charset=utf-8'});
|
||||||
|
const fileName = `${rawLayer.name}.geojson`;
|
||||||
|
zipArchive.file(fileName, fileContent);
|
||||||
|
});
|
||||||
|
|
||||||
|
// save zip archive
|
||||||
|
zipArchive.generateAsync({type: 'blob'})
|
||||||
|
.then((blob) => {
|
||||||
|
saveAs(blob, `lm_export_${new Date().toISOString()}.zip`);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ export class RawLayer {
|
|||||||
* Data of Layer (normally in geojson format)
|
* Data of Layer (normally in geojson format)
|
||||||
*/
|
*/
|
||||||
public data: string
|
public data: string
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a RawLayer instance from a VectorLayer and saves the style properties in geojson. Consider that the
|
* Creates a RawLayer instance from a VectorLayer and saves the style properties in geojson. Consider that the
|
||||||
|
|||||||
Reference in New Issue
Block a user