mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 09:47:08 +00:00
Add position filters to Vue.
Given some text and an item containing a Point geometry, the `position` filter replaces occurences of @POS@ or @POSITION@ with the item's geometry (it has to be lat/lon). Occurrences of @DMS@ are replaced with the position in sexagesimal degrees. This can be used anywhere a Vue filter can. However, we have used it in the event comments edit dialogue. The positions are replaced before saving the comment to the database.
This commit is contained in:
@@ -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 }
|
||||
|
||||
@@ -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 () {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user