Skip to content

Commit f8a057b

Browse files
committed
Add map
1 parent 1f61f1a commit f8a057b

File tree

3 files changed

+143
-6
lines changed

3 files changed

+143
-6
lines changed

resources/vue/components/TripCreation/StationInput.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,12 @@ export default {
198198
:aria-label="placeholder" aria-describedby="basic-addon1"
199199
v-model="stationInput" @focusin="showModal"
200200
>
201-
<span class="input-group-text font-monospace">
202-
{{ this.timeFieldB }}
203-
</span>
204201
<span class="input-group-text font-monospace" v-if="departure && arrival">
205202
{{ this.timeFieldA }}
206203
</span>
204+
<span class="input-group-text font-monospace">
205+
{{ this.timeFieldB }}
206+
</span>
207207
<button class="btn btn-sm btn-outline-danger input-group-button py-1" type="button" @click="$emit('delete')">
208208
<i class="fas fa-trash-alt"></i>
209209
</button>
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
<script>
2+
import {defineComponent} from 'vue'
3+
import 'leaflet';
4+
import {trans} from "laravel-vue-i18n";
5+
6+
const trainIcon = L.divIcon({
7+
className: 'custom-div-icon',
8+
html: '<div style="background-color:#c30b82;" class="marker-pin">&nbsp;</div>',
9+
iconSize: [20, 20],
10+
iconAnchor: [9, 18]
11+
});
12+
13+
export default defineComponent({
14+
name: "TripCreationMap",
15+
props: {
16+
mapProvider: {
17+
type: String,
18+
default: 'default'
19+
},
20+
},
21+
data() {
22+
return {
23+
map: null,
24+
points: [],
25+
origin: null,
26+
destination: null,
27+
}
28+
},
29+
computed: {
30+
mapStyle() {
31+
return '';
32+
}
33+
},
34+
mounted() {
35+
this.renderMap();
36+
this.initializeMap();
37+
let temp = this;
38+
},
39+
methods: {
40+
trans,
41+
renderMap() {
42+
this.map = L.map(this.$refs.map, {
43+
center: [50.3, 10.47],
44+
zoom: 5
45+
});
46+
setTilingLayer(this.$props.mapProvider, this.map);
47+
},
48+
clearAllElements() {
49+
this.points.forEach(point => {
50+
if (point.marker) {
51+
point.marker.remove()
52+
}
53+
});
54+
this.points = [];
55+
},
56+
addMarker(data, index) {
57+
console.log(index);
58+
let marker = L.marker(
59+
[data.latitude, data.longitude],
60+
{icon: trainIcon}
61+
).addTo(this.map);
62+
63+
if (index === "origin") {
64+
this.origin = this.createPointObject(data, marker);
65+
} else if (index === "destination") {
66+
this.destination = this.createPointObject(data, marker);
67+
} else {
68+
if (index === 0 || index === this.points.length) {
69+
this.points.push(this.createPointObject(data, marker));
70+
} else {
71+
this.points.splice(index, 0, this.createPointObject(data, marker));
72+
}
73+
}
74+
75+
this.zoomToMarkers();
76+
},
77+
zoomToMarkers() {
78+
let points = this.points;
79+
80+
if (this.origin) {
81+
points = [this.origin, ...points];
82+
}
83+
84+
if (this.destination) {
85+
points = [...points, this.destination];
86+
}
87+
88+
let bounds = new L.featureGroup(
89+
points.map(point => point.marker)
90+
);
91+
this.map.fitBounds(bounds.getBounds());
92+
},
93+
removeMarker(index) {
94+
this.points[index].marker.remove();
95+
this.points.splice(index, 1);
96+
},
97+
initializeMap() {
98+
this.clearAllElements();
99+
100+
},
101+
createPointObject(point, marker = null) {
102+
return {
103+
marker: marker ?? null,
104+
}
105+
},
106+
}
107+
})
108+
</script>
109+
110+
<template>
111+
112+
<div
113+
class="map h-100"
114+
ref="map"
115+
></div>
116+
</template>
117+
118+
<style>
119+
.marker-pin {
120+
width: 20px;
121+
height: 20px;
122+
border-radius: 50% 50% 50% 0;
123+
border-color: #830b62;
124+
border-width: 1px;
125+
background: #c30b82;
126+
position: absolute;
127+
transform: rotate(-45deg);
128+
left: 50%;
129+
top: 50%;
130+
margin: -15px 0 0 -15px;
131+
}
132+
</style>

resources/vue/components/TripCreation/TripCreationPage.vue

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import StationRow from "./StationRow.vue";
33
import {DateTime} from "luxon";
44
import {trans} from "laravel-vue-i18n";
55
import StationInput from "./StationInput.vue";
6+
import TripCreationMap from "./TripCreationMap.vue";
67
78
export default {
89
name: "TripCreationForm",
9-
components: {StationInput, StationRow},
10+
components: {TripCreationMap, StationInput, StationRow},
1011
mounted() {
1112
this.initForm();
1213
this.loadOperators();
@@ -68,10 +69,12 @@ export default {
6869
this.stopovers.push(dummyStopover);
6970
},
7071
removeStopover(index) {
72+
this.$refs.map.removeMarker(index);
7173
this.stopovers.splice(index, 1);
7274
this.validateTimes(); // Optional: Zeiten erneut validieren
7375
},
7476
setOrigin(item) {
77+
this.$refs.map.addMarker(item, "origin");
7578
this.origin = item;
7679
this.form.originId = item.id;
7780
},
@@ -80,6 +83,7 @@ export default {
8083
this.validateTimes();
8184
},
8285
setDestination(item) {
86+
this.$refs.map.addMarker(item, "destination");
8387
this.destination = item;
8488
this.form.destinationId = item.id;
8589
},
@@ -155,6 +159,7 @@ export default {
155159
});
156160
},
157161
setStopoverStation(item, key) {
162+
this.$refs.map.addMarker(item, key);
158163
this.stopovers[key].station = item;
159164
},
160165
setStopoverDeparture(time, key) {
@@ -361,8 +366,8 @@ export default {
361366
</form>
362367

363368
</div>
364-
<div class="col d-none d-md-block bg-warning">
365-
col 2
369+
<div class="col d-none d-md-block bg-warning px-0">
370+
<TripCreationMap ref="map"></TripCreationMap>
366371
</div>
367372
</div>
368373
</template>

0 commit comments

Comments
 (0)