cesium/Apps/Sandcastle/gallery/Parallels and Meridians.html

289 lines
9.5 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>
<meta
name="description"
content="Use polylines to draw parallels and meridians on the globe."
/>
<meta name="cesium-sandcastle-labels" content="Geometries" />
<title>Cesium Demo</title>
<script type="text/javascript" src="../Sandcastle-header.js"></script>
<script
type="text/javascript"
src="../../../Build/CesiumUnminified/Cesium.js"
nomodule
></script>
<script type="module" src="../load-cesium-es6.js"></script>
</head>
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html">
<style>
@import url(../templates/bucket.css);
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar"></div>
<script id="cesium_sandcastle_script">
window.startup = async function (Cesium) {
"use strict";
//Sandcastle_Begin
const viewer = new Cesium.Viewer("cesiumContainer");
const toDegrees = Cesium.Math.toDegrees;
function parallel(latitude, color, granularity) {
const name = `Parallel ${latitude}`;
return viewer.entities.add({
name: name,
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
-180,
latitude,
-90,
latitude,
0,
latitude,
90,
latitude,
180,
latitude,
]),
width: 2,
arcType: Cesium.ArcType.RHUMB,
material: color,
granularity: granularity,
},
});
}
function meridian(longitude, color, granularity) {
const name = `Meridian ${longitude}`;
return viewer.entities.add({
name: name,
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([
longitude,
90,
longitude,
0,
longitude,
-90,
]),
width: 2,
arcType: Cesium.ArcType.RHUMB,
material: color,
granularity: granularity,
},
});
}
function labelCoordinates(cartographic) {
const position = Cesium.Cartographic.toCartesian(cartographic);
const latitude = toDegrees(cartographic.latitude).toFixed(4);
const longitude = toDegrees(cartographic.longitude).toFixed(4);
const label = `lat: ${latitude}°\nlon: ${longitude}°`;
return viewer.entities.add({
position: position,
label: {
text: label,
showBackground: true,
font: "14px monospace",
},
});
}
function makeGrid(numberOfDivisions, color, show) {
const parallels = makeParallelsRecursive(-90, 90, numberOfDivisions, color);
const meridians = makeMeridiansRecursive(-180, 180, numberOfDivisions, color);
meridians.push(meridian(180, color));
const allLines = parallels.concat(meridians);
allLines.forEach(function (line) {
line.show = show;
});
return allLines;
}
function makeParallelsRecursive(minLatitude, maxLatitude, depth, color) {
let result = [];
const midpoint = (minLatitude + maxLatitude) / 2;
result.push(parallel(midpoint, color));
if (depth > 0) {
const southernLines = makeParallelsRecursive(
minLatitude,
midpoint,
depth - 1,
color,
);
const northernLines = makeParallelsRecursive(
midpoint,
maxLatitude,
depth - 1,
color,
);
result = southernLines.concat(result, northernLines);
}
return result;
}
function makeMeridiansRecursive(minLongitude, maxLongitude, depth, color) {
let result = [];
const midpoint = (minLongitude + maxLongitude) / 2;
result.push(meridian(midpoint, color));
if (depth > 0) {
const westernLines = makeMeridiansRecursive(
minLongitude,
midpoint,
depth - 1,
color,
);
const easternLines = makeMeridiansRecursive(
midpoint,
maxLongitude,
depth - 1,
color,
);
result = westernLines.concat(result, easternLines);
}
return result;
}
let showAntipodalPoint = false;
const primitives = {
equator: parallel(0, Cesium.Color.BLUE),
primeMeridian: meridian(0, Cesium.Color.BLUE),
selectedPoint: {
meridian: undefined,
parallel: undefined,
label: undefined,
},
antipodalPoint: {
meridian: undefined,
parallel: undefined,
label: undefined,
},
lowResolutionGrid: makeGrid(2, Cesium.Color.PALEGREEN, false),
higherResolutionGrid: makeGrid(5, Cesium.Color.DARKORANGE, false),
};
function updateCrosshairs(cartographic) {
const selectedPoint = primitives.selectedPoint;
const antipodalPoint = primitives.antipodalPoint;
if (Cesium.defined(selectedPoint.parallel)) {
viewer.entities.remove(selectedPoint.parallel);
viewer.entities.remove(selectedPoint.meridian);
viewer.entities.remove(selectedPoint.label);
viewer.entities.remove(antipodalPoint.parallel);
viewer.entities.remove(antipodalPoint.meridian);
viewer.entities.remove(antipodalPoint.label);
}
const pointLatitude = toDegrees(cartographic.latitude);
const antipodeLatitude = -pointLatitude;
const pointLongitude = toDegrees(cartographic.longitude);
const antipodeLongitude = (pointLongitude + 180) % 360;
// Increase the granularity to improve accuracy when zoomed in
const finerGranularity = 0.001;
const red = Cesium.Color.RED;
selectedPoint.parallel = parallel(
toDegrees(cartographic.latitude),
red,
finerGranularity,
);
selectedPoint.meridian = meridian(
toDegrees(cartographic.longitude),
red,
finerGranularity,
);
selectedPoint.label = labelCoordinates(cartographic);
const cyan = Cesium.Color.CYAN;
const antipode = new Cesium.Cartographic.fromDegrees(
antipodeLongitude,
antipodeLatitude,
0,
);
antipodalPoint.parallel = parallel(antipodeLatitude, cyan, finerGranularity);
antipodalPoint.meridian = meridian(antipodeLongitude, cyan, finerGranularity);
antipodalPoint.label = labelCoordinates(antipode);
antipodalPoint.parallel.show = showAntipodalPoint;
antipodalPoint.meridian.show = showAntipodalPoint;
antipodalPoint.label.show = showAntipodalPoint;
}
// Click to shift the cross-hairs
viewer.screenSpaceEventHandler.setInputAction(function (mouse) {
viewer.scene.pick(mouse.position);
const ray = viewer.camera.getPickRay(mouse.position);
const globe = viewer.scene.globe;
const cartesian = globe.pick(ray, viewer.scene);
if (!Cesium.defined(cartesian)) {
return;
}
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
updateCrosshairs(cartographic);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
Sandcastle.addToggleButton("Show equator", true, function (checked) {
primitives.equator.show = checked;
});
Sandcastle.addToggleButton("Show prime meridian", true, function (checked) {
primitives.primeMeridian.show = checked;
});
Sandcastle.addToggleButton("Show low-resolution grid", false, function (checked) {
primitives.lowResolutionGrid.forEach(function (line) {
line.show = checked;
});
});
Sandcastle.addToggleButton(
"Show higher-resolution grid",
false,
function (checked) {
primitives.higherResolutionGrid.forEach(function (line) {
line.show = checked;
});
},
);
Sandcastle.addToggleButton("Show antipodal point", false, function (checked) {
showAntipodalPoint = checked;
const antipodalPoint = primitives.antipodalPoint;
if (Cesium.defined(antipodalPoint.parallel)) {
antipodalPoint.parallel.show = showAntipodalPoint;
antipodalPoint.meridian.show = showAntipodalPoint;
antipodalPoint.label.show = showAntipodalPoint;
}
});
//Sandcastle_End
};
if (typeof Cesium !== "undefined") {
window.startupCalled = true;
window.startup(Cesium).catch((error) => {
"use strict";
console.error(error);
});
Sandcastle.finishedLoading();
}
</script>
</body>
</html>