improve color saving; improve property handling

This commit is contained in:
Fabian Jeglinski
2019-05-03 17:02:53 +02:00
parent 258cc9abb6
commit d0892f4c57
6 changed files with 159 additions and 84 deletions
@@ -36,7 +36,8 @@ export class AddLayerComponent {
if (data) { if (data) {
this.formData.layerName = data.name; this.formData.layerName = data.name;
this.formData.layerData = data.data; this.formData.layerData = data.data;
this.formData.color = Utils.rgbToHex(data.color[0],data.color[1],data.color[2]); const colorRgb = data.getDefaultColor();
this.formData.color = Utils.rgbToHex(colorRgb[0],colorRgb[1],colorRgb[2]);
this.editMode = true; this.editMode = true;
} }
} }
@@ -75,7 +76,8 @@ export class AddLayerComponent {
} }
onSubmit() { onSubmit() {
const rawLayer = new RawLayer(this.formData.layerName, this.formData.layerData, Utils.hexToRgba(this.formData.color)); const rawLayer = new RawLayer(this.formData.layerName, this.formData.layerData);
rawLayer.saveDefaultColor(Utils.hexToRgba(this.formData.color));
this.close(rawLayer); this.close(rawLayer);
} }
} }
+9 -1
View File
@@ -8,7 +8,14 @@ import { LeafletMapComponent } from './leaflet-map/leaflet-map.component';
import {HttpClient, HttpClientModule} from "@angular/common/http"; import {HttpClient, HttpClientModule} from "@angular/common/http";
import {FormsModule} from "@angular/forms"; import {FormsModule} from "@angular/forms";
import {BrowserAnimationsModule} from "@angular/platform-browser/animations"; import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
import {MatCardModule, MatDialogModule, MatGridListModule, MatInputModule, MatToolbarModule} from "@angular/material"; import {
MatCardModule,
MatDialogModule,
MatGridListModule,
MatInputModule,
MatTableModule,
MatToolbarModule
} from "@angular/material";
import {DragDropModule} from "@angular/cdk/drag-drop"; import {DragDropModule} from "@angular/cdk/drag-drop";
import { AddLayerComponent } from './add-layer-component/add-layer.component'; import { AddLayerComponent } from './add-layer-component/add-layer.component';
@@ -31,6 +38,7 @@ import { AddLayerComponent } from './add-layer-component/add-layer.component';
DragDropModule, DragDropModule,
MatInputModule, MatInputModule,
MatDialogModule, MatDialogModule,
MatTableModule,
], ],
entryComponents: [ entryComponents: [
AddLayerComponent AddLayerComponent
+8 -2
View File
@@ -22,8 +22,14 @@
<mat-card-title>Layer Properties</mat-card-title> <mat-card-title>Layer Properties</mat-card-title>
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<div> <div *ngFor="let item of currentFeatureInfo | keyvalue" class="entry">
{{ currentFeatureInfo | json}} {{item.key}}
<br>
{{item.value}}
<div class="controls">
<i class="material-icons">edit</i>
<i class="material-icons">delete</i>
</div>
</div> </div>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
+19 -2
View File
@@ -38,8 +38,6 @@
} }
.layer-control-area { .layer-control-area {
.layer-list { .layer-list {
max-width: 100%; max-width: 100%;
border: solid 1px #ccc; border: solid 1px #ccc;
@@ -73,6 +71,25 @@
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
} }
} }
.layer-property-area {
.mat-card-content {
.entry {
display: flex;
height: 3rem;
align-items: center;
margin: 0 0 .125rem 0;
border: 1px black solid;
padding: .5rem;
.controls {
margin-left: auto;
}
}
}
}
} }
.cdk-drag-preview { .cdk-drag-preview {
+81 -46
View File
@@ -13,6 +13,10 @@ import LayerGroup from 'ol/layer/Group';
import {Collection} from "openlayers"; import {Collection} from "openlayers";
import {EPSG} from "../enums/EPSG"; import {EPSG} from "../enums/EPSG";
import {inAndOut} from 'ol/easing'; import {inAndOut} from 'ol/easing';
import {Feature} from 'ol/Feature';
import Style from 'ol/style/Style';
import Stroke from 'ol/style/Stroke';
import Fill from 'ol/style/Fill';
/** /**
* TODO: add description * TODO: add description
@@ -50,6 +54,35 @@ export class MapComponent implements OnInit {
*/ */
public currentFeatureInfo: any; public currentFeatureInfo: any;
public propertyMockData = JSON.parse('{\n' +
'\t"FL": "345",\n' +
'\t"FLST_LABEL": "93\\/0",\n' +
'\t"FLAECHE_HA": 0.19303757998400001,\n' +
'\t"FBID": "DEHBEE0433450039",\n' +
'\t"FELDBL_NR": "043345-0039",\n' +
'\t"BESCHRIFT": "?",\n' +
'\t"NUTZER": "?",\n' +
'\t"TEILRAUM": "Blockland - Waller Feldmark",\n' +
'\t"BAUM17Code": "-",\n' +
'\t"B_AUM_2017": "-",\n' +
'\t"Parz_Code": "-",\n' +
'\t"Nutzung": "Grünland",\n' +
'\t"Nat_schutz": "-",\n' +
'\t"Gebiet": "Blockland",\n' +
'\t"Thema": "Informationen Agrarflächen",\n' +
'\t"Flurstck": "Flst. 345: 93\\/0"\n' +
'}');
/**
* A simple cache to save styles
*/
private styleCache: { [key: string]: Style } = {};
/**
* A simple feature cache
*/
private featureCache: { [key: string]: Feature } = {};
constructor(public dialog: MatDialog) { constructor(public dialog: MatDialog) {
} }
@@ -117,62 +150,64 @@ export class MapComponent implements OnInit {
return; return;
} }
const pixel = this.map.getEventPixel(evt.originalEvent); const pixel = this.map.getEventPixel(evt.originalEvent);
this.displayFeatureInfo(pixel); const features = this.map.getFeaturesAtPixel(pixel);
if (features && features.length > 0) {
this.displayFeatureInfo(features[0]);
this.highlightFeature(features[0]);
} else {
// reapply original style to last highlighted feature
if (this.featureCache['lastHighlighted']) {
this.featureCache['lastHighlighted'].setStyle(this.styleCache['lastHighlightedStyle']);
}
// reset cache for feature and style
this.featureCache['lastHighlighted'] = null;
this.styleCache['lastHighlightedStyle'] = null;
this.currentFeatureInfo = null;
}
}); });
} }
/** /**
* Gets all feature infos for each feature at the given pixel. * Prepared feature properties and shows them
* @param pixel * @param features
*/ */
private displayFeatureInfo(pixel) { private displayFeatureInfo(feature: Feature) {
const features = [];
this.map.forEachFeatureAtPixel(pixel, (feature) => {
features.push(feature)
}
);
if (features.length == 0) {
this.currentFeatureInfo = 'Too many features. Please zoom in to see feature infos';
} else if (features.length == 1) {
features.forEach(feature => {
const properties = feature.getProperties(); const properties = feature.getProperties();
delete properties.geometry; delete properties.geometry;
this.currentFeatureInfo = properties; this.currentFeatureInfo = properties;
})
} else {
this.currentFeatureInfo = null;
}
}; };
// private colorPolygons(feature: Feature, resolution: any) { /**
// const styles = { * Highlights a Features
// black: new Style({ * @param feature
// stroke: new Stroke({ */
// color: '#86665a', private highlightFeature(feature: Feature) {
// width: 1 // init case
// }), if (!this.styleCache['defaultHighlight']) {
// fill: new Fill({ this.styleCache['defaultHighlight'] = new Style({
// color: 'rgba(121,85,72, 0.4)', stroke: new Stroke({
// }) color: 'rgb(245, 64, 41)',
// }), width: 2
// green: new Style({ }),
// stroke: new Stroke({ fill: new Fill({
// color: '#b8c633', color: 'rgba(245, 64, 41, 0.1)',
// width: 1 })
// }), })
// fill: new Fill({ }
// color: 'rgba(205,220,57,0.4)',
// }) // reapply saved feature and style
// }) if (this.featureCache['lastHighlighted']) {
// } this.featureCache['lastHighlighted'].setStyle(this.styleCache['lastHighlightedStyle']);
// // console.log(feature.getProperties()['Grünland'],feature.getProperties()); }
// if (feature.getProperties()['Nutzung'] === 'Grünland') { // save current feature and style
// return styles.green; this.featureCache['lastHighlighted'] = feature;
// } else { this.styleCache['lastHighlightedStyle'] = feature.getStyle();
// return styles.black;
// } // set new feature style
// } feature.setStyle(this.styleCache['defaultHighlight']);
}
/** /**
* Opens a dialog to create a new custom layer * Opens a dialog to create a new custom layer
+35 -28
View File
@@ -6,7 +6,7 @@ import Style from 'ol/style/Style';
import Stroke from 'ol/style/Stroke'; import Stroke from 'ol/style/Stroke';
import Fill from 'ol/style/Fill'; import Fill from 'ol/style/Fill';
import {Config} from "../misc/Config"; import {Config} from "../misc/Config";
import {Feature} from 'ol/Feature';
/** /**
* Represents a raw (not processed) map layer * Represents a raw (not processed) map layer
*/ */
@@ -19,14 +19,8 @@ export class RawLayer {
/** /**
* Data of Layer (normally in geojson format) * Data of Layer (normally in geojson format)
*/ */
public data: string, public data: string
/**
* Layer stroke color as number array with opacity like -> [255, 255, 255, 0.5]
* The fill color is an opaque decreased derivation of this value.
*/
public color: number[]
) { ) {
this.saveColorToGeoJSON();
} }
/** /**
@@ -35,16 +29,10 @@ export class RawLayer {
* @param layer * @param layer
*/ */
public static fromVectorLayer(layer: VectorLayer): RawLayer { public static fromVectorLayer(layer: VectorLayer): RawLayer {
const writer = new GeoJSON();
const source = layer.getSource(); const source = layer.getSource();
// get default style values
const features = source.getFeatures(); const features = source.getFeatures();
const featureProperties = features[0].getProperties(); const geoJSONString = RawLayer.featuresToGeoJSON(features);
const rawLayerColor = featureProperties[Config.GEO_JSON_PREFIX]['default-style-stroke']; return new RawLayer(layer.get('name'), geoJSONString);
const geoJSONString = writer.writeFeatures(features,{featureProjection: EPSG.openLayersDefault});
return new RawLayer(layer.get('name'), geoJSONString, rawLayerColor);
} }
/** /**
@@ -53,10 +41,7 @@ export class RawLayer {
*/ */
public static toVectorLayer(rawLayer: RawLayer): VectorLayer { public static toVectorLayer(rawLayer: RawLayer): VectorLayer {
const vectorSource = new VectorSource(); const vectorSource = new VectorSource();
const geoJSON = new GeoJSON(); const features = RawLayer.geoJSONToFeatures(rawLayer.data);
// load geoJSON features from rawLayer
const features = geoJSON.readFeatures(rawLayer.data, {featureProjection: EPSG.openLayersDefault});
// apply style to all features // apply style to all features
features.forEach(feature => { features.forEach(feature => {
// TODO // TODO
@@ -87,20 +72,42 @@ export class RawLayer {
} }
/** /**
* Adds the RawLayer color property to all feature properties from data attribute * Saves a default color property to geoJSON
*/ */
private saveColorToGeoJSON() { public saveDefaultColor(color: number[]) {
const geoJSON = new GeoJSON(); const features = RawLayer.geoJSONToFeatures(this.data);
// load geoJSON features from rawLayer
const features = geoJSON.readFeatures(this.data, {featureProjection: EPSG.openLayersDefault});
features.forEach(feature => { features.forEach(feature => {
// save default color in feature properties // save default color in feature properties
const stylesToSave = {}; const stylesToSave = {};
stylesToSave[Config.GEO_JSON_PREFIX] = {}; stylesToSave[Config.GEO_JSON_PREFIX] = {};
stylesToSave[Config.GEO_JSON_PREFIX]['default-style-stroke'] = this.color; stylesToSave[Config.GEO_JSON_PREFIX]['default-style-stroke'] = color;
stylesToSave[Config.GEO_JSON_PREFIX]['default-style-fill'] = [...this.color.slice(0, 3), 0.1]; stylesToSave[Config.GEO_JSON_PREFIX]['default-style-fill'] = [...color.slice(0, 3), 0.1];
feature.setProperties(stylesToSave); feature.setProperties(stylesToSave);
}) })
this.data = geoJSON.writeFeatures(features, {featureProjection: EPSG.openLayersDefault}); this.data = RawLayer.featuresToGeoJSON(features);
}
/**
* Reads the default color property from geoJSON
*/
public getDefaultColor(): number[]{
const features = RawLayer.geoJSONToFeatures(this.data);
const featureProperties = features[0].getProperties();
return featureProperties[Config.GEO_JSON_PREFIX]['default-style-stroke'];
}
/**
* Creates the features from geoJSON
*/
private static geoJSONToFeatures(geoJSON: string): Feature[] {
return new GeoJSON().readFeatures(geoJSON, {featureProjection: EPSG.openLayersDefault});
}
/**
* Creates geoJSON string from features
* @param features
*/
private static featuresToGeoJSON(features: Feature[]): string {
return new GeoJSON().writeFeatures(features, {featureProjection: EPSG.openLayersDefault});
} }
} }