NWS New York, NY
The weather data is provided by the National Weather Service. The astronomical data is provided by ipgeolocation.io forecast.weather.gov updates in minute 53. Sun/Moon updates at midnight. Refresh the page. See Legend.
Time: 22 Jul 04:23 pm EDT
LINK: Sun / Moon data ipgeolocation.io
LINK: Sun / Moon data ipgeolocation.io local.
Legend
<!DOCTYPE html><html lang='en'><head><title>How to query api.weather.gov, forecast.weather.gov and ipgeolocation.io and display weather and astronomical json data using Windows, PHP and Javascript. Crop and resize image with PHP and GD Library.</title><meta content="text/html; charset=utf-8" http-equiv="Content-Type"><meta content="width=device-width, initial-scale=1.0" name="viewport"><style>a{text-decoration: none;}}</style></head>
<?php
// Save as a php file.
// Creates file: weatherData7dayForecastGraphic'.date('mdy').'.webp e.g. weatherData7dayForecastGraphic110123.webp
// Query the NWS and USNO too often (NWS > once/hour. USNO > once/day. ipgeolocation.io > 30K requests per month OR > 1K per day.) and data might not be returned.
// See https://www.weather.gov/documentation/services-web-api
// Find your lat/long in xx.xxxx/yy.yyyy format
// https://api.weather.gov/points/40.7766,-73.9713
// Fetch weather data from the forecast URL: https://api.weather.gov/gridpoints/OKX/33,35/forecast
// Fetch weather data from https://forecast.weather.gov/MapClick.php?lat=40.7766&lon=-73.9713&unit=0&lg=english&FcstType=json
// See https://ipgeolocation.io/astronomy-api.html Create apiKey and replace apiKey=?????????????????????????????????
// https://api.ipgeolocation.io/astronomy?apiKey=?????????????????????????????????&lat=40.7766&long=-73.9713
// See https://aa.usno.navy.mil/data/api Create ID and replace ID=yourID e.g. ID=MYcharID
// https://aa.usno.navy.mil/api/rstt/oneday?date=2023-11-1&coords=40.7766,-73.9713&tz=-4&dst=false&ID=yourID (USNO)
// https://aa.usno.navy.mil/.... is harder to implement, more robust?, and free. Do not query > once per day.
// Thanks to https://abc7ny.com/weather/ for the 7-day weather forecast graphic.
date_default_timezone_set('America/New_York');
if (date('I', time())) {$zdst='true';} else {$zdst='false';}// true=DaylightSavingsTime false=Standard Time. USNO query.
$ztimezone=str_replace('0', '', date('O'));// Timezone offset stripped of 0 e.g. -0400 to -4 e.g. -0500 to -5. USNO query.
$zurl="http://dig.abclocal.go.com/wabc/weather/web7day.jpg"; // Source image
$zfilename='weatherData7dayForecastGraphic'.date('mdy').'.webp'; // Source image edited
// zprocessImage1($zurl,$zfilename,72,166,1207,672,0,0,480,196,100);
// BEGIN Crop and resize image with PHP GD Library
function zprocessImage1($zurl,$zfilename,$x1,$y1,$x2,$y2,$dst_x,$dst_y,$zFinalWidth,$zFinalHeight,$zcompression){
$src_image = imagecreatefromjpeg($zurl); // get the source image.
/*
if(!isset ($src_image)){
echo '<p>zprocessImage1 failed. The imageType is '.$zimageType.'</p>';}
only display above if imagecreatefromwebp displays: "is not a valid JPEG file"
*/
$dst_image = imagecreatetruecolor($zFinalWidth,$zFinalHeight); // Create a truecolor canvas to draw on the size of $zFinalWidth,$zFinalHeight. e.g. 480 x 196
/*
$x2 = 1166; $y2 = 560; // BottomRight X,Y
$x1 = 0034; $y1 = 134; // TopLeft X,Y
$x2-$x1 = CROP WIDTH
$y2-$y1 = CROP HEIGHT
$dst_x = 0; $dst_y = 0; = Where in the output image do you want the crop paste to begin.
*/
// Crop and resize
imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $x1, $y1, $zFinalWidth, $zFinalHeight, $x2-$x1, $y2-$y1); // arguments must be in this order
// Output to file
imagewebp ($dst_image,$zfilename,$zcompression); // output $resized with no compression (100 = none)
// END Crop and resize image with PHP
}// END Crop and resize image with PHP GD Library
if(!file_exists('weatherData7dayForecastGraphic'.date('mdy').'.webp')){
/*
Crop, resize and output to file.
Arguments must be in this order:
zurl,zfilename,x1,y1,x2,y2,0,0,final width,final height,zcompression (100 = none. 75 is the default.)
*/
zprocessImage1($zurl,$zfilename,72,166,1207,672,0,0,480,196,100);
/*
CLEAN UP
DELETE 7DAY WEATHER FORECAST GRAPHIC >= 2 days old
*/
$files = glob('weatherData7dayForecastGraphic[0-9]*.webp');
$threshold = strtotime('-2 day');
foreach ($files as $file) {
if (is_file($file)) {
if ($threshold >= filemtime($file)) {
unlink($file).'<br>';
}
}
} // END CLEANUP
} // END if(!file_exists('weather'.date('mdy').'BoiseID.webp')){
?>
<body style="font-size:18px;font-family:Segoe UI Semibold,Arial,Sans-Serif;">
<div class="page" style="max-width:1360px;margin:0 auto;position:relative;background-color:#fff;padding:.5em;li{list-style-type: none;">
<a href="http://dig.abclocal.go.com/wabc/weather/web7day.jpg"><img alt='The source 7day weather forecast graphic is missing. http://dig.abclocal.go.com/wabc/weather/web7day.jpg' height='196px' src="weatherData7dayForecastGraphic<?php echo date('mdy');?>.webp" width='480px'></a>
<h3>How to query api.weather.gov, forecast.weather.gov and ipgeolocation.io and display weather and astronomical json data using Windows, PHP and Javascript. Crop and resize image with PHP and GD Library.
<p>NWS New York, NY</p>
</h3>
<p>The weather data is provided by the National Weather Service. The astronomical data is provided by ipgeolocation.io. forecast.weather.gov updates in minute 53. Sun/Moon updates at midnight. Refresh the page. See Legend.<br />Time: <?php echo date('d M h:i a T');?></p>
<p><a href="https://api.weather.gov/gridpoints/OKX/33,35/forecast" title="Weather data in .json format"><strong>api.weather.gov:</strong></a><br />
<span id="z1"></span><br />
<span id="z2"></span><br />
<span id="z3"></span></p>
<p><a href="https://forecast.weather.gov/MapClick.php?lat=40.7766&lon=-73.9713&unit=0&lg=english&FcstType=json" title="Weather data in .json format"><strong>forecast.weather.gov:</strong></a><br />
<span id="zhi"></span><br />
<span id="ztemp"></span><br />
<span id="zlow"></span></p>
<script>
//https://stackoverflow.com/a/62734322/8826818
fetch("https://api.weather.gov/gridpoints/OKX/33,35/forecast", {
method: "GET",
})
.then(response => {
if (!response.ok) {
return Promise.reject(response);
}
return response.json();
})
.then(data => {
console.log("Success");
//console.log(data);
document.getElementById("z1").innerHTML=data.properties.periods[0].name+': '+data.properties.periods[0].temperature+"°F";
document.getElementById("z2").innerHTML=data.properties.periods[1].name+': '+data.properties.periods[1].temperature+"°F";
document.getElementById("z3").innerHTML=data.properties.periods[2].name+': '+data.properties.periods[2].temperature+"°F";
})
.catch(error => {
if (typeof error.json === "function") {
error.json().then(jsonError => {
console.log("Json error from API");
console.log(jsonError);
}).catch(genericError => {
console.log("Generic error from API");
console.log(error.statusText);
});
} else {
console.log(error);
document.getElementById("z1").innerHTML="https://api.weather.gov/gridpoints/OKX/33,35/forecast failed at "+new Date().toLocaleString()+"<br /><a href=mailto:nco.ops@noaa.gov?Subject=https://api.weather.gov/gridpoints/OKX/33,35/forecast failed at "+new Date().toLocaleDateString().replace(', ','')+" "+new Date().toLocaleTimeString().replace(' ','')+"&Body=https://api.weather.gov/gridpoints/OKX/33,35/forecast failed at "+new Date().toLocaleDateString().replace(', ','')+" "+new Date().toLocaleTimeString().replace(' ','')+">Report query failure.</a>" ;
}
});
fetch("https://forecast.weather.gov/MapClick.php?lat=40.7766&lon=-73.9713&unit=0&lg=english&FcstType=json", {
method: "GET",
})
.then(response => {
if (!response.ok) {
return Promise.reject(response);
}
return response.json();
})
.then(data => {
console.log("Success");
//console.log(data);
if(data.time.tempLabel[0].match(/High/)){var zhi=0;var zlow=1;}else{var zlow=0;var zhi=1;}
document.getElementById("zhi").innerHTML="HI: "+Math.ceil(data.data.temperature[zhi])+"°F";
document.getElementById("ztemp").innerHTML="CURRENT: "+ Math.floor(data.currentobservation.Temp)+"°F";
document.getElementById("zlow").innerHTML="LOW: "+ Math.floor(data.data.temperature[zlow])+"°F";
})
.catch(error => {
if (typeof error.json === "function") {
error.json().then(jsonError => {
console.log("Json error from API");
console.log(jsonError);
}).catch(genericError => {
console.log("Generic error from API");
console.log(error.statusText);
});
} else {
console.log("forecast.weather.gov is down");
console.log(error);
document.getElementById("zhi").innerHTML="forecast.weather.gov is down";
}
});
</script>
<p>
<a href="https://api.ipgeolocation.io/astronomy?apiKey=?????????????????????????????????&lat=40.7766&long=-73.9713">LINK: Sun / Moon data</a>
</p>
<?php
$z56sunMoon=json_decode(file_get_contents("https://api.ipgeolocation.io/astronomy?apiKey=?????????????????????????????????&lat=40.7766&long=-73.9713"));
// BEGIN SUN RISE/SET in 12hr format.
echo 'SUN</a>: '.(new DateTime($z56sunMoon->sunrise))->format("h:ia").' '.(new DateTime($z56sunMoon->sunset))->format("h:ia");
// END SUN RISE/SET in 12hr format.
// BEGIN MOON RISE/SET in 12hr format. Not everyday has both a moonrise and moonset
if($z56sunMoon->moonrise !== '-:-' && $z56sunMoon->moonset !== '-:-'){echo '<br>MOON</a>: '.(new DateTime($z56sunMoon->moonrise))->format('h:ia').' '.(new DateTime($z56sunMoon->moonset))->format('h:ia');}else{
if($z56sunMoon->moonrise == '-:-'){echo '<br>MOON</a>: N/A '.(new DateTime($z56sunMoon->moonset))->format('h:ia');}else{echo '<br>MOON</a>: '.(new DateTime($z56sunMoon->moonrise))->format('h:ia').' N/A';}
}// END MOON RISE/SET in 12hr format. Not everyday has both a moonrise and moonset
?>
<p>Make this:</p>
<!--
BEGIN Get x,y coordinates on graphic to plug into GD library
https://github.com/makeuseofcode/x-y-coordinates-tooltip/tree/main
changed .tooltip { position: absolute} to .tooltip { position: fixed}
-->
<style>.container {position: relative;display: inline-block;}.tooltip { position: fixed;top: -30px; left: 0; display: none; padding: 5px; background-color: #fff; color: #000; font-size: 24px; border: .2em solid green; text-align:center }</style>
<p>
<div class="container" style="height:720px; width:1280px;" >
<img id="myImgId" src="weatherData7dayForecastGraphicMakeThis.jpg" class="image" height=720px width=1280px alt="Complete the task at hand to display the weather 7day forecast graphic." />
<div class="tooltip"></div>
</div>
</p>
<script>const image = document.querySelector(".image");const tooltip = document.querySelector(".tooltip");image.addEventListener("mousemove", (e) => {
tooltip.style.left = e.clientX + "px";tooltip.style.top = e.clientY - tooltip.offsetHeight - 10 + "px";tooltip.textContent = `X: ${e.offsetX}, Y: ${e.offsetY}`;});image.addEventListener("mouseover", () => {tooltip.style.display = "block";});image.addEventListener("mouseout", () => { tooltip.style.display = "none";});</script>
<!--
END Get x,y coordinates on graphic to plug into GD library
-->
Into this:<br />
<img alt='The source 7day weather forecast graphic is missing. http://dig.abclocal.go.com/wabc/weather/web7day.jpg' width='480px' height='196px' title='Thanks to https://abc7ny.com/weather/ for the 7-day weather forecast graphic.' src="weatherData7dayForecastGraphicIntoThis.jpg">
</div>
</body>
</html>