Created
June 5, 2023 02:57
-
-
Save pathtrk/528e23118dc9904c517cfeaadeefafdc to your computer and use it in GitHub Desktop.
Flying view sample for Google Maps Tile API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Flying View</title> | |
<script src="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Cesium.js"></script> | |
<link href="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Widgets/widgets.css" rel="stylesheet"> | |
<style> | |
body, | |
html, | |
* { | |
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', "Yu Gothic", sans-serif; | |
font-size: 1em; | |
} | |
label { | |
color: #333; | |
} | |
::placeholder { | |
color: #b2b2b2; | |
} | |
#searchBox { | |
padding-bottom: 0.45em; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="searchBox"> | |
<label for="pacViewPlace">Fly to a place: </label> | |
<input type="text" id="pacViewPlace" name="pacViewPlace" placeholder="Enter a location..." | |
style="width: 300px" /> | |
<input type="checkbox" id="animation" checked> | |
<label for="animation">Animation</label> | |
</div> | |
<div id="cesiumContainer"></div> | |
<script> | |
// Enable simultaneous requests. | |
Cesium.RequestScheduler.requestsByServer["tile.googleapis.com:443"] = 18; | |
// Create the viewer and remove unneeded options. | |
const viewer = new Cesium.Viewer("cesiumContainer", { | |
imageryProvider: false, | |
baseLayerPicker: false, | |
homeButton: false, | |
fullscreenButton: false, | |
navigationHelpButton: false, | |
vrButton: false, | |
sceneModePicker: false, | |
geocoder: false, | |
globe: false, | |
infobox: false, | |
selectionIndicator: false, | |
timeline: false, | |
projectionPicker: false, | |
clockViewModel: null, | |
animation: false, | |
requestRenderMode: true, | |
}); | |
// Add 3D Tile set. | |
const tileset = viewer.scene.primitives.add( | |
new Cesium.Cesium3DTileset({ | |
// Set your API key obtained from GCP console here: ****** | |
url: "https://tile.googleapis.com/v1/3dtiles/root.json?key=******", | |
// This property is required to display attributions. | |
showCreditsOnScreen: true, | |
}) | |
); | |
// Point the camera at a location and elevation, at a viewport-appropriate distance. | |
function pointCameraAt(location, viewport, elevation) { | |
const distance = Cesium.Cartesian3.distance( | |
Cesium.Cartesian3.fromDegrees( | |
viewport.getSouthWest().lng(), viewport.getSouthWest().lat(), elevation), | |
Cesium.Cartesian3.fromDegrees( | |
viewport.getNorthEast().lng(), viewport.getNorthEast().lat(), elevation) | |
) / 2; | |
const target = new Cesium.Cartesian3.fromDegrees(location.lng(), location.lat(), elevation); | |
const pitch = -Math.PI / 4; | |
const heading = 0; | |
viewer.camera.lookAt(target, new Cesium.HeadingPitchRange(heading, pitch, distance)); | |
} | |
// Rotate the camera around a location and elevation, at a viewport-appropriate distance. | |
const toggleAnimation = document.getElementById("animation"); | |
let unsubscribe = null; | |
const startAnimation = () => { | |
unsubscribe = viewer.clock.onTick.addEventListener(() => | |
viewer.camera.rotate(Cesium.Cartesian3.UNIT_Z)); | |
toggleAnimation.checked = true; | |
}; | |
const stopAnimation = () => { | |
unsubscribe(); | |
toggleAnimation.checked = false; | |
} | |
function rotateCameraAround(location, viewport, elevation) { | |
if (unsubscribe) unsubscribe(); | |
pointCameraAt(location, viewport, elevation); | |
startAnimation(); | |
} | |
toggleAnimation.addEventListener('change', () => { | |
if (toggleAnimation.checked) startAnimation(); | |
else stopAnimation(); | |
}); | |
function initAutocomplete() { | |
const autocomplete = new google.maps.places.Autocomplete( | |
document.getElementById("pacViewPlace"), { | |
fields: [ | |
"geometry", | |
"name", | |
], | |
} | |
); | |
autocomplete.addListener("place_changed", async () => { | |
const place = autocomplete.getPlace(); | |
if (!(place.geometry && place.geometry.viewport && place.geometry.location)) { | |
window.alert(`Insufficient geometry data for place: ${place.name}`); | |
return; | |
} | |
// Get place elevation using the ElevationService. | |
const elevatorService = new google.maps.ElevationService(); | |
const elevationResponse = await elevatorService.getElevationForLocations({ | |
locations: [place.geometry.location], | |
}); | |
if (!(elevationResponse.results && elevationResponse.results.length)) { | |
window.alert(`Insufficient elevation data for place: ${place.name}`); | |
return; | |
} | |
const elevation = elevationResponse.results[0].elevation || 10; | |
rotateCameraAround( | |
place.geometry.location, | |
place.geometry.viewport, | |
elevation | |
); | |
}); | |
} | |
</script> | |
<script async | |
src="https://maps.googleapis.com/maps/api/js?key=******&libraries=places&callback=initAutocomplete"></script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment