From calm to a gale¶
One wind speed decides the whole sea state
water_sea_state.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>From calm to a gale</title>
<meta property="og:description" content="One wind speed decides the whole sea state" />
<meta name="mapray-version" content="0.10.1">
<meta name="mapray-api-status" content="experimental">
<script src="./v0.10.6/mapray.min.js"></script>
<script src="./v0.10.6/maprayui.min.js"></script>
<link rel="stylesheet" href="./v0.10.6/mapray.css">
<style>
body { margin: 0; padding: 0; }
html, body, div#mapray-container { height: 100%; }
.caption {
position: absolute; top: 0; left: 0; margin: 10px;
font: 13px/1.5 sans-serif; background: rgba(255,255,255,0.85);
border-radius: 3px; padding: 8px 10px; max-width: 24em;
}
.caption b { display: block; margin-bottom: 4px; }
.caption label { display: block; margin-top: 8px; font-weight: bold; }
.caption input[type=range] { width: 100%; }
.caption select { width: 100%; }
.caption .beaufort { font-weight: normal; color: #444; }
</style>
</head>
<body>
<div id="mapray-container"></div>
<div class="caption">
<b>From calm to a gale</b>
Wind speed alone sets the wave height, how fast the crests travel and how much
the tops break into whitecaps. Fetch is the distance the wind has blown over
open water, so the same wind builds a bigger sea on the ocean than on a river.
<label for="wind_speed">Wind <span id="wind_speed_value">6</span> m/s
<span class="beaufort" id="beaufort"></span></label>
<input type="range" id="wind_speed" min="0" max="25" step="0.5" value="6">
<label for="wind_fetch">Fetch</label>
<select id="wind_fetch">
<option value="100">River (100 m)</option>
<option value="2000">Lake (2 km)</option>
<option value="8620" selected>Bay (8.6 km)</option>
<option value="30000">Open sea (30 km)</option>
</select>
<label for="current_speed">Surface current <span id="current_speed_value">0</span> m/s</label>
<input type="range" id="current_speed" min="0" max="4" step="0.1" value="0">
</div>
</body>
</html>
<script>
async function main() {
const cloud_api = new mapray.cloud.CloudApiV2( {
tokenType: mapray.cloud.CloudApi.TokenType.ACCESS_TOKEN,
token: "<YOUR_MAPRAY_ACCESS_TOKEN>",
} );
const uiviewer = new maprayui.StandardUIViewer( "mapray-container", {
image_provider: new mapray.StandardImageProvider( {
url: "https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/", format: "jpg", min_level: 2, max_level: 18,
} ),
dem_provider: new mapray.StandardDemProvider( cloud_api.getDefaultDemAsResource() ),
sun_visualizer: new mapray.SunVisualizer( 32 ),
atmosphere: new mapray.Atmosphere(),
} );
// The default DEM stops at 0 m over the sea; the bay's bathymetry gives the water its depth.
await uiviewer.viewer.dem_layers.add(
new mapray.StandardDemProvider( cloud_api.getDemDatasetAsResource( "5136875538874368" ) ) );
// Inside the bay and looking along it, so the far edge of the water data stays
// out of frame.
uiviewer.setCameraPosition( { longitude: 139.790512, latitude: 35.577699, height: 120.0 } );
uiviewer.setLookAtPosition( { longitude: 139.767058, latitude: 35.574366, height: 0.0 } );
uiviewer.viewer.sun.setSunDirection( [ -0.55, 0.72, 0.42 ] );
const visualizer = new mapray.WaterPolygonEntityVisualizer();
await mapray.WaterPolygonEntity.loadWaterPolygonGeoJSON(
uiviewer.viewer.scene, [ cloud_api.getDatasetAsResource( "5157340395339776" ) ], {
// Water is always at an absolute height: its depth comes from the
// difference between the surface and whatever is behind it.
altitude_mode: mapray.AltitudeMode.ABSOLUTE,
height: 0.0,
visualizer: visualizer,
}
);
visualizer.setWaterTurbidity( 0.35 );
// Beaufort is only a label for the slider; nothing in the renderer reads it.
const beaufort = function ( v ) {
const limits = [ 0.3, 1.6, 3.4, 5.5, 8.0, 10.8, 13.9, 17.2, 20.8, 24.5 ];
let i = 0;
while ( i < limits.length && v > limits[i] ) ++i;
return "(Beaufort " + i + ")";
};
const bind = function ( id, apply, format ) {
const input = document.getElementById( id );
const label = document.getElementById( id + "_value" );
const update = function () {
const value = input.type === "range" ? Number( input.value ) : input.value;
if ( label ) label.textContent = input.value;
if ( format ) format( value );
apply( value );
};
input.addEventListener( input.type === "range" ? "input" : "change", update );
update();
};
bind( "wind_speed", ( v ) => visualizer.setWindSpeed( v ),
( v ) => { document.getElementById( "beaufort" ).textContent = beaufort( v ); } );
bind( "wind_fetch", ( v ) => visualizer.setWindFetch( Number( v ) ) );
bind( "current_speed", ( v ) => visualizer.setCurrentSpeed( v ) );
}
main();
</script>
Info
このサンプルコードは、<YOUR_MAPRAY_ACCESS_TOKEN>を、あなたのMapray CloudのアカウントのOrganization Tokenに置き換えるまで、期待通りに動作しません。