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) {
this.formData.layerName = data.name;
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;
}
}
@@ -75,7 +76,8 @@ export class AddLayerComponent {
}
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);
}
}
+9 -1
View File
@@ -8,7 +8,14 @@ import { LeafletMapComponent } from './leaflet-map/leaflet-map.component';
import {HttpClient, HttpClientModule} from "@angular/common/http";
import {FormsModule} from "@angular/forms";
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 { AddLayerComponent } from './add-layer-component/add-layer.component';
@@ -31,6 +38,7 @@ import { AddLayerComponent } from './add-layer-component/add-layer.component';
DragDropModule,
MatInputModule,
MatDialogModule,
MatTableModule,
],
entryComponents: [
AddLayerComponent
+8 -2
View File
@@ -22,8 +22,14 @@
<mat-card-title>Layer Properties</mat-card-title>
</mat-card-header>
<mat-card-content>
<div>
{{ currentFeatureInfo | json}}
<div *ngFor="let item of currentFeatureInfo | keyvalue" class="entry">
{{item.key}}
<br>
{{item.value}}
<div class="controls">
<i class="material-icons">edit</i>
<i class="material-icons">delete</i>
</div>
</div>
</mat-card-content>
</mat-card>
+19 -2
View File
@@ -38,8 +38,6 @@
}
.layer-control-area {
.layer-list {
max-width: 100%;
border: solid 1px #ccc;
@@ -73,6 +71,25 @@
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 {
+81 -46
View File
@@ -13,6 +13,10 @@ import LayerGroup from 'ol/layer/Group';
import {Collection} from "openlayers";
import {EPSG} from "../enums/EPSG";
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
@@ -50,6 +54,35 @@ export class MapComponent implements OnInit {
*/
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) {
}
@@ -117,62 +150,64 @@ export class MapComponent implements OnInit {
return;
}
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.
* @param pixel
* Prepared feature properties and shows them
* @param features
*/
private displayFeatureInfo(pixel) {
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 => {
private displayFeatureInfo(feature: Feature) {
const properties = feature.getProperties();
delete properties.geometry;
this.currentFeatureInfo = properties;
})
} else {
this.currentFeatureInfo = null;
}
};
// private colorPolygons(feature: Feature, resolution: any) {
// const styles = {
// black: new Style({
// stroke: new Stroke({
// color: '#86665a',
// width: 1
// }),
// fill: new Fill({
// color: 'rgba(121,85,72, 0.4)',
// })
// }),
// green: new Style({
// stroke: new Stroke({
// color: '#b8c633',
// width: 1
// }),
// fill: new Fill({
// color: 'rgba(205,220,57,0.4)',
// })
// })
// }
// // console.log(feature.getProperties()['Grünland'],feature.getProperties());
// if (feature.getProperties()['Nutzung'] === 'Grünland') {
// return styles.green;
// } else {
// return styles.black;
// }
// }
/**
* Highlights a Features
* @param feature
*/
private highlightFeature(feature: Feature) {
// init case
if (!this.styleCache['defaultHighlight']) {
this.styleCache['defaultHighlight'] = new Style({
stroke: new Stroke({
color: 'rgb(245, 64, 41)',
width: 2
}),
fill: new Fill({
color: 'rgba(245, 64, 41, 0.1)',
})
})
}
// reapply saved feature and style
if (this.featureCache['lastHighlighted']) {
this.featureCache['lastHighlighted'].setStyle(this.styleCache['lastHighlightedStyle']);
}
// save current feature and style
this.featureCache['lastHighlighted'] = feature;
this.styleCache['lastHighlightedStyle'] = feature.getStyle();
// set new feature style
feature.setStyle(this.styleCache['defaultHighlight']);
}
/**
* 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 Fill from 'ol/style/Fill';
import {Config} from "../misc/Config";
import {Feature} from 'ol/Feature';
/**
* Represents a raw (not processed) map layer
*/
@@ -19,14 +19,8 @@ export class RawLayer {
/**
* Data of Layer (normally in geojson format)
*/
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[]
public data: string
) {
this.saveColorToGeoJSON();
}
/**
@@ -35,16 +29,10 @@ export class RawLayer {
* @param layer
*/
public static fromVectorLayer(layer: VectorLayer): RawLayer {
const writer = new GeoJSON();
const source = layer.getSource();
// get default style values
const features = source.getFeatures();
const featureProperties = features[0].getProperties();
const rawLayerColor = featureProperties[Config.GEO_JSON_PREFIX]['default-style-stroke'];
const geoJSONString = writer.writeFeatures(features,{featureProjection: EPSG.openLayersDefault});
return new RawLayer(layer.get('name'), geoJSONString, rawLayerColor);
const geoJSONString = RawLayer.featuresToGeoJSON(features);
return new RawLayer(layer.get('name'), geoJSONString);
}
/**
@@ -53,10 +41,7 @@ export class RawLayer {
*/
public static toVectorLayer(rawLayer: RawLayer): VectorLayer {
const vectorSource = new VectorSource();
const geoJSON = new GeoJSON();
// load geoJSON features from rawLayer
const features = geoJSON.readFeatures(rawLayer.data, {featureProjection: EPSG.openLayersDefault});
const features = RawLayer.geoJSONToFeatures(rawLayer.data);
// apply style to all features
features.forEach(feature => {
// 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() {
const geoJSON = new GeoJSON();
// load geoJSON features from rawLayer
const features = geoJSON.readFeatures(this.data, {featureProjection: EPSG.openLayersDefault});
public saveDefaultColor(color: number[]) {
const features = RawLayer.geoJSONToFeatures(this.data);
features.forEach(feature => {
// save default color in feature properties
const stylesToSave = {};
stylesToSave[Config.GEO_JSON_PREFIX] = {};
stylesToSave[Config.GEO_JSON_PREFIX]['default-style-stroke'] = this.color;
stylesToSave[Config.GEO_JSON_PREFIX]['default-style-fill'] = [...this.color.slice(0, 3), 0.1];
stylesToSave[Config.GEO_JSON_PREFIX]['default-style-stroke'] = color;
stylesToSave[Config.GEO_JSON_PREFIX]['default-style-fill'] = [...color.slice(0, 3), 0.1];
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});
}
}