Merge branch 'develop' into backend/max
This commit is contained in:
commit
18612e3f11
@ -19,7 +19,9 @@
|
||||
"openlayers": "^4.6.5",
|
||||
"quasar": "^1.0.0-rc.2",
|
||||
"vue-qrcode-reader": "^1.4.2",
|
||||
"vuelayers": "^0.11.4"
|
||||
"vuelayers": "^0.11.4",
|
||||
"lodash": "^4.17.11",
|
||||
"ol": "^5.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@quasar/app": "^1.0.0-rc.4",
|
||||
|
||||
@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="q-mb-sm" style="height: 400px">
|
||||
<vl-map v-if="mapVisible" class="map" ref="map" :load-tiles-while-animating="true"
|
||||
:load-tiles-while-interacting="true"
|
||||
@click="clickCoordinate = $event.coordinate" @postcompose="onMapPostCompose"
|
||||
data-projection="EPSG:4326" @mounted="onMapMounted">
|
||||
<!-- map view aka ol.View -->
|
||||
<vl-view ref="view" :center.sync="computedCoords" :zoom.sync="zoom" :rotation.sync="rotation"></vl-view>
|
||||
|
||||
<!-- interactions -->
|
||||
<!-- <vl-interaction-select :features.sync="selectedFeatures" v-if="drawType == null">-->
|
||||
<!-- <template slot-scope="select">-->
|
||||
<!-- <!– select styles –>-->
|
||||
<!-- <vl-style-box>-->
|
||||
<!-- <vl-style-stroke color="#423e9e" :width="7"></vl-style-stroke>-->
|
||||
<!-- <vl-style-fill :color="[254, 178, 76, 0.7]"></vl-style-fill>-->
|
||||
<!-- <vl-style-circle :radius="5">-->
|
||||
<!-- <vl-style-stroke color="#423e9e" :width="7"></vl-style-stroke>-->
|
||||
<!-- <vl-style-fill :color="[254, 178, 76, 0.7]"></vl-style-fill>-->
|
||||
<!-- </vl-style-circle>-->
|
||||
<!-- </vl-style-box>-->
|
||||
<!-- <vl-style-box :z-index="1">-->
|
||||
<!-- <vl-style-stroke color="#d43f45" :width="2"></vl-style-stroke>-->
|
||||
<!-- <vl-style-circle :radius="5">-->
|
||||
<!-- <vl-style-stroke color="#d43f45" :width="2"></vl-style-stroke>-->
|
||||
<!-- </vl-style-circle>-->
|
||||
<!-- </vl-style-box>-->
|
||||
<!-- <!–// select styles –>-->
|
||||
|
||||
<!-- </template>-->
|
||||
<!-- </vl-interaction-select>-->
|
||||
<!--// interactions -->
|
||||
|
||||
<!-- geolocation -->
|
||||
<vl-geoloc @update:position="onUpdatePosition">
|
||||
<template slot-scope="geoloc">
|
||||
<vl-feature v-if="geoloc.position" id="position-feature">
|
||||
<vl-geom-point :coordinates="geoloc.position"></vl-geom-point>
|
||||
</vl-feature>
|
||||
</template>
|
||||
</vl-geoloc>
|
||||
<!--// geolocation -->
|
||||
|
||||
<vl-feature id="marker" ref="marker">
|
||||
<template>
|
||||
<vl-geom-point :coordinates="center"></vl-geom-point>
|
||||
<vl-style-box>
|
||||
<vl-style-icon src="./statics/map-marker.svg" :scale="2" :anchor="[0.095,0.17]"
|
||||
:size="[128, 128]"></vl-style-icon>
|
||||
</vl-style-box>
|
||||
</template>
|
||||
</vl-feature>
|
||||
<!-- !!Snippet -->
|
||||
<!--// overlay marker -->
|
||||
|
||||
|
||||
<!-- base layers -->
|
||||
<vl-layer-tile v-for="layer in baseLayers" :key="layer.name" :id="layer.name" :visible="layer.visible">
|
||||
<component :is="'vl-source-' + layer.name" v-bind="layer"></component>
|
||||
</vl-layer-tile>
|
||||
<!--// base layers -->
|
||||
|
||||
</vl-map>
|
||||
</div>
|
||||
<div class="row q-col-gutter-md">
|
||||
<q-input class="col" dense stack-label filled v-model="center[1]"
|
||||
label="Breitengrad"/>
|
||||
<q-input class="col" dense stack-label filled v-model="center[0]"
|
||||
label="Längengrad"/>
|
||||
<div class="col-shrink">
|
||||
<q-btn unelevated color="primary" class="full-height" icon="my_location" @click="setCenter(deviceCoordinate)"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import VueLayers from 'vuelayers'
|
||||
import 'vuelayers/lib/style.css' // needs css-loader
|
||||
import {camelCase, kebabCase} from 'lodash'
|
||||
import {addProj, createMultiPointGeom, createProj, createStyle, findPointOnSurface} from 'vuelayers/lib/ol-ext'
|
||||
import ScaleLine from 'ol/control/ScaleLine'
|
||||
import FullScreen from 'ol/control/FullScreen'
|
||||
import OverviewMap from 'ol/control/OverviewMap'
|
||||
import ZoomSlider from 'ol/control/ZoomSlider'
|
||||
|
||||
Vue.use(VueLayers);
|
||||
|
||||
// Custom projection for static Image layer
|
||||
let x = 1024 * 10000
|
||||
let y = 968 * 10000
|
||||
let imageExtent = [-x / 2, -y / 2, x / 2, y / 2]
|
||||
let customProj = createProj({
|
||||
code: 'xkcd-image',
|
||||
units: 'pixels',
|
||||
extent: imageExtent,
|
||||
})
|
||||
// add to the list of known projections
|
||||
// after that it can be used by code
|
||||
addProj(customProj)
|
||||
|
||||
const easeInOut = t => 1 - Math.pow(1 - t, 3)
|
||||
|
||||
const methods = {
|
||||
camelCase,
|
||||
pointOnSurface: findPointOnSurface,
|
||||
geometryTypeToCmpName(type) {
|
||||
return 'vl-geom-' + kebabCase(type)
|
||||
},
|
||||
/**
|
||||
* Packman layer Style function factory
|
||||
* @return {ol.StyleFunction}
|
||||
*/
|
||||
pacmanStyleFunc() {
|
||||
const pacman = [
|
||||
createStyle({
|
||||
strokeColor: '#de9147',
|
||||
strokeWidth: 3,
|
||||
fillColor: [222, 189, 36, 0.8],
|
||||
}),
|
||||
]
|
||||
const path = [
|
||||
createStyle({
|
||||
strokeColor: 'blue',
|
||||
strokeWidth: 1,
|
||||
}),
|
||||
createStyle({
|
||||
imageRadius: 5,
|
||||
imageFillColor: 'orange',
|
||||
geom(feature) {
|
||||
// geometry is an LineString, convert it to MultiPoint to style vertex
|
||||
return createMultiPointGeom(feature.getGeometry().getCoordinates())
|
||||
},
|
||||
}),
|
||||
]
|
||||
const eye = [
|
||||
createStyle({
|
||||
imageRadius: 6,
|
||||
imageFillColor: '#444444',
|
||||
}),
|
||||
]
|
||||
},
|
||||
/**
|
||||
* Cluster layer style function factory
|
||||
* @return {ol.StyleFunction}
|
||||
*/
|
||||
clusterStyleFunc() {
|
||||
const cache = {}
|
||||
|
||||
return function __clusterStyleFunc(feature) {
|
||||
const size = feature.get('features').length
|
||||
let style = cache[size]
|
||||
|
||||
if (!style) {
|
||||
style = createStyle({
|
||||
imageRadius: 10,
|
||||
strokeColor: '#fff',
|
||||
fillColor: '#3399cc',
|
||||
text: size.toString(),
|
||||
textFillColor: '#fff',
|
||||
})
|
||||
cache[size] = style
|
||||
}
|
||||
return [style]
|
||||
}
|
||||
},
|
||||
selectFilter(feature) {
|
||||
return ['position-feature'].indexOf(feature.getId()) === -1
|
||||
},
|
||||
onUpdatePosition(coordinate) {
|
||||
console.log("onUpdatePosition")
|
||||
this.deviceCoordinate = coordinate;
|
||||
this.$emit('updatecoords', this.center);
|
||||
},
|
||||
onMapPostCompose({vectorContext, frameState}) {
|
||||
if (!this.$refs.marker || !this.$refs.marker.$feature) return
|
||||
|
||||
const feature = this.$refs.marker.$feature
|
||||
if (!feature.getGeometry() || !feature.getStyle()) return
|
||||
|
||||
const flashGeom = feature.getGeometry().clone()
|
||||
const duration = feature.get('duration')
|
||||
const elapsed = frameState.time - feature.get('start')
|
||||
const elapsedRatio = elapsed / duration
|
||||
const radius = easeInOut(elapsedRatio) * 35 + 5
|
||||
const opacity = easeInOut(1 - elapsedRatio)
|
||||
const fillOpacity = easeInOut(0.5 - elapsedRatio)
|
||||
|
||||
vectorContext.setStyle(createStyle({
|
||||
imageRadius: radius,
|
||||
fillColor: [119, 170, 203, fillOpacity],
|
||||
strokeColor: [119, 170, 203, opacity],
|
||||
strokeWidth: 2 + opacity,
|
||||
}))
|
||||
|
||||
vectorContext.drawGeometry(flashGeom)
|
||||
vectorContext.setStyle(feature.getStyle()(feature)[0])
|
||||
vectorContext.drawGeometry(feature.getGeometry())
|
||||
|
||||
if (elapsed > duration) {
|
||||
feature.set('start', Date.now())
|
||||
}
|
||||
|
||||
this.$refs.map.render()
|
||||
},
|
||||
onMapMounted() {
|
||||
// now ol.Map instance is ready and we can work with it directly
|
||||
this.$refs.map.$map.getControls().extend([
|
||||
new ScaleLine(),
|
||||
// new FullScreen(),
|
||||
// new OverviewMap({
|
||||
// collapsed: false,
|
||||
// collapsible: true,
|
||||
// }),
|
||||
// new ZoomSlider(),
|
||||
])
|
||||
},
|
||||
// base layers
|
||||
showBaseLayer(name) {
|
||||
let layer = this.baseLayers.find(layer => layer.visible)
|
||||
if (layer != null) {
|
||||
layer.visible = false
|
||||
}
|
||||
|
||||
layer = this.baseLayers.find(layer => layer.name === name)
|
||||
if (layer != null) {
|
||||
layer.visible = true
|
||||
}
|
||||
},
|
||||
// map panel
|
||||
mapPanelTabClasses(tab) {
|
||||
return {
|
||||
'is-active': this.mapPanel.tab === tab,
|
||||
}
|
||||
},
|
||||
showMapPanelLayer(layer) {
|
||||
layer.visible = !layer.visible
|
||||
},
|
||||
showMapPanelTab(tab) {
|
||||
this.mapPanel.tab = tab
|
||||
if (tab !== 'draw') {
|
||||
this.drawType = undefined
|
||||
}
|
||||
},
|
||||
setCenter(position) {
|
||||
this.center = position;
|
||||
this.$emit('updatecoords', this.center);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
name: 'mapclickable',
|
||||
methods,
|
||||
props: {
|
||||
coords: Array,
|
||||
cacheObject: Object,
|
||||
stationObject: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
center: [9.208858198755664, 49.14785422283188],
|
||||
zoom: 15,
|
||||
rotation: 0,
|
||||
clickCoordinate: undefined,
|
||||
selectedFeatures: [],
|
||||
deviceCoordinate: undefined,
|
||||
mapPanel: {
|
||||
tab: 'state',
|
||||
},
|
||||
panelOpen: true,
|
||||
mapVisible: true,
|
||||
// drawControls: [
|
||||
// {
|
||||
// type: 'point',
|
||||
// label: 'Draw Point',
|
||||
// icon: 'map-marker',
|
||||
// },
|
||||
// {
|
||||
// type: 'line-string',
|
||||
// label: 'Draw LineString',
|
||||
// icon: 'minus',
|
||||
// },
|
||||
// {
|
||||
// type: 'polygon',
|
||||
// label: 'Draw Polygon',
|
||||
// icon: 'square-o',
|
||||
// },
|
||||
// {
|
||||
// type: 'circle',
|
||||
// label: 'Draw Circle',
|
||||
// icon: 'circle-thin',
|
||||
// },
|
||||
// {
|
||||
// type: undefined,
|
||||
// label: 'Stop drawing',
|
||||
// icon: 'times',
|
||||
// },
|
||||
// ],
|
||||
drawType: "point",
|
||||
drawnFeatures: [],
|
||||
// base layers
|
||||
baseLayers: [
|
||||
{
|
||||
name: 'osm',
|
||||
title: 'OpenStreetMap',
|
||||
visible: true,
|
||||
},
|
||||
],
|
||||
// layers config
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (!(this.coords === undefined || this.coords[0] === undefined || this.coords[1] === undefined)) {
|
||||
this.center = this.coords;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
computedCoords: {
|
||||
get() {
|
||||
return this.center;
|
||||
},
|
||||
set(val) {
|
||||
this.center = val;
|
||||
this.$emit('updatecoords', this.center);
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@ -9,7 +9,7 @@
|
||||
// to match your app's branding.
|
||||
// Tip: Use the "Theme Builder" on Quasar's documentation website.
|
||||
|
||||
$primary = #027BE3
|
||||
$primary = #2fbf28
|
||||
$secondary = #26A69A
|
||||
$accent = #9C27B0
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
<q-item-label header>BuGa Geocaching</q-item-label>
|
||||
<q-item
|
||||
clickable
|
||||
class="text-primary"
|
||||
class="text-black"
|
||||
v-ripple
|
||||
tag="a"
|
||||
to="/"
|
||||
@ -77,7 +77,7 @@
|
||||
<q-item
|
||||
v-if="this.$store.state.auth.isAuthenticated"
|
||||
clickable
|
||||
class="text-primary"
|
||||
class="text-black"
|
||||
v-ripple
|
||||
tag="a"
|
||||
to="/qr-scanner"
|
||||
@ -91,7 +91,7 @@
|
||||
</q-item>
|
||||
<q-item
|
||||
clickable
|
||||
class="text-primary"
|
||||
class="text-black"
|
||||
v-ripple
|
||||
tag="a"
|
||||
to="/Overview"
|
||||
@ -106,7 +106,7 @@
|
||||
<q-item
|
||||
v-if="this.$store.state.auth.isAuthenticated"
|
||||
clickable
|
||||
class="text-primary"
|
||||
class="text-black"
|
||||
v-ripple
|
||||
tag="a"
|
||||
to="/mycaches"
|
||||
@ -120,7 +120,7 @@
|
||||
</q-item>
|
||||
<q-item
|
||||
clickable
|
||||
class="text-primary"
|
||||
class="text-black"
|
||||
v-ripple
|
||||
tag="a"
|
||||
to="/ranking"
|
||||
@ -135,7 +135,7 @@
|
||||
<q-item
|
||||
v-if="this.$store.state.auth.isAuthenticated"
|
||||
clickable
|
||||
class="text-primary"
|
||||
class="text-black"
|
||||
v-ripple
|
||||
tag="a"
|
||||
to="/Profile"
|
||||
@ -150,7 +150,7 @@
|
||||
<q-item
|
||||
v-if="!this.$store.state.auth.isAuthenticated"
|
||||
clickable
|
||||
class="text-primary"
|
||||
class="text-black"
|
||||
v-ripple
|
||||
tag="a"
|
||||
to="/Register"
|
||||
@ -165,7 +165,7 @@
|
||||
<q-item
|
||||
v-if="this.$store.state.auth.isAuthenticated"
|
||||
clickable
|
||||
class="text-primary"
|
||||
class="text-black"
|
||||
v-ripple
|
||||
tag="a"
|
||||
@click="logout()"
|
||||
@ -181,7 +181,7 @@
|
||||
<q-item
|
||||
v-if="!this.$store.state.auth.isAuthenticated"
|
||||
clickable
|
||||
class="text-primary"
|
||||
class="text-black"
|
||||
v-ripple
|
||||
tag="a"
|
||||
to="/Login"
|
||||
|
||||
@ -60,9 +60,11 @@
|
||||
</q-item>
|
||||
|
||||
</q-list>
|
||||
<p class=""><b>Hinweis:</b> Ein Cache muss mindestens aus zwei Stationen bestehen (inklusive der Endstation).</p>
|
||||
<p class=""><b>Hinweis:</b> Ein Cache muss mindestens aus zwei Stationen bestehen (inklusive der Endstation).
|
||||
</p>
|
||||
<div class="row reverse">
|
||||
<q-btn @click="addStation" class="full-width" unelevated color="primary" label="Station hinzufügen" icon-right="add"/>
|
||||
<q-btn @click="addStation" class="full-width" unelevated color="primary" label="Station hinzufügen"
|
||||
icon-right="add"/>
|
||||
</div>
|
||||
<p class="text-h6">Endstation</p>
|
||||
<q-card flat bordered class="rounded-borders">
|
||||
@ -95,7 +97,7 @@
|
||||
<div class="row q-mt-xl">
|
||||
<q-btn @click="saveCache" class="full-width q-mb-md" color="primary" unelevated stack label="Cache speichern"
|
||||
icon="save_alt"/>
|
||||
<q-btn to="/overview" class="full-width" color="negative" unelevated stack label="Abbrechen" />
|
||||
<q-btn to="/overview" class="full-width" color="negative" unelevated stack label="Abbrechen"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@ -123,7 +125,7 @@
|
||||
},
|
||||
created: function () {
|
||||
console.log("isNewCache: " + this.isNewCache);
|
||||
console.log("Route Params: " + this.$route.params.id);
|
||||
//console.log("Route Params: " + this.$route.params.id);
|
||||
if (!this.isNewCache && !this.$store.getters['cacheCollector/GET_LOCK']) {
|
||||
this.$axios.get('/api/allCaches')
|
||||
.then((response) => {
|
||||
@ -163,6 +165,7 @@
|
||||
const station = this.$store.getters['cacheCollector/GET_ENDSTATION'];
|
||||
console.log(station);
|
||||
this.$store.commit('cacheCollector/SET_TEMPSTATION', station);
|
||||
this.$store.commit('cacheCollector/SET_LOCK', true);
|
||||
this.$router.push({path: `/tempendstation/`}); // add parameter
|
||||
|
||||
},
|
||||
@ -187,75 +190,73 @@
|
||||
let cache = JSON.parse(JSON.stringify(this.computedCache));
|
||||
console.log(cache);
|
||||
cache.stationen.push(this.computedEndstation);
|
||||
console.log("isnewcache "+this.isNewCache)
|
||||
console.log("isnewcache " + this.isNewCache)
|
||||
|
||||
//Error messages
|
||||
if(!this.validateRankingPoints()){
|
||||
if (!this.validateRankingPoints()) {
|
||||
let title = "Falsche Formatierung";
|
||||
let msg = "Die Ranglistenpunkte müssen eine ganze Zahl sein";
|
||||
this.$store.commit('dialog/NEW_MESSAGE_DIALOG', {message: msg, title: title,});
|
||||
}
|
||||
|
||||
if(this.validateEverything()) {
|
||||
if (this.isNewCache) {
|
||||
console.log("CREATECACHE")
|
||||
this.$axios.post('/api/createCache', cache)
|
||||
.then((response) => {
|
||||
console.log("POST api/createCache: " + response.statusText);
|
||||
this.$store.commit('cacheCollector/RESET_NEW_CACHE');
|
||||
this.$router.push({path: '/overview'});
|
||||
}).catch((error) => {
|
||||
let msg;
|
||||
let title;
|
||||
if (error.response) {
|
||||
title = "Bitte Eingaben überprüfen!";
|
||||
msg = error.response.data;
|
||||
} else if (error.request) {
|
||||
title = "Verbindungsfehler!";
|
||||
msg = "Es konnte keine Verbindung zum Server aufgebaut werden. Versuchen Sie es später noch einmal!"
|
||||
console.log(error.request);
|
||||
} else {
|
||||
title = "Error";
|
||||
msg = error.message;
|
||||
console.log('Error', error.message);
|
||||
}
|
||||
console.log(error.config);
|
||||
this.$store.commit('dialog/NEW_MESSAGE_DIALOG', {message: msg, title: title,});
|
||||
})
|
||||
} else {
|
||||
console.log("EDITCACHE")
|
||||
this.$axios.put('/api/editCache', cache)
|
||||
.then((response) => {
|
||||
console.log("POST api/editCache: " + response.statusText);
|
||||
this.$store.commit('cacheCollector/RESET_NEW_CACHE');
|
||||
this.$router.push({path: '/overview'});
|
||||
}).catch((error) => {
|
||||
let msg;
|
||||
let title;
|
||||
if (error.response) {
|
||||
title = "Bitte Eingaben überprüfen!";
|
||||
msg = error.response.data;
|
||||
} else if (error.request) {
|
||||
title = "Verbindungsfehler!";
|
||||
msg = "Es konnte keine Verbindung zum Server aufgebaut werden. Versuchen Sie es später noch einmal!"
|
||||
console.log(error.request);
|
||||
} else {
|
||||
title = "Error";
|
||||
msg = error.message;
|
||||
console.log('Error', error.message);
|
||||
}
|
||||
console.log(error.config);
|
||||
this.$store.commit('dialog/NEW_MESSAGE_DIALOG', {message: msg, title: title,});
|
||||
})
|
||||
}
|
||||
if (this.isNewCache) {
|
||||
console.log("CREATECACHE")
|
||||
this.$axios.post('/api/createCache', cache)
|
||||
.then((response) => {
|
||||
console.log("POST api/createCache: " + response.statusText);
|
||||
this.$store.commit('cacheCollector/RESET_NEW_CACHE');
|
||||
this.$router.push({path: '/overview'});
|
||||
}).catch((error) => {
|
||||
let msg;
|
||||
let title;
|
||||
if (error.response) {
|
||||
title = "Bitte Eingaben überprüfen!";
|
||||
msg = error.response.data;
|
||||
} else if (error.request) {
|
||||
title = "Verbindungsfehler!";
|
||||
msg = "Es konnte keine Verbindung zum Server aufgebaut werden. Versuchen Sie es später noch einmal!"
|
||||
console.log(error.request);
|
||||
} else {
|
||||
title = "Error";
|
||||
msg = error.message;
|
||||
console.log('Error', error.message);
|
||||
}
|
||||
console.log(error.config);
|
||||
this.$store.commit('dialog/NEW_MESSAGE_DIALOG', {message: msg, title: title,});
|
||||
})
|
||||
} else {
|
||||
console.log("EDITCACHE")
|
||||
this.$axios.put('/api/editCache', cache)
|
||||
.then((response) => {
|
||||
console.log("POST api/editCache: " + response.statusText);
|
||||
this.$store.commit('cacheCollector/RESET_NEW_CACHE');
|
||||
this.$router.push({path: '/overview'});
|
||||
}).catch((error) => {
|
||||
let msg;
|
||||
let title;
|
||||
if (error.response) {
|
||||
title = "Bitte Eingaben überprüfen!";
|
||||
msg = error.response.data;
|
||||
} else if (error.request) {
|
||||
title = "Verbindungsfehler!";
|
||||
msg = "Es konnte keine Verbindung zum Server aufgebaut werden. Versuchen Sie es später noch einmal!"
|
||||
console.log(error.request);
|
||||
} else {
|
||||
title = "Error";
|
||||
msg = error.message;
|
||||
console.log('Error', error.message);
|
||||
}
|
||||
console.log(error.config);
|
||||
this.$store.commit('dialog/NEW_MESSAGE_DIALOG', {message: msg, title: title,});
|
||||
})
|
||||
}
|
||||
},
|
||||
validateRankingPoints: function () {
|
||||
var re = new RegExp('^[0-9]+$');
|
||||
var rps = String(this.computedCache.rankingPoints);
|
||||
let re = new RegExp('^[0-9]+$');
|
||||
let rps = String(this.computedCache.rankingPoints);
|
||||
return re.test(rps);
|
||||
},
|
||||
validateEverything(){
|
||||
validateEverything() {
|
||||
return this.validateRankingPoints();
|
||||
}
|
||||
},
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
<q-expansion-item
|
||||
expand-separator
|
||||
rounded-borders
|
||||
class="bg-green-3 text-black shadow-2 full-width q-mt-md"
|
||||
class="bg-primary text-black shadow-2 full-width q-mt-md"
|
||||
label="Was ist GeoCaching?"
|
||||
>
|
||||
<q-card>
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
<q-card-section>
|
||||
<div class="text-h6">Loslegen</div>
|
||||
<q-btn color="green-3" text-color="black" class="full-width q-mt-md" label="Zu den Caches" to="/Overview"/>
|
||||
<q-btn color="primary" text-color="black" class="full-width q-mt-md" label="Zu den Caches" to="/Overview"/>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
|
||||
@ -170,7 +170,6 @@ Vue.use(VueLayers);
|
||||
tab: 'list',
|
||||
caches: [],
|
||||
stations: [],
|
||||
features: [],
|
||||
render: false,
|
||||
renderMarker: false,
|
||||
zoom: 15,
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<div class="col">
|
||||
<div class="">
|
||||
<div class="" style="max-width: 440px">
|
||||
<q-input lazy-rules outlined filled stack-label v-model="user.name" type="text" label="Vor- und Nachname"
|
||||
<q-input lazy-rules outlined filled stack-label v-model="user.name" type="text" label="Vor- und Nachname" autocomplete="new-password"
|
||||
:rules="[val=>validateUsername(val)||'Name muss mindestens 2 Zeichen lang sein und darf nur aus Buchstaben, Zahlen und Unterstrichen bestehen!']"/>
|
||||
</div>
|
||||
</div>
|
||||
@ -15,7 +15,7 @@
|
||||
<div class="col">
|
||||
<div class="">
|
||||
<div class="" style="max-width: 440px">
|
||||
<q-input lazy-rules outlined filled stack-label v-model="user.email" type="text" label="E-Mail"
|
||||
<q-input lazy-rules outlined filled stack-label v-model="user.email" type="text" label="E-Mail" autocomplete="new-password"
|
||||
:rules="[val=>validateEmail(val)||'Bitte gültige E-Mail angeben!']"/>
|
||||
</div>
|
||||
</div>
|
||||
@ -23,7 +23,7 @@
|
||||
<div class="col">
|
||||
<div class="">
|
||||
<div class="" style="max-width: 440px">
|
||||
<q-input lazy-rules outlined filled stack-label v-model="user.checkemail" type="text"
|
||||
<q-input lazy-rules outlined filled stack-label v-model="user.checkemail" type="text" autocomplete="new-password"
|
||||
label="E-Mail erneut eingeben" placeholer="Email"
|
||||
:rules="[val=>val===user.email||'E-Mail stimmt nicht überein!']"/>
|
||||
</div>
|
||||
@ -32,7 +32,7 @@
|
||||
<div class="col">
|
||||
<div class="">
|
||||
<div class="" style="max-width: 440px">
|
||||
<q-input lazy-rules outlined filled stack-label v-model="user.password" type="password"
|
||||
<q-input lazy-rules outlined filled stack-label v-model="user.password" type="password" autocomplete="new-password"
|
||||
label="Passwort"
|
||||
:rules="[val=>val.length>=8||'Passwort muss mindestens 8 Zeichen lang sein!']"/>
|
||||
</div>
|
||||
@ -41,7 +41,7 @@
|
||||
<div class="col">
|
||||
<div class="">
|
||||
<div class="" style="max-width: 440px">
|
||||
<q-input lazy-rules outlined filled stack-label v-model="user.checkpassword" type="password"
|
||||
<q-input lazy-rules outlined filled stack-label v-model="user.checkpassword" type="password" autocomplete="new-password"
|
||||
label="Passwort erneut eingeben"
|
||||
:rules="[val=>val===user.password||'Passwort stimmt nicht überein']"/>
|
||||
</div>
|
||||
@ -97,7 +97,8 @@
|
||||
},
|
||||
methods: {
|
||||
validateEmail(email) {
|
||||
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
//var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
let re = new RegExp('^[a-zA-Z0-9.!#$%&\'*+/=?^_`{|}~-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$');
|
||||
return re.test(String(email).toLowerCase());
|
||||
},
|
||||
register: function () {
|
||||
|
||||
@ -1,46 +1,25 @@
|
||||
<template>
|
||||
<div class="q-ma-md">
|
||||
<p class="text-h5">Neue Station</p>
|
||||
<q-editor
|
||||
:toolbar="[
|
||||
<p class="text-h5">{{ isEndstation ? "Endstation bearbeiten"
|
||||
: isNewStation ? "Neue Station"
|
||||
: "Station bearbeiten"}}</p>
|
||||
<q-editor v-show="!isEndstation && station.description"
|
||||
:toolbar="[
|
||||
['bold', 'italic', 'strike', 'underline'],
|
||||
['undo', 'redo'],
|
||||
['hr', 'link'],
|
||||
['fullscreen'],
|
||||
]"
|
||||
v-model="station.description" min-height="10rem"/>
|
||||
v-model="station.description" min-height="10rem"/>
|
||||
<!--<q-input-->
|
||||
<!--v-model="description"-->
|
||||
<!--filled-->
|
||||
<!--type="textarea"-->
|
||||
<!--/>-->
|
||||
<p class="text-h6 q-mt-md">Location</p>
|
||||
<vl-map :load-tiles-while-animating="true" :load-tiles-while-interacting="true"
|
||||
data-projection="EPSG:4326">
|
||||
<vl-view :zoom.sync="zoom" :center.sync="center" :rotation.sync="rotation"></vl-view>
|
||||
<mapclick v-if="!loading" :coords="[this.station.longitude, this.station.lattitude]" @updatecoords="updateCoords($event)">
|
||||
|
||||
<vl-geoloc @update:position="geolocPosition = $event">
|
||||
<template slot-scope="geoloc">
|
||||
<vl-feature v-if="geoloc.position" id="position-feature">
|
||||
<vl-geom-point :coordinates="geoloc.position"></vl-geom-point>
|
||||
</vl-feature>
|
||||
</template>
|
||||
</vl-geoloc>
|
||||
|
||||
<vl-layer-tile id="osm">
|
||||
<vl-source-osm></vl-source-osm>
|
||||
</vl-layer-tile>
|
||||
</vl-map>
|
||||
<div class="row q-col-gutter-md">
|
||||
<q-input class="col" dense stack-label filled v-model="latlang" @input="separateLatlang"
|
||||
label="Breitengrad/Längengrad"/>
|
||||
<div class="col-shrink">
|
||||
<q-btn unelevated color="primary" class="full-height" icon="my_location"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <p class="text-h6 q-mt-md">Lösung</p>-->
|
||||
<!-- <q-input class="col" dense stack-label filled v-model="station.solution" label="Lösung"/>-->
|
||||
<!-- <q-input class="col q-mt-md" dense stack-label filled v-model="station.code" label="Code" readonly/>-->
|
||||
</mapclick>
|
||||
<div class="row reverse q-mt-md q-gutter-x-md">
|
||||
<q-btn @click="saveStation" unelevated color="primary" label="Speichern" icon-right="add"/>
|
||||
<q-btn @click="dismiss" unelevated color="negative" label="verwerfen" icon-right="delete"/>
|
||||
@ -51,14 +30,15 @@
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
import mapclick from "../components/mapClickable";
|
||||
|
||||
export default {
|
||||
name: "Station",
|
||||
|
||||
components: {mapclick},
|
||||
data() {
|
||||
return {
|
||||
description: "Rätsel, Aufgabe und Informationen zur Station.",
|
||||
latlang: "",
|
||||
// latlang: "",
|
||||
station: {
|
||||
description: "Rätsel, Aufgabe und Informationen zur Station.",
|
||||
lattitude: 49.1474082,
|
||||
@ -67,32 +47,64 @@
|
||||
code: ""
|
||||
},
|
||||
isNewStation: true,
|
||||
// stationObject: null,
|
||||
isEndstation: false,
|
||||
loading: true,
|
||||
}
|
||||
},
|
||||
// props: [ 'stationObject' ],
|
||||
created: function () {
|
||||
this.isNewStation = (this.$route.params.pos === undefined);
|
||||
console.log("CREATED");
|
||||
console.log(this.tempStation);
|
||||
if (this.$route.path.includes("endstation")) {
|
||||
this.isEndstation = true;
|
||||
this.station.description = "Endstation";
|
||||
}
|
||||
this.isNewStation = this.isEndstation ? false : (this.$route.params.pos === undefined);
|
||||
// this.isNewStation = (this.$route.query.page === );
|
||||
console.log(this.$route.path)
|
||||
if (!this.isNewStation) {
|
||||
this.station = JSON.parse(JSON.stringify(this.tempStation));
|
||||
}
|
||||
console.log("neu: " + this.isNewStation);
|
||||
console.log("pos: " + this.$route.params.pos);
|
||||
console.log(this.$route);
|
||||
console.log(this.station);
|
||||
if (!this.isNewStation) {
|
||||
this.station = JSON.parse(JSON.stringify(this.tempStation));
|
||||
}
|
||||
console.log("is newStation & is Endstation");
|
||||
console.log(this.isNewStation);
|
||||
|
||||
console.log(this.isEndstation);
|
||||
console.log(this.station);
|
||||
this.loading = false;
|
||||
},
|
||||
beforeMount: function () {
|
||||
},
|
||||
mounted: function () {
|
||||
this.concatLatlang();
|
||||
// this.concatLatlang();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
tempStation: 'cacheCollector/GET_TEMPSTATION'
|
||||
tempStation: 'cacheCollector/GET_TEMPSTATION',
|
||||
endStation: 'cacheCollector/GET_ENDSTATION'
|
||||
}),
|
||||
sourceStation() {
|
||||
if (this.isEndstation) {
|
||||
console.log("returned this.endStation")
|
||||
return this.endStation;
|
||||
} else {
|
||||
console.log("returned this.tempStation")
|
||||
return this.tempStation;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateCoords(event) {
|
||||
// console.log("updateCoords")
|
||||
// console.log(event)
|
||||
if (!(event === undefined || event[0] === undefined || event[1] === undefined)) {
|
||||
this.station.longitude = event[0];
|
||||
this.station.lattitude = event[1];
|
||||
}
|
||||
},
|
||||
separateLatlang() {
|
||||
//console.log("separateLatlang()");
|
||||
if (this.latlang.includes(',')) {
|
||||
@ -109,40 +121,45 @@
|
||||
console.log("saveStation(): ");
|
||||
console.log(this.station);
|
||||
console.log(this.isNewStation);
|
||||
console.log(this.isEndstation);
|
||||
console.log(this.$route.params.pos);
|
||||
console.log("Test Latlang: " + this.validateLatLangFormat());
|
||||
if(!this.validateLatLangFormat()){
|
||||
let title = "Falsche Formatierung";
|
||||
let msg = "Die Koordinaten sind in einer falschen Formatierung eingegeben. Beispiel: 49.98767, 9.87637";
|
||||
this.$store.commit('dialog/NEW_MESSAGE_DIALOG', {message: msg, title: title,});
|
||||
}
|
||||
if(this.validateEverything()) {
|
||||
// console.log("Test Latlang: " + this.validateLatLangFormat());
|
||||
// if(!this.validateLatLangFormat()){
|
||||
// let title = "Falsche Formatierung";
|
||||
// let msg = "Die Koordinaten sind in einer falschen Formatierung eingegeben. Beispiel: 49.98767, 9.87637";
|
||||
// this.$store.commit('dialog/NEW_MESSAGE_DIALOG', {message: msg, title: title,});
|
||||
// }
|
||||
if (this.isEndstation) {
|
||||
console.log(this.station)
|
||||
console.log("cacheCollector/SET_ENDSTATION")
|
||||
this.$store.commit('cacheCollector/SET_ENDSTATION', this.station);
|
||||
} else {
|
||||
if (this.isNewStation) {
|
||||
this.$store.commit('cacheCollector/ADD_STATION', this.station);
|
||||
} else {
|
||||
this.$store.commit('cacheCollector/EDIT_STATION', {index: this.$route.params.pos, station: this.station});
|
||||
this.$store.commit('cacheCollector/SET_TEMPSTATION', null);
|
||||
}
|
||||
|
||||
let cache = this.$store.getters['cacheCollector/GET_CACHE'];
|
||||
if (cache.hasOwnProperty('id')) {
|
||||
this.$router.push({path: `/cache/${cache.id}`});
|
||||
} else {
|
||||
this.$router.push({path: `/cache`});
|
||||
}
|
||||
console.log("Station saved");
|
||||
}
|
||||
|
||||
let cache = this.$store.getters['cacheCollector/GET_CACHE'];
|
||||
if (cache.hasOwnProperty('id')) {
|
||||
this.$router.push({path: `/cache/${cache.id}`});
|
||||
} else {
|
||||
this.$router.push({path: `/cache`});
|
||||
}
|
||||
console.log("Station saved");
|
||||
|
||||
},
|
||||
dismiss() {
|
||||
this.$store.commit('cacheCollector/SET_TEMPSTATION', null);
|
||||
if (!this.isEndstation) this.$store.commit('cacheCollector/SET_TEMPSTATION', null);
|
||||
this.$router.push({path: `/cache`});
|
||||
},
|
||||
validateLatLangFormat(){
|
||||
validateLatLangFormat() {
|
||||
var re = new RegExp('\\d+(\\.\\d+)?\\,(\\s)?\\d+(\\.\\d+)?');
|
||||
return re.test(this.latlang);
|
||||
},
|
||||
validateEverything(){
|
||||
validateEverything() {
|
||||
return this.validateLatLangFormat();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,97 +0,0 @@
|
||||
<template>
|
||||
<div class="q-ma-md">
|
||||
<p class="text-h5">Endstation</p>
|
||||
<p class="text-h6 q-mt-md">Location</p>
|
||||
<q-img transition="fade"
|
||||
class="q-mb-md "
|
||||
:ratio="16/9"
|
||||
src="https://www.buga2019.de/we-bilder/3.Gartenausstellung/Gelaendeplan/190320_Gelaendeplan-quadratisch.jpg"
|
||||
></q-img>
|
||||
<div class="row q-col-gutter-md">
|
||||
<q-input class="col" dense stack-label filled v-model="latlang" @input="separateLatlang"
|
||||
label="Breitengrad/Längengrad"/>
|
||||
<div class="col-shrink">
|
||||
<q-btn unelevated color="primary" class="full-height" icon="my_location"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <p class="text-h6 q-mt-md">Lösung</p>-->
|
||||
<!-- <q-input class="col" dense stack-label filled v-model="station.solution" label="Lösung"/>-->
|
||||
<!-- <q-input class="col q-mt-md" dense stack-label filled v-model="station.code" label="Code" readonly/>-->
|
||||
<div class="row reverse q-mt-md q-gutter-x-md">
|
||||
<q-btn @click="saveStation" unelevated color="primary" label="Speichern" icon-right="add"/>
|
||||
<q-btn @click="dismiss" unelevated color="negative" label="verwerfen" icon-right="delete"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "Station",
|
||||
|
||||
data() {
|
||||
return {
|
||||
description: "Rätsel, Aufgabe und Informationen zur Station.",
|
||||
latlang: "",
|
||||
station: {
|
||||
description: "Beschreibung",
|
||||
lattitude: 49.1474082,
|
||||
longitude: 9.2065282,
|
||||
solution: "",
|
||||
code: ""
|
||||
},
|
||||
// stationObject: null,
|
||||
}
|
||||
},
|
||||
// props: [ 'stationObject' ],
|
||||
created: function () {
|
||||
//this.isNewStation = (this.$route.params.pos === undefined);
|
||||
console.log("pos: " + this.$route.params.pos);
|
||||
console.log(this.$route);
|
||||
console.log(this.station);
|
||||
this.station = JSON.parse(JSON.stringify(this.tempStation));
|
||||
console.log(this.station);
|
||||
},
|
||||
beforeMount: function () {
|
||||
},
|
||||
mounted: function () {
|
||||
this.concatLatlang();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
tempStation: 'cacheCollector/GET_ENDSTATION'
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
separateLatlang() {
|
||||
//console.log("separateLatlang()");
|
||||
if (this.latlang.includes(',')) {
|
||||
this.station.lattitude = this.latlang.substr(0, this.latlang.indexOf(',')).trim();
|
||||
this.station.longitude = this.latlang.substr(this.latlang.indexOf(',') + 1, this.latlang.length).trim();
|
||||
console.log(this.latlang);
|
||||
console.log(this.station.lattitude + ", " + this.station.longitude);
|
||||
}
|
||||
},
|
||||
concatLatlang() {
|
||||
this.latlang = this.station.lattitude + ", " + this.station.longitude;
|
||||
},
|
||||
saveStation() {
|
||||
console.log("saveStation(): ");
|
||||
console.log(this.station);
|
||||
this.$store.commit('cacheCollector/SET_ENDSTATION', this.station);
|
||||
this.$router.push({path: `/cache`});
|
||||
console.log("station saved..");
|
||||
},
|
||||
dismiss() {
|
||||
//this.$store.commit('cacheCollector/SET_ENDSTATION', null);
|
||||
this.$router.push({path: `/cache`});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -2,19 +2,29 @@
|
||||
<div>
|
||||
<vl-map :load-tiles-while-animating="true" :load-tiles-while-interacting="true"
|
||||
data-projection="EPSG:4326" style="height: 200px" v-if="!cameraActive">
|
||||
<vl-view :zoom.sync="zoom" :center.sync="center" :rotation.sync="rotation"></vl-view>
|
||||
<vl-view :zoom.sync="zoom" :center.sync="center" :rotation.sync="rotation"></vl-view>
|
||||
|
||||
<vl-geoloc @update:position="geolocPosition = $event">
|
||||
<template slot-scope="geoloc">
|
||||
<vl-feature v-if="geoloc.position" id="position-feature">
|
||||
<vl-geom-point :coordinates="geoloc.position"></vl-geom-point>
|
||||
</vl-feature>
|
||||
</template>
|
||||
</vl-geoloc>
|
||||
<vl-feature ref="marker" v-for="station in cache.stationen" :key="station.id">
|
||||
<template>
|
||||
|
||||
<vl-layer-tile id="osm">
|
||||
<vl-source-osm></vl-source-osm>
|
||||
</vl-layer-tile>
|
||||
<vl-geom-point :coordinates="[station.longitude, station.lattitude]"></vl-geom-point>
|
||||
<vl-style-box>
|
||||
<vl-style-icon :src="getMarkerURL(station)" :scale="2.0" :anchor="[0.5, 1]"></vl-style-icon>
|
||||
</vl-style-box>
|
||||
</template>
|
||||
</vl-feature>
|
||||
|
||||
<vl-geoloc @update:position="geolocPosition = $event">
|
||||
<template slot-scope="geoloc">
|
||||
<vl-feature v-if="geoloc.position" id="position-feature">
|
||||
<vl-geom-point :coordinates="geoloc.position"></vl-geom-point>
|
||||
</vl-feature>
|
||||
</template>
|
||||
</vl-geoloc>
|
||||
|
||||
<vl-layer-tile id="osm">
|
||||
<vl-source-osm></vl-source-osm>
|
||||
</vl-layer-tile>
|
||||
</vl-map>
|
||||
<div class="q-ma-md" v-if="!cameraActive">
|
||||
<p class="text-h4">{{ cache.name }}</p>
|
||||
@ -47,6 +57,7 @@ Vue.use(VueLayers);
|
||||
stationen: [],
|
||||
},
|
||||
station: {},
|
||||
markercolor: "red",
|
||||
cameraActive: false,
|
||||
result: null,
|
||||
zoom: 15,
|
||||
@ -109,6 +120,11 @@ Vue.use(VueLayers);
|
||||
})
|
||||
},
|
||||
|
||||
getMarkerURL(station) {
|
||||
console.log(station);
|
||||
return `./statics/map-marker_${this.markercolor}.svg`
|
||||
},
|
||||
|
||||
updateResult(event) {
|
||||
console.log("updateResult()");
|
||||
console.log(event);
|
||||
|
||||
@ -63,7 +63,7 @@ const routes = [
|
||||
{
|
||||
path: "/endstation/",
|
||||
component: () => import("layouts/MyLayout.vue"),
|
||||
children: [{ path: "", component: () => import("pages/StationEndEdit.vue") }],
|
||||
children: [{ path: "", component: () => import("pages/StationEdit.vue") }],
|
||||
meta: {
|
||||
public: false, // Allow access to even if not logged in
|
||||
onlyWhenLoggedOut: false,
|
||||
@ -83,7 +83,7 @@ const routes = [
|
||||
{
|
||||
path: "/tempendstation/",
|
||||
component: () => import("layouts/MyLayout.vue"),
|
||||
children: [{path: "", component: () => import("pages/StationEndEdit.vue")}],
|
||||
children: [{path: "", component: () => import("pages/StationEdit.vue")}],
|
||||
meta: {
|
||||
public: false, // Allow access to even if not logged in
|
||||
onlyWhenLoggedOut: false,
|
||||
|
||||
|
Before Width: | Height: | Size: 889 B After Width: | Height: | Size: 889 B |
Loading…
Reference in New Issue
Block a user