init show map and routes

This commit is contained in:
sedum 2022-09-18 23:15:22 +02:00
parent 5671e3b6ca
commit 838d1988ad
8 changed files with 171 additions and 14 deletions

138
components/Map.vue Normal file
View file

@ -0,0 +1,138 @@
<template lang="pug">
v-container
LMap(ref="map"
id="leaflet-map"
:zoom="zoom"
:center="center")
LTileLayer(
:url="url"
:attribution="attribution")
LMarker(
v-for="item in markers"
:key="item.id"
:lat-lng="item.position"
:visible="item.visible"
:draggable="item.draggable")
v-row.my-4.d-flex.justify-center
v-btn.ml-2(icon large :href="routeByWalk()")
v-icon(v-text='mdiWalk' color='white')
v-btn.ml-2(icon large :href="routeByBike()")
v-icon(v-text='mdiBike' color='white')
v-btn.ml-2(icon large :href="routeByBus()")
v-icon(v-text='mdiBus' color='white')
v-btn.ml-2(icon large :href="routeByCar()")
v-icon(v-text='mdiCar' color='white')
</template>
<script>
import "leaflet/dist/leaflet.css";
import { LMap, LTileLayer, LMarker, LPopup } from 'vue2-leaflet';
import dayjs from 'dayjs';
import { mapActions, mapState } from 'vuex'
import { Icon } from 'leaflet';
import { mdiWalk, mdiBike, mdiCar, mdiBus } from '@mdi/js'
export default {
components: {
LMap,
LTileLayer,
LMarker,
LPopup
},
data ({ $store }) {
return {
mdiWalk, mdiBike, mdiCar, mdiBus,
// url: "https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png",
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution:
'&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors',
zoom: 10,
center: [42, 12],
markers: [],
osm_navigation: 'https://www.openstreetmap.org/directions?from=&to=',
routingType: [
{foot: "engine=fossgis_osrm_foot"},
{bike: "engine=fossgis_osrm_bike"},
{transit: null},
{car: "engine=fossgis_osrm_car"},
]
}
},
props: {
event: { type: Object, default: () => ({}) }
},
mounted() {
delete Icon.Default.prototype._getIconUrl;
Icon.Default.mergeOptions({
iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
iconUrl: require('leaflet/dist/images/marker-icon.png'),
shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});
setTimeout(() => {
this.$refs.map.mapObject.invalidateSize();
}, 200);
},
computed: {
...mapState(['settings']),
},
methods: {
...mapActions(['setSetting']),
routeByWalk() {
console.log(this.$root.$event)
// return this.osm_navigation+this.$root.event.place.details+'&'+this.routingType.bike
},
routeByBike() {
console.log(this.event.place)
// return this.osm_navigation+this.$root.event.place.details+'&'+this.routingType.bike
},
routeByBus() {
console.log(this.$root)
// return this.osm_navigation+this.$root.event.place.details+'&'+this.routingType.bike
},
routeByCar() {
console.log(this.$root)
// return this.osm_navigation+this.$root.event.place.details+'&'+this.routingType.bike
},
route() {
}
// loadMarker(d) {
// this.event = JSON.stringify(d);
//
// let newMarker = [{
// id: d.id,
// title: d.title,
// event: JSON.stringify(d),
// description: d.description,
// place: d.place,
// tags: d.tags,
// multidate: d.multidate,
// start_datetime: d.start_datetime,
// end_datetime: d.end_datetime,
// position: { lat: d.place.details.geometry.coordinates[1], lng: d.place.details.geometry.coordinates[0] },
// draggable: false,
// visible: true
// }]
//
// this.markers.push.apply(this.markers, newMarker)
// },
}
}
</script>
<style>
#leaflet-map {
height: 55vh;
width: 100%;
border-radius: .5rem;
border: 1px solid #fff;
z-index: 1;
}
</style>

View file

@ -47,7 +47,7 @@ v-row
v-list-item-content(two-line v-if='item')
v-list-item-title(v-text='item.display_name')
v-list-item-subtitle(v-text='`${item.lat}`+`,`+`${item.lon}`')
v-text-field(ref='details' v-show='false' v-if='settings.allow_geolocation')
v-text-field(ref='details' v-if='settings.allow_geolocation')
</template>
<script>

View file

