Click to GPS
Demonstrates converting a point in the scene back into real-world coordinates. The capture is loaded in the colmap coordinate system, and clicking anywhere raycasts against the mesh, transforms the hit point through the capture's gps_transform into latitude/longitude, and opens Google Maps at that location.
Source Code#
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
<title>Teleport.js Click to GPS Sample</title>
<style>
body { margin: 0; overflow: hidden; background: #222; }
canvas { display: block; width: 100vw; height: 100vh; }
</style>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.180.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.180.0/examples/jsm/",
"teleport": "https://d1ziouw89q7sp5.cloudfront.net/teleport-js/0.0.2/teleport.module.js"
}
}
</script>
</head>
<body>
<script type="module">
import * as THREE from "three";
import * as TELEPORT from "teleport";
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 10000);
const renderer = new THREE.WebGLRenderer({ antialias: false, logarithmicDepthBuffer: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
const teleportManager = new TELEPORT.Manager({ renderer: renderer, scene: scene, camera: camera });
const capture = await teleportManager.loadCapture("524ee89f293a4a2e907009191ba7b9f4", {
coordSystem: "colmap"
});
const enu2geodetic = (e, n, refLat, refLon) => {
const R = 6378137.0;
return {
lat: refLat + (n / R) * (180 / Math.PI),
lon: refLon + (e / (R * Math.cos(refLat * Math.PI / 180))) * (180 / Math.PI)
};
};
camera.position.set(-900, 850, 0);
camera.updateProjectionMatrix();
camera.lookAt(new THREE.Vector3(-300, 0, 0));
renderer.domElement.addEventListener("click", (event) => {
const hit = teleportManager.raycast(event.clientX, event.clientY, camera);
if (!hit) return;
const enu = new THREE.Vector3(hit.point.z, 0, hit.point.x).applyMatrix4(new THREE.Matrix4().set(...capture.metadata.gps_transform.matrix));
const { lat, lon } = enu2geodetic(enu.x, enu.y, capture.metadata.gps_transform.gps.latitude, capture.metadata.gps_transform.gps.longitude);
window.open(`https://www.google.com/maps?q=${lat.toFixed(8)},${lon.toFixed(8)}`, "_blank");
});
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
</script>
</body>
</html>