Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PB-199: add new point on an existing line #1129

Merged
merged 29 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
dae9c76
PB-199: Add new point to the line on right click.
ismailsunni Nov 11, 2024
3ae57c9
PB-199: Add tooltip for right click to add new point.
ismailsunni Nov 11, 2024
eb92d92
PB-199: Add basic buttons for adding new vertex as an overlay.
ismailsunni Nov 13, 2024
8169577
PB-199: Use LineString instead Feature.
ismailsunni Nov 13, 2024
3a26d8d
PB-199: Use tippy
ismailsunni Nov 13, 2024
7569ce2
PB-199: Implement extend line string.
ismailsunni Nov 18, 2024
5241b63
PB-199: Continue the line from start or end vertex.
ismailsunni Nov 18, 2024
c2f9ed9
PB-199: Only show add vertex button while selecting line but not when…
ismailsunni Nov 18, 2024
ba277ad
PB-199: Remove unused code from the previous approach.
ismailsunni Nov 18, 2024
65bb604
PB-199: Use proper tooltip.
ismailsunni Nov 18, 2024
2994ed2
PB-199: Add style for overlay buttons.
ismailsunni Nov 18, 2024
4f2ef78
PB-199: Position add vertex button depending on the line string geome…
ismailsunni Nov 18, 2024
8ec2467
PB-199: Only show the add vertex button on linestring excluding measu…
ismailsunni Nov 18, 2024
4239c2a
PB-199: Use different approach, putting the continue drawing interact…
ismailsunni Nov 20, 2024
48206c3
PB-199: add vertex from the starting point.
ismailsunni Nov 20, 2024
96c5186
PB-199: Remove old approach.
ismailsunni Nov 20, 2024
101fb7b
PB-199: Add edit mode for better handling the add vertex buttons.
ismailsunni Nov 20, 2024
96a8856
PB-199: Update store selected feature to update the add vertex button…
ismailsunni Nov 20, 2024
87dd1ed
PB-199: Remove unused comment.
ismailsunni Nov 20, 2024
13d820d
PB-199: remove last point with right click on extend line mode.
ismailsunni Nov 20, 2024
b9e9d1f
PB-199: Remove last point on right click on modify mode.
ismailsunni Nov 20, 2024
d80e856
PB-199: Address PR review.
ismailsunni Nov 21, 2024
e364bc6
PB-199: Merge edit mode and reverseLineStringExtension
ismailsunni Nov 21, 2024
2e64f37
PB-199: Use computed to access store.
ismailsunni Nov 21, 2024
4e1fb66
PB-199: Use computed from props.
ismailsunni Nov 21, 2024
09dc269
PB-199: Update translation.
ismailsunni Nov 21, 2024
e2d55f5
PB-199: Keep the direction of the updated line after extending.
ismailsunni Nov 21, 2024
5dabbd2
PB-199: Also add vertex for measurement line.
ismailsunni Nov 21, 2024
d07f885
PB-199: Make sure that the add vertex button does not covering measur…
ismailsunni Nov 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion src/modules/drawing/DrawingModule.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import { computed, inject, onBeforeUnmount, onMounted, provide, ref, watch } fro
import { useI18n } from 'vue-i18n'
import { useStore } from 'vuex'

import { EditableFeatureTypes } from '@/api/features/EditableFeature.class'
import { IS_TESTING_WITH_CYPRESS } from '@/config/staging.config'
import AddVertexButtonOverlay from '@/modules/drawing/components/AddVertexButtonOverlay.vue'
import DrawingInteractions from '@/modules/drawing/components/DrawingInteractions.vue'
import DrawingToolbox from '@/modules/drawing/components/DrawingToolbox.vue'
import DrawingTooltip from '@/modules/drawing/components/DrawingTooltip.vue'
import { DrawingState } from '@/modules/drawing/lib/export-utils'
import useKmlDataManagement from '@/modules/drawing/useKmlDataManagement.composable'
import { EditMode } from '@/store/modules/drawing.store'
import { FeatureInfoPositions } from '@/store/modules/ui.store'
import { getIcon, parseIconUrl } from '@/utils/kmlUtils'
import log from '@/utils/logging'
Expand All @@ -32,6 +35,24 @@ const featureIds = computed(() => store.state.drawing.featureIds)
const isDrawingEmpty = computed(() => store.getters.isDrawingEmpty)
const noFeatureInfo = computed(() => store.getters.noFeatureInfo)
const online = computed(() => store.state.drawing.online)
const selectedEditableFeatures = computed(() => store.state.features.selectedEditableFeatures)
const selectedLineString = computed(() => {
if (selectedEditableFeatures.value && selectedEditableFeatures.value.length > 0) {
const selectedFeature = selectedEditableFeatures.value[0]
if (
selectedFeature.geometry.type === 'LineString' &&
(selectedFeature.featureType === EditableFeatureTypes.LINEPOLYGON ||
selectedFeature.featureType === EditableFeatureTypes.MEASURE)
) {
return selectedFeature
}
}
return null
})
const showAddVertexButton = computed(() => {
return store.state.drawing.editingMode === EditMode.MODIFY && !!selectedLineString.value
})

const hasKml = computed(() => {
if (online.value) {
return !!activeKmlLayer.value
Expand Down Expand Up @@ -107,7 +128,15 @@ watch(availableIconSets, () => {
}
})
})

