Skip to content

Commit

Permalink
Merge pull request #435 from geoadmin/feat-BGDIINF_SB-3009_floating_t…
Browse files Browse the repository at this point in the history
…olltip

BGDIINF_SB-3009: Create a floating tooltip for Cesium (+ BGDIINF_SB-2977 Create a profile position tracker for Cesium)
  • Loading branch information
pakb authored Aug 21, 2023
2 parents 6c048a7 + c308012 commit f3dc6ca
Show file tree
Hide file tree
Showing 13 changed files with 766 additions and 195 deletions.
85 changes: 85 additions & 0 deletions src/modules/infobox/FeatureElevationProfilePlotCesiumBridge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<template>
<slot />
</template>
<script>
import { LV95, WGS84 } from '@/utils/coordinateSystems'
import { FeatureStyleColor, RED } from '@/utils/featureStyleUtils'
import proj4 from 'proj4'
import { CallbackProperty, Cartesian3, Color, Ellipsoid, Entity, HeightReference } from 'cesium'
export default {
inject: ['getViewer'],
props: {
coordinates: {
type: Array,
default: null,
},
trackingPointColor: {
type: FeatureStyleColor,
default: RED,
},
},
watch: {
coordinates(newCoordinates) {
if (newCoordinates) {
this.updatePosition()
if (!this.pointAdded) this.addTrackingPoint()
} else {
this.removeTrackingPoint()
}
},
trackingPointColor(newColor) {
this.pointFill = Color.fromCssColorString(newColor.fill)
this.pointBorder = Color.fromCssColorString(newColor.border)
this.getViewer()?.scene.requestRender()
},
},
mounted() {
this.pointAdded = false
this.trackingPointPosition = new Cartesian3()
this.pointFill = Color.fromCssColorString(this.trackingPointColor.fill)
this.pointBorder = Color.fromCssColorString(this.trackingPointColor.border)
this.trackingPoint = new Entity({
position: new CallbackProperty(() => this.trackingPointPosition, false),
point: {
show: true,
color: new CallbackProperty(() => this.pointFill, false),
outlineWidth: 5,
outlineColor: new CallbackProperty(() => this.pointBorder, false),
pixelSize: 15,
heightReference: HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
})
if (this.coordinates) {
this.updatePosition()
this.addTrackingPoint()
}
},
unmounted() {
this.removeTrackingPoint()
delete this.removeTrackingPoint()
},
methods: {
addTrackingPoint() {
this.pointAdded = true
this.getViewer()?.entities.add(this.trackingPoint)
},
removeTrackingPoint() {
this.pointAdded = false
this.getViewer()?.entities.remove(this.trackingPoint)
},
updatePosition() {
const wgs84Position = proj4(LV95.epsg, WGS84.epsg, this.coordinates)
Cartesian3.fromDegrees(
wgs84Position[0],
wgs84Position[1],
0,
Ellipsoid.WGS84,
this.trackingPointPosition
)
this.getViewer()?.scene.requestRender()
},
},
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@
:tracking-point-color="trackingPointColor"
:coordinates="pointBeingHovered?.coordinates"
/>
<!--TODO BGDIINF_SB-2977 : create a position tracker for Cesium, similar to FeatureElevationProfilePlotOpenLayersBridge-->
<FeatureElevationProfilePlotCesiumBridge
v-if="showIn3d"
:tracking-point-color="trackingPointColor"
:coordinates="pointBeingHovered?.coordinates"
/>
</div>
</div>
</template>
Expand All @@ -65,6 +69,7 @@ import { round } from '@/utils/numberUtils'
import { resetZoom } from 'chartjs-plugin-zoom'
import { Line as LineChart } from 'vue-chartjs'
import { mapState } from 'vuex'
import FeatureElevationProfilePlotCesiumBridge from '@/modules/infobox/FeatureElevationProfilePlotCesiumBridge.vue'
const GAP_BETWEEN_TOOLTIP_AND_PROFILE = 12 //px
Expand All @@ -86,6 +91,7 @@ const GAP_BETWEEN_TOOLTIP_AND_PROFILE = 12 //px
export default {
components: {
FeatureElevationProfilePlotOpenLayersBridge,
FeatureElevationProfilePlotCesiumBridge,
LineChart,
},
props: {
Expand Down
147 changes: 147 additions & 0 deletions src/modules/map/components/MapPopover.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<template>
<div
ref="mapPopover"
class="map-popover"
:class="{ cesium: is3DActive }"
data-cy="popover"
@contextmenu.stop
>
<div class="card">
<div class="card-header d-flex">
<span class="flex-grow-1 align-self-center">
{{ title }}
</span>
<slot name="extra-buttons"></slot>
<button
v-if="authorizePrint"
class="btn btn-sm btn-light d-flex align-items-center"
@click="printContent"
>
<FontAwesomeIcon icon="print" />
</button>
<button
class="btn btn-sm btn-light d-flex align-items-center"
data-cy="map-popover-close-button"
@click="onClose"
>
<FontAwesomeIcon icon="times" />
</button>
</div>
<div
id="mapPopoverContent"
ref="mapPopoverContent"
class="map-popover-content"
:class="{ 'card-body': useContentPadding }"
>
<slot />
</div>
</div>
</div>
<OpenLayersPopover v-if="!is3DActive" :coordinates="coordinates"></OpenLayersPopover>
<CesiumPopover v-if="is3DActive" :coordinates="coordinates"></CesiumPopover>
</template>

<script>
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import promptUserToPrintHtmlContent from '@/utils/print'
import OpenLayersPopover from '@/modules/map/components/openlayers/OpenLayersPopover.vue'
import CesiumPopover from '@/modules/map/components/cesium/CesiumPopover.vue'
import { mapState } from 'vuex'
/** Map popover content and styles. Position handling is done in corresponding library components */
export default {
components: { CesiumPopover, OpenLayersPopover, FontAwesomeIcon },
provide() {
return {
onClose: () => this.onClose(),
getMapPopoverRef: () => this.getMapPopoverRef(),
}
},
props: {
coordinates: {
type: Array,
required: true,
},
authorizePrint: {
type: Boolean,
default: false,
},
title: {
type: String,
default: '',
},
useContentPadding: {
type: Boolean,
default: false,
},
},
emits: ['close'],
computed: {
...mapState({
is3DActive: (state) => state.ui.showIn3d,
}),
},
methods: {
getMapPopoverRef() {
return this.$refs.mapPopover
},
onClose() {
this.$emit('close')
},
printContent() {
promptUserToPrintHtmlContent('mapPopoverContent')
},
},
}
</script>

<style lang="scss" scoped>
@import 'src/scss/webmapviewer-bootstrap-theme';
.map-popover {
pointer-events: none;
.card {
max-width: $overlay-width;
pointer-events: auto;
}
.map-popover-content {
max-height: 350px;
overflow-y: auto;
}
.card-body {
display: flex;
flex-direction: column;
}
// Triangle border
$arrow-height: 12px;
&::before {
position: absolute;
top: -($arrow-height * 2);
left: 50%;
margin-left: -$arrow-height;
border: $arrow-height solid transparent;
border-bottom-color: $border-color-translucent;
content: '';
}
// Triangle background
&::after {
$arrow-border-height: $arrow-height - 1;
content: '';
border: $arrow-border-height solid transparent;
border-bottom-color: $light;
position: absolute;
top: -($arrow-border-height * 2);
left: 50%;
margin-left: -$arrow-border-height;
}
}
.map-popover.cesium {
position: absolute;
z-index: 1;
}
@media (min-height: 600px) {
.map-popover .card-body {
max-height: 510px;
}
}
</style>
Loading

0 comments on commit f3dc6ca

Please sign in to comment.