Hello. Could someone correct me if I'm wrong . . . Eyeballing the json from the currenthurricane api doesn't seem to include a cone of uncertainty. I suppose it's up to us to connect the dots to come up w/ it ourselves? No complaints here! Just want to make sure that I wouldn't be duplicating work that's somehow available elsewhere.
I imagine ErrorRadius is the ticket, but it's not described in the API docs. What are its units?
I imagine ErrorRadius is the ticket, but it's not described in the API docs. What are its units?
- 1 Post
- 0 Reply Likes
Posted 5 years ago
- 267 Posts
- 18 Reply Likes
The API does not include a cone of uncertainty or tracking in the documented features.
The query includes a radunits option to specify units:
http://www.wunderground.com/weather/a...
The query includes a radunits option to specify units:
http://www.wunderground.com/weather/a...
- 4 Posts
- 0 Reply Likes
Tim Roche, Official Rep
- 331 Posts
- 36 Reply Likes
Yes, ErrorRadius is the correct field.
It is the uncertainty in degrees of latitude
It is the uncertainty in degrees of latitude
- 4 Posts
- 0 Reply Likes
Do you have an example formula on how that would be calculated to generate a point and radius of a circle?
Tim Roche, Official Rep
- 331 Posts
- 36 Reply Likes
Here's some javascript code that is based on that API
It should guide you, but isn't a cut and paste example
Hurricane.drawConeOfDeathNode = function(point, radius, prevPoint, prevRadius, display) {
// set display properties: default coneofdeath for backwards compatibility
if (!display) {
display = this.display_['coneofdeath'];
}
var strokeColor = display.strokeColor;
var strokeWeight = display.strokeWeight;
var strokeOpacity = display.strokeOpacity;
var fillColor = display.fillColor;
var fillOpacity = display.fillOpacity;
try {
// draw circle at new radius
var cod_circle = wunder.utils.drawCircleWedge(
this.map_, point, radius, radius, 0, 360, strokeColor, strokeWeight, strokeOpacity,
fillColor, this.options_.fillopacity/100 || fillOpacity, 2
);
cod_circle.set("type", "cod");
this.markerlayers_[0].addMarker(cod_circle);
} catch (e) {
if (this.debug_==1) {
wui.log(e.toString());
google.maps.event.trigger(this, "loaderror", "Hurricane::drawForecastTrackNode() -- point: " + point + ", radius: "+radius);
}
}
var lat = point.lat();
var lon = point.lng();
var prevCenterLat = prevPoint.lat();
var prevCenterLon = prevPoint.lng();
var deltaLat = lat - prevCenterLat;
var deltaLon = lon - prevCenterLon;
if (deltaLon < -180.0) deltaLon += 360.0;
if (deltaLon > 180.0) deltaLon = 360.0 - deltaLon;
var tilt = Math.atan(deltaLat/deltaLon);
if (this.debug_==1) {
//console.write("tilt = " + tilt+ ", deltaLon = " +deltaLon);
}
// math adjustments if heading to west
if (deltaLon < 0) {
tilt += Math.PI;
}
var centerLength = Math.sqrt(deltaLon*deltaLon + deltaLat*deltaLat);
var radiusDiff = radius - prevRadius;
var theta = Math.asin(radiusDiff / centerLength);
var thetaPlusNinety = theta + Math.PI/2;
// angles for the first and second lines
var angles = [];
angles[0] = thetaPlusNinety + tilt;
angles[1] = (-1.0)*thetaPlusNinety + tilt;
var tangentPoints = [];
// draw the lines, same loop, the only difference is the angle
for (var angleIndex=0; angleIndex < angles.length; angleIndex++) {
var angle = angles[angleIndex];
if (!angle) continue;
var latOffset1 = prevRadius * Math.sin(angle);
var lonOffset1 = prevRadius * Math.cos(angle);
var latOffset2 = radius * Math.sin(angle);
var lonOffset2 = radius * Math.cos(angle);
var point1 = new google.maps.LatLng(prevCenterLat+latOffset1, prevCenterLon+lonOffset1, false);
var point2 = new google.maps.LatLng(lat+latOffset2, lon+lonOffset2, false);
tangentPoints[angleIndex] = point2;
var line = new google.maps.Polyline({
clickable: false,
map: this.map_,
path: [point1, point2],
strokeColor: strokeColor,
strokeWeight: strokeWeight,
strokeOpacity: strokeOpacity,
zIndex: 3
});
line.set("type", "cod");
this.markerlayers_[0].addMarker(line);
}
return;
}
It should guide you, but isn't a cut and paste example
Hurricane.drawConeOfDeathNode = function(point, radius, prevPoint, prevRadius, display) {
// set display properties: default coneofdeath for backwards compatibility
if (!display) {
display = this.display_['coneofdeath'];
}
var strokeColor = display.strokeColor;
var strokeWeight = display.strokeWeight;
var strokeOpacity = display.strokeOpacity;
var fillColor = display.fillColor;
var fillOpacity = display.fillOpacity;
try {
// draw circle at new radius
var cod_circle = wunder.utils.drawCircleWedge(
this.map_, point, radius, radius, 0, 360, strokeColor, strokeWeight, strokeOpacity,
fillColor, this.options_.fillopacity/100 || fillOpacity, 2
);
cod_circle.set("type", "cod");
this.markerlayers_[0].addMarker(cod_circle);
} catch (e) {
if (this.debug_==1) {
wui.log(e.toString());
google.maps.event.trigger(this, "loaderror", "Hurricane::drawForecastTrackNode() -- point: " + point + ", radius: "+radius);
}
}
var lat = point.lat();
var lon = point.lng();
var prevCenterLat = prevPoint.lat();
var prevCenterLon = prevPoint.lng();
var deltaLat = lat - prevCenterLat;
var deltaLon = lon - prevCenterLon;
if (deltaLon < -180.0) deltaLon += 360.0;
if (deltaLon > 180.0) deltaLon = 360.0 - deltaLon;
var tilt = Math.atan(deltaLat/deltaLon);
if (this.debug_==1) {
//console.write("tilt = " + tilt+ ", deltaLon = " +deltaLon);
}
// math adjustments if heading to west
if (deltaLon < 0) {
tilt += Math.PI;
}
var centerLength = Math.sqrt(deltaLon*deltaLon + deltaLat*deltaLat);
var radiusDiff = radius - prevRadius;
var theta = Math.asin(radiusDiff / centerLength);
var thetaPlusNinety = theta + Math.PI/2;
// angles for the first and second lines
var angles = [];
angles[0] = thetaPlusNinety + tilt;
angles[1] = (-1.0)*thetaPlusNinety + tilt;
var tangentPoints = [];
// draw the lines, same loop, the only difference is the angle
for (var angleIndex=0; angleIndex < angles.length; angleIndex++) {
var angle = angles[angleIndex];
if (!angle) continue;
var latOffset1 = prevRadius * Math.sin(angle);
var lonOffset1 = prevRadius * Math.cos(angle);
var latOffset2 = radius * Math.sin(angle);
var lonOffset2 = radius * Math.cos(angle);
var point1 = new google.maps.LatLng(prevCenterLat+latOffset1, prevCenterLon+lonOffset1, false);
var point2 = new google.maps.LatLng(lat+latOffset2, lon+lonOffset2, false);
tangentPoints[angleIndex] = point2;
var line = new google.maps.Polyline({
clickable: false,
map: this.map_,
path: [point1, point2],
strokeColor: strokeColor,
strokeWeight: strokeWeight,
strokeOpacity: strokeOpacity,
zIndex: 3
});
line.set("type", "cod");
this.markerlayers_[0].addMarker(line);
}
return;
}