Tag Archives: Open Weather Map

OpenWeatherMap IDW

idwOpenWeatherMap has a nice API that allows you to consume live weather data. I have made other simple examples here (v2.1) and here (v2.0 – doesn’t work), but you should check out the OWM API documentation and examples for more.

This example (v2.5) collects weather info from several stations across British Columbia and Alberta, interpolates temperature values between the stations using the Inverse Distance Weighting method, and displays both the stations (points) and interpolated surface (raster) as PaperJS objects.

 <!DOCTYPE html>
 <html>
 <head>
 <!---------------------
 Code by Darren Wiens
 dkwiens@gmail.com
 ----------------------->
 <style type="text/css">
 html { height: 100% }
 #map { height: 500px; width: 500px; }
 canvas { position: absolute; top: 10; left: 10; z-index: 1; pointer-events:none; }
 </style>
 <!-- Load the Paper.js library -->
 <script type="text/javascript" src="http://darrenwiens.net/scripts/paper.js"></script>
 <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
 <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
 <!-- Define inlined PaperScript associate it with myCanvas -->
 <script type="text/paperscript" canvas="myCanvas">
 var maxWidth = 500;
 var maxHeight = 500;
 var maxPoint = new Point(maxWidth,maxHeight);
var rect = new Path.Rectangle(0,0,maxWidth, maxHeight);
 rect.strokeColor = 'black';
 rect.strokeWidth = 3;
var map;
 var sampleCirs = new Group();
 var texts = new Group();
 var interpRaster = new Raster('myImg');
 var minTemp = 1000;
 var maxTemp = -1000;
function onFrame(event)
 {
}
function pointToLatLng(point)
 {
 var proj = map.getProjection();
 var bounds = map.getBounds();
 var ne = bounds.getNorthEast();
 var sw = bounds.getSouthWest();
 var neWorldXY = proj.fromLatLngToPoint(ne);
 var swWorldXY = proj.fromLatLngToPoint(sw);
 var curPixelX = point.x / Math.pow(2,map.getZoom());
 var curPixelY = point.y / Math.pow(2,map.getZoom());
 var curWorldX = curPixelX + swWorldXY.x;
 var curWorldY = curPixelY + neWorldXY.y;
 var curWorldPoint = new google.maps.Point(curWorldX,curWorldY);
 var curLatLng = proj.fromPointToLatLng(curWorldPoint);
 return curLatLng;
 }
function latLngToPoint(latLng)
 {
 var proj = map.getProjection();
 var calWorldPoint = proj.fromLatLngToPoint(latLng);
 var calPixelPointx = calWorldPoint.x * Math.pow(2,map.getZoom());
 var calPixelPointy = calWorldPoint.y * Math.pow(2,map.getZoom());
 var bounds = map.getBounds();
 var ne = bounds.getNorthEast();
 var sw = bounds.getSouthWest();
 var neWorldPoint = proj.fromLatLngToPoint(ne);
 var swWorldPoint = proj.fromLatLngToPoint(sw);
 var ePixelPoint = neWorldPoint.x * Math.pow(2,map.getZoom());
 var nPixelPoint = neWorldPoint.y * Math.pow(2,map.getZoom());
 var wPixelPoint = swWorldPoint.x * Math.pow(2,map.getZoom());
 var sPixelPoint = swWorldPoint.y * Math.pow(2,map.getZoom());
 var screenPixelX = calPixelPointx - wPixelPoint;
 var screenPixelY = calPixelPointy - nPixelPoint;
 var point = new Point(screenPixelX, screenPixelY);
 return point;
 }
function drawPoints(s)
 {
 childCount = 0;
 for (var station=0;station<s.length;station++) {
 if (s[station].last.hasOwnProperty('main')) {
 if (s[station].last.main.hasOwnProperty('temp')) {
 var lat = s[station].station.coord.lat;
 var lng = s[station].station.coord.lon;
 var newPoint = new Point(latLngToPoint(new google.maps.LatLng(lat, lng)));
 sampleCirs.addChild(new Path.Circle(newPoint,2));
 sampleCirs.children[childCount].value = s[station].last.main.temp - 273.15;
 sampleCirs.children[childCount].latlng = pointToLatLng(sampleCirs.children[childCount].position);
 if (sampleCirs.children[childCount].value < minTemp) {
 minTemp = sampleCirs.children[childCount].value;
 }
 if (sampleCirs.children[childCount].value > maxTemp) {
 maxTemp = sampleCirs.children[childCount].value;
 }
 sampleCirs.strokeColor = 'black';
 sampleCirs.fillColor = 'black';
 var text = new PointText(newPoint + new Point(3,-3));
 text.content = Math.round(sampleCirs.children[childCount].value);
 text.latlng = pointToLatLng(text.position);
 texts.addChild(text);
 childCount++;
 }
 }
 }
 drawRaster();
 }
