diff --git a/index.html b/index.html
index 432ff20..695a3bc 100644
--- a/index.html
+++ b/index.html
@@ -23,12 +23,17 @@
type="text/css"
href="/libs/jstree/themes/mixed/style.css"
/>
+
+
-
@@ -45,8 +50,10 @@
+
+
diff --git a/src/config.js b/src/config.js
index fa55e71..16ac6ec 100644
--- a/src/config.js
+++ b/src/config.js
@@ -5,3 +5,6 @@ export const POTREE_SETTINGS = {
fov: 60,
pointBudget: 1_000_000
}
+
+export const ecef = '+proj=geocent +datum=WGS84 +units=m +no_defs' // EPSG:4978 (geocentric coordinates)
+export const wgs84 = '+proj=longlat +datum=WGS84 +no_defs' // EPSG:4326 (geographic coordinates)
\ No newline at end of file
diff --git a/src/coordinateShowing/coordinateShowing.css b/src/coordinateShowing/coordinateShowing.css
new file mode 100644
index 0000000..dd46e72
--- /dev/null
+++ b/src/coordinateShowing/coordinateShowing.css
@@ -0,0 +1,27 @@
+#canvasContainer {
+ display: flex;
+ flex-direction: column;
+ position: absolute;
+ right: 10px;
+ bottom: 10px;
+}
+
+#posCanvas {
+ position: relative;
+ width: 300px;
+ height: 50px;
+ background-color: #19282c;
+ z-index: 10;
+ border-radius: 5px;
+}
+
+#elevationCanvas {
+ position: relative;
+ width: 300px;
+ height: 50px;
+ background-color: #19282c;
+ z-index: 10;
+ margin-bottom: 10px;
+ border-radius: 5px;
+}
+
diff --git a/src/coordinateShowing/coordinateShowing.js b/src/coordinateShowing/coordinateShowing.js
new file mode 100644
index 0000000..bb7f360
--- /dev/null
+++ b/src/coordinateShowing/coordinateShowing.js
@@ -0,0 +1,80 @@
+import { ecef } from "../config.js";
+import { wgs84 } from "../config.js";
+
+const posCanvas = document.getElementById('posCanvas') // lat/lon
+const elevationCanvas = document.getElementById('elevationCanvas')
+
+export let posCtx
+export let elevationCtx
+
+/**
+ * Initializes the canvases and their contexts.
+ */
+export function initCoordinateCanvases() {
+ posCtx = resizeCanvas(posCanvas)
+ elevationCtx = resizeCanvas(elevationCanvas)
+}
+
+/**
+ * Resizes the canvas and its context to account for device pixel ratio.
+ * @param {*} canvas - The canvas element to resize.
+ * @returns {*} - The resized canvas context.
+ */
+function resizeCanvas(canvas) {
+ const dpr = window.devicePixelRatio || 1
+ const ctx = canvas.getContext('2d')
+
+ canvas.width = canvas.clientWidth * dpr
+ canvas.height = canvas.clientHeight * dpr
+
+ // Scale context so drawing uses CSS pixels
+ ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
+ return ctx
+}
+
+/**
+ * Draw the text on a given canvas.
+ */
+function drawText(ctx, text, canvas) {
+ const centerX = canvas.clientWidth / 2
+ const centerY = canvas.clientHeight / 2
+ ctx.clearRect(0, 0, canvas.width, canvas.height)
+ ctx.fillStyle = '#cccccc'
+ ctx.font = '20px Arial'
+ ctx.textAlign = 'center'
+ ctx.textBaseline = 'middle'
+ ctx.fillText(text, centerX, centerY)
+}
+
+/**
+ * Updates the lat/lon coordinates.
+ */
+export function updateCoordinateText() {
+ const cam = window.potreeViewer.scene.view.position
+ const [lon, lat] = proj4(ecef, wgs84, [cam.x, cam.y, cam.z])
+ drawText(
+ posCtx,
+ `lat = ${lat.toFixed(5)}˚ lon = ${lon.toFixed(5)}˚`,
+ posCanvas
+ )
+}
+
+/**
+ * Shows target elevations if camera is in orbit mode.
+ */
+export function updateTargetElevation() {
+ const pivot = window.potreeViewer.scene.view.getPivot()
+ const controls = window.potreeViewer.getControls()
+ const height = proj4(ecef, wgs84, [pivot.x, pivot.y, pivot.z])[2]
+
+ if (controls === window.potreeViewer.orbitControls) {
+ elevationCanvas.style.display = 'inline'
+ drawText(
+ elevationCtx,
+ `Target elevation = ${height.toFixed(4)}m`,
+ elevationCanvas
+ )
+ } else {
+ elevationCanvas.style.display = 'none'
+ }
+}
diff --git a/src/main.js b/src/main.js
index 82f7e1e..af6efff 100644
--- a/src/main.js
+++ b/src/main.js
@@ -2,6 +2,11 @@ import { POTREE_POINTCLOUD_URL, POTREE_SETTINGS } from './config.js'
import { createCesiumViewer } from './cesiumViewer.js'
import { createPotreeViewer } from './potreeViewer.js'
import { syncCameras } from './cameraSync.js'
+import {
+ initCoordinateCanvases,
+ updateCoordinateText,
+ updateTargetElevation
+} from "./CoordinateShowing/coordinateShowing.js";
async function init() {
window.cesiumViewer = createCesiumViewer('cesiumContainer')
@@ -12,6 +17,13 @@ async function init() {
POTREE_SETTINGS
)
+ initCoordinateCanvases()
+
+ potreeViewer.addEventListener('update', updateCoordinateText)
+ potreeViewer.addEventListener('update', updateTargetElevation)
+
+ window.addEventListener('resize', initCoordinateCanvases)
+
function loop(timestamp) {
requestAnimationFrame(loop)
potreeViewer.update(potreeViewer.clock.getDelta(), timestamp)
diff --git a/src/potreeViewer.js b/src/potreeViewer.js
index 3f04686..4644388 100644
--- a/src/potreeViewer.js
+++ b/src/potreeViewer.js
@@ -1,4 +1,5 @@
import { initElevationControls } from './ElevationControl/elevationControl.js'
+import { ecef } from './config.js'
/**
* Initializes the Potree viewer used to visualize the point cloud.
@@ -55,7 +56,7 @@ export async function createPotreeViewer(containerId, pointcloudUrl, settings) {
pc.material.activeAttributeName = 'elevation'
pc.material.gradient = Potree.Gradients['VIRIDIS']
- e.pointcloud.projection = '+proj=geocent +datum=WGS84 +units=m +no_defs'
+ e.pointcloud.projection = ecef
// Initialize camera position and target point (manually chosen)
viewer.scene.view.setView(