Home

Awesome

erddap-leaflet-velocity-demo

A demonstration of connecting Erddap to Leaflet-Velocity maps

See here for an online demonstration.

See here for example with time dimension control.

Contents

Including the Code

To include the code in your own website, you will need to first add the Leaflet.js mapping library, Leaflet-Velocity and then include errdapToLeafletVelocity, e.g.:

<script src="https://irishmarineinstitute.github.io/erddap-leaflet-velocity-demo/erddapToLeafletVelocity.js"></src>

Example Usage

L.erddapVelocityLayer({
	erddapBaseUrl: 'https://erddap.marine.ie',
	datasetID: 'IMI_Model_Stats',
	uParameter: 'sea_surface_x_velocity',
	vParameter: 'sea_surface_y_velocity',
	minLat: 48.5,
	maxLat: 58.5,
	minLon: -17.0,
	maxLon: -2.0,
	refTime: '2019-12-15T00:00:00Z',
	strideLon: 10,
	strideLat: 10,
	minVelocity: 0,
	maxVelocity: 1}).addTo('map');

Function Inputs

Once you have added the erddapToLeafletVelocity.js script to your webpages, you can use the erddapToLeafletVelocity function or the L.erddapVelocityLayer function with the following inputs:

Grib2JSON output format

Leaflet-Velocity expects input in the form of a JSON object conforming to the output of Grib2JSON. Some of the fields are documented below:

JavaScript boilerplate

The following should allow you to build the expected output from any Erddap instance, using a griddap enabled dataset. Contains input from @abkfenris.

const erddapBaseUrl = 'https://erddap.marine.ie';
const datasetID = 'IMI_Model_Stats';
const uParameter = 'sea_surface_x_velocity';
const vParameter = 'sea_surface_y_velocity';
const minLat = 48.5;
const maxLat = 58.5;
const minLon = -17.0;
const maxLon = -2.0;
const refTime = '2019-12-15T00:00:00Z';
const strideLon = 20;
const strideLat = 20;

function jsonp(url) {
    return new Promise(function(resolve, reject) {
        let script = document.createElement('script')
        const name = "_jsonp_" + Math.round(100000 * Math.random());
        //url formatting
        if (url.match(/\?/)) url += "&.jsonp="+name
        else url += "?.jsonp="+name
        script.src = url;

        window[name] = function(data) {
            resolve(data);
            document.body.removeChild(script);
            delete window[name];
        }
        document.body.appendChild(script);
    });
}

jsonp(erddapBaseUrl 
			+ '/erddap/griddap/' 
			+ datasetID 
			+ '.json?' 
			+ uParameter + '[(' + refTime + '):1:(' + refTime + ')][(' +  String(minLat) + '):' + String(strideLat) + ':(' + String(maxLat) + ')][(' + String(minLon) + '):'+ String(strideLon) +':(' + String(maxLon) + ')],' 
			+ vParameter + '[(' + refTime + '):1:(' + refTime + ')][(' + String(minLat) + '):' + String(strideLat)+ ':(' + String(maxLat) + ')][(' + String(minLon) + '):' + String(strideLon) + ':(' + String(maxLon) + ')]')
.then(
	data => [{
		'header':{
			'la1': Math.max(...Array.from([...new Set(data.table.rows.map(x => x[1]))])),
			'la2': Math.min(...Array.from([...new Set(data.table.rows.map(x => x[1]))])),
			'lo1': Math.min(...Array.from([...new Set(data.table.rows.map(x => x[2]))])),
			'lo2': Math.max(...Array.from([...new Set(data.table.rows.map(x => x[2]))])),
			'dx': (Math.max(...Array.from([...new Set(data.table.rows.map(x => x[2]))])) - Math.min(...Array.from([...new Set(data.table.rows.map(x => x[2]))]))) / ([...new Set(data.table.rows.map(x => x[2]))].length - 1),
			'dy': (Math.max(...Array.from([...new Set(data.table.rows.map(x => x[1]))])) - Math.min(...Array.from([...new Set(data.table.rows.map(x => x[1]))]))) / ([...new Set(data.table.rows.map(x => x[1]))].length - 1),
			'nx': [...new Set(data.table.rows.map(x => x[2]))].length,
			'ny': [...new Set(data.table.rows.map(x => x[1]))].length,
			'parameterCategory': 2,
			'parameterNumber': 2,
			'parameterUnit': 'm.s-1',
			'parameterNumberName': data.table.columnNames[3],
			'refTime': refTime.replace('T', ' ').replace('Z','')
		}, 
		'data': data.table.rows.sort((a,b) => b[1]-a[1]).map(x => x[3])
	},{
		'header':{
			'la1': Math.max(...Array.from([...new Set(data.table.rows.map(x => x[1]))])),
			'la2': Math.min(...Array.from([...new Set(data.table.rows.map(x => x[1]))])),
			'lo1': Math.min(...Array.from([...new Set(data.table.rows.map(x => x[2]))])),
			'lo2': Math.max(...Array.from([...new Set(data.table.rows.map(x => x[2]))])),
			'dx': (Math.max(...Array.from([...new Set(data.table.rows.map(x => x[2]))])) - Math.min(...Array.from([...new Set(data.table.rows.map(x => x[2]))]))) / ([...new Set(data.table.rows.map(x => x[2]))].length - 1),
			'dy': (Math.max(...Array.from([...new Set(data.table.rows.map(x => x[1]))])) - Math.min(...Array.from([...new Set(data.table.rows.map(x => x[1]))]))) / ([...new Set(data.table.rows.map(x => x[1]))].length - 1),
			'nx': [...new Set(data.table.rows.map(x => x[2]))].length,
			'ny': [...new Set(data.table.rows.map(x => x[1]))].length,
			'parameterCategory': 2,
			'parameterNumber': 3,
			'parameterUnit': 'm.s-1',
			'parameterNumberName': data.table.columnNames[4],
			'refTime': refTime.replace('T', ' ').replace('Z','')
		}, 
		'data': data.table.rows.sort((a,b) => b[1]-a[1]).map(x => x[4])
	}]
)