function drawRaster()
 {
 interpRaster.size = new Size(100,100);
 interpRaster.fitBounds(view.bounds);
 for (var i=0;i<100;i++)
 {
 for (var j=0;j<100;j++)
 {
 var wj = 0;
 var wis = [];
 for (var k=0;k<sampleCirs.children.length;k++)
 {
 var dx = sampleCirs.children[k].position.x - (i * 5);
 var dy = sampleCirs.children[k].position.y - (j * 5);
 var dk = Math.sqrt(Math.pow(dx,2) + Math.pow(dy,2));
 var p = 3;
 var wj_inst = 1/(Math.pow(dk,p))
 wj += wj_inst;
 wis.push(wj_inst*sampleCirs.children[k].value);
 }
 var u = 0;
 for (var l=0;l<wis.length;l++)
 {
 u += wis[l]/wj;
 }
 var scale = (u-minTemp)/(maxTemp-minTemp);
 interpRaster.setPixel(i,j,new RgbColor(scale,0,1-scale,1));
 }
 }
 interpRaster.opacity = 0.7;
 interpRaster.latlng = map.getCenter();
 interpRaster.TLlatlng = pointToLatLng(interpRaster.bounds.topLeft);
 interpRaster.BRlatlng = pointToLatLng(interpRaster.bounds.bottomRight);
 interpRaster.moveBelow(sampleCirs);
 console.log("MAX: " + maxTemp);
 console.log("MIN: " + minTemp);
 }
function getData(s){
 drawPoints(s);
 }
$(document).ready(function() {
 var style = [
 { "elementType": "geometry.fill",
 "stylers": [ { "visibility": "off" } ]
 },{ "featureType":
 "road",
 "elementType": "geometry.fill",
 "stylers": [ { "visibility": "on" },
 { "color": "#000000" } ]
 },{ "featureType": "water",
 "elementType": "geometry.fill",
 "stylers": [ { "color": "#000000" } ]
 } ]
var myLatlng = new google.maps.LatLng(53.917, -122.75);
 var myOptions = {
 zoom: 5,
 center: myLatlng,
 mapTypeId: google.maps.MapTypeId.ROADMAP,
 disableDefaultUI: true
 }
 map = new google.maps.Map(document.getElementById("map"), myOptions);
 map.setOptions({styles: style});
google.maps.event.addListener(map, 'projection_changed', function() {
 $.getJSON('http://api.openweathermap.org/data/2.5/station/find?lat=53.917&lon=-122.75&cnt=30', getData); // API v.2.5
 });
google.maps.event.addListener(map, 'center_changed', function() {
 for (var i=0;i<sampleCirs.children.length;i++)
 {
 sampleCirs.children[i].position = latLngToPoint(sampleCirs.children[i].latlng);
 sampleCirs.children[i].latlng = pointToLatLng(sampleCirs.children[i].position);
 texts.children[i].position = latLngToPoint(texts.children[i].latlng);
 texts.children[i].latlng = pointToLatLng(texts.children[i].position);
 }
 interpRaster.position = latLngToPoint(interpRaster.latlng);
 interpRaster.latlng = pointToLatLng(interpRaster.position);
 });
google.maps.event.addListener(map, 'zoom_changed', function() {
 for (var i=0;i<sampleCirs.children.length;i++)
 {
 sampleCirs.children[i].position = latLngToPoint(sampleCirs.children[i].latlng);
 sampleCirs.children[i].latlng = pointToLatLng(sampleCirs.children[i].position);
 texts.children[i].position = sampleCirs.children[i].position + new Point(3,-3);
 texts.children[i].latlng = pointToLatLng(texts.children[i].position);
 }
 var tl = latLngToPoint(interpRaster.TLlatlng);
 var br = latLngToPoint(interpRaster.BRlatlng);
 var bounds = new Rectangle(tl,br);
interpRaster.fitBounds(bounds);
 interpRaster.TLlatlng = pointToLatLng(interpRaster.bounds.topLeft);
 interpRaster.BRlatlng = pointToLatLng(interpRaster.bounds.bottomRight);
 });
 });
</script>
 </head>
 <body>
 <canvas id="myCanvas" width="500" height="500"></canvas>
 <div id="map" width="500" height="500"></div>
 <img id="myImg"></img>
 </body>
 </html>
Advertisements

Open Weather Map 2.1: Example

Image

A long time ago, I posted an example using Open Weather Map to display public weather station data on a map. Well, since then, apparently the API has moved to version 2.1, which made my example non-functional. So, here is my new example using Open Weather Map 2.1. It’s not very exciting, at the moment, but there looks like some new cool features that I will be checking out in the near future.