# HG changeset patch # User Tom Gottfried # Date 1570200004 -7200 # Node ID d2eac69ba86bb9d8a4282a8c5891bd98fe84fa68 # Parent f77a6f9216aedf30811ba62aea15c3a51d40eb45# Parent 7caf620dda50ebf9b5adc33832ccd8d03855a525 Merge default into geoserver_sql_views diff -r f77a6f9216ae -r d2eac69ba86b 3rdpartylibs.sh --- a/3rdpartylibs.sh Fri Sep 20 17:48:47 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -#!/bin/sh - -# pgx hase undergone some major incompatible changes in v4, -# we need to stick to v3 for now... -# Unfortunatly using gopkg.in does not work as expected here, so lets -# get hackisch... -go get -u -v gopkg.in/jackc/pgx.v3 -oldcwd="$CWD" -cd "$GOPATH"/src/github.com/jackc/pgx -git checkout v3.6.0 -cd "$oldcwd" -# MIT - -go get -u -v github.com/etcd-io/bbolt/... -# MIT - -go get -u -v github.com/mitchellh/go-homedir -# MIT - -go get -u -v github.com/spf13/cobra -# Apache-2.0 - -go get -u -v github.com/spf13/viper -# MIT - -go get -u -v github.com/gorilla/mux -# BSD-3-Clause - -go get -u -v gopkg.in/gomail.v2 -# MIT - -go get -u -v github.com/rs/cors -# MIT - -go get -u -v golang.org/x/net/html/charset -# Go License (aka BSD-3-Clause?) - -go get -u -v github.com/golang/snappy -# BSD-3-Clause - -go get -u -v github.com/jonas-p/go-shp -# MIT - -go get -u -v gopkg.in/robfig/cron.v1 -# MIT - -go get -u -v github.com/tidwall/rtree -# MIT - -go get -u -v golang.org/x/sync/semaphore -# Go License (aka BSD-3-Clause?) - -go get -u -v gonum.org/v1/gonum/stat -# BSD-3-Clause - -go get -u -v github.com/sergi/go-diff/diffmatchpatch -# MIT -# Only used in tests. - -# Only needed when generating SVG graphics for debugging. -# go get -u -v github.com/ajstarks/svgo -# Attribution 3.0 United States (CC BY 3.0 US) - -## list of additional licenses that get fetched and installed as dependencies -# github.com/fsnotify/fsnotify/ BSD-3-Clause -# github.com/hashicorp/hcl/ MPL-2.0 -# github.com/magiconair/properties/ BSD-2-Clause -# github.com/mitchellh/go-homedir/ MIT -# github.com/mitchellh/mapstructure MIT -# github.com/pelletier/go-toml/ MIT -# github.com/pkg/errors BSD-2-Clause -# github.com/spf13/afero/ Apache 2.0 -# github.com/spf13/cast MIT -# github.com/spf13/jwalterweatherman MIT -# gopkg.in/yaml.v2/# diff -r f77a6f9216ae -r d2eac69ba86b Makefile --- a/Makefile Fri Sep 20 17:48:47 2019 +0200 +++ b/Makefile Fri Oct 04 16:40:04 2019 +0200 @@ -12,18 +12,14 @@ export BUILDBASE -3rdpartylibs-stamp := $(BUILDBASE)/3rdpartylibs-build - -.PHONY: all 3rdpartylibs gemma client clean +.PHONY: all gemma client clean all: gemma client $(ENVWARPPER): @echo "Preparing go build environment:" + mkdir -p "$(GOPATH)" mkdir -p "$(GOCACHE)" - mkdir -p "$(GOPATH)/src/gemma.intevation.de" - [ -e "$(GOPATH)/src/gemma.intevation.de/gemma" ] || \ - ln -s "$(basedir)" "$(GOPATH)/src/gemma.intevation.de/gemma" @echo "Creating wrapper script:" echo '#!/bin/sh' >"$(ENVWARPPER)" echo 'export GOPATH=$(GOPATH)' >>"$(ENVWARPPER)" @@ -31,14 +27,8 @@ echo 'exec "$$@"' >>"$(ENVWARPPER)" chmod +x "$(ENVWARPPER)" -$(3rdpartylibs-stamp): $(ENVWARPPER) 3rdpartylibs.sh - "$(ENVWARPPER)" bash ./3rdpartylibs.sh && \ - touch $@ - -3rdpartylibs: $(3rdpartylibs-stamp) - -gemma: $(3rdpartylibs-stamp) $(ENVWARPPER) - cd cmd/gemma && "$(ENVWARPPER)" go build +gemma: $(ENVWARPPER) + "$(ENVWARPPER)" go build -o ./cmd/gemma/gemma ./cmd/gemma client: $(MAKE) -f Makefile.build -C client @@ -50,9 +40,10 @@ v="gemma-$$(hg id -i)" ;\ tar --transform "s@^@$${v}/@" \ -cJf "../$${v}.tar.xz" \ - cmd/gemma/gemma schema web misc example_conf.toml + cmd/gemma/gemma schema style-templates web misc example_conf.toml clean: $(MAKE) -f Makefile.build -C client $@ rm -f "$(gemma-bin)" + chmod -R u+w "$(BUILDBASE)" # This is neccessary for deletion to work... rm -rf "$(BUILDBASE)" diff -r f77a6f9216ae -r d2eac69ba86b README.md --- a/README.md Fri Sep 20 17:48:47 2019 +0200 +++ b/README.md Fri Oct 04 16:40:04 2019 +0200 @@ -18,6 +18,9 @@ - To only build the SPA-Client in demo mode you can use `make clientdemo`. +Check [client/README](client/README.md) for details, especially +if you want to do a production setup. + For further details see [docs/DEVELOPMENT](docs/DEVELOPMENT.md). @@ -40,7 +43,8 @@ - You will need a PostgreSQL cluster with PostGIS. -- To install the **gemma** schema and roles use the script +- To install the **gemma** schema, roles and some default system configuration + use the script `./schema/install-db.sh`. - `./schema/install-db.sh --help` shows you available options. @@ -57,7 +61,7 @@ - Install and run GeoServer as described here: http://docs.geoserver.org/stable/en/user/installation/ -- Add tables you want to publish as OGC-Service Layers via GeoServer in +- Add addional tables you want to publish as OGC-Service Layers via GeoServer in the database. For example publish the bottleneck areas: ``` INSERT INTO sys_admin.published_services (name, as_wfs) VALUES @@ -92,6 +96,16 @@ ./cmd/gemma/gemma ``` +## Adding default style templates for geoserver + +- To add default style layers for geoserver run the script: + ``` + ./style-templates/upload-styles.sh + ``` + +- `./style-templates/upload-styles.sh --help` shows an overview of its options. + + ## Proxying OGC services through gemma - Add services you want to publish via gemma (e.g. for same-origin policy diff -r f77a6f9216ae -r d2eac69ba86b client/README.md --- a/client/README.md Fri Sep 20 17:48:47 2019 +0200 +++ b/client/README.md Fri Oct 04 16:40:04 2019 +0200 @@ -35,6 +35,11 @@ * Build `yarn build` builds the production ready assets to `web` folder. + This is what the `../Makefile` will call, which you should use anyway. + + For a real production use, edit the `title` tag in `public/index.html` + to something matching your installation. + * Build `yarn build-demo` sets the hg revision as a node env var and builds the production ready assets to `web` folder. diff -r f77a6f9216ae -r d2eac69ba86b client/package.json --- a/client/package.json Fri Sep 20 17:48:47 2019 +0200 +++ b/client/package.json Fri Oct 04 16:40:04 2019 +0200 @@ -40,11 +40,11 @@ "file-saver": "^2.0.2", "glob-all": "^3.1.0", "locale2": "^2.2.0", - "lodash.debounce": "^4.0.8", "ol": "^5.3.0", "path": "^0.12.7", "prettier": "^1.15.3", "purgecss-webpack-plugin": "^1.4.0", + "sanitize-filename": "^1.6.3", "svg2pdf.js": "https://github.com/Intevation/svg2pdf.js.git#production", "v-tooltip": "^2.0.0-rc.33", "vue": "^2.5.16", diff -r f77a6f9216ae -r d2eac69ba86b client/src/assets/gauge.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/src/assets/gauge.svg Fri Oct 04 16:40:04 2019 +0200 @@ -0,0 +1,119 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff -r f77a6f9216ae -r d2eac69ba86b client/src/assets/marker-gauge-blue.png Binary file client/src/assets/marker-gauge-blue.png has changed diff -r f77a6f9216ae -r d2eac69ba86b client/src/assets/marker-gauge-brown.png Binary file client/src/assets/marker-gauge-brown.png has changed diff -r f77a6f9216ae -r d2eac69ba86b client/src/assets/marker-gauge-red.png Binary file client/src/assets/marker-gauge-red.png has changed diff -r f77a6f9216ae -r d2eac69ba86b client/src/assets/marker-gauge-white.png Binary file client/src/assets/marker-gauge-white.png has changed diff -r f77a6f9216ae -r d2eac69ba86b client/src/components/Bottlenecks.vue --- a/client/src/components/Bottlenecks.vue Fri Sep 20 17:48:47 2019 +0200 +++ b/client/src/components/Bottlenecks.vue Fri Oct 04 16:40:04 2019 +0200 @@ -162,6 +162,10 @@ preventZoomOut: true }); }); + this.$store.commit( + "bottlenecks/setBottleneckForPrint", + bottleneck.properties.name + ); }, loadSurveys(bottleneck) { if (bottleneck === this.openBottleneck) { diff -r f77a6f9216ae -r d2eac69ba86b client/src/components/Pdftool.vue --- a/client/src/components/Pdftool.vue Fri Sep 20 17:48:47 2019 +0200 +++ b/client/src/components/Pdftool.vue Fri Oct 04 16:40:04 2019 +0200 @@ -118,6 +118,8 @@ import { HTTP } from "@/lib/http"; import { displayError } from "@/lib/errors"; import { pdfgen, templateLoader } from "@/lib/mixins"; +import sanitize from "sanitize-filename"; +import { containsCoordinate } from "ol/extent"; const paperSizes = { // in millimeter, landscape [width, height] @@ -152,13 +154,12 @@ { type: "scalebar", position: "bottomright", - offset: { x: 2, y: 2 } + offset: { x: 1, y: 1 } }, { type: "textbox", position: "bottomleft", - offset: { x: 2, y: 2 }, - width: 60, + offset: { x: 1, y: 1 }, fontSize: 8, text: this.$gettext("Generated by") + " " + "{user}, {date}" }, @@ -167,6 +168,16 @@ position: "topleft", offset: { x: 6, y: 4 }, size: 2 + }, + { + type: "bottleneck", + position: "topright", + offset: { x: 2, y: 2 } + }, + { + type: "legend", + position: "topright", + offset: { x: 2, y: 25 } } ] } @@ -186,31 +197,49 @@ }, computed: { ...mapState("application", ["showPdfTool", "logoForPDF"]), - ...mapState("bottlenecks", ["selectedBottleneck", "selectedSurvey"]), + ...mapState("bottlenecks", [ + "selectedBottleneck", + "selectedSurvey", + "bottleneckForPrint" + ]), ...mapState("map", ["isolinesLegendImgDataURL"]), ...mapGetters("map", ["openLayersMap"]), generatePdfLable() { return this.$gettext("Generate PDF"); }, filename() { - let date = new Date() - .toISOString() - .slice(0, 10) - .replace(/-/g, ""); let filename = "map"; - - if (this.selectedBottleneck) { - filename = this.selectedBottleneck; - if (this.selectedSurvey) { - filename += "-sr" + this.selectedSurvey.date_info.replace(/-/g, ""); + if (this.bottleneckForPrint) { + if (this.isBottleneckInView()) { + filename = `BN-${sanitize(this.bottleneckForPrint)}`; + if (this.selectedSurvey) { + filename += "-sr" + this.selectedSurvey.date_info.replace(/-/g, ""); + } } } - - filename = filename.toLowerCase() + "-exported" + date + ".pdf"; - return filename; + return `${filename}-${this.dateForPDF()}.pdf`; } }, methods: { + // Check if the view contains the selected bottleneck + // to avoid including bottleneck info in pdf in case view has changed to another location + isBottleneckInView() { + let map = this.openLayersMap(); + // Get extent of the viewport + let viewExtent = map.getView().calculateExtent(map.getSize()); + let btnExtent = map // Extent of the selected bottleneck + .getLayer("BOTTLENECKS") + .getSource() + .getFeatures() + .find(f => f.get("objnam") === this.bottleneckForPrint) + .getGeometry().extent_; + // Get center of bottleneck from extent + let centerCoordinat = [ + (btnExtent[0] + btnExtent[2]) / 2, + (btnExtent[1] + btnExtent[3]) / 2 + ]; + return containsCoordinate(viewExtent, centerCoordinat); + }, close() { this.$store.commit("application/showPdfTool", false); }, @@ -262,13 +291,6 @@ * */ this.readyToGenerate = false; - console.log( - "will generate pdf with", - this.form.paperSize, - this.form.format, - this.form.resolution - ); - if (this.form.format !== "portrait") { this.pdf.width = paperSizes[this.form.paperSize][0]; this.pdf.height = paperSizes[this.form.paperSize][1]; @@ -300,7 +322,6 @@ .getResolution() ) ); - console.log("scaleDenominator = ", scaleDenominator); var snapshot = canvas.toDataURL("image/jpeg"); this.pdf.doc.addImage( snapshot, @@ -422,7 +443,6 @@ } } }); - this.pdf.doc.save(this.filename); } map.setSize(this.mapSize); @@ -518,12 +538,10 @@ maxLength /= unitConversionFactor; - // DEBUG console.log(maxLength, unit); let unroundedLength = maxLength; let numberOfDigits = Math.floor(log10(unroundedLength)); let factor = Math.pow(10, numberOfDigits); let mapped = unroundedLength / factor; - // DEBUG console.log(mapped); var length = Math.floor(maxLength); // just to have an upper limit @@ -656,8 +674,9 @@ }, addLegend(position, offset, rounding, brcolor) { if ( - this.selectedBottleneck && + this.bottleneckForPrint && this.selectedSurvey && + this.isBottleneckInView() && this.openLayersMap() .getLayer("BOTTLENECKISOLINE") .getVisible() @@ -697,8 +716,9 @@ }, addBottleneckInfo(position, offset, rounding, color, brcolor) { if ( - this.selectedBottleneck && + this.bottleneckForPrint && this.selectedSurvey && + this.isBottleneckInView() && this.openLayersMap() .getLayer("BOTTLENECKISOLINE") .getVisible() @@ -766,39 +786,44 @@ // bottleneck this.pdf.doc.setFontStyle("italic"); - this.pdf.doc.text(x + padding, y + padding, str1_1, textOptions); + this.pdf.doc.text(x + padding, y + padding + 2, str1_1, textOptions); this.pdf.doc.setFontStyle("bold"); - this.pdf.doc.text(x + padding + w1_1, y + padding, str1_2, textOptions); + this.pdf.doc.text( + x + padding + w1_1, + y + padding + 2, + str1_2, + textOptions + ); // survey date this.pdf.doc.setFontStyle("italic"); - this.pdf.doc.text(x + padding, y + padding + 4, str2_1, textOptions); + this.pdf.doc.text(x + padding, y + padding + 6, str2_1, textOptions); this.pdf.doc.setFontStyle("normal"); this.pdf.doc.text( x + padding + w2_1, - y + padding + 4, + y + padding + 6, str2_2, textOptions ); // ref gauge this.pdf.doc.setFontStyle("italic"); - this.pdf.doc.text(x + padding, y + padding + 8, str3_1, textOptions); + this.pdf.doc.text(x + padding, y + padding + 10, str3_1, textOptions); this.pdf.doc.setFontStyle("normal"); this.pdf.doc.text( x + padding + w3_1, - y + padding + 8, + y + padding + 10, str3_2, textOptions ); // depth relative to this.pdf.doc.setFontStyle("italic"); - this.pdf.doc.text(x + padding, y + padding + 12, str4_1, textOptions); + this.pdf.doc.text(x + padding, y + padding + 14, str4_1, textOptions); this.pdf.doc.setFontStyle("normal"); this.pdf.doc.text( x + padding + w4_1, - y + padding + 12, + y + padding + 14, str4_2, textOptions ); diff -r f77a6f9216ae -r d2eac69ba86b client/src/components/Popup.vue --- a/client/src/components/Popup.vue Fri Sep 20 17:48:47 2019 +0200 +++ b/client/src/components/Popup.vue Fri Oct 04 16:40:04 2019 +0200 @@ -14,6 +14,23 @@ :class="{ 'p-3': popup.padding !== false }" v-html="popup.content" > +
+
+ + From + + +
+
+ + To + + +
+