Mercurial > gemma
view client/src/components/identify/Identify.vue @ 3044:c71373594719
client: map: prepared store to hold multiple map objects
This will be necessary to sync maps, toggle layers per map, etc. Therefore the methods to move the map
(moveToExtent, etc.) became actions instead of mutations.
author | Markus Kottlaender <markus@intevation.de> |
---|---|
date | Sat, 13 Apr 2019 16:02:06 +0200 |
parents | 81c2e561fe03 |
children | 5487abeb380c |
line wrap: on
line source
<template> <div :class="[ 'box ui-element rounded bg-white text-nowrap', { expanded: showIdentify } ]" > <div style="width: 18rem"> <UIBoxHeader icon="info" :title="identifiedLabel" :closeCallback="close" /> <div class="features"> <div v-if="currentMeasurement"> <small class="d-block bg-secondary text-light px-2 py-1"> {{ $gettext("Measurement") }} </small> <small class="d-flex justify-content-between px-2"> <b> {{ currentMeasurement.quantity }} </b> {{ currentMeasurement.value }} {{ currentMeasurement.unitSymbol }} </small> </div> <div v-for="feature of filteredIdentifiedFeatures" :key="feature.getId()" > <small class="d-flex justify-content-between bg-secondary text-light px-2 py-1" > {{ $gettext(featureLabel(feature)) }} <a v-if="feature.getProperties().hasOwnProperty('bbox')" @click="zoomTo(feature)" class="btn btn-info btn-xs pointer rounded-0 zoom-btn" > <font-awesome-icon icon="crosshairs" /> </a> </small> <small v-for="prop in featureProps(feature)" :key="prop.key" v-if="prop.val" class="d-flex justify-content-between px-2" > <b>{{ $gettext(prop.key) }}</b> <span>{{ prop.val }}</span> </small> </div> <div v-if="!currentMeasurement && !filteredIdentifiedFeatures.length" class="text-muted small text-center my-auto py-3 px-2" > <translate>No features identified.</translate> </div> </div> <div class="versioninfo border-top box-body"> <span v-translate="{ license: 'AGPL-3.0-or-later' }"> This app uses <i>gemma</i>, which is Free Software under <br /> %{ license } without warranty, see docs for details. </span> <br /> <a href="https://hg.intevation.de/gemma/file/tip"> <translate>source-code</translate> </a> {{ versionStr }} <br />© via donau. ⓔ Intevation. <br /> <span v-translate="{ name: 'OpenSteetMap' }" >Some data © <a href="https://www.openstreetmap.org/copyright">%{ name }</a> contributors. </span> <br /> <span v-translate="{ geoLicense: 'CC-BY-4.0' }"> Uses <a href="https://download.geonames.org/export/dump/readme.txt" >GeoNames</a > under %{ geoLicense }. </span> <translate>Generated PDFs use font: </translate> <a href="http://libertine-fonts.org">LinBiolinum</a> </div> </div> </div> </template> <style lang="scss" scoped> .features { max-height: 19rem; overflow-y: auto; small { .zoom-btn { margin-top: -0.25rem; margin-right: -0.5rem; margin-bottom: -0.25rem; svg { vertical-align: middle; } } &:nth-child(even) { background: #f8f8f8; } &:hover { background: #eeeeee; } } } .versioninfo { font-size: 60%; white-space: normal; } </style> <script> /* This is Free Software under GNU Affero General Public License v >= 3.0 * without warranty, see README.md and license for details. * * SPDX-License-Identifier: AGPL-3.0-or-later * License-Filename: LICENSES/AGPL-3.0.txt * * Copyright (C) 2018, 2019 by via donau * – Österreichische Wasserstraßen-Gesellschaft mbH * Software engineering by Intevation GmbH * * Author(s): * Thomas Junk <thomas.junk@intevation.de> * Bernhard E. Reiter <bernhard.reiter@intevation.de> * Markus Kottländer <markus.kottlaender@intevation.de> */ import { mapState, mapGetters } from "vuex"; import { formatter } from "./formatter"; import { getCenter } from "ol/extent"; export default { name: "identify", computed: { ...mapGetters("application", ["versionStr"]), ...mapState("application", ["showIdentify"]), ...mapGetters("map", ["filteredIdentifiedFeatures"]), ...mapState("map", ["currentMeasurement"]), identifiedLabel() { return this.$gettext("Identified"); } }, methods: { zoomTo(feature) { this.$store.dispatch("map/moveMap", { coordinates: getCenter( feature .getGeometry() .clone() .transform("EPSG:3857", "EPSG:4326") .getExtent() ), zoom: 17, preventZoomOut: true }); }, close() { this.$store.commit("application/showIdentify", false); }, featureId(feature) { // cut away everything from the last . to the end let id = ""; if (feature.getId) { id = feature.getId(); } if (feature.id) { id = feature.id; } return id.replace(/[.][^.]*$/, ""); }, featureLabel(feature) { if (formatter.hasOwnProperty(this.featureId(feature))) { return formatter[this.featureId(feature)].label; } return this.featureId(feature); }, featureProps(feature) { let featureId = this.featureId(feature); // create array with {key, val} objects let propsArray = []; Object.keys(feature.getProperties()).forEach(key => { // skip geometry (would lead to cyclic object error) if (key !== feature.getGeometryName()) { let val = feature.getProperties()[key]; // if val is a valid json object string, spread its values into the array let jsonObj = this.getObjectFromString(val); if (jsonObj) { Object.keys(jsonObj).forEach(key => { propsArray.push({ key, val: jsonObj[key] }); }); } else { // otherwise just put the key value pair into the array propsArray.push({ key, val }); } } }); // change labels and remove unneeded properties // for all features propsArray = propsArray.map(formatter.all).filter(p => p); // feature specific if ( formatter.hasOwnProperty(featureId) && formatter[featureId].hasOwnProperty("props") ) { propsArray = propsArray.map(formatter[featureId].props).filter(p => p); } // remove underscores in labels that where not previously changed already propsArray = propsArray.map(prop => { return { key: prop.key.replace(/_/g, " "), val: prop.val }; }); return propsArray; }, getObjectFromString(val) { // JSON.parse() accepts integers and null as valid json. So to be sure to // get an object, we cannot just try JSON.parse() but we need to check if // the given value is a string and starts with a {. if ( Object.prototype.toString.call(val) === "[object String]" && val[0] === "{" ) { try { return JSON.parse(val); } catch (e) { return null; } } return null; } } }; </script>