diff --git a/demo/src/app/geo/geometry/geometry.component.ts b/demo/src/app/geo/geometry/geometry.component.ts index de27aa5da8..0e68ebe2d2 100644 --- a/demo/src/app/geo/geometry/geometry.component.ts +++ b/demo/src/app/geo/geometry/geometry.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { Validators } from '@angular/forms'; import { BehaviorSubject, Subscription } from 'rxjs'; +import * as olstyle from 'ol/style'; import { LanguageService } from '@igo2/core'; import { Form, FormService } from '@igo2/common'; @@ -70,7 +71,25 @@ export class AppGeometryComponent implements OnInit, OnDestroy { geometryType: 'Polygon', drawGuideField: true, drawGuide: 50, - drawGuidePlaceholder: 'Draw Guide' + drawGuidePlaceholder: 'Draw Guide', + drawStyle: new olstyle.Style({ + stroke: new olstyle.Stroke({ + color: [255, 0, 0, 1], + width: 2 + }), + fill: new olstyle.Fill({ + color: [255, 0, 0, 0.2] + }), + image: new olstyle.Circle({ + radius: 8, + stroke: new olstyle.Stroke({ + color: [255, 0, 0, 1] + }), + fill: new olstyle.Fill({ + color: [255, 0, 0, 0.2] + }) + }) + }) } }, { diff --git a/packages/geo/src/lib/geometry/geometry-form-field/geometry-form-field-input.component.ts b/packages/geo/src/lib/geometry/geometry-form-field/geometry-form-field-input.component.ts index aece77d017..ee9734e52e 100644 --- a/packages/geo/src/lib/geometry/geometry-form-field/geometry-form-field-input.component.ts +++ b/packages/geo/src/lib/geometry/geometry-form-field/geometry-form-field-input.component.ts @@ -12,7 +12,7 @@ import { NgControl, ControlValueAccessor } from '@angular/forms'; import { Subscription } from 'rxjs'; -import { Style as OlStyle } from 'ol/style'; +import * as OlStyle from 'ol/style'; import OlGeoJSON from 'ol/format/GeoJSON'; import OlGeometry from 'ol/geom/Geometry'; import OlGeometryType from 'ol/geom/GeometryType'; @@ -24,7 +24,6 @@ import OlOverlay from 'ol/Overlay'; import { IgoMap } from '../../map'; import { MeasureLengthUnit, - clearOlGeometryMidpoints, updateOlGeometryMidpoints, formatMeasure, measureOlGeometry @@ -52,11 +51,9 @@ export class GeometryFormFieldInputComponent implements OnInit, OnDestroy, Contr private drawControl: DrawControl; private modifyControl: ModifyControl; - private drawInteractionStyle: OlStyle; private defaultDrawStyleRadius: number; private olGeometryEnds$$: Subscription; private olGeometryChanges$$: Subscription; - private olTooltip = OlOverlay; /** @@ -89,13 +86,41 @@ export class GeometryFormFieldInputComponent implements OnInit, OnDestroy, Contr /** * The drawGuide around the mouse pointer to help drawing */ - @Input() drawGuide = 0; + @Input() drawGuide: number = null; /** * Whether a measure tooltip should be displayed */ @Input() measure: boolean = false; + /** + * Style for the draw control (applies while the geometry is being drawn) + */ + @Input() + set drawStyle(value: OlStyle) { + this._drawStyle = value || createDrawInteractionStyle(); + if (this.isStyleWithRadius(this.drawStyle)) { + this.defaultDrawStyleRadius = this.drawStyle.getImage().getRadius(); + } else { + this.defaultDrawStyleRadius = null; + } + } + get drawStyle(): OlStyle { return this._drawStyle; } + private _drawStyle: OlStyle; + + /** + * Style for the overlay layer (applies once the geometry is added to the map) + * If not specified, drawStyle applies + */ + @Input() + set overlayStyle(value: OlStyle) { + this._overlayStyle = value; + } + get overlayStyle(): OlStyle { + return this._overlayStyle || this.drawStyle; + } + private _overlayStyle: OlStyle; + /** * The geometry value (GeoJSON) * Implemented as part of ControlValueAccessor. @@ -148,8 +173,6 @@ export class GeometryFormFieldInputComponent implements OnInit, OnDestroy, Contr ngOnInit() { this.addOlOverlayLayer(); this.createMeasureTooltip(); - this.drawInteractionStyle = createDrawInteractionStyle(); - this.defaultDrawStyleRadius = this.drawInteractionStyle.getImage().getRadius(); this.createDrawControl(); this.createModifyControl(); if (this.value) { @@ -200,7 +223,8 @@ export class GeometryFormFieldInputComponent implements OnInit, OnDestroy, Contr private addOlOverlayLayer(): OlVectorLayer { this.olOverlayLayer = new OlVectorLayer({ source: new OlVectorSource(), - zIndex: 500 + zIndex: 500, + style: null }); this.map.ol.addLayer(this.olOverlayLayer); } @@ -210,10 +234,10 @@ export class GeometryFormFieldInputComponent implements OnInit, OnDestroy, Contr */ private createDrawControl() { this.drawControl = new DrawControl({ - geometryType: this.geometryType, + geometryType: this.geometryType || 'Point', layer: this.olOverlayLayer, drawStyle: (olFeature: OlFeature, resolution: number) => { - const style = this.drawInteractionStyle; + const style = this.drawStyle; this.updateDrawStyleWithDrawGuide(style, resolution); return style; } @@ -227,7 +251,7 @@ export class GeometryFormFieldInputComponent implements OnInit, OnDestroy, Contr this.modifyControl = new ModifyControl({ layer: this.olOverlayLayer, drawStyle: (olFeature: OlFeature, resolution: number) => { - const style = this.drawInteractionStyle; + const style = this.drawStyle; this.updateDrawStyleWithDrawGuide(style, resolution); return style; } @@ -239,7 +263,7 @@ export class GeometryFormFieldInputComponent implements OnInit, OnDestroy, Contr */ private toggleControl() { this.deactivateControl(); - if (!this.value) { + if (!this.value && this.geometryType) { this.activateControl(this.drawControl); } else { this.activateControl(this.modifyControl); @@ -322,7 +346,10 @@ export class GeometryFormFieldInputComponent implements OnInit, OnDestroy, Contr dataProjection: 'EPSG:4326', featureProjection: this.map.projection }); - const olFeature = new OlFeature({geometry: olGeometry}); + const olFeature = new OlFeature({ + geometry: olGeometry + }); + olFeature.setStyle(this.overlayStyle); this.olOverlaySource.clear(); this.olOverlaySource.addFeature(olFeature); } @@ -377,21 +404,35 @@ export class GeometryFormFieldInputComponent implements OnInit, OnDestroy, Contr * Remove the measure tooltip from the map */ private removeMeasureTooltip() { - if (this.olTooltip.getMap() !== undefined) { + if (this.olTooltip.getMap && this.olTooltip.getMap() !== undefined) { this.map.ol.removeOverlay(this.olTooltip); this.olTooltip.setMap(undefined); } } + /** + * Adjust the draw style with the specified draw guide distance, if possible + * @param olStyle Draw style to update + * @param resolution Resolution (to make the screen size of symbol fit the drawGuide value) + */ private updateDrawStyleWithDrawGuide(olStyle: OlStyle, resolution: number) { - const drawGuide = this.drawGuide; - let radius; - if (drawGuide === undefined || drawGuide < 0) { - radius = this.defaultDrawStyleRadius; - } else { - radius = drawGuide > 0 ? drawGuide / resolution : drawGuide; + if (this.isStyleWithRadius(olStyle)) { + const drawGuide = this.drawGuide; + let radius; + if (drawGuide === null || drawGuide < 0) { + radius = this.defaultDrawStyleRadius; + } else { + radius = drawGuide > 0 ? drawGuide / resolution : drawGuide; + } + olStyle.getImage().setRadius(radius); } - olStyle.getImage().setRadius(radius); } + /** + * Returns wether a given Open Layers style has a radius property that can be set (used to set draw guide) + * @param olStyle The style on which to perform the check + */ + private isStyleWithRadius(olStyle: OlStyle): boolean { + return olStyle.getImage && olStyle.getImage().setRadius; + } } diff --git a/packages/geo/src/lib/geometry/geometry-form-field/geometry-form-field.component.html b/packages/geo/src/lib/geometry/geometry-form-field/geometry-form-field.component.html index 5a860c3a6a..cea7af14e5 100644 --- a/packages/geo/src/lib/geometry/geometry-form-field/geometry-form-field.component.html +++ b/packages/geo/src/lib/geometry/geometry-form-field/geometry-form-field.component.html @@ -3,7 +3,9 @@ [map]="map" [geometryType]="geometryType$ | async" [drawGuide]="drawGuide$ | async" - [measure]="measure"> + [measure]="measure" + [drawStyle]="drawStyle" + [overlayStyle]="overlayStyle">