diff --git a/lib/www/client/source/src/lib/utils.js b/lib/www/client/source/src/lib/utils.js index 9432880..8ff901a 100644 --- a/lib/www/client/source/src/lib/utils.js +++ b/lib/www/client/source/src/lib/utils.js @@ -26,4 +26,70 @@ function withParentProps(item, parent, childrenKey, prop, currentValue) { return []; } -export { withParentProps } +function dms (lat, lon) { + const λh = lat < 0 ? "S" : "N"; + const φh = lon < 0 ? "W" : "E"; + + const λn = Math.abs(lat); + const φn = Math.abs(lon); + + const λi = Math.trunc(λn); + const φi = Math.trunc(φn); + + const λf = λn - λi; + const φf = φn - φi; + + const λs = ((λf*3600)%60).toFixed(1); + const φs = ((φf*3600)%60).toFixed(1); + + const λm = Math.trunc(λf*60); + const φm = Math.trunc(φf*60); + + const λ = + String(λi).padStart(2, "0") + "°" + + String(λm).padStart(2, "0") + "'" + + String(λs).padStart(4, "0") + '" ' + + λh; + + const φ = + String(φi).padStart(3, "0") + "°" + + String(φm).padStart(2, "0") + "'" + + String(φs).padStart(4, "0") + '" ' + + φh; + + return λ+" "+φ; +} + +function geometryAsString (item, opts = {}) { + const key = "key" in opts ? opts.key : "geometry"; + const formatDMS = opts.dms; + + let str = ""; + + if (key in item) { + const geometry = item[key]; + if ("coordinates" in geometry) { + if (geometry.type == "Point") { + if (formatDMS) { + str = dms(geometry.coordinates[1], geometry.coordinates[0]); + } else { + str = `${geometry.coordinates[1].toFixed(6)}, ${geometry.coordinates[0].toFixed(6)}`; + } + } + + if (str) { + if (opts.url) { + if (typeof opts.url === 'string') { + str = `[${str}](${opts.url.replace("$x", geometry.coordinates[0]).replace("$y", geometry.coordinates[1])})`; + } else { + str = `[${str}](geo:${geometry.coordinates[0]},${geometry.coordinates[1]})`; + } + } + } + } + } + + return str; +} + +export { withParentProps, geometryAsString } diff --git a/lib/www/client/source/src/main.js b/lib/www/client/source/src/main.js index 893d3de..ab80b5d 100644 --- a/lib/www/client/source/src/main.js +++ b/lib/www/client/source/src/main.js @@ -6,6 +6,7 @@ import vuetify from './plugins/vuetify' import vueDebounce from 'vue-debounce' import { mapMutations } from 'vuex'; import { markdown, markdownInline } from './lib/markdown'; +import { geometryAsString } from './lib/utils'; Vue.config.productionTip = false @@ -13,7 +14,12 @@ Vue.use(vueDebounce); Vue.filter('markdown', markdown); Vue.filter('markdownInline', markdownInline); - +Vue.filter('position', (str, item, opts) => + str + .replace(/@POS(ITION)?@/g, geometryAsString(item, opts)) + .replace(/@DMS@/g, geometryAsString(item, {...opts, dms:true})) +); +// Vue.filter('position', (str, item, opts) => str.replace(/@POS(ITION)?@/, "☺")); new Vue({ data () { diff --git a/lib/www/client/source/src/views/Log.vue b/lib/www/client/source/src/views/Log.vue index a249f84..56a7027 100644 --- a/lib/www/client/source/src/views/Log.vue +++ b/lib/www/client/source/src/views/Log.vue @@ -573,6 +573,11 @@ export default { const promises = []; for (const editedItem of this.editedRow.items) { + + // Process special text in remarks + if (editedItem.remarks) { + editedItem.remarks = this.$options.filters.position(editedItem.remarks, editedItem); + } // Discard non user writable labels editedItem.labels = editedItem.labels.filter(l => this.labels[l].model.user);