Skip to content

Commit

Permalink
BGDIINF_SB-2977 : using a mouse event approach to position tooltip
Browse files Browse the repository at this point in the history
this way it alleviate the issue raised by previous method here : CesiumGS/cesium#3247
We will have to make sure this works also with mobile
  • Loading branch information
pakb committed Aug 18, 2023
1 parent 7a23d57 commit 3a93418
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 86 deletions.
70 changes: 19 additions & 51 deletions src/modules/map/components/cesium/CesiumMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@
<slot />
</template>
<script>
import GeoAdminGeoJsonLayer from '@/api/layers/GeoAdminGeoJsonLayer.class'
import GeoAdminWMSLayer from '@/api/layers/GeoAdminWMSLayer.class'
import GeoAdminWMTSLayer from '@/api/layers/GeoAdminWMTSLayer.class'
import KMLLayer from '@/api/layers/KMLLayer.class'
import LayerTimeConfig from '@/api/layers/LayerTimeConfig.class'
import { CURRENT_YEAR_WMTS_TIMESTAMP } from '@/api/layers/LayerTimeConfigEntry.class'
import {
Expand All @@ -58,7 +61,20 @@ import {
WMS_BASE_URL,
WMTS_BASE_URL,
} from '@/config'
import { extractOlFeatureGeodesicCoordinates } from '@/modules/drawing/lib/drawingUtils'
import FeatureEdit from '@/modules/infobox/components/FeatureEdit.vue'
import FeatureList from '@/modules/infobox/components/FeatureList.vue'
import MapPopover from '@/modules/map/components/MapPopover.vue'
import { ClickInfo, ClickType } from '@/store/modules/map.store'
import { UIModes } from '@/store/modules/ui.store'
import { LV95, WEBMERCATOR, WGS84 } from '@/utils/coordinateSystems'
import {
isInBounds,
LV95_BOUNDS,
reprojectUnknownSrsCoordsToWebMercator,
} from '@/utils/coordinateUtils'
import { createGeoJSONFeature } from '@/utils/layerUtils'
import log from '@/utils/logging'
import '@geoblocks/cesium-compass'
import * as cesium from 'cesium'
import {
Expand All @@ -71,36 +87,19 @@ import {
ScreenSpaceEventType,
Viewer,
} from 'cesium'
import { LineString, Point, Polygon } from 'ol/geom'
import proj4 from 'proj4'
import { mapActions, mapGetters, mapState } from 'vuex'
import CesiumInternalLayer from './CesiumInternalLayer.vue'
import {
CAMERA_MAX_PITCH,
CAMERA_MAX_ZOOM_DISTANCE,
CAMERA_MIN_PITCH,
CAMERA_MIN_ZOOM_DISTANCE,
MINIMUM_DISTANCE_TO_SHOW_TOOLTIP,
TERRAIN_URL,
} from './constants'
import { calculateHeight, limitCameraCenter, limitCameraPitchRoll } from './utils/cameraUtils'
import { ClickInfo, ClickType } from '@/store/modules/map.store'
import GeoAdminWMSLayer from '@/api/layers/GeoAdminWMSLayer.class'
import GeoAdminGeoJsonLayer from '@/api/layers/GeoAdminGeoJsonLayer.class'
import KMLLayer from '@/api/layers/KMLLayer.class'
import proj4 from 'proj4'
import { LV95, WEBMERCATOR, WGS84 } from '@/utils/coordinateSystems'
import FeatureList from '@/modules/infobox/components/FeatureList.vue'
import { highlightGroup, unhighlightGroup } from './utils/highlightUtils'
import { createGeoJSONFeature } from '@/utils/layerUtils'
import {
isInBounds,
LV95_BOUNDS,
reprojectUnknownSrsCoordsToWebMercator,
} from '@/utils/coordinateUtils'
import { extractOlFeatureGeodesicCoordinates } from '@/modules/drawing/lib/drawingUtils'
import log from '@/utils/logging'
import { LineString, Point, Polygon } from 'ol/geom'
import FeatureEdit from '@/modules/infobox/components/FeatureEdit.vue'
import MapPopover from '@/modules/map/components/MapPopover.vue'
export default {
components: { MapPopover, FeatureEdit, FeatureList, CesiumInternalLayer },
Expand Down Expand Up @@ -206,9 +205,6 @@ export default {
featureCoords[0],
featureCoords[1]
)
this.viewer?.camera.changed.addEventListener(this.onCameraMove)
} else {
this.viewer?.camera.changed.removeEventListener(this.onCameraMove)
}
},
deep: true,
Expand Down Expand Up @@ -297,7 +293,6 @@ export default {
)
this.flyToPosition()
this.tooltipToggledAutomaticaly = false
if (IS_TESTING_WITH_CYPRESS) {
window.cesiumViewer = this.viewer
Expand All @@ -314,12 +309,7 @@ export default {
delete this.viewer
},
methods: {
...mapActions([
'setCameraPosition',
'clearAllSelectedFeatures',
'click',
'toggleFloatingTooltip',
]),
...mapActions(['setCameraPosition', 'clearAllSelectedFeatures', 'click']),
flyToPosition() {
const x = this.camera ? this.camera.x : this.centerEpsg4326[0]
const y = this.camera ? this.camera.y : this.centerEpsg4326[1]
Expand Down Expand Up @@ -353,23 +343,7 @@ export default {
roll: CesiumMath.toDegrees(camera.roll).toFixed(0),
})
},
onCameraMove() {
const camera = this.viewer.camera
const position = camera.positionCartographic
if (
position.height <= MINIMUM_DISTANCE_TO_SHOW_TOOLTIP &&
this.showFeaturesPopover &&
!this.isFeatureTooltipInFooter
) {
this.toggleFloatingTooltip()
this.tooltipToggledAutomaticaly = true
}
},
onClick(event) {
if (this.tooltipToggledAutomaticaly) {
this.toggleFloatingTooltip()
this.tooltipToggledAutomaticaly = false
}
unhighlightGroup(this.viewer)
const features = []
let coordinates = []
Expand Down Expand Up @@ -446,12 +420,6 @@ export default {
unhighlightGroup(this.viewer)
this.clearAllSelectedFeatures()
},
onToggleFloatingTooltipClick() {
if (this.tooltipToggledAutomaticaly) {
this.tooltipToggledAutomaticaly = false
}
this.toggleFloatingTooltip()
},
},
}
</script>
Expand Down
78 changes: 43 additions & 35 deletions src/modules/map/components/cesium/CesiumPopover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
</template>

<script>
import { Cartesian2, Cartesian3, Ellipsoid, SceneTransforms } from 'cesium'
const popup3DCoordScratch = new Cartesian3()
const popup2DCoordScratch = new Cartesian2()
import {
Cartesian3,
Cartographic,
defined,
KeyboardEventModifier,
SceneTransforms,
ScreenSpaceEventHandler,
ScreenSpaceEventType,
} from 'cesium'
/**
* Places a popover on the cesium viewer at the given position (coordinates) and with the slot as
Expand All @@ -24,55 +29,58 @@ export default {
},
watch: {
coordinates() {
this.updateCoordinateHeight()
this.updatePosition()
},
},
mounted() {
this.updatePosition()
const viewer = this.getViewer()
if (viewer) {
this.cesiumHandler = new ScreenSpaceEventHandler(viewer.scene.canvas)
this.cesiumHandler.setInputAction(this.updatePosition, ScreenSpaceEventType.MOUSE_MOVE)
// wheel event will trigger a zoom, the tooltip will need repositioning
this.cesiumHandler.setInputAction(this.updatePosition, ScreenSpaceEventType.WHEEL)
// rotating the view/camera is done by CTRL+click and move, so we also listen to mouse move when CTRL is down
this.cesiumHandler.setInputAction(
this.updatePosition,
ScreenSpaceEventType.MOUSE_MOVE,
KeyboardEventModifier.CTRL
)
viewer.camera.changed.addEventListener(this.updatePosition)
// By default, the `camera.changed` event will trigger when the camera has changed by 50%
// To make it more sensitive, we set down sensitivity
viewer.camera.percentageChanged = 0.001
// implementing something similar to the sandcastle found on https://github.com/CesiumGS/cesium/issues/3247#issuecomment-1533505387
// but taking into account height using globe.getHeight for the given coordinate
this.updateCoordinateHeight()
this.updatePosition()
}
},
unmounted() {
const viewer = this.getViewer()
if (viewer) {
viewer.camera.changed.removeEventListener(this.updatePosition)
// Set default value
viewer.camera.percentageChanged = 0.5
}
this.cesiumHandler?.destroy()
},
methods: {
updateCoordinateHeight() {
this.coordinatesHeight = this.getViewer()?.scene.globe.getHeight(
Cartographic.fromDegrees(this.coordinates[0], this.coordinates[1])
)
},
updatePosition() {
if (!this.coordinates?.length) {
this.onClose()
return
}
const cartesianCoords = Cartesian3.fromDegrees(
this.coordinates[0],
this.coordinates[1],
0,
Ellipsoid.WGS84,
popup3DCoordScratch
)
if (cartesianCoords) {
// Cesium has an issue with coordinates conversion.
// The popup placed is not exactly correct when zooming close to the terrain
// https://github.com/CesiumGS/cesium/issues/3247
const pixel = SceneTransforms.wgs84ToWindowCoordinates(
this.getViewer().scene,
cartesianCoords,
popup2DCoordScratch
const cartesianCoords = SceneTransforms.wgs84ToWindowCoordinates(
this.getViewer().scene,
Cartesian3.fromDegrees(
this.coordinates[0],
this.coordinates[1],
this.coordinatesHeight
)
if (pixel) {
const mapPopover = this.getMapPopoverRef()
const width = mapPopover.getBoundingClientRect().width
mapPopover.style.left = `${pixel.x - width / 2}px`
mapPopover.style.top = `${pixel.y + 10}px`
}
)
if (defined(cartesianCoords)) {
const mapPopover = this.getMapPopoverRef()
const { width } = mapPopover.getBoundingClientRect()
mapPopover.style.left = `${cartesianCoords.x - width / 2}px`
mapPopover.style.top = `${cartesianCoords.y + 15}px`
}
},
},
Expand Down

0 comments on commit 3a93418

Please sign in to comment.