|
|
|
@ -152,218 +152,6 @@ const GetMonthPrecipitation = async (WeatherParameters) => {
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var GetOutlook = function (WeatherParameters) {
|
|
|
|
|
WeatherParameters.Outlook = null;
|
|
|
|
|
|
|
|
|
|
// No current support for HI and AK.
|
|
|
|
|
if (WeatherParameters.State === 'HI' || WeatherParameters.State === 'AK') {
|
|
|
|
|
GetTideInfo2(WeatherParameters);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var ImagesLoadedCounter = 0;
|
|
|
|
|
var ImagesLoadedMax = 2;
|
|
|
|
|
|
|
|
|
|
var ImageOnError = function () {
|
|
|
|
|
GetTideInfo2(WeatherParameters);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var ImageOnLoad = function () {
|
|
|
|
|
ImagesLoadedCounter++;
|
|
|
|
|
if (ImagesLoadedCounter < ImagesLoadedMax) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var Outlook = {};
|
|
|
|
|
|
|
|
|
|
var now = new Date();
|
|
|
|
|
var CurrentMonth = new Date(now.getYear(), now.getMonth(), 1);
|
|
|
|
|
if (now.getDate() <= 14) {
|
|
|
|
|
CurrentMonth = CurrentMonth.addMonths(-1);
|
|
|
|
|
}
|
|
|
|
|
Outlook.From = CurrentMonth.getMonthShortName();
|
|
|
|
|
CurrentMonth = CurrentMonth.addMonths(1);
|
|
|
|
|
Outlook.To = CurrentMonth.getMonthShortName();
|
|
|
|
|
|
|
|
|
|
var cnvOutlookTempId = 'cnvOutlookTemp';
|
|
|
|
|
var contextTemp;
|
|
|
|
|
|
|
|
|
|
if (_DontLoadGifs === false) {
|
|
|
|
|
// Clear the current image.
|
|
|
|
|
divOutlookTemp.empty();
|
|
|
|
|
|
|
|
|
|
divOutlookTemp.html('<canvas id=\'' + cnvOutlookTempId + '\' />');
|
|
|
|
|
cnvOutlookTemp = $('#' + cnvOutlookTempId);
|
|
|
|
|
cnvOutlookTemp.attr('width', '719'); // For Chrome.
|
|
|
|
|
cnvOutlookTemp.attr('height', '707'); // For Chrome.
|
|
|
|
|
}
|
|
|
|
|
cnvOutlookTemp = $('#' + cnvOutlookTempId);
|
|
|
|
|
contextTemp = cnvOutlookTemp[0].getContext('2d');
|
|
|
|
|
contextTemp.drawImage(TempImage, 0, 0);
|
|
|
|
|
|
|
|
|
|
var TempColor = GetOutlookColor(WeatherParameters, contextTemp);
|
|
|
|
|
var Temperature = GetOutlookTemperatureIndicator(TempColor);
|
|
|
|
|
Outlook.Temperature = Temperature;
|
|
|
|
|
|
|
|
|
|
var cnvOutlookPrcpId = 'cnvOutlookPrcp';
|
|
|
|
|
var contextPrcp;
|
|
|
|
|
|
|
|
|
|
if (_DontLoadGifs === false) {
|
|
|
|
|
// Clear the current image.
|
|
|
|
|
divOutlookPrcp.empty();
|
|
|
|
|
|
|
|
|
|
divOutlookPrcp.html('<canvas id=\'' + cnvOutlookPrcpId + '\' />');
|
|
|
|
|
cnvOutlookPrcp = $('#' + cnvOutlookPrcpId);
|
|
|
|
|
cnvOutlookPrcp.attr('width', '719'); // For Chrome.
|
|
|
|
|
cnvOutlookPrcp.attr('height', '707'); // For Chrome.
|
|
|
|
|
}
|
|
|
|
|
cnvOutlookPrcp = $('#' + cnvOutlookPrcpId);
|
|
|
|
|
contextPrcp = cnvOutlookPrcp[0].getContext('2d');
|
|
|
|
|
contextPrcp.drawImage(PrcpImage, 0, 0);
|
|
|
|
|
|
|
|
|
|
var PrcpColor = GetOutlookColor(WeatherParameters, contextPrcp);
|
|
|
|
|
var Precipitation = GetOutlookPrecipitationIndicator(PrcpColor);
|
|
|
|
|
Outlook.Precipitation = Precipitation;
|
|
|
|
|
|
|
|
|
|
WeatherParameters.Outlook = Outlook;
|
|
|
|
|
|
|
|
|
|
PopulateOutlook(WeatherParameters);
|
|
|
|
|
|
|
|
|
|
GetTideInfo2(WeatherParameters);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var TempUrl = 'https://www.cpc.ncep.noaa.gov/products/predictions/30day/off14_temp.gif';
|
|
|
|
|
TempUrl = 'cors/?u=' + encodeURIComponent(TempUrl);
|
|
|
|
|
var TempImage = new Image();
|
|
|
|
|
TempImage.onload = ImageOnLoad;
|
|
|
|
|
TempImage.onerror = ImageOnError;
|
|
|
|
|
TempImage.src = TempUrl;
|
|
|
|
|
|
|
|
|
|
var PrcpUrl = 'https://www.cpc.ncep.noaa.gov/products/predictions/30day/off14_prcp.gif';
|
|
|
|
|
PrcpUrl = 'cors/?u=' + encodeURIComponent(PrcpUrl);
|
|
|
|
|
var PrcpImage = new Image();
|
|
|
|
|
PrcpImage.onload = ImageOnLoad;
|
|
|
|
|
TempImage.onerror = ImageOnError;
|
|
|
|
|
PrcpImage.src = PrcpUrl;
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var GetOutlookColor = function (WeatherParameters, context) {
|
|
|
|
|
var X = 0;
|
|
|
|
|
var Y = 0;
|
|
|
|
|
var PixelColor = '';
|
|
|
|
|
var Latitude = WeatherParameters.Latitude;
|
|
|
|
|
var Longitude = WeatherParameters.Longitude;
|
|
|
|
|
|
|
|
|
|
// The height is in the range of latitude 75'N (top) - 15'N (bottom)
|
|
|
|
|
Y = ((75 - Latitude) / 53) * 707;
|
|
|
|
|
|
|
|
|
|
if (Latitude < 48.83) {
|
|
|
|
|
Y -= Math.abs(48.83 - Latitude) * 2.9;
|
|
|
|
|
}
|
|
|
|
|
if (Longitude < -100.46) {
|
|
|
|
|
Y -= Math.abs(-100.46 - Longitude) * 1.7;
|
|
|
|
|
} else {
|
|
|
|
|
Y -= Math.abs(-100.46 - Longitude) * 1.7;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The width is in the range of the longitude ???
|
|
|
|
|
X = ((-155 - Longitude) / -110) * 719; // -155 - -40
|
|
|
|
|
|
|
|
|
|
if (Longitude < -100.46) {
|
|
|
|
|
X -= Math.abs(-100.46 - Longitude) * 1;
|
|
|
|
|
|
|
|
|
|
if (Latitude > 40) {
|
|
|
|
|
X += Math.abs(40 - Latitude) * 4;
|
|
|
|
|
} else {
|
|
|
|
|
X -= Math.abs(40 - Latitude) * 4;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
X += Math.abs(-100.46 - Longitude) * 2;
|
|
|
|
|
|
|
|
|
|
if (Latitude < 36 && Longitude > -90) {
|
|
|
|
|
X += Math.abs(36 - Latitude) * 8;
|
|
|
|
|
} else {
|
|
|
|
|
X -= Math.abs(36 - Latitude) * 6;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The further left and right from lat 45 and lon -97 the y increases
|
|
|
|
|
X = Math.round(X);
|
|
|
|
|
Y = Math.round(Y);
|
|
|
|
|
|
|
|
|
|
// Determine if there is any "non-white" colors around the area.
|
|
|
|
|
// Search a 16x16 region.
|
|
|
|
|
var FoundColor = false;
|
|
|
|
|
for (var ColorX = X - 8; ColorX <= X + 8; ColorX++) {
|
|
|
|
|
for (var ColorY = Y - 8; ColorY <= Y + 8; ColorY++) {
|
|
|
|
|
PixelColor = GetPixelColor(context, ColorX, ColorY);
|
|
|
|
|
|
|
|
|
|
if (PixelColor !== '#FFFFFF' && PixelColor !== '#000000') {
|
|
|
|
|
FoundColor = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FoundColor) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FoundColor) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PixelColor;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var GetOutlookTemperatureIndicator = function (PixelColor) {
|
|
|
|
|
var RGB = HexToRgb(PixelColor);
|
|
|
|
|
|
|
|
|
|
if (RGB.b > RGB.r) {
|
|
|
|
|
return 'B';
|
|
|
|
|
} else if (RGB.r > RGB.b) {
|
|
|
|
|
return 'A';
|
|
|
|
|
} else {
|
|
|
|
|
return 'N';
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var GetOutlookPrecipitationIndicator = function (PixelColor) {
|
|
|
|
|
var RGB = HexToRgb(PixelColor);
|
|
|
|
|
|
|
|
|
|
if (RGB.g > RGB.r) {
|
|
|
|
|
return 'A';
|
|
|
|
|
} else if (RGB.r > RGB.g) {
|
|
|
|
|
return 'B';
|
|
|
|
|
} else {
|
|
|
|
|
return 'N';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const GetPixelColor = (context, x, y) => {
|
|
|
|
|
var PixelData = context.getImageData(x, y, 1, 1).data;
|
|
|
|
|
var R = PixelData[0];
|
|
|
|
|
var G = PixelData[1];
|
|
|
|
|
var B = PixelData[2];
|
|
|
|
|
return '#' + ('000000' + RgbToHex(R, G, B)).slice(-6);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const RgbToHex = (r, g, b) => {
|
|
|
|
|
if (r > 255 || g > 255 || b > 255) throw 'Invalid color component';
|
|
|
|
|
return ((r << 16) | (g << 8) | b).toString(16).toUpperCase();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const HexToRgb = (h) => {
|
|
|
|
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(h);
|
|
|
|
|
return result ? {
|
|
|
|
|
r: parseInt(result[1], 16),
|
|
|
|
|
g: parseInt(result[2], 16),
|
|
|
|
|
b: parseInt(result[3], 16),
|
|
|
|
|
} : null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var PopulateOutlook = function (WeatherParameters) {
|
|
|
|
|
if (WeatherParameters === null || (_DontLoadGifs && WeatherParameters.Progress.Almanac !== LoadStatuses.Loaded)) {
|
|
|
|
|
return;
|
|
|
|
|