Skip to content

Commit

Permalink
Merge pull request #417 from geoadmin/feat_BGDIINF_SB-2958_groundwork…
Browse files Browse the repository at this point in the history
…_cesium_components
  • Loading branch information
pakb authored Jun 29, 2023
2 parents bedbd7c + 0a0f44e commit 73b9188
Show file tree
Hide file tree
Showing 19 changed files with 172 additions and 176 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<template>
<slot />
</template>
<script>
import { LV95, WEBMERCATOR } from '@/utils/coordinateSystems'
import { FeatureStyleColor, RED } from '@/utils/featureStyleUtils'
import Overlay from 'ol/Overlay'
import proj4 from 'proj4'
export default {
inject: ['getMap'],
props: {
coordinates: {
type: Array,
default: null,
},
trackingPointColor: {
type: FeatureStyleColor,
default: RED,
},
},
watch: {
coordinates(newCoordinates) {
if (newCoordinates) {
this.currentHoverPosOverlay.setPosition(
proj4(LV95.epsg, WEBMERCATOR.epsg, newCoordinates)
)
this.addHoverPositionOverlay()
} else {
this.currentHoverPosOverlay.setPosition(null)
this.removeHoverPositionOverlay()
}
},
trackingPointColor(newColor) {
this.currentHoverPosOverlay.getElement().style.backgroundColor = newColor.fill
},
},
mounted() {
// Overlay that shows the corresponding position on the OL map when hovering over the profile graph.
this.currentHoverPosOverlay = new Overlay({
element: document.createElement('div'),
positioning: 'center-center',
stopEvent: false,
})
// setting up a CSS class on the element so that we can style it (see below in the <style> section)
this.currentHoverPosOverlay.getElement().classList.add('profile-circle-current-hover-pos')
this.currentHoverPosOverlay.getElement().style.backgroundColor =
this.trackingPointColor.fill
if (this.coordinates) {
this.currentHoverPosOverlay.setPosition(
proj4(LV95.epsg, WEBMERCATOR.epsg, this.coordinates)
)
this.addHoverPositionOverlay()
}
},
unmounted() {
this.removeHoverPositionOverlay()
},
methods: {
addHoverPositionOverlay() {
this.getMap()?.addOverlay(this.currentHoverPosOverlay)
},
removeHoverPositionOverlay() {
this.getMap()?.removeOverlay(this.currentHoverPosOverlay)
},
},
}
</script>
2 changes: 1 addition & 1 deletion src/modules/infobox/InfoboxModule.vue
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export default {
},
setMaxHeight() {
if (!this.showContainer) {
if (!this.showContainer || !this.$refs.content) {
return
}
Expand Down
1 change: 0 additions & 1 deletion src/modules/infobox/components/FeatureElevationProfile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export default {
FeatureElevationProfilePlot,
FeatureElevationProfileInformation,
},
inject: ['getMap'],
props: {
feature: {
type: EditableFeature,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export default {
@import 'src/scss/webmapviewer-bootstrap-theme';
.profile-info-container {
overflow-x: auto;
max-width: 100vw;
max-width: 100%;
}
.profile-popup-info-buttons {
button {
Expand Down
59 changes: 15 additions & 44 deletions src/modules/infobox/components/FeatureElevationProfilePlot.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<div
ref="profileChartContainer"
@mouseenter="addHoverPositionOverlay"
@mouseleave="removeHoverPositionOverlay"
@mouseenter="startPositionTracking"
@mouseleave="stopPositionTracking"
>
<LineChart
ref="chart"
Expand Down Expand Up @@ -47,19 +47,24 @@
class="profile-tooltip-arrow"
:style="tooltipArrowStyle"
></div>
<FeatureElevationProfilePlotOpenLayersBridge
v-if="!showIn3d"
:tracking-point-color="trackingPointColor"
:coordinates="pointBeingHovered?.coordinates"
/>
<!--TODO BGDIINF_SB-2977 : create a position tracker for Cesium, similar to FeatureElevationProfilePlotOpenLayersBridge-->
</div>
</div>
</template>
<script>
import ElevationProfile from '@/api/profile/ElevationProfile.class'
import { LV95, WEBMERCATOR } from '@/utils/coordinateSystems'
import FeatureElevationProfilePlotOpenLayersBridge from '@/modules/infobox/FeatureElevationProfilePlotOpenLayersBridge.vue'
import { FeatureStyleColor } from '@/utils/featureStyleUtils'
import { round } from '@/utils/numberUtils'
import { resetZoom } from 'chartjs-plugin-zoom'
import Overlay from 'ol/Overlay'
import proj4 from 'proj4'
import { Line as LineChart } from 'vue-chartjs'
import { mapState } from 'vuex'
const GAP_BETWEEN_TOOLTIP_AND_PROFILE = 12 //px
Expand All @@ -80,9 +85,9 @@ const GAP_BETWEEN_TOOLTIP_AND_PROFILE = 12 //px
*/
export default {
components: {
FeatureElevationProfilePlotOpenLayersBridge,
LineChart,
},
inject: ['getMap'],
props: {
elevationProfile: {
type: ElevationProfile,
Expand All @@ -108,6 +113,9 @@ export default {
}
},
computed: {
...mapState({
showIn3d: (state) => state.ui.showIn3d,
}),
tooltipStyle() {
if (this.pointBeingHovered) {
const tooltipWidth = this.$refs.profileTooltip.clientWidth
Expand Down Expand Up @@ -264,7 +272,7 @@ export default {
this.clearHoverPosition()
return
}
if (tooltip.dataPoints.length > 0) {
if (tooltip.dataPoints.length > 0 && this.track) {
const point = tooltip.dataPoints[0]
const chartPosition = chart.canvas.getBoundingClientRect()
this.pointBeingHovered = {
Expand Down Expand Up @@ -351,58 +359,21 @@ export default {
}
},
},
watch: {
/** Updating the tracking point color if the props with the color is changed */
trackingPointColor(newColor) {
this.currentHoverPosOverlay.getElement().style.backgroundColor = newColor.fill
},
pointBeingHovered(newPoint) {
if (newPoint) {
this.currentHoverPosOverlay.setPosition(
proj4(LV95.epsg, WEBMERCATOR.epsg, newPoint.coordinates)
)
} else {
this.currentHoverPosOverlay.setPosition(null)
}
},
},
mounted() {
/* Overlay that shows the corresponding position on the map when hovering over the profile
graph. */
this.currentHoverPosOverlay = new Overlay({
element: document.createElement('div'),
positioning: 'center-center',
stopEvent: false,
})
// setting up a CSS class on the element so that we can style it (see below in the <style> section)
this.currentHoverPosOverlay.getElement().classList.add('profile-circle-current-hover-pos')
this.currentHoverPosOverlay.getElement().style.backgroundColor =
this.trackingPointColor.fill
this.$nextTick(() => {
// sending an update event after Vue-ChartJS has been rendered, so that the parent container can be resized
// to fit the canvas from Vue-ChartJS
// see FeatureElevationProfile and InfoboxModule height logic for more comprehension
this.$emit('update')
})
},
unmounted() {
this.getMap().removeOverlay(this.currentHoverPosOverlay)
},
methods: {
startPositionTracking() {
this.track = true
},
stopPositionTracking() {
this.track = false
},
addHoverPositionOverlay() {
this.startPositionTracking()
this.getMap().addOverlay(this.currentHoverPosOverlay)
},
removeHoverPositionOverlay() {
this.stopPositionTracking()
this.getMap().removeOverlay(this.currentHoverPosOverlay)
},
clearHoverPosition() {
this.pointBeingHovered = null
},
Expand Down
24 changes: 22 additions & 2 deletions src/modules/map/MapModule.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,35 @@
<!-- So that external modules can have access to the map instance through the provided 'getMap' -->
<slot />
<LocationPopup />
<teleport :to="`#map-footer-${isPhoneMode ? 'mobile-' : ''}scale-line`">
<OpenLayersScale />
</teleport>
<teleport to="#map-footer-mouse-tracker">
<OpenLayersMouseTracker />
</teleport>
<teleport to="#toolbox-compass-button">
<OpenLayersCompassButton />
</teleport>
</OpenLayersMap>
<WarningRibbon />
</div>
</template>

<script>
import OpenLayersCompassButton from '@/modules/map/components/openlayers/OpenLayersCompassButton.vue'
import OpenLayersMouseTracker from '@/modules/map/components/openlayers/OpenLayersMouseTracker.vue'
import OpenLayersScale from '@/modules/map/components/openlayers/OpenLayersScale.vue'
import { UIModes } from '@/store/modules/ui.store'
import { defineAsyncComponent } from 'vue'
import { mapState } from 'vuex'
import LocationPopup from './components/LocationPopup.vue'
import WarningRibbon from './components/WarningRibbon.vue'
import { mapState } from 'vuex'
import { defineAsyncComponent } from 'vue'
export default {
components: {
OpenLayersCompassButton,
OpenLayersMouseTracker,
OpenLayersScale,
LocationPopup,
WarningRibbon,
OpenLayersMap: defineAsyncComponent(() =>
Expand All @@ -31,7 +47,11 @@ export default {
computed: {
...mapState({
is3DActive: (state) => state.ui.showIn3d,
uiMode: (state) => state.ui.mode,
}),
isPhoneMode() {
return this.uiMode === UIModes.PHONE
},
},
}
</script>
Expand Down
4 changes: 2 additions & 2 deletions src/modules/map/components/cesium/CesiumMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ export default {
z-index: $zindex-map;
.cesium-widget canvas {
width: 100vw;
height: 100vh;
width: 100%;
height: 100%;
}
.cesium-viewer-bottom {
Expand Down
41 changes: 5 additions & 36 deletions src/modules/map/components/footer/MapFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,15 @@
<div class="map-background-selector">
<MapFooterBackgroundSelector />
</div>
<MapFooterScale :current-zoom="zoom" class="scale-line-phone" />
<div id="map-footer-mobile-scale-line" />
</div>
</div>
<div id="map-footer-middle" class="map-footer-middle">
<!-- Infobox, Profile, ... -->
<!-- teleport for: Infobox, Profile, ... -->
</div>
<div class="map-footer-bottom">
<MapFooterScale :current-zoom="zoom" />
<MapFooterProjection
:displayed-projection-id="displayedProjectionId"
@projection-change="setDisplayedProjectionWithId"
/>
<MapFooterMousePosition :displayed-projection-id="displayedProjectionId" />
<div id="map-footer-scale-line" />
<div id="map-footer-mouse-tracker" class="d-flex gap-1 align-items-center" />
<span class="map-footer-bottom-spacer" />
<MapFooterAppVersion />
<MapFooterAppCopyright />
Expand All @@ -28,47 +24,26 @@

<script>
import MapFooterAttributionList from '@/modules/map/components/footer/MapFooterAttributionList.vue'
import { mapActions, mapState } from 'vuex'
import { mapState } from 'vuex'
import MapFooterAppCopyright from './MapFooterAppCopyright.vue'
import MapFooterAppVersion from './MapFooterAppVersion.vue'
import MapFooterBackgroundSelector from './MapFooterBackgroundSelector.vue'
import MapFooterMousePosition from './MapFooterMousePosition.vue'
import MapFooterProjection from './MapFooterProjection.vue'
import MapFooterScale from './MapFooterScale.vue'
export default {
components: {
MapFooterAttributionList,
MapFooterAppCopyright,
MapFooterAppVersion,
MapFooterBackgroundSelector,
MapFooterMousePosition,
MapFooterProjection,
MapFooterScale,
},
computed: {
...mapState({
zoom: (state) => state.position.zoom,
isFullscreenMode: (state) => state.ui.fullscreenMode,
displayedProjectionId: (state) => state.map.displayedProjection.id,
}),
},
methods: {
...mapActions(['setDisplayedProjectionWithId']),
},
}
</script>

<style lang="scss">
@import 'src/scss/webmapviewer-bootstrap-theme';
/* Must be unscoped, as the scaleLine is defined in the child component MapFooterScale.vue */
.scale-line-phone .scale-line-inner {
/* If in phone mode, we need a background color, as the scale line is directly displayed on the
map in this case. */
background-color: rgba($white, 0.7);
}
</style>

<style lang="scss" scoped>
@import 'src/scss/media-query.mixin';
@import 'src/scss/webmapviewer-bootstrap-theme';
Expand Down Expand Up @@ -105,12 +80,6 @@ $flex-gap: 1em;
@include respond-above(tablet) {
flex-direction: column-reverse;
}
.scale-line-phone {
font-size: 0.6rem;
@include respond-above(phone) {
display: none;
}
}
}
&-middle {
Expand Down
Loading

0 comments on commit 73b9188

Please sign in to comment.