Mercurial > gemma
changeset 719:d1b60ad2f50d octree
Merged default into octree branch.
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Fri, 21 Sep 2018 16:29:38 +0200 |
parents | c0bba602b60e (current diff) bb0788567609 (diff) |
children | aeaa2adf5a8b |
files | |
diffstat | 17 files changed, 307 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/client/package.json Fri Sep 21 14:47:44 2018 +0200 +++ b/client/package.json Fri Sep 21 16:29:38 2018 +0200 @@ -25,6 +25,7 @@ "purgecss-webpack-plugin": "^1.2.1", "v-tooltip": "^2.0.0-rc.33", "vue": "^2.5.16", + "vue-highlightjs": "^1.3.3", "vue-router": "^3.0.1", "vuex": "^3.0.1" },
--- a/client/src/App.vue Fri Sep 21 14:47:44 2018 +0200 +++ b/client/src/App.vue Fri Sep 21 16:29:38 2018 +0200 @@ -17,7 +17,7 @@ </div> <div class="bottomcontainer d-flex flex-row align-items-end"> <Userbar></Userbar> - <Linetool v-if="routeName != 'usermanagement'"></Linetool> + <Linetool v-if="routeName == 'mainview'"></Linetool> </div> </div> <div class="d-flex flex-column">
--- a/client/src/application/Main.vue Fri Sep 21 14:47:44 2018 +0200 +++ b/client/src/application/Main.vue Fri Sep 21 16:29:38 2018 +0200 @@ -71,6 +71,9 @@ }, updated() { if (!document.querySelector(".profile")) return; + const clientHeight = document.querySelector(".profile").clientHeight; + const clientWidth = document.querySelector(".profile").clientWidth; + if (!clientHeight || !clientWidth) return; this.height = document.querySelector(".profile").clientHeight - 25; this.width = document.querySelector(".profile").clientWidth - 100; },
--- a/client/src/application/Sidebar.vue Fri Sep 21 14:47:44 2018 +0200 +++ b/client/src/application/Sidebar.vue Fri Sep 21 16:29:38 2018 +0200 @@ -10,6 +10,9 @@ <router-link class="text-body d-flex flex-row nav-link" to="usermanagement"> <i class="fa fa-address-card-o align-self-center navicon"></i>Users </router-link> + <router-link class="text-body d-flex flex-row nav-link" to="logs"> + <i class="fa fa-book align-self-center navicon"></i>Systeminformation + </router-link> </div> </div> </div>
--- a/client/src/application/Topbar.vue Fri Sep 21 14:47:44 2018 +0200 +++ b/client/src/application/Topbar.vue Fri Sep 21 16:29:38 2018 +0200 @@ -3,7 +3,7 @@ <div @click="toggleSidebar"> <i class="ui-element menubutton fa fa-bars"></i> </div> - <div v-if="routeName != 'usermanagement'" :class="searchbarContainerStyle"> + <div v-if="routeName == 'mainview'" :class="searchbarContainerStyle"> <div class="input-group-prepend shadow"> <span @click="toggleSearchbar" class="ui-element input-group-text searchlabel" for="search"> <i class="fa fa-search"></i> @@ -11,11 +11,11 @@ </div> <input v-if="!searchbarCollapsed" id="search" type="text" class="form-control ui-element search searchbar"> </div> - <div v-if="routeName != 'usermanagement'" class="splitbutton"> + <div v-if="routeName == 'mainview'" class="splitbutton"> <i @click="splitScreen" class="ui-element splitscreen fa fa-window-restore shadow"></i> </div> <div class=""> - <Layers v-if="routeName != 'usermanagement'"></Layers> + <Layers v-if="routeName == 'mainview'"></Layers> </div> </div> </template> @@ -92,7 +92,7 @@ }, data() { return { - searchbarCollapsed: false + searchbarCollapsed: true }; }, computed: {
--- a/client/src/application/assets/application.scss Fri Sep 21 14:47:44 2018 +0200 +++ b/client/src/application/assets/application.scss Fri Sep 21 16:29:38 2018 +0200 @@ -1,23 +1,23 @@ -$offset: 1rem; -$small-offset: 0.5rem; -$x-small-offset: 0.25rem; +$basic-shadow-light: 1px 1px 12px 1px rgba(235, 235, 235, 0.75); +$basic-shadow: 1px 3px 8px 2px rgba(220, 220, 220, 0.75); +$border-radius: 5px; +$icon-height: 2rem; +$icon-width: 2rem; $large-offset: 2rem; -$x-large-offset: 3rem; -$basic-shadow: 1px 3px 8px 2px rgba(220, 220, 220, 0.75); -$basic-shadow-light: 1px 1px 12px 1px rgba(235, 235, 235, 0.75); -$transition: 0.5s; +$layerselect-height: 20rem; +$layerselect-width: 20rem; +$offset: 1rem; +$searchbar-width: 50vw; +$sidebar-height: 16rem; +$sidebar-width: 15rem; +$slight-transparent: 0.96; +$small-offset: 0.5rem; +$smaller: 0.9rem; $transition-fast: 0.3s; $transition-slow: 3s; -$smaller: 0.9rem; -$border-radius: 5px; -$sidebar-width: 15rem; -$sidebar-height: 13rem; -$icon-height: 2rem; -$icon-width: 2rem; -$layerselect-height: 20rem; -$layerselect-width: 20rem; -$slight-transparent: 0.96; -$searchbar-width: 50vw; +$transition: 0.5s; +$x-large-offset: 3rem; +$x-small-offset: 0.25rem; .debug { border: 1px solid red;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/logs/logs.vue Fri Sep 21 16:29:38 2018 +0200 @@ -0,0 +1,186 @@ +<template> + <div class="main d-flex flex-column"> + <div class="d-flex flex-row"> + <div :class="spacer"></div> + <div class="logoutput shadow"> + <pre v-highlightjs="logs"><code class="javascript"></code></pre> + </div> + </div> + </div> +</template> + +<style scoped lang="scss"> +.logoutput { + width: 95%; + height: 85vh; + margin-top: $offset; + margin-right: $offset; + margin-left: $offset; + text-align: left; + background-color: white; + overflow: scroll; + transition: $transition-fast; +} + +.spacer { + margin-left: $offset; + height: 90vh; +} + +.spacer-collapsed { + min-width: $icon-width + $offset; + transition: $transition-fast; +} + +.spacer-expanded { + min-width: $sidebar-width + $offset; +} +</style> + +<script> +import { mapGetters } from "vuex"; + +export default { + name: "logs", + data() { + return { + logs: `gemma ❯ ./run-app.sh +2018/09/21 11:13:37 Configure GeoServer... +2018/09/21 11:13:37 listen on localhost:8000 +2018/09/21 11:13:37 info: creating workspace gemma +2018/09/21 11:13:38 info: creating datastore gemma +2018/09/21 11:13:38 info: number of tables to publish 2 +2018/09/21 11:13:38 info: creating featuretype distance_marks_geoserver. +2018/09/21 11:13:39 warn: configure GeoServer failed: Status code 'Internal Server Error' (500) +2018/09/21 11:48:22 Injecting user sophie +2018/09/21 11:48:22 proxyDirector: /api/internal/wfs +2018/09/21 11:48:22 proxyDirector: /api/external/d4d +2018/09/21 11:48:22 proxyDirector: /api/external/d4d +2018/09/21 11:48:22 Injecting user sophie +2018/09/21 11:48:22 proxyDirector: /api/internal/wfs +2018/09/21 11:48:25 gzip compression +2018/09/21 11:48:25 rewrite successful +2018/09/21 11:48:25 rewrite took 25.603973ms +2018/09/21 11:48:27 gzip compression +2018/09/21 11:48:27 rewrite successful +2018/09/21 11:48:27 rewrite took 1.039415ms +2018/09/21 11:48:52 Injecting user sophie +2018/09/21 11:48:52 proxyDirector: /api/internal/wfs +2018/09/21 11:48:52 proxyDirector: /api/external/d4d +2018/09/21 11:48:53 gzip compression +2018/09/21 11:48:53 rewrite successful +2018/09/21 11:48:53 rewrite took 1.039695ms +2018/09/21 11:48:53 proxyDirector: /api/external/d4d +2018/09/21 11:48:53 Injecting user sophie +2018/09/21 11:48:53 proxyDirector: /api/internal/wfs +2018/09/21 11:48:53 gzip compression +2018/09/21 11:48:53 rewrite successful +2018/09/21 11:48:53 rewrite took 16.220881ms +2018/09/21 11:49:05 Injecting user sophie +2018/09/21 11:49:05 proxyDirector: /api/internal/wfs +2018/09/21 11:49:05 proxyDirector: /api/external/d4d +2018/09/21 11:49:05 gzip compression +2018/09/21 11:49:05 rewrite successful +2018/09/21 11:49:05 rewrite took 973.896µs +2018/09/21 11:49:05 Injecting user sophie +2018/09/21 11:49:05 proxyDirector: /api/internal/wfs +2018/09/21 11:49:05 gzip compression +2018/09/21 11:49:05 rewrite successful +2018/09/21 11:49:05 rewrite took 1.396081ms +2018/09/21 11:49:38 Injecting user sophie +2018/09/21 11:49:38 proxyDirector: /api/internal/wfs +2018/09/21 11:49:38 proxyDirector: /api/external/d4d +2018/09/21 11:49:38 gzip compression +2018/09/21 11:49:38 rewrite successful +2018/09/21 11:49:38 rewrite took 853.268µs +2018/09/21 11:49:38 proxyDirector: /api/external/d4d +2018/09/21 11:49:38 Injecting user sophie +2018/09/21 11:49:38 proxyDirector: /api/internal/wfs +2018/09/21 11:49:38 gzip compression +2018/09/21 11:49:38 rewrite successful +2018/09/21 11:49:38 rewrite took 5.146315ms +2018/09/21 11:50:38 Injecting user sophie +2018/09/21 11:50:38 proxyDirector: /api/internal/wfs +2018/09/21 11:50:38 proxyDirector: /api/external/d4d +2018/09/21 11:50:38 gzip compression +2018/09/21 11:50:38 rewrite successful +2018/09/21 11:50:38 rewrite took 1.221311ms +2018/09/21 11:50:38 Injecting user sophie +2018/09/21 11:50:38 proxyDirector: /api/internal/wfs +2018/09/21 11:50:38 proxyDirector: /api/external/d4d +2018/09/21 11:50:38 gzip compression +2018/09/21 11:50:38 rewrite successful +2018/09/21 11:50:38 rewrite took 1.427937ms +2018/09/21 11:51:06 proxyDirector: /api/external/d4d +2018/09/21 11:51:06 Injecting user sophie +2018/09/21 11:51:06 proxyDirector: /api/internal/wfs +2018/09/21 11:51:06 gzip compression +2018/09/21 11:51:06 rewrite successful +2018/09/21 11:51:06 rewrite took 8.170505ms +2018/09/21 11:51:17 Injecting user sophie +2018/09/21 11:51:17 proxyDirector: /api/internal/wfs +2018/09/21 11:51:17 proxyDirector: /api/external/d4d +2018/09/21 11:51:17 gzip compression +2018/09/21 11:51:17 rewrite successful +2018/09/21 11:51:17 rewrite took 1.222553ms +2018/09/21 11:51:17 Injecting user sophie +2018/09/21 11:51:17 proxyDirector: /api/internal/wfs +2018/09/21 11:51:17 gzip compression +2018/09/21 11:51:17 rewrite successful +2018/09/21 11:51:17 rewrite took 2.78996ms +2018/09/21 11:51:34 proxyDirector: /api/external/d4d +2018/09/21 11:51:34 Injecting user sophie +2018/09/21 11:51:34 proxyDirector: /api/internal/wfs +2018/09/21 11:51:34 gzip compression +2018/09/21 11:51:34 rewrite successful +2018/09/21 11:51:34 rewrite took 1.33321ms +2018/09/21 11:51:34 proxyDirector: /api/external/d4d +2018/09/21 11:51:34 Injecting user sophie +2018/09/21 11:51:34 proxyDirector: /api/internal/wfs +2018/09/21 11:51:34 gzip compression +2018/09/21 11:51:34 rewrite successful +2018/09/21 11:51:34 rewrite took 3.687839ms +2018/09/21 11:52:08 Injecting user sophie +2018/09/21 11:52:08 proxyDirector: /api/internal/wfs +2018/09/21 11:52:08 proxyDirector: /api/external/d4d +2018/09/21 11:52:08 gzip compression +2018/09/21 11:52:08 rewrite successful +2018/09/21 11:52:08 rewrite took 1.26564ms +2018/09/21 11:52:08 proxyDirector: /api/external/d4d +2018/09/21 11:52:08 Injecting user sophie +2018/09/21 11:52:08 proxyDirector: /api/internal/wfs +2018/09/21 11:52:08 gzip compression +2018/09/21 11:52:08 rewrite successful +2018/09/21 11:52:08 rewrite took 1.024643ms +2018/09/21 11:54:23 Injecting user sophie +2018/09/21 11:54:23 proxyDirector: /api/internal/wfs +2018/09/21 11:54:23 proxyDirector: /api/external/d4d +2018/09/21 11:54:23 gzip compression +2018/09/21 11:54:23 rewrite successful +2018/09/21 11:54:23 rewrite took 1.162201ms +2018/09/21 11:54:23 proxyDirector: /api/external/d4d +2018/09/21 11:54:23 Injecting user sophie +2018/09/21 11:54:23 proxyDirector: /api/internal/wfs +2018/09/21 11:54:23 gzip compression +2018/09/21 11:54:23 rewrite successful +2018/09/21 11:54:23 rewrite took 990.32µs +` + }; + }, + methods: { + disallow(e) { + e.target.blur(); + } + }, + computed: { + ...mapGetters("application", ["sidebarCollapsed", "isUsermenuCollapsed"]), + spacer() { + return { + spacer: true, + "spacer-expanded": !this.sidebarCollapsed, + "spacer-collapsed": this.sidebarCollapsed + }; + } + } +}; +</script>
--- a/client/src/main.js Fri Sep 21 14:47:44 2018 +0200 +++ b/client/src/main.js Fri Sep 21 16:29:38 2018 +0200 @@ -11,7 +11,10 @@ import "../node_modules/animate.css/animate.min.css"; import "../node_modules/ol/ol.css"; import "../node_modules/cxlt-vue2-toastr/dist/css/cxlt-vue2-toastr.css"; +import "../node_modules/highlight.js/styles/paraiso-dark.css"; import VTooltip from "v-tooltip"; +import VueHighlightJS from "vue-highlightjs"; +Vue.use(VueHighlightJS); Vue.use(VTooltip);
--- a/client/src/map/Maplayer.vue Fri Sep 21 14:47:44 2018 +0200 +++ b/client/src/map/Maplayer.vue Fri Sep 21 16:29:38 2018 +0200 @@ -14,14 +14,18 @@ <script> import { HTTP } from "../application/lib/http"; +import { mapGetters } from "vuex"; import "ol/ol.css"; +// openlayers imports, sorted by module name import { Map, View } from "ol"; -import { bbox as bboxFilter } from "ol/format/filter.js"; +import Feature from "ol/Feature"; +// import { bbox as bboxFilter } from "ol/format/filter.js"; import { WFS, GeoJSON } from "ol/format.js"; -import { mapGetters } from "vuex"; +import GeometryType from "ol/geom/GeometryType.js"; +import LineString from "ol/geom/LineString.js"; import Draw from "ol/interaction/Draw.js"; +import { Vector as VectorLayer } from "ol/layer.js"; import { Vector as VectorSource } from "ol/source.js"; -import { Vector as VectorLayer } from "ol/layer.js"; export default { name: "maplayer", @@ -65,20 +69,45 @@ }, createInteraction() { var that = this; - this.vectorSource.clear(); // start empty + this.vectorSource.clear(); // start empty var draw = new Draw({ source: this.vectorSource, type: this.drawMode }); draw.on("drawstart", function(event) { console.log(event); - that.vectorSource.clear(); // remove old features when draw starts + that.vectorSource.clear(); // remove old features when draw starts }); draw.on("drawend", this.drawEnd); return draw; }, drawEnd(event) { console.log(event); + var inputLineString = event.feature.getGeometry().clone(); + if (inputLineString.getType() == GeometryType.LINE_STRING) { + // prepare to send the first line seqment to the server as GeoJSON + inputLineString.transform("EPSG:3857", "EPSG:4326"); + var coords = inputLineString.getCoordinates(); + if (coords.length >= 2) { + var feature = new Feature({ + geometry: new LineString([coords[0], coords[1]]), + // FIXME: hardcoded bottleneck and survey date + bottleneck: "AT_Bottleneck_44", + date: "2017-11-20" + }); + var gStr = new GeoJSON({ geometryName: "geometry" }).writeFeature( + feature + ); + console.log("Ready to start profile view with: ", feature, gStr); + + // FIXME: assuming that we have the fairway dimensions loaded + var vectorSource = this.getLayerByName( + "Fairway Dimensions" + ).data.getSource(); + console.log(vectorSource); + // vectorSource.forEachFeatureIntersectingExtent() + } + } }, activateInteraction() { const interaction = this.createInteraction(this.drawMode); @@ -121,11 +150,19 @@ ); // DEBUG console.log("loaded ", features, "for", vectorSource); // eslint-disable-next-line - }).catch(error => { + }) + .catch(() => { vectorSource.removeLoadedExtent(extent); }); }; return loader; + }, + getLayerByName(name) { + for (let layer of this.layers) { + if (layer.name === name) { + return layer; + } + } } }, watch: { @@ -226,9 +263,9 @@ var featureRequestOptions5 = { featurePrefix: "ws-wamos", featureTypes: ["ienc_dismar"], - geometryName: "geom", + geometryName: "geom" //, /* restrict loading approximately to extend of danube in Austria */ - filter: bboxFilter("geom", [13.3, 48.0, 17.1, 48.6], "EPSG:4326") + // filter: bboxFilter("geom", [13.3, 48.0, 17.1, 48.6], "EPSG:4326") }; this.layers[5].data
--- a/client/src/map/store.js Fri Sep 21 14:47:44 2018 +0200 +++ b/client/src/map/store.js Fri Sep 21 16:29:38 2018 +0200 @@ -30,7 +30,7 @@ isVisible: true }, { - name: "Fairways Dimensions", + name: "Fairway Dimensions", data: new VectorLayer({ source: new VectorSource(), style: function(feature) {
--- a/client/src/router.js Fri Sep 21 14:47:44 2018 +0200 +++ b/client/src/router.js Fri Sep 21 16:29:38 2018 +0200 @@ -10,6 +10,7 @@ const Login = () => import("./login/Login.vue"); const Main = () => import("./application/Main.vue"); const Usermanagement = () => import("./usermanagement/Usermanagement.vue"); +const Logs = () => import("./logs/logs.vue"); Vue.use(Router); @@ -37,6 +38,22 @@ } }, { + path: "/logs", + name: "logs", + component: Logs, + meta: { + requiresAuth: true + }, + beforeEnter: (to, from, next) => { + const isSysadmin = store.getters["user/isSysAdmin"]; + if (!isSysadmin) { + next("/"); + } else { + next(); + } + } + }, + { path: "/", name: "mainview", component: Main,
--- a/client/src/usermanagement/Usermanagement.vue Fri Sep 21 14:47:44 2018 +0200 +++ b/client/src/usermanagement/Usermanagement.vue Fri Sep 21 16:29:38 2018 +0200 @@ -70,7 +70,7 @@ </div> </template> -<style lang="scss"> +<style scoped lang="scss"> @import "../application/assets/tooltip.scss"; .spacer { @@ -80,6 +80,7 @@ .spacer-collapsed { min-width: $icon-width + $offset; + transition: $transition-fast; } @media screen and (min-width: 600px) {
--- a/client/yarn.lock Fri Sep 21 14:47:44 2018 +0200 +++ b/client/yarn.lock Fri Sep 21 16:29:38 2018 +0200 @@ -4387,6 +4387,10 @@ version "1.1.0" resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" +highlight.js@*: + version "9.12.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -9213,6 +9217,12 @@ version "2.1.0" resolved "https://registry.yarnpkg.com/vue-gettext/-/vue-gettext-2.1.0.tgz#e4932037a8601412dd9f7d7d7a5d60c4bdb341d1" +vue-highlightjs@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/vue-highlightjs/-/vue-highlightjs-1.3.3.tgz#29a0d57132fc1ce15cfa61e896918f5b718c5d52" + dependencies: + highlight.js "*" + vue-hot-reload-api@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.0.tgz#97976142405d13d8efae154749e88c4e358cf926"
--- a/docker/Dockerfile.spa Fri Sep 21 14:47:44 2018 +0200 +++ b/docker/Dockerfile.spa Fri Sep 21 16:29:38 2018 +0200 @@ -4,7 +4,7 @@ RUN sed -i 's/\(deb.*\)$/\1 universe/' /etc/apt/sources.list RUN apt-get update &&\ - apt-get -y install --no-install-recommends curl nodejs make + apt-get -y install --no-install-recommends curl gnupg nodejs make # Install yarn RUN curl https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - &&\
--- a/docker/README.md Fri Sep 21 14:47:44 2018 +0200 +++ b/docker/README.md Fri Sep 21 16:29:38 2018 +0200 @@ -6,6 +6,13 @@ Other example commands, too, assume they are run from the root of your checkout. +## Network setup + +- Create a network to connect containers: + ``` + docker network create gemma + ``` + ## Database setup - Build Dockerfile with e.g.: @@ -16,8 +23,9 @@ - Get a running instance with e.g.: ``` docker run --name gemma_db -d -p 54321:5432 -v $PWD/schema:/opt/gemma \ - gemma_db + --network gemma gemma_db ``` + Use `--network-alias gemma_db` if your container has a different name - Run tests for RLS policies: ``` @@ -39,19 +47,6 @@ Omit the `-s` option to get a diagram with all tables or use any other schema name to see other parts of the whole picture. -## Network setup - -- Create a network to connect containers: - ``` - docker network create gemma - ``` - -- Connect database to new network - ``` - docker network connect gemma gemma_db - ``` - Use `--alias gemma_db` if your container has a different name - ## GeoServer setup - Build Dockerfile with e.g.:
--- a/pkg/controllers/cross.go Fri Sep 21 14:47:44 2018 +0200 +++ b/pkg/controllers/cross.go Fri Sep 21 16:29:38 2018 +0200 @@ -11,13 +11,13 @@ const crossSQL = ` WITH line AS ( -SELECT ST_3DIntersection( +SELECT ST_LineMerge(ST_Union(ST_3DIntersection( ST_Translate( ST_Extrude( ST_GeomFromWKB($1, 4326), 0, 0, 1000), 0, 0, -500), - geom) AS geom + geom))) AS geom FROM waterway.meshes m JOIN waterway.sounding_results sr ON m.sounding_result_id = sr.id WHERE ST_Intersects(geom, ST_GeomFromWKB($1, 4326)) AND sr.bottleneck_id = $2 AND sr.date_info = $3
--- a/pkg/controllers/routes.go Fri Sep 21 14:47:44 2018 +0200 +++ b/pkg/controllers/routes.go Fri Sep 21 16:29:38 2018 +0200 @@ -47,10 +47,12 @@ api.Handle("/users/passwordreset", &JSONHandler{ Input: func() interface{} { return new(models.PWResetUser) }, Handle: passwordResetRequest, + NoConn: true, }).Methods(http.MethodPost) api.Handle("/users/passwordreset/{hash}", &JSONHandler{ Handle: passwordReset, + NoConn: true, }).Methods(http.MethodGet) // External proxies.