@ -90,7 +90,8 @@
"max_events": "N. max events",
"label": "Label",
"collections": "Collections",
"close": "Close"
"close": "Close",
"show_map": "Show map"
},
"login": {
"description": "By logging in you can publish new events.",

View file

@ -54,6 +54,7 @@
"ics": "^2.37.0",
"jsdom": "^20.0.0",
"jsonwebtoken": "^8.5.1",
"leaflet": "^1.8.0",
"linkify-html": "^3.0.4",
"linkifyjs": "3.0.5",
"lodash": "^4.17.21",
@ -74,6 +75,7 @@
"umzug": "^2.3.0",
"v-calendar": "^2.4.1",
"vue-i18n": "^8.26.7",
"vue2-leaflet": "^2.7.1",
"vuetify": "2.6.9",
"winston": "^3.8.1",
"winston-daily-rotate-file": "^4.7.1",

View file

@ -20,7 +20,7 @@ v-container#event.pa-0.pa-sm-2
v-icon.float-right(v-if='event.parentId' color='success' v-text='mdiRepeat')
.title.text-h5.mb-5
strong.p-name.text--primary(itemprop="name") {{event.title}}
time.dt-start.text-h6(:datetime='event.start_datetime|unixFormat("YYYY-MM-DD HH:mm")' itemprop="startDate" :content="event.start_datetime|unixFormat('YYYY-MM-DDTHH:mm')")
v-icon(v-text='mdiCalendar')
strong.ml-2 {{event|when}}
@ -32,6 +32,11 @@ v-container#event.pa-0.pa-sm-2
v-icon(v-text='mdiMapMarker')
nuxt-link.vcard.ml-2.p-name.text-decoration-none(itemprop="name" :to='`/place/${event.place.name}`') {{event.place && event.place.name}}
.text-subtitle-1.p-street-address(itemprop='address') {{event.place && event.place.address}}
v-btn.mt-2(small v-text="$t('common.show_map')" :aria-label="$t('common.show_map')" @click="mapModal = true")
v-dialog(v-model='mapModal' :fullscreen='$vuetify.breakpoint.xsOnly' destroy-on-close)
v-card
client-only(placeholder='Loading...' )
Map(:event='event')
//- tags, hashtags
v-card-text.pt-0(v-if='event.tags && event.tags.length')
@ -50,7 +55,7 @@ v-container#event.pa-0.pa-sm-2
v-icon(v-text='mdiCalendarExport')
v-btn.ml-2(v-if='hasMedia' large icon :title="$t('event.download_flyer')" color='primary' :aria-label="$t('event.download_flyer')"
:href='event | mediaURL("download")')
v-icon(v-text='mdiFileDownloadOutline')
v-icon(v-text='mdiFileDownloadOutline')
.p-description.text-body-1.pa-3.rounded(v-if='hasMedia && event.description' itemprop='description' v-html='event.description')
@ -145,7 +150,8 @@ export default {
components: {
EventAdmin,
EmbedEvent,
MyPicture
MyPicture,
[process.client && 'Map']: () => import('@/components/Map.vue')
},
async asyncData ({ $axios, params, error }) {
try {
@ -163,7 +169,8 @@ export default {
event: {},
showEmbed: false,
showResources: false,
selectedResource: { data: { attachment: [] } }
selectedResource: { data: { attachment: [] } },
mapModal: false
}
},
head () {

View file

@ -34,7 +34,7 @@ const eventController = {
Sequelize.where(Sequelize.fn('LOWER', Sequelize.col('address')), 'LIKE', '%' + search + '%')
]
},
attributes: [['name', 'label'], 'address', 'id', [Sequelize.cast(Sequelize.fn('COUNT', Sequelize.col('events.placeId')), 'INTEGER'), 'w']],
attributes: [['name', 'label'], 'address', 'details', 'id', [Sequelize.cast(Sequelize.fn('COUNT', Sequelize.col('events.placeId')), 'INTEGER'), 'w']],
include: [{ model: Event, where: { is_visible: true }, required: true, attributes: [] }],
group: ['place.id'],
raw: true
@ -110,7 +110,7 @@ const eventController = {
attributes: ['tag'],
through: { attributes: [] }
},
{ model: Place, required: true, attributes: ['id', 'name', 'address'] }
{ model: Place, required: true, attributes: ['id', 'name', 'address', 'details'] }
],
replacements,
limit: 30,
@ -192,7 +192,7 @@ const eventController = {
},
include: [
{ model: Tag, required: false, attributes: ['tag'], through: { attributes: [] } },
{ model: Place, attributes: ['name', 'address', 'id'] },
{ model: Place, attributes: ['name', 'address', 'details', 'id'] },
{
model: Resource,
where: !is_admin && { hidden: false },
@ -626,7 +626,7 @@ const eventController = {
/**
* Method to search for events with pagination and filtering
* @returns
* @returns
*/
async _select({
start = dayjs().unix(),
@ -700,7 +700,7 @@ const eventController = {
attributes: ['tag'],
through: { attributes: [] }
},
{ model: Place, required: true, attributes: ['id', 'name', 'address'] }
{ model: Place, required: true, attributes: ['id', 'name', 'address', 'details'] }
],
...pagination,
replacements

View file

@ -105,7 +105,8 @@ Event.prototype.toAP = function (username, locale, to = []) {
endTime: this.end_datetime ? dayjs.unix(this.end_datetime).tz().locale(locale).format() : null,
location: {
name: this.place.name,
address: this.place.address
address: this.place.address,
details: this.place.details
},
attachment,
tag: tags && tags.map(tag => ({

View file

@ -7342,6 +7342,11 @@ launch-editor@^2.6.0:
picocolors "^1.0.0"
shell-quote "^1.7.3"
leaflet@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.8.0.tgz#4615db4a22a304e8e692cae9270b983b38a2055e"
integrity sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA==
leven@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
@ -12396,6 +12401,11 @@ vue-template-es2015-compiler@^1.9.0:
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
vue2-leaflet@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/vue2-leaflet/-/vue2-leaflet-2.7.1.tgz#2f95c287621bf778f10804c88223877f5c049257"
integrity sha512-K7HOlzRhjt3Z7+IvTqEavIBRbmCwSZSCVUlz9u4Rc+3xGCLsHKz4TAL4diAmfHElCQdPPVdZdJk8wPUt2fu6WQ==
vue@^2.7.0:
version "2.7.10"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.7.10.tgz#ae516cc6c88e1c424754468844218fdd5e280f40"
@ -12463,10 +12473,8 @@ watchpack@^1.7.4:
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453"
integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==
dependencies:
chokidar "^3.4.1"
graceful-fs "^4.1.2"
neo-async "^2.5.0"
watchpack-chokidar2 "^2.0.1"
optionalDependencies:
chokidar "^3.4.1"
watchpack-chokidar2 "^2.0.1"