Waves washing up on the shore¶
Shore waves and foam driven by the terrain around the water
water_shore_waves.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Waves washing up on the shore</title>
<meta property="og:description" content="Shore waves and foam driven by the terrain around the water" />
<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%; }
</style>
</head>
<body>
<div id="mapray-container"></div>
<div class="caption">
<b>Waves washing up on the shore</b>
The shoreline is found from the terrain, not from the polygon outline, so the
waves turn to face the beach, shorten as the water gets shallow and break where
they run out of depth. Foam collects along the water line.
<label for="shore_break_scale">Shore waves and foam × <span id="shore_break_scale_value">0.9</span></label>
<input type="range" id="shore_break_scale" min="0" max="1" step="0.05" value="0.9">
<label for="foam_life_scale">Foam life × <span id="foam_life_scale_value">1.9</span> (× 3.1 s)</label>
<input type="range" id="foam_life_scale" min="0" max="6" step="0.1" value="1.9">
</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" ) ) );
// From 70 m off a stretch where the water outline meets the terrain, facing 108 degrees.
// The shore band is narrow, so a near-horizontal view puts it below one pixel.
uiviewer.setCameraPosition( { longitude: 139.747255, latitude: 35.574752, height: 25.0 } );
uiviewer.setLookAtPosition( { longitude: 139.747011, latitude: 35.575351, height: 0.0 } );
uiviewer.viewer.sun.setSunDirection( [ -0.76, 0.65, 0.25 ] );
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,
}
);
// 7 m/s over a 7.4 km bay gives waves about 8 m long. Waves only wash up on a
// shore they travel towards, so the wind blows onto this one.
visualizer.setWindSpeed( 7.0 );
visualizer.setWindAngleDegree( 108.0 );
visualizer.setWindFetch( 7354 );
visualizer.setWaterTurbidity( 0.35 );
// The seabed decides where waves break. Taking it from the DEM follows the real
// slope of the beach instead of a constant one.
visualizer.setSeabed( mapray.WaterPolygonEntityVisualizer.Seabed.MIXED );
const bind = function ( id, apply ) {
const input = document.getElementById( id );
const label = document.getElementById( id + "_value" );
const update = function () {
label.textContent = input.value;
apply( Number( input.value ) );
};
input.addEventListener( "input", update );
update();
};
bind( "shore_break_scale", ( v ) => visualizer.setShoreBreakScale( v ) );
bind( "foam_life_scale", ( v ) => visualizer.setFoamLifeScale( v ) );
}
main();
</script>
Info
このサンプルコードは、<YOUR_MAPRAY_ACCESS_TOKEN>を、あなたのMapray CloudのアカウントのOrganization Tokenに置き換えるまで、期待通りに動作しません。