Sofar API
Search…
Tile Server
This endpoint returns raster tiles (images) of our time series weather data. The tile endpoint can be used with a mapping client, such as Leaflet.js or Mapbox, to make an interactive world map.
get
https://api.sofarocean.com
/marine-weather/v1/models/:model/tile/:zoom/:x/:y.png
Get Tile PNG

Example Usage

The following HTML code uses Mapbox GL JS to display model data served by our Tile Server API. The page features a slider that allows you to select the desired time (anywhere from 24 hours in the past, to 6 hours in the future). You can run this demo either by visiting the file in a local browser or using the code pen featured below.
1
<!-- Simple example using mapbox-gl-js along with the Sofar tile api to create a map that shows data from a certain model/variable at various times-->
2
<!DOCTYPE html>
3
<html>
4
5
<head>
6
<meta charset="utf-8" />
7
<title>Sofar Tile Server Demo</title>
8
9
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
10
11
<script src="https://api.mapbox.com/mapbox-gl-js/v1.9.1/mapbox-gl.js"></script>
12
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.25.3/moment.js"></script>
13
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
14
15
<link href="https://api.mapbox.com/mapbox-gl-js/v1.9.1/mapbox-gl.css" rel="stylesheet" />
16
17
<style>
18
body { margin: 0; padding: 0; font-family: sans-serif; }
19
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
20
#model-info {
21
position: relative;
22
background-color: #eee;
23
margin: 5px;
24
padding: 5px;
25
display: inline-block;
26
}
27
#map-overlay {
28
position: relative;
29
background-color:#eee;
30
margin: 5px;
31
padding: 5px;
32
display: inline-block;
33
}
34
</style>
35
</head>
36
37
<body>
38
39
<div id="map"></div>
40
<div id="model-info">
41
<b>Model:</b> <label id="model-name"></label> <br>
42
<b>Variable:</b> <label id="variable-name"></label> <br>
43
</div>
44
45
<br>
46
<div id="map-overlay">
47
<b>Inference Time:</b>
48
<label id="timestamp"></label>
49
<br>
50
<input id="slider" type="range" min="0" max="4" step="1" value="3" />
51
</div>
52
53
<script>
54
// CONSTANTS
55
// link used to access the sofar api. The timestamp is appended on dynamically as the slider changes
56
// This particular demo accesses significant wave height data from the Sofar Wave Model
57
const modelName = "SofarOperationalWaveModel"
58
const variableName = "significantWaveHeight";
59
const cmap = "turbo";
60
const sofarApiToken = "383d59964809ca8c6438867e590f16";
61
62
// get closest available hour
63
const modelTimesEndpoint =
64
"https://api.sofarocean.com/marine-weather/v1/models/" +
65
modelName +
66
"/outputTimes?token=" +
67
sofarApiToken +
68
"&closest=" +
69
moment.utc().startOf("hour").toISOString();
70
71
const linkPrefix =
72
"https://api.sofarocean.com/marine-weather/v1/models/" +
73
modelName +
74
"/tile/{z}/{x}/{y}.png?colormap="
75
+ cmap +
76
"&token=" +
77
sofarApiToken +
78
"&variableID=" +
79
variableName +
80
"&timestamp=";
81
82
$.get( modelTimesEndpoint, function( data ) {
83
// upon loading a valid model time, use that as a starting point
84
const timestamp = moment(data.outputTimes[0]);
85
86
// Add 30 hours of available times to the slider. 1 day ago to 6 hours in the future
87
const dates = [];
88
const startDate = timestamp.subtract(1, "day");
89
for (let i = 0; i < 5; i++) {
90
dates.push(startDate.add(6, "hour").toISOString());
91
}
92
93
// update info box
94
document.getElementById("model-name").textContent = modelName;
95
document.getElementById("variable-name").textContent = variableName;
96
97
mapboxgl.accessToken = 'pk.eyJ1Ijoiam9uc2VuIiwiYSI6IkR6UU9oMDQifQ.dymRIgqv-UV6oz0-HCFx1w'
98
99
let map = new mapboxgl.Map({
100
container: "map", // container id
101
style: "mapbox://styles/jonsen/ck8i301kh0cy31ipfi7y8j6bb",
102
center: [-74.5, 40], // starting position
103
zoom: 2, // starting zoom
104
});
105
106
// Function that updates the map data based on the current slider timestamp
107
function updateDate(newIndex) {
108
let currentTime = dates[newIndex];
109
document.getElementById("timestamp").textContent = currentTime;
110
let link = linkPrefix + currentTime;
111
map.addSource("sofar-tiles", {
112
type: "raster",
113
tiles: [link],
114
tileSize: 256,
115
attribution: "Sofar Ocean Technologies"
116
});
117
118
map.addLayer({
119
id: "sofar-tiles",
120
type: "raster",
121
source: "sofar-tiles",
122
minzoom: 0,
123
maxzoon: 10
124
});
125
}
126
127
map.on("load", function () {
128
// set to be the current time which has index 23
129
updateDate(3);
130
document.getElementById("slider").addEventListener("input", function (e) {
131
const dateIndex = parseInt(e.target.value, 10);
132
133
if (map.getLayer("sofar-tiles")) map.removeLayer("sofar-tiles");
134
if (map.getSource("sofar-tiles")) map.removeSource("sofar-tiles");
135
updateDate(dateIndex);
136
});
137
});
138
139
});
140
</script>
141
142
</body>
143
144
</html>
Copied!

Additional Information

Colormap Options

Last modified 6mo ago