app/javascript/vue/components/Form/FormCollectingEvent/components/map/Depictions.vue
<template>
<div class="full_width">
<Dropzone
class="dropzone-card"
@vdropzone-sending="sending"
@vdropzone-file-added="addedfile"
@vdropzone-success="success"
@vdropzone-error="error"
ref="depictionRef"
:id="`depiction-${dropzoneId}`"
url="/depictions"
:use-custom-dropzone-options="true"
:dropzone-options="dropzone"
/>
<div
class="flex-wrap-row"
v-if="figuresList.length"
>
<DepictionImage
v-for="item in figuresList"
@delete="removeDepiction"
:key="item.id"
:depiction="item"
/>
</div>
<table class="full_width">
<thead>
<tr>
<th>
<input
v-model="setAutogeo"
type="checkbox"
/>
</th>
<th>Latitude</th>
<th>Longitude</th>
</tr>
</thead>
<tbody>
<tr v-for="item in coordinatesEXIF">
<td>
<input
v-model="queueGeoreferences"
:value="item"
type="checkbox"
/>
</td>
<td>{{ parseGeoJson(item).latitude }}</td>
<td>{{ parseGeoJson(item).longitude }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue'
import { Depiction } from '@/routes/endpoints'
import { GEOREFERENCE_EXIF, COLLECTING_EVENT } from '@/constants/index.js'
import Dropzone from '@/components/dropzone.vue'
import ParseDMS from '@/helpers/parseDMS.js'
import addGeoreference from '../../helpers/addGeoreference.js'
import createGeoJSONFeature from '../../helpers/createGeoJSONFeature.js'
import DepictionImage from './depictionImage'
import EXIF from 'exif-js'
import useStore from '../../store/georeferences.js'
const store = useStore()
const collectingEvent = defineModel()
const emit = defineEmits(['create', 'delete'])
const setAutogeo = computed({
get() {
return autogeo.value
},
set(value) {
if (value) {
coordinatesEXIF.value.forEach((item) => {
const found = store.queueGeoreferences.find(
(geo) => geo.tmpId === item.tmpId
)
if (!found) {
store.queueGeoreferences.push(item)
}
})
} else {
coordinatesEXIF.value.forEach((item) => {
const index = store.queueGeoreferences.findIndex(
(geo) => geo.tmpId === item.tmpId
)
if (index > -1) {
store.queueGeoreferences.splice(index, 1)
}
})
}
autogeo.value = value
}
})
const autogeo = ref(true)
const depictionRef = ref(null)
const figuresList = ref([])
const dropzoneId = Math.random().toString(36).substr(2, 5)
const dropzone = {
paramName: 'depiction[image_attributes][image_file]',
url: '/depictions',
autoProcessQueue: false,
headers: {
'X-CSRF-Token': document
.querySelector('meta[name="csrf-token"]')
.getAttribute('content')
},
dictDefaultMessage: 'Drop image or click to browse',
acceptedFiles: 'image/*,.heic'
}
const coordinatesEXIF = ref([])
watch(collectingEvent, (newVal, oldVal) => {
if (newVal.id && newVal.id !== oldVal.id) {
depictionRef.value.setOption('autoProcessQueue', true)
depictionRef.value.processQueue()
coordinatesEXIF.value = []
Depiction.where({
depiction_object_id: newVal.id,
depiction_object_type: COLLECTING_EVENT
})
.then((response) => {
figuresList.value = response.body
})
.catch(() => {})
} else {
if (!newVal.id) {
figuresList.value = []
coordinatesEXIF.value = []
depictionRef.value.setOption('autoProcessQueue', false)
}
}
})
watch(
store.queueGeoreferences,
(newVal, oldVal) => {
if (collectingEvent.value.id) {
const removed = oldVal.filter(
(val) => newVal.findIndex((v) => v.tmpId === val.tmpId) === -1
)
removed.forEach((item) => {
const index = coordinatesEXIF.value.findIndex(
(v) => v.tmpId === item.tmpId
)
if (index > -1) {
coordinatesEXIF.value.splice(index, 1)
}
})
}
},
{ deep: true }
)
function success(file, response) {
figuresList.value.push(response)
depictionRef.value.removeFile(file)
emit('create', response)
}
function sending(file, xhr, formData) {
formData.append('depiction[depiction_object_id]', collectingEvent.value.id)
formData.append('depiction[depiction_object_type]', 'CollectingEvent')
}
function addedfile(file) {
EXIF.getData(file, () => {
const allMetaData = EXIF.getAllTags(file)
if (allMetaData?.GPSLatitude) {
const coordinates = {
latitude: ParseDMS(
parseEXIFCoordinate(allMetaData.GPSLatitude) +
allMetaData.GPSLatitudeRef
),
longitude: ParseDMS(
parseEXIFCoordinate(allMetaData.GPSLongitude) +
allMetaData.GPSLongitudeRef
)
}
const geojson = addGeoreference(
createGeoJSONFeature(coordinates.longitude, coordinates.latitude),
GEOREFERENCE_EXIF
)
coordinatesEXIF.value.push(geojson)
if (autogeo.value) {
store.queueGeoreferences.push(geojson)
}
setExifCoordinates(coordinates)
}
if (allMetaData?.DateTimeOriginal) {
let [date, time] = allMetaData.DateTimeOriginal.split(' ')
date = date.split(':')
time = time.split(':')
setExitDate(date)
setExifTime(time)
}
})
if (collectingEvent.value.id) {
depictionRef.value.setOption('autoProcessQueue', true)
depictionRef.value.processQueue()
}
}
function removeDepiction(depiction) {
if (window.confirm('Are you sure want to proceed?')) {
Depiction.destroy(depiction.id).then((_) => {
TW.workbench.alert.create('Depiction was successfully deleted.', 'notice')
figuresList.value.splice(
figuresList.value.findIndex((figure) => figure.id === depiction.id),
1
)
emit('delete', depiction)
})
}
}
function error(event) {
TW.workbench.alert.create(
`There was an error uploading the image: ${event.xhr.responseText}`,
'error'
)
}
function parseEXIFCoordinate(GPSCoordinate) {
return `${GPSCoordinate[0]}° ${GPSCoordinate[1]}' ${GPSCoordinate[2]}"`
}
function parseGeoJson(georeference) {
const shape = JSON.parse(georeference.geographic_item_attributes.shape)
const [latitude, longitude] = shape.geometry.coordinates
return {
longitude,
latitude
}
}
function setExitDate(date) {
if (
!(
collectingEvent.value.start_date_day ||
collectingEvent.value.start_date_month ||
collectingEvent.value.start_date_year
)
) {
collectingEvent.value.start_date_day = date[2]
collectingEvent.value.start_date_month = date[1]
collectingEvent.value.start_date_year = date[0]
}
}
function setExifTime(time) {
if (
!(
collectingEvent.value.time_start_hour ||
collectingEvent.value.time_start_minute ||
collectingEvent.value.time_start_second
)
) {
collectingEvent.value.time_start_second = time[2]
collectingEvent.value.time_start_minute = time[1]
collectingEvent.value.time_start_hour = time[0]
}
}
function setExifCoordinates(coordinates) {
if (
!(
collectingEvent.value.verbatim_latitude ||
collectingEvent.value.verbatim_latitude
)
) {
collectingEvent.value.verbatim_latitude = coordinates.latitude
collectingEvent.value.verbatim_longitude = coordinates.longitude
}
}
</script>