Skip to content

Commit

Permalink
Feat/dave 180 versetzen der messstelle (#57)
Browse files Browse the repository at this point in the history
* neuer Tab zur Verschiebung der Messstelle

* refactor

* fix readonly Messstellen

* fix zindex
  • Loading branch information
Der-Alex-K authored Apr 4, 2024
1 parent 6fe9769 commit 5f9ecae
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 45 deletions.
1 change: 1 addition & 0 deletions frontend/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ declare module '@vue/runtime-core' {
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SaveLeaveDialog: typeof import('./src/components/common/SaveLeaveDialog.vue')['default']
StandortTabItem: typeof import('./src/components/messstelle/StandortTabItem.vue')['default']
TheSnackbar: typeof import('./src/components/common/TheSnackbar.vue')['default']
TooltipWithIcon: typeof import('./src/components/icons/TooltipWithIcon.vue')['default']
UnreadMessages: typeof import('./src/components/app/UnreadMessages.vue')['default']
Expand Down
117 changes: 79 additions & 38 deletions frontend/src/components/map/MiniMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,69 +12,107 @@
</template>

<script setup lang="ts">
import L, { Icon, LatLng, Marker } from "leaflet";
import { computed, ComputedRef, onMounted } from "vue";
import L, { Icon, LatLng } from "leaflet";
import { computed, ComputedRef, onMounted, Ref, ref, watch } from "vue";
import markerIconRed from "@/assets/marker-icon-red.png";
import markerIconDiamondRed from "@/assets/cards-diamond-red.png";
interface Props {
coords: LatLng;
height?: string;
width?: string;
minheight?: string;
isMessstelle?: boolean;
resetMarker?: boolean;
draggable?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
height: "100%",
width: "100%",
minheight: "160px",
isMessstelle: false,
resetMarker: false,
draggable: true,
});
const emit = defineEmits<(e: "updateZaehlstellenCoords", v: LatLng) => void>();
const mapAttribution =
'&copy; <a href="https://stadt.muenchen.de/infos/geobasisdaten.html">GeodatenService München</a>';
const map: Ref<L.Map | undefined> = ref(undefined);
const marker = ref(createMarker());
onMounted(() => {
const map = createMap();
createLayersAndAddToMap(map);
const resetMarkerSwitch: ComputedRef<boolean> = computed(() => {
return props.resetMarker;
});
const marker = createMarker();
marker.addTo(map);
watch(resetMarkerSwitch, () => {
resetMarker();
});
map.whenReady(() =>
setTimeout(() => {
map.invalidateSize();
}, 10)
);
onMounted(() => {
createMap();
initMap();
});
function createMap(): L.Map {
const map = new L.Map("map", {
minZoom: 10,
maxZoom: 18,
preferCanvas: false,
attributionControl: false,
fullscreenControl: true,
fullscreenControlOptions: {
position: "topleft",
},
});
function initMap(): void {
if (map.value) {
map.value.setView(props.coords, 18);
createLayersAndAddToMap();
marker.value.addTo(map.value);
map.value.whenReady(() =>
setTimeout(() => {
if (map.value) {
map.value.invalidateSize();
map.value.addControl(
L.control.attribution({
position: "bottomleft",
prefix: "Leaflet",
})
);
}
}, 10)
);
}
}
map.setView(props.coords, 18);
function resetMarker(): void {
if (map.value) {
marker.value.removeFrom(map.value);
marker.value = createMarker();
marker.value.addTo(map.value);
}
}
return map;
function createMap(): void {
if (!map.value) {
map.value = new L.Map("map", {
minZoom: 10,
maxZoom: 18,
preferCanvas: false,
attributionControl: false,
fullscreenControl: true,
fullscreenControlOptions: {
position: "topleft",
},
});
}
}
function createLayersAndAddToMap(map: L.Map): void {
const baseMaps = createBaseLayersAndAddDefaultToMap(map);
const overlayMaps = createOverlayLayers();
L.control.layers(baseMaps, overlayMaps).addTo(map);
function createLayersAndAddToMap(): void {
if (map.value) {
const baseLayers = createBaseLayers();
const overlayLayers = createOverlayLayers();
baseLayers.Stadtkarte.addTo(map.value);
L.control.layers(baseLayers, overlayLayers).addTo(map.value);
}
}
function createBaseLayersAndAddDefaultToMap(
map: L.Map
): L.Control.LayersObject {
function createBaseLayers(): L.Control.LayersObject {
const stadtkarteGesamt = L.tileLayer.wms(
"https://geoportal.muenchen.de/geoserver/gsm/wms?",
{
Expand All @@ -83,7 +121,6 @@ function createBaseLayersAndAddDefaultToMap(
attribution: mapAttribution,
}
);
stadtkarteGesamt.addTo(map);
const luftbild = L.tileLayer.wms(
"https://geoportal.muenchen.de/geoserver/gsm/wms?",
Expand Down Expand Up @@ -136,14 +173,18 @@ function createOverlayLayers(): L.Control.LayersObject {
};
}
function createMarker(): Marker {
function createMarker(): L.Marker {
let defaultIcon = new Icon.Default();
defaultIcon.options.iconUrl = markerIconRed;
if (props.isMessstelle) {
defaultIcon.options.iconUrl = markerIconDiamondRed;
} else {
defaultIcon.options.iconUrl = markerIconRed;
}
const marker = L.marker(props.coords, {
icon: defaultIcon,
opacity: 1.0,
draggable: true,
draggable: props.draggable,
});
marker.on("dragend", () => {
Expand All @@ -154,7 +195,7 @@ function createMarker(): Marker {
}
const mapStyle: ComputedRef<string> = computed(() => {
return `height: ${props.height}; width: ${props.width}; min-height: ${props.minheight}`;
return `height: ${props.height}; width: ${props.width}; min-height: ${props.minheight}; z-index: 1`;
});
</script>

Expand Down
66 changes: 66 additions & 0 deletions frontend/src/components/messstelle/StandortTabItem.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<template>
<v-sheet
width="100%"
:min-height="height"
:max-height="height"
class="overflow-y-auto"
>
<v-card elevation="0">
<v-card-text>
<mini-map
:coords="coords"
:height="heightMap"
width="100%"
:is-messstelle="true"
:show-attribution="true"
:reset-marker="resetMarker"
:draggable="draggable"
@updateZaehlstellenCoords="updateZaehlstellenCoords"
/>
</v-card-text>
</v-card>
</v-sheet>
</template>

<script setup lang="ts">
import MiniMap from "@/components/map/MiniMap.vue";
import { LatLng } from "leaflet";
import MessstelleEditDTO from "@/domain/dto/messstelle/MessstelleEditDTO";
import { computed, ComputedRef } from "vue";
import DefaultObjectCreator from "@/util/DefaultObjectCreator";
interface Props {
height: string;
heightMap: string;
resetMarker: boolean;
draggable: boolean;
value: MessstelleEditDTO;
}
const props = defineProps<Props>();
const emits = defineEmits<{
(e: "input", v: MessstelleEditDTO): void;
}>();
const editMessstelle = computed({
get: () => props.value,
set: (v) => emits("input", v),
});
const coords: ComputedRef<LatLng> = computed(() => {
let coords = DefaultObjectCreator.createCenterOfMunichLatLng();
if (editMessstelle.value.latitude && editMessstelle.value.longitude) {
return new LatLng(
editMessstelle.value.latitude,
editMessstelle.value.longitude
);
}
return coords;
});
function updateZaehlstellenCoords(newCoords: LatLng): void {
editMessstelle.value.latitude = newCoords.lat;
editMessstelle.value.longitude = newCoords.lng;
}
</script>
36 changes: 29 additions & 7 deletions frontend/src/components/messstelle/UpdateMessstelleForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,16 @@
Messquerschnitt
<v-icon>mdi-routes</v-icon>
</v-tab>
<v-tab>
Standort
<v-icon>mdi-map-marker-outline</v-icon>
</v-tab>
<v-tab>
Lagepläne
<v-icon>mdi-map-outline</v-icon>
</v-tab>
</v-tabs>
<div v-if="isMessstelleInPlanung">
<div v-if="isMessstelleReadonly">
<v-row
dense
justify="center"
Expand Down Expand Up @@ -59,23 +63,32 @@
v-model="messstelle"
:valid.sync="validMst"
:height="contentHeightVh"
:disabled="isMessstelleInPlanung"
:disabled="isMessstelleReadonly"
/>
</v-tab-item>
<v-tab-item ref="messquerschnittform">
<messquerschnitt-form
v-model="messstelle"
:valid.sync="validMqs"
:height="contentHeightVh"
:disabled="isMessstelleInPlanung"
:disabled="isMessstelleReadonly"
/>
</v-tab-item>
<v-tab-item ref="standort">
<standort-tab-item
v-model="messstelle"
:height="contentHeightVh"
:height-map="mapHeightVh"
:reset-marker="resetMarker"
:draggable="!isMessstelleReadonly"
/>
</v-tab-item>
<v-tab-item ref="lageplaene">
<lageplan-form :height="contentHeightVh" />
</v-tab-item>
</v-tabs-items>

<v-card-actions v-if="!isMessstelleInPlanung">
<v-card-actions v-if="!isMessstelleReadonly">
<v-spacer />
<v-btn
color="secondary"
Expand Down Expand Up @@ -106,13 +119,15 @@ import DefaultObjectCreator from "@/util/DefaultObjectCreator";
import { MessstelleStatus } from "@/domain/enums/MessstelleStatus";
import LageplanForm from "@/components/messstelle/LageplanForm.vue";
import { useVuetify } from "@/util/useVuetify";
import StandortTabItem from "@/components/messstelle/StandortTabItem.vue";
const activeTab: Ref<number> = ref(0);
const validMst: Ref<boolean> = ref(false);
const validMqs: Ref<Map<string, boolean>> = ref(new Map<string, boolean>());
const messstelle: Ref<MessstelleEditDTO> = ref(
DefaultObjectCreator.createDefaultMessstelleEditDTO()
);
const resetMarker: Ref<boolean> = ref(false);
interface Props {
height: string;
Expand All @@ -125,13 +140,19 @@ const store = useStore();
const route = useRoute();
const vuetify = useVuetify();
const isMessstelleInPlanung: ComputedRef<boolean> = computed(() => {
const isMessstelleReadonly: ComputedRef<boolean> = computed(() => {
return messstelle.value.status === MessstelleStatus.IN_PLANUNG;
});
const contentHeightVh: ComputedRef<string> = computed(() => {
return props.contentHeight - 70 / (vuetify.breakpoint.height / 100) + "vh";
});
const mapHeightVh: ComputedRef<string> = computed(() => {
return props.contentHeight - 105 / (vuetify.breakpoint.height / 100) + "vh";
});
const emit = defineEmits<(e: "reload") => void>();
onMounted(() => {
loadMessstelle();
});
Expand All @@ -150,14 +171,14 @@ function save(): void {
})
.finally(() => {
activeTab.value = 0;
loadMessstelle();
emit("reload");
});
}
}
function cancel(): void {
activeTab.value = 0;
loadMessstelle();
emit("reload");
}
function loadMessstelle(): void {
Expand All @@ -168,6 +189,7 @@ function loadMessstelle(): void {
messstelleById.messquerschnitte.forEach((value) =>
validMqs.value.set(value.mqId, !!value.standort)
);
resetMarker.value = !resetMarker.value;
}
);
}
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/views/MessstelleView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<update-messstelle-form
:height="heightVh"
:content-height="contentHeight"
@reload="loadMessstelle"
/>
</v-row>
</v-container>
Expand Down Expand Up @@ -136,6 +137,7 @@ function loadMessstelle(): void {
const messstelleId = route.params.messstelleId;
MessstelleService.getMessstelleInfo(messstelleId).then((messstelleById) => {
messstelle.value = messstelleById;
reloadMessstelleMap.value = !reloadMessstelleMap.value;
});
}
</script>

0 comments on commit 5f9ecae

Please sign in to comment.