watch(selectedEditableFeatures, (newValue) => {
if (newValue) {
if (store.state.drawing.editingMode === EditMode.OFF) {
store.dispatch('setEditingMode', { mode: EditMode.MODIFY, ...dispatcher })
}
} else {
store.dispatch('setEditingMode', { mode: EditMode.OFF, ...dispatcher })
}
})
onMounted(() => {
if (noFeatureInfo.value) {
// Left clicking while in drawing mode has its own logic not covered in click-on-map-management.plugin.js
Expand Down Expand Up @@ -211,5 +240,9 @@ async function closeDrawing() {
<DrawingToolbox @remove-last-point="removeLastPoint" @close-drawing="closeDrawing" />
<DrawingTooltip />
<DrawingInteractions ref="drawingInteractions" />
<AddVertexButtonOverlay
v-if="showAddVertexButton"
:line-string="selectedLineString.geometry"
/>
</div>
</template>
60 changes: 60 additions & 0 deletions src/modules/drawing/components/AddVertexButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<script setup>
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useStore } from 'vuex'

import { EditMode } from '@/store/modules/drawing.store'
import { useTippyTooltip } from '@/utils/composables/useTippyTooltip'
const dispatcher = { dispatcher: 'AddVertexButton.vue' }

const props = defineProps({
tooltipText: {
type: String,
default: 'modify_add_vertex',
},
// If true, the button will add a vertex in the reverse direction
reverse: {
type: Boolean,
default: false,
},
})

const emit = defineEmits(['button-mounted'])

const buttonRef = ref(null)

const i18n = useI18n()
const store = useStore()

useTippyTooltip('#addVertexButton [data-tippy-content]', { placement: 'left' })

onMounted(() => {
// Emit an event to notify the parent component that the button is mounted
emit('button-mounted', buttonRef.value)
})

function addVertex() {
store.dispatch('setEditingMode', {
mode: EditMode.EXTEND,
reverseLineStringExtension: props.reverse,
...dispatcher,
})
}
</script>

<template>
<div id="addVertexButton" ref="buttonRef">
<button
class="overlay-button d-print-none"
:data-tippy-content="i18n.t(props.tooltipText)"
@click="addVertex"
>
<font-awesome-icon :icon="['fas', 'plus']" />
</button>
</div>
</template>

<style lang="scss" scoped>
@import '@/modules/map/scss/toolbox-buttons';
</style>
125 changes: 125 additions & 0 deletions src/modules/drawing/components/AddVertexButtonOverlay.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<script setup>
import { LineString } from 'ol/geom'
import Overlay from 'ol/Overlay'
import { computed, onMounted, ref, watch } from 'vue'
import { inject } from 'vue'
import { onUnmounted } from 'vue'
import { useStore } from 'vuex'

import AddVertexButton from '@/modules/drawing/components/AddVertexButton.vue'

const props = defineProps({
lineString: {
type: LineString,
required: true,
},
})

const coordinates = computed(() => props.lineString.coordinates)

const olMap = inject('olMap')

const firstButtonOverlay = ref(null)
const lastButtonOverlay = ref(null)

const firstButtonCoordinate = ref(null)
const lastButtonCoordinate = ref(null)

const store = useStore()
const selectedEditableFeatures = computed(() => store.state.features.selectedEditableFeatures)
const selectedFeatureType = computed(() => {
if (selectedEditableFeatures.value && selectedEditableFeatures.value.length > 0) {
const selectedFeature = selectedEditableFeatures.value[0]
return selectedFeature.featureType
}
return null
})

const calculateOffset = (point1, point2, distance) => {
if (!point1 || !point2) {
return [distance, -distance]
}

// Vector from point1 to point2
const dx = point2[0] - point1[0]
const dy = point2[1] - point1[1]

// Normalize the vector
const length = Math.sqrt(dx * dx + dy * dy)
if (length === 0) return [distance, -distance]

// Get unit vector in opposite direction
const ux = -dx / length
const uy = -dy / length

// There is minus in y-direction because the y-axis is inverted in the map
return [ux * distance, -uy * distance]
}

const updateButtonPositions = () => {
const coords = coordinates.value
firstButtonCoordinate.value = coords[0]
lastButtonCoordinate.value = coords[coords.length - 1]

let distance = 35
const firstOffset = calculateOffset(coords[0], coords[1], distance)
// adding this so that the button is not on top of the measure line label
if (selectedFeatureType.value === 'MEASURE') {
distance = distance + 40
}
const lastOffset = calculateOffset(
coords[coords.length - 1],
coords[coords.length - 2],
distance
)

if (firstButtonOverlay.value) {
firstButtonOverlay.value.setPosition(firstButtonCoordinate.value)
firstButtonOverlay.value.setOffset(firstOffset)
}
if (lastButtonOverlay.value) {
lastButtonOverlay.value.setPosition(lastButtonCoordinate.value)
lastButtonOverlay.value.setOffset(lastOffset)
}
}

const onFirstButtonMounted = (buttonElement) => {
firstButtonOverlay.value = new Overlay({
element: buttonElement,
positioning: 'center-center',
stopEvent: true,
})
olMap.addOverlay(firstButtonOverlay.value)
updateButtonPositions()
}

const onLastButtonMounted = (buttonElement) => {
lastButtonOverlay.value = new Overlay({
element: buttonElement,
positioning: 'center-center',
stopEvent: true,
})
olMap.addOverlay(lastButtonOverlay.value)
updateButtonPositions()
}

watch(coordinates, updateButtonPositions)

onMounted(() => {
updateButtonPositions()
})

onUnmounted(() => {
if (firstButtonOverlay.value) {
olMap.removeOverlay(firstButtonOverlay.value)
}
if (lastButtonOverlay.value) {
olMap.removeOverlay(lastButtonOverlay.value)
}
})
</script>

<template>
<AddVertexButton :reverse="true" @button-mounted="onFirstButtonMounted" />
<AddVertexButton :reverse="false" @button-mounted="onLastButtonMounted" />
</template>
Loading
Loading