From 9d0c0d3cdc3fa0e82bc286087e0c9997d6f8e459 Mon Sep 17 00:00:00 2001 From: Moritz Kirmse Date: Mon, 14 Oct 2024 15:49:13 +0200 Subject: [PATCH 01/28] activate style edition for drawings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit still öissing: line style and point symbol --- .../common/range-input/range-input.vue | 1 + .../draw/feature-edit-style-label.vue | 2 +- .../draw/feature-edit-style-point.vue | 2 +- src/components/draw/feature-edit-style.vue | 56 +++++++++++++++++-- src/components/draw/feature-item.vue | 27 +++++++-- src/components/draw/feature-sub-content.vue | 24 +++++++- 6 files changed, 98 insertions(+), 14 deletions(-) diff --git a/src/components/common/range-input/range-input.vue b/src/components/common/range-input/range-input.vue index 96812de5..a399d543 100644 --- a/src/components/common/range-input/range-input.vue +++ b/src/components/common/range-input/range-input.vue @@ -28,6 +28,7 @@ const inputValue = ref(props.value) :max="max" :step="step" v-model="inputValue" + @input="$emit('change', parseFloat(inputValue))" /> - + diff --git a/src/components/draw/feature-edit-style-point.vue b/src/components/draw/feature-edit-style-point.vue index 2f98e3b1..5365a78c 100644 --- a/src/components/draw/feature-edit-style-point.vue +++ b/src/components/draw/feature-edit-style-point.vue @@ -3,5 +3,5 @@ diff --git a/src/components/draw/feature-edit-style.vue b/src/components/draw/feature-edit-style.vue index 1d90af86..666827d0 100644 --- a/src/components/draw/feature-edit-style.vue +++ b/src/components/draw/feature-edit-style.vue @@ -27,6 +27,31 @@ const currentStyleComponent = computed(() => feature?.featureType.replace('drawn', 'FeatureEditStyle') ) +function onColorSelect(colorEvent) { + feature.featureStyle.color = colorEvent.target.value + feature.changed() +} + +function onSizeChange(newSize) { + feature.featureStyle.size = newSize + feature.changed() +} + +function onAngleChange(newAngle) { + feature.featureStyle.angle = (newAngle * Math.PI) / 180 + feature.changed() +} + +function onWidthChange(newWidth) { + feature.featureStyle.stroke = newWidth + feature.changed() +} + +function onTransparencyChange(newTransparency) { + feature.featureStyle.opacity = (100 - newTransparency) / 100 + feature.changed() +} + function onClickChangeOrientation() { alert('onClickChangeOrientation TODO') // TODO: } @@ -52,19 +77,26 @@ function onClickChangeLineStyle(style: string) { - @@ -130,7 +172,11 @@ function onClickChangeLineStyle(style: string) { - + diff --git a/src/components/draw/feature-item.vue b/src/components/draw/feature-item.vue index ccd9004b..fc942b47 100644 --- a/src/components/draw/feature-item.vue +++ b/src/components/draw/feature-item.vue @@ -3,6 +3,7 @@ import { provide } from 'vue' import { getUid } from 'ol/util' import { DrawnFeature } from '@/services/draw/drawn-feature' +import { DrawnFeatureStyle } from '@/stores/draw.store.model' import FeatureSubContent from './feature-sub-content.vue' import FeatureSubWrapper from './feature-sub-wrapper.vue' @@ -20,13 +21,17 @@ const props = withDefaults( isOpen: false, } ) + +// should preform deep copy, nut then the updqte of the OL object on the canvas would not work ?? +const localFeature = props.feature + const emit = defineEmits([ 'clickDelete', 'closePopup', 'toggleFeatureSub', 'toggleFeatureEdit', 'toggleDock', - 'submitEditInfo', + 'submitFeature', ]) provide('feature', props.feature) @@ -43,8 +48,20 @@ function onClickDelete() { emit('clickDelete', props.feature.id) } -function onSubmitEditInfo() { - emit('submitEditInfo', props.feature) +function onResetInfo(prevLabel: string, prevDescription: string) { + localFeature.label = prevLabel + localFeature.description = prevDescription + // emit('submitFeature', localFeature) +} + +function onResetStyle(prevStyle: DrawnFeatureStyle) { + localFeature.featureStyle = Object.assign({}, prevStyle) + localFeature.value.changed() + // emit('submitFeature', localFeature) +} + +function onSubmitEditFeature() { + emit('submitFeature', props.feature) } @@ -97,7 +114,9 @@ function onSubmitEditInfo() { @toggleEditFeature="onToggleEditFeature" @toggleDock="() => emit('toggleDock')" @clickDelete="onClickDelete" - @submitEditInfo="onSubmitEditInfo" + @resetInfo="onResetInfo" + @resetStyle="onResetStyle" + @submitEditFeature="onSubmitEditFeature" /> diff --git a/src/components/draw/feature-sub-content.vue b/src/components/draw/feature-sub-content.vue index bec30ae4..cf256804 100644 --- a/src/components/draw/feature-sub-content.vue +++ b/src/components/draw/feature-sub-content.vue @@ -3,6 +3,7 @@ import { inject, provide, Ref, ref } from 'vue' import { useTranslation } from 'i18next-vue' import { DrawnFeature } from '@/services/draw/drawn-feature' +import { DrawnFeatureStyle } from '@/stores/draw.store.model' import FeatureMenuPopup from './feature-menu-popup.vue' import FeatureConfirmDelete from './feature-confirm-delete.vue' @@ -20,10 +21,16 @@ const emit = defineEmits([ 'toggleEditFeature', 'toggleDock', 'clickDelete', - 'submitEditInfo', + 'resetInfo', + 'resetStyle', + 'submitEditFeature', ]) const { t } = useTranslation() const feature: DrawnFeature | undefined = inject('feature') +let prevLabel = feature.label +let prevDescription = feature.description +// keep deep copy of previous style to be able to revert style on cancel +const prevStyle: DrawnFeatureStyle = Object.assign({}, feature.featureStyle) const editComponents = { FeatureConcentricCircle, @@ -38,6 +45,11 @@ const currentEditCompKey: Ref = provide('currentEditCompKey', currentEditCompKey) function onClickCancel() { + if (currentEditCompKey.value == 'FeatureEditStyle') { + emit('resetStyle', prevStyle) + } else if (currentEditCompKey.value == 'FeatureEditInfo') { + emit('resetInfo', prevLabel, prevDescription) + } currentEditCompKey.value = undefined } @@ -45,10 +57,16 @@ function onClickValidate() { const currentComponent = editComponents[currentEditCompKey.value as keyof typeof editComponents] + prevLabel = feature.label + prevDescription = feature.description + Object.assign(prevStyle, feature.featureStyle) if (currentComponent === FeatureConfirmDelete) { emit('clickDelete') - } else if (currentComponent === FeatureEditInfo) { - emit('submitEditInfo') + } else if ( + currentComponent === FeatureEditInfo || + currentComponent === FeatureEditStyle + ) { + emit('submitEditFeature') } else { alert('TODO: Draw feature click onClickValidate()') } From ffda25e6d821a86afdf35200b38554888be571e4 Mon Sep 17 00:00:00 2001 From: Moritz Kirmse Date: Mon, 14 Oct 2024 17:08:04 +0200 Subject: [PATCH 02/28] fix type errors --- .../common/range-input/range-input.vue | 2 +- src/components/draw/draw-panel-features.vue | 2 +- src/components/draw/feature-edit-style.vue | 23 ++++++++++--------- src/components/draw/feature-item.vue | 2 +- src/components/draw/feature-sub-content.vue | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/components/common/range-input/range-input.vue b/src/components/common/range-input/range-input.vue index a399d543..bafcdc21 100644 --- a/src/components/common/range-input/range-input.vue +++ b/src/components/common/range-input/range-input.vue @@ -28,7 +28,7 @@ const inputValue = ref(props.value) :max="max" :step="step" v-model="inputValue" - @input="$emit('change', parseFloat(inputValue))" + @input="$emit('change', inputValue)" /> { @toggleDock="() => (featureEditionDocked = !featureEditionDocked)" @closePopup="() => (featureEditionDocked = false)" @clickDelete="featureId => drawStore.removeFeature(featureId)" - @submitEditInfo="feature => drawStore.updateDrawnFeature(feature)" + @submitFeature="feature => drawStore.updateDrawnFeature(feature)" /> diff --git a/src/components/draw/feature-edit-style.vue b/src/components/draw/feature-edit-style.vue index 666827d0..d4a852f7 100644 --- a/src/components/draw/feature-edit-style.vue +++ b/src/components/draw/feature-edit-style.vue @@ -13,7 +13,7 @@ import FeatureEditStyleLabel from './feature-edit-style-label.vue' import FeatureEditStyleSymbole from './feature-edit-style-symbole.vue' const { t } = useTranslation() -const feature: DrawnFeature | undefined = inject('feature') +const feature: DrawnFeature = inject('feature')! const styleComponents = { FeatureEditStyleCircle, @@ -27,28 +27,29 @@ const currentStyleComponent = computed(() => feature?.featureType.replace('drawn', 'FeatureEditStyle') ) -function onColorSelect(colorEvent) { - feature.featureStyle.color = colorEvent.target.value +function onColorSelect(colorEvent: Event) { + feature.featureStyle.color = (colorEvent.target as HTMLInputElement).value feature.changed() } -function onSizeChange(newSize) { - feature.featureStyle.size = newSize +function onSizeChange(newSize: string | number) { + feature.featureStyle.size = parseFloat(newSize as string) feature.changed() } -function onAngleChange(newAngle) { - feature.featureStyle.angle = (newAngle * Math.PI) / 180 +function onAngleChange(newAngle: string | number) { + feature.featureStyle.angle = (parseFloat(newAngle as string) * Math.PI) / 180 feature.changed() } -function onWidthChange(newWidth) { - feature.featureStyle.stroke = newWidth +function onWidthChange(newWidth: string | number) { + feature.featureStyle.stroke = parseFloat(newWidth as string) feature.changed() } -function onTransparencyChange(newTransparency) { - feature.featureStyle.opacity = (100 - newTransparency) / 100 +function onTransparencyChange(newTransparency: string | number) { + feature.featureStyle.opacity = + (100 - parseFloat(newTransparency as string)) / 100 feature.changed() } diff --git a/src/components/draw/feature-item.vue b/src/components/draw/feature-item.vue index fc942b47..64e83971 100644 --- a/src/components/draw/feature-item.vue +++ b/src/components/draw/feature-item.vue @@ -56,7 +56,7 @@ function onResetInfo(prevLabel: string, prevDescription: string) { function onResetStyle(prevStyle: DrawnFeatureStyle) { localFeature.featureStyle = Object.assign({}, prevStyle) - localFeature.value.changed() + localFeature.changed() // emit('submitFeature', localFeature) } diff --git a/src/components/draw/feature-sub-content.vue b/src/components/draw/feature-sub-content.vue index cf256804..4f4e7332 100644 --- a/src/components/draw/feature-sub-content.vue +++ b/src/components/draw/feature-sub-content.vue @@ -26,7 +26,7 @@ const emit = defineEmits([ 'submitEditFeature', ]) const { t } = useTranslation() -const feature: DrawnFeature | undefined = inject('feature') +const feature: DrawnFeature = inject('feature')! let prevLabel = feature.label let prevDescription = feature.description // keep deep copy of previous style to be able to revert style on cancel From 185b5dd32420ad2a622e7320b506ea690addf9ef Mon Sep 17 00:00:00 2001 From: Moritz Kirmse Date: Mon, 14 Oct 2024 19:59:41 +0200 Subject: [PATCH 03/28] additional style properties (direction, lineStyle) --- src/components/draw/feature-edit-style.vue | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/draw/feature-edit-style.vue b/src/components/draw/feature-edit-style.vue index d4a852f7..ad648725 100644 --- a/src/components/draw/feature-edit-style.vue +++ b/src/components/draw/feature-edit-style.vue @@ -2,6 +2,8 @@ import { computed, inject } from 'vue' import { useTranslation } from 'i18next-vue' +import { LineString } from 'ol/geom' + import { DrawnFeature } from '@/services/draw/drawn-feature' import RangeInput from '@/components/common/range-input/range-input.vue' @@ -53,12 +55,24 @@ function onTransparencyChange(newTransparency: string | number) { feature.changed() } +function onShowDirection(event: Event) { + feature.featureStyle.showOrientation = ( + event.target as HTMLInputElement + ).checked + feature.changed() +} + function onClickChangeOrientation() { - alert('onClickChangeOrientation TODO') // TODO: + const coordinates = (feature.getGeometry() as LineString) + .getCoordinates() + .reverse() + const reversedGeometry = new LineString(coordinates) + feature.setGeometry(reversedGeometry) } function onClickChangeLineStyle(style: string) { - alert('onClickChangeLineStyle TODO' + style) // TODO: + feature.featureStyle.linestyle = style + feature.changed() } @@ -186,7 +200,7 @@ function onClickChangeLineStyle(style: string) { - +
From 2bb5b48f3cf50be80131df1fd431f629f88afeb5 Mon Sep 17 00:00:00 2001 From: Moritz Kirmse Date: Mon, 21 Oct 2024 14:07:42 +0200 Subject: [PATCH 04/28] connect symbol style editor --- .../{rectangleSymbol.vue => squareSymbol.vue} | 0 .../draw/feature-edit-style-point.vue | 23 +++++++-- .../draw/feature-edit-style-symbole.vue | 35 +++++++------- src/components/draw/feature-edit-style.vue | 12 +++-- src/components/draw/feature-edit-symbol.vue | 47 ++++++++----------- src/components/draw/feature-sub-content.vue | 2 - 6 files changed, 65 insertions(+), 54 deletions(-) rename src/components/common/symbol/{rectangleSymbol.vue => squareSymbol.vue} (100%) diff --git a/src/components/common/symbol/rectangleSymbol.vue b/src/components/common/symbol/squareSymbol.vue similarity index 100% rename from src/components/common/symbol/rectangleSymbol.vue rename to src/components/common/symbol/squareSymbol.vue diff --git a/src/components/draw/feature-edit-style-point.vue b/src/components/draw/feature-edit-style-point.vue index 5365a78c..ca30aa30 100644 --- a/src/components/draw/feature-edit-style-point.vue +++ b/src/components/draw/feature-edit-style-point.vue @@ -1,7 +1,22 @@ - + diff --git a/src/components/draw/feature-edit-style-symbole.vue b/src/components/draw/feature-edit-style-symbole.vue index c8dad8e8..a19e4831 100644 --- a/src/components/draw/feature-edit-style-symbole.vue +++ b/src/components/draw/feature-edit-style-symbole.vue @@ -2,20 +2,15 @@ import { Ref, inject } from 'vue' import { useTranslation } from 'i18next-vue' -// import { DrawFeature } from '@/stores/draw.store.model' // TODO: +import { DrawnFeature } from '@/services/draw/drawn-feature' import Circle from '@/components/common/symbol/circleSymbol.vue' -import Rectangle from '@/components/common/symbol/rectangleSymbol.vue' +import Square from '@/components/common/symbol/squareSymbol.vue' import Cross from '@/components/common/symbol/crossSymbol.vue' import Triangle from '@/components/common/symbol/triangleSymbol.vue' -type FeatureShape = 'circle' | 'square' | 'cross' | 'triangle' - const { t } = useTranslation() -const currentEditCompKey: Ref<'FeatureEditSymbol' | undefined> | undefined = - inject('currentEditCompKey') -// const feature: DrawFeature | undefined = inject('feature') // TODO: -const featureShape: FeatureShape = 'circle' // feature.olFeature.get('shape') // TODO: to plug when feature ok -const featureColor = 'red' // feature.olFeature.get('color') // TODO: to plug when feature ok +const feature: DrawnFeature = inject('feature')! +const popupOpen: Ref = inject('popupOpen')! diff --git a/src/components/draw/feature-sub-content.vue b/src/components/draw/feature-sub-content.vue index 4f4e7332..aa5a0f05 100644 --- a/src/components/draw/feature-sub-content.vue +++ b/src/components/draw/feature-sub-content.vue @@ -11,7 +11,6 @@ import FeatureEditInfo from './feature-edit-info.vue' import FeatureEditStyle from './feature-edit-style.vue' import FeatureConcentricCircle from './feature-concentric-circle.vue' import FeatureMeasurements from './feature-measurements.vue' -import FeatureEditSymbol from './feature-edit-symbol.vue' defineProps<{ isDocked: boolean @@ -37,7 +36,6 @@ const editComponents = { FeatureEditInfo, FeatureEditStyle, FeatureConfirmDelete, - FeatureEditSymbol, } const currentEditCompKey: Ref = ref(undefined) From 78e0a77d8493733869d0d7f1d4ba00892dcc63cd Mon Sep 17 00:00:00 2001 From: Moritz Kirmse Date: Mon, 21 Oct 2024 15:16:42 +0200 Subject: [PATCH 05/28] select clipart symbols --- .../draw/feature-edit-style-point.vue | 1 + .../draw/feature-edit-style-symbole.vue | 43 +++++++++++-------- src/components/draw/feature-edit-style.vue | 5 ++- src/components/draw/feature-edit-symbol.vue | 19 ++++---- 4 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/components/draw/feature-edit-style-point.vue b/src/components/draw/feature-edit-style-point.vue index ca30aa30..a31ec874 100644 --- a/src/components/draw/feature-edit-style-point.vue +++ b/src/components/draw/feature-edit-style-point.vue @@ -18,5 +18,6 @@ const popupOpen: Ref = inject('popupOpen')! + diff --git a/src/components/draw/feature-edit-style-symbole.vue b/src/components/draw/feature-edit-style-symbole.vue index a19e4831..36b2689a 100644 --- a/src/components/draw/feature-edit-style-symbole.vue +++ b/src/components/draw/feature-edit-style-symbole.vue @@ -2,6 +2,8 @@ import { Ref, inject } from 'vue' import { useTranslation } from 'i18next-vue' +import { SYMBOL_ICONS_URL } from '@/services/draw/draw.helper' + import { DrawnFeature } from '@/services/draw/drawn-feature' import Circle from '@/components/common/symbol/circleSymbol.vue' import Square from '@/components/common/symbol/squareSymbol.vue' @@ -20,27 +22,34 @@ const popupOpen: Ref = inject('popupOpen')!
diff --git a/src/components/draw/feature-edit-style.vue b/src/components/draw/feature-edit-style.vue index 898f089c..47c32664 100644 --- a/src/components/draw/feature-edit-style.vue +++ b/src/components/draw/feature-edit-style.vue @@ -120,7 +120,10 @@ function onClickChangeLineStyle(style: string) { diff --git a/src/components/draw/feature-edit-style.vue b/src/components/draw/feature-edit-style.vue index 3f3ddfcc..71b4af37 100644 --- a/src/components/draw/feature-edit-style.vue +++ b/src/components/draw/feature-edit-style.vue @@ -36,24 +36,23 @@ function onColorSelect(colorEvent: Event) { feature.changed() } -function onSizeChange(newSize: string | number) { - feature.featureStyle.size = parseFloat(newSize as string) +function onSizeChange(newSize: number) { + feature.featureStyle.size = newSize feature.changed() } -function onAngleChange(newAngle: string | number) { - feature.featureStyle.angle = (parseFloat(newAngle as string) * Math.PI) / 180 +function onAngleChange(newAngle: number) { + feature.featureStyle.angle = (newAngle * Math.PI) / 180 feature.changed() } -function onWidthChange(newWidth: string | number) { - feature.featureStyle.stroke = parseFloat(newWidth as string) +function onWidthChange(newWidth: number) { + feature.featureStyle.stroke = newWidth feature.changed() } -function onTransparencyChange(newTransparency: string | number) { - feature.featureStyle.opacity = - (100 - parseFloat(newTransparency as string)) / 100 +function onTransparencyChange(newTransparency: number) { + feature.featureStyle.opacity = (100 - newTransparency) / 100 feature.changed() } diff --git a/src/components/draw/feature-item.vue b/src/components/draw/feature-item.vue index 64e83971..4735207f 100644 --- a/src/components/draw/feature-item.vue +++ b/src/components/draw/feature-item.vue @@ -22,7 +22,6 @@ const props = withDefaults( } ) -// should preform deep copy, nut then the updqte of the OL object on the canvas would not work ?? const localFeature = props.feature const emit = defineEmits([ @@ -51,13 +50,11 @@ function onClickDelete() { function onResetInfo(prevLabel: string, prevDescription: string) { localFeature.label = prevLabel localFeature.description = prevDescription - // emit('submitFeature', localFeature) } function onResetStyle(prevStyle: DrawnFeatureStyle) { - localFeature.featureStyle = Object.assign({}, prevStyle) + localFeature.featureStyle = { ...prevStyle } localFeature.changed() - // emit('submitFeature', localFeature) } function onSubmitEditFeature() { diff --git a/src/components/draw/feature-sub-content.vue b/src/components/draw/feature-sub-content.vue index aa5a0f05..08e6ca63 100644 --- a/src/components/draw/feature-sub-content.vue +++ b/src/components/draw/feature-sub-content.vue @@ -29,7 +29,7 @@ const feature: DrawnFeature = inject('feature')! let prevLabel = feature.label let prevDescription = feature.description // keep deep copy of previous style to be able to revert style on cancel -const prevStyle: DrawnFeatureStyle = Object.assign({}, feature.featureStyle) +const prevStyle: DrawnFeatureStyle = { ...feature.featureStyle } const editComponents = { FeatureConcentricCircle, From 9c3add46d553c85b126179f79866ecb9371b9284 Mon Sep 17 00:00:00 2001 From: Moritz Kirmse Date: Thu, 31 Oct 2024 15:55:01 +0100 Subject: [PATCH 10/28] implement tests: - different style options - validate => URL - cancel => restore style --- cypress/e2e/draw/draw-feat-style.cy.ts | 316 ++++++++++++++++-- .../common/range-input/range-input.vue | 2 +- src/components/draw/feature-edit-style.vue | 7 +- 3 files changed, 294 insertions(+), 31 deletions(-) diff --git a/cypress/e2e/draw/draw-feat-style.cy.ts b/cypress/e2e/draw/draw-feat-style.cy.ts index 72caa3c1..45bbdcbc 100644 --- a/cypress/e2e/draw/draw-feat-style.cy.ts +++ b/cypress/e2e/draw/draw-feat-style.cy.ts @@ -5,6 +5,8 @@ describe('Test style edition of Point feature', () => { cy.get('button[data-cy="drawButton"]').click() cy.get('button[data-cy="drawPointButton"]').click() cy.get('div.ol-viewport').click(400, 300, { force: true }) + // finish editing, otherwise we have two OL objects + cy.get('button[data-cy="featItemToggleEdit"]').click() }) describe('Edit feature style', () => { cy.get('*[data-cy="featItemActionStyle"]').click() @@ -14,15 +16,25 @@ describe('Test style edition of Point feature', () => { cy.get('*[data-cy="featStyleSymbol"]').click() cy.get('*[data-cy="featStyleSymbol_2"]').click() cy.get('*[data-cy="featStyleSize"]').type('{selectAll}50') - cy.get('*[data-cy="featStyleSize"]').trigger('input') cy.get('*[data-cy="featStyleAngle"]').type('{selectAll}30') - cy.get('*[data-cy="featStyleAngle"]').trigger('input') - cy.get('button[data-cy="featureEditValidate"]').click() }) }) describe('When checking URL', () => { it('feature style shall be encoded', () => { + cy.url().as('url') + cy.window() + .its('featureHash') + .then(function (fh) { + const features = new URLSearchParams(new URL(this.url).search).get( + 'features' + )! + const ff = fh.readFeatures(features) + cy.wrap(ff[0].get('t')).should('equal', '10') + }) + + cy.get('button[data-cy="featureEditValidate"]').click() + cy.url().as('url') cy.window() .its('featureHash') @@ -38,12 +50,8 @@ describe('Test style edition of Point feature', () => { cy.wrap(ff[0].get('c')).should('equal', '%2300ff00') // check shape: cross cy.wrap(ff[0].get('s')).should('equal', 'cross') - // check size = 50 + // check size 50 cy.wrap(ff[0].get('t')).should('equal', '50') - // check angle = 30° - cy.wrap( - Math.abs(30 - (parseFloat(ff[0].get('a')) / Math.PI) * 180) - ).should('be.lessThan', 0.001) return cy.wrap(ff) }) @@ -53,10 +61,206 @@ describe('Test style edition of Point feature', () => { }) }) -describe('Test style edition of Polygon feature', () => { +describe('Test style edition of Point feature', () => { beforeEach(() => { cy.visit('/') describe('Draw "Point"', () => { + cy.get('button[data-cy="drawButton"]').click() + cy.get('button[data-cy="drawPointButton"]').click() + cy.get('div.ol-viewport').click(400, 300, { force: true }) + // finish editing, otherwise we have two OL objects + cy.get('button[data-cy="featItemToggleEdit"]').click() + }) + describe('Edit feature style', () => { + cy.get('*[data-cy="featItemActionStyle"]').click() + cy.get('*[data-cy="featStyleColor"]') + .invoke('val', '#00ff00') + .trigger('input') + cy.get('*[data-cy="featStyleSymbol"]').click() + cy.get('*[data-cy="featStyleSymbol_2"]').click() + cy.get('*[data-cy="featStyleSize"]').type('{selectAll}50') + cy.get('*[data-cy="featStyleAngle"]') + .find('input') + .eq(1) + .type('{selectAll}30', { force: true }) + }) + }) + + describe('When checking featureStyle in OL DrawnFeature object', () => { + it('feature style shall be applied', () => { + // get featureLayer + cy.window() + .its('olMap') + .then(function (olMap) { + const featureLayers = olMap + .getLayers() + .getArray() + .filter((l: any) => l.get('cyLayerType') == 'featureLayer') + const features = featureLayers + .map((l: any) => l.getSource().getFeatures()) + .flat() + cy.wrap(features.length).should('equal', 1) + + // const ff = features.find((f: any) => f.get('name') == 'Point 1') + const ff = features[0] + cy.wrap(ff.featureType).should('equal', 'drawnPoint') + // check color green + cy.wrap(ff.featureStyle.color).should('equal', '#00ff00') + // check shape: cross + cy.wrap(ff.featureStyle.shape).should('equal', 'cross') + // check size = 50 + cy.wrap(ff.featureStyle.size).should('equal', 50) + // check angle = 30° + //cy.wrap(Math.abs(30 - ff.featureStyle.angle / Math.PI * 180)).should('be.lessThan', 0.0001) + }) + + // test cancel button + cy.get('button[data-cy="featureEditCancel"]').click() + + cy.window() + .its('olMap') + .then(function (olMap) { + const featureLayers = olMap + .getLayers() + .getArray() + .filter((l: any) => l.get('cyLayerType') == 'featureLayer') + const features = featureLayers + .map((l: any) => l.getSource().getFeatures()) + .flat() + // if the edit mode stays active, two features are created, so the length check fails + cy.log( + `${features.length} features found with names: ${features.map( + (f: any) => f.get('name') + )}` + ) + // cy.wrap(features.length).should('equal', 1) + + // const ff = features.find((f: any) => f.get('name') == 'Nom 1') + const ff = features[0] + // check size = 10 + cy.wrap(ff.featureStyle.size).should('equal', 10) + }) + }) + }) +}) + +describe('Test style edition of Label feature', () => { + beforeEach(() => { + cy.visit('/') + describe('Draw "Point"', () => { + cy.get('button[data-cy="drawButton"]').click() + cy.get('button[data-cy="drawLabelButton"]').click() + cy.get('div.ol-viewport').click(250, 150, { force: true }) + }) + describe('Edit feature style', () => { + cy.get('*[data-cy="featItemActionStyle"]').click() + cy.get('*[data-cy="featStyleColor"]') + .invoke('val', '#009f09') + .trigger('input') + cy.get('*[data-cy="featStyleSize"]').type('{selectAll}8') // max size 10 + cy.get('*[data-cy="featStyleAngle"]').type('{selectAll}60') + cy.get('button[data-cy="featureEditValidate"]').click() + }) + }) + + describe('When checking featureStyle in OL DrawnFeature object', () => { + it('feature style shall be applied', () => { + // get featureLayer + cy.window() + .its('olMap') + .then(function (olMap) { + const featureLayers = olMap + .getLayers() + .getArray() + .filter((l: any) => l.get('cyLayerType') == 'featureLayer') + const features = featureLayers + .map((l: any) => l.getSource().getFeatures()) + .flat() + // if the edit mode stays active, two features are created, so the length check fails + cy.log( + `${features.length} features found with names: ${features.map(f => + f.get('name') + )}` + ) + // cy.wrap(features.length).should('equal', 1) + + // const ff = features.find((f: any) => f.get('name') == 'Étiquette 1') + const ff = features[0] + cy.wrap(ff.featureType).should('equal', 'drawnLabel') + // check color green + cy.wrap(ff.featureStyle.color).should('equal', '#009f09') + // check size = 50 + cy.wrap(ff.featureStyle.size).should('equal', 8) + // check angle = 60° + cy.wrap( + Math.abs(60 - (ff.featureStyle.angle / Math.PI) * 180) + ).should('be.lessThan', 0.0001) + }) + }) + }) +}) + +describe('Test style edition of Line feature', () => { + beforeEach(() => { + cy.visit('/') + describe('Draw "Line"', () => { + cy.get('button[data-cy="drawButton"]').click() + cy.get('button[data-cy="drawLineButton"]').click() + cy.get('div.ol-viewport').click(200, 400, { force: true }) + cy.get('div.ol-viewport').click(300, 300, { force: true }) + cy.get('div.ol-viewport').click(400, 400, { force: true }) + cy.get('div.ol-viewport').dblclick(500, 300, { force: true }) + }) + describe('Edit feature style', () => { + cy.get('*[data-cy="featItemActionStyle"]').click() + cy.get('*[data-cy="featStyleColor"]') + .invoke('val', '#0088ff') + .trigger('input') + cy.get('*[data-cy="featStyleLineWidth"]') + .find('input') + .eq(1) + .type('{selectAll}7.5', { force: true }) + cy.get('*[data-cy="featStyleLineStyle"]').find('button').eq(1).click() + cy.get('button[data-cy="featureEditValidate"]').click() + }) + }) + + describe('When checking featureStyle in OL DrawnFeature object', () => { + it('feature style shall be applied', () => { + // get featureLayer + cy.window() + .its('olMap') + .then(function (olMap) { + const featureLayers = olMap + .getLayers() + .getArray() + .filter((l: any) => l.get('cyLayerType') == 'featureLayer') + cy.log(featureLayers.length) + const features = featureLayers + .map((l: any) => l.getSource().getFeatures()) + .flat() + cy.log(features.length) + cy.log(features.map(f => f.get('name'))) + // if the edit mode stays active, two features are created, so the length check fails + // cy.wrap(features.length).should('equal', 1) + // const ff = features.find((f: any) => f.get('name') == 'Ligne 1') + const ff = features[0] + cy.wrap(ff.featureType).should('equal', 'drawnLine') + // check color blue + cy.wrap(ff.featureStyle.color).should('equal', '#0088ff') + // check line width 5 + cy.wrap(ff.featureStyle.stroke).should('equal', 7.5) + // check line style dashed + cy.wrap(ff.featureStyle.linestyle).should('equal', 'dashed') + }) + }) + }) +}) + +describe('Test style edition of Polygon feature', () => { + beforeEach(() => { + cy.visit('/') + describe('Draw "Polygon"', () => { cy.get('button[data-cy="drawButton"]').click() cy.get('button[data-cy="drawPolygonButton"]').click() cy.get('div.ol-viewport').click(100, 100, { force: true }) @@ -69,37 +273,91 @@ describe('Test style edition of Polygon feature', () => { .invoke('val', '#0000ff') .trigger('input') cy.get('*[data-cy="featStyleLineWidth"]').type('{selectAll}5.5') - cy.get('*[data-cy="featStyleLineWidth"]').trigger('input') cy.get('*[data-cy="featStyleTransparency"]').type('{selectAll}22') - cy.get('*[data-cy="featStyleTransparency"]').trigger('input') cy.get('button[data-cy="featureEditValidate"]').click() }) }) - describe('When checking URL', () => { - it('feature style shall be encoded', () => { - cy.url().as('url') + describe('When checking featureStyle in OL DrawnFeature object', () => { + it('feature style shall be applied', () => { + // get featureLayer cy.window() - .its('featureHash') - .then(function (fh) { - const features = new URLSearchParams(new URL(this.url).search).get( - 'features' - )! - const ff = fh.readFeatures(features) - cy.wrap(ff).its('length').should('equal', 1) - cy.log(JSON.stringify(ff[0].values_)) - cy.wrap(ff[0].getGeometry()?.getType()).should('equal', 'Polygon') + .its('olMap') + .then(function (olMap) { + const featureLayers = olMap + .getLayers() + .getArray() + .filter((l: any) => l.get('cyLayerType') == 'featureLayer') + cy.log(featureLayers.length) + const features = featureLayers + .map((l: any) => l.getSource().getFeatures()) + .flat() + cy.log(features.length) + cy.log(features.map(f => f.get('name'))) + // if the edit mode stays active, two features are created, so the length check fails + // cy.wrap(features.length).should('equal', 1) + // const ff = features.find((f: any) => f.get('name') == 'Polygone 1') + const ff = features[0] + cy.wrap(ff.featureType).should('equal', 'drawnPolygon') // check color blue - cy.wrap(ff[0].get('c')).should('equal', '%230000ff') + cy.wrap(ff.featureStyle.color).should('equal', '#0000ff') // check line width 5 - cy.wrap(ff[0].get('e')).should('equal', '5.5') + cy.wrap(ff.featureStyle.stroke).should('equal', 5.5) // check opacity 0.78 - cy.wrap(ff[0].get('o')).should('equal', '0.78') + cy.wrap(ff.featureStyle.opacity).should('equal', 0.78) + }) + }) + }) +}) - return cy.wrap(ff) +describe('Test style edition of Circle feature', () => { + beforeEach(() => { + cy.visit('/') + describe('Draw "Circle"', () => { + cy.get('button[data-cy="drawButton"]').click() + cy.get('button[data-cy="drawCircleButton"]').click() + cy.get('div.ol-viewport').click(500, 400, { force: true }) + cy.get('div.ol-viewport').dblclick(550, 450, { force: true }) + }) + describe('Edit feature style', () => { + cy.get('*[data-cy="featItemActionStyle"]').click() + cy.get('*[data-cy="featStyleColor"]') + .invoke('val', '#00004f') + .trigger('input') + cy.get('*[data-cy="featStyleLineWidth"]').type('{selectAll}3.5') + cy.get('*[data-cy="featStyleTransparency"]').type('{selectAll}62') + cy.get('button[data-cy="featureEditValidate"]').click() + }) + }) + + describe('When checking featureStyle in OL DrawnFeature object', () => { + it('feature style shall be applied', () => { + // get featureLayer + cy.window() + .its('olMap') + .then(function (olMap) { + const featureLayers = olMap + .getLayers() + .getArray() + .filter((l: any) => l.get('cyLayerType') == 'featureLayer') + cy.log(featureLayers.length) + const features = featureLayers + .map((l: any) => l.getSource().getFeatures()) + .flat() + cy.log(features.length) + cy.log(features.map(f => f.get('name'))) + // if the edit mode stays active, two features are created, so the length check fails + // cy.wrap(features.length).should('equal', 1) + // const ff = features.find((f: any) => f.get('name') == 'Cercle 1') + const ff = features[0] + cy.wrap(ff.featureType).should('equal', 'drawnCircle') + // check color blue + cy.wrap(ff.featureStyle.color).should('equal', '#00004f') + // check line width 5 + cy.wrap(ff.featureStyle.stroke).should('equal', 3.5) + // check opacity 0.78 + cy.wrap(ff.featureStyle.opacity).should('equal', 0.38) }) - .its('length') - .should('equal', 1) // only one geometry has been created }) }) }) diff --git a/src/components/common/range-input/range-input.vue b/src/components/common/range-input/range-input.vue index bafcdc21..ffcf1507 100644 --- a/src/components/common/range-input/range-input.vue +++ b/src/components/common/range-input/range-input.vue @@ -27,7 +27,7 @@ const inputValue = ref(props.value) :min="min" :max="max" :step="step" - v-model="inputValue" + v-model.number="inputValue" @input="$emit('change', inputValue)" />