Here is HTML code for a basic wind forecast app for your area. This was all created in around 10 to 15 minutes using ChatGPT. See full tutorial below and here: https://youtu.be/0Qnd59X9qKs
Here is my weather app code below. NOTE: You will need sign up to get an API key at openweathermap.org and then insert as shown below;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>7-Day Wind Forecast</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet-velocity/dist/leaflet-velocity.min.css" />
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f9;
color: #333;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
text-align: center;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
border-radius: 8px;
}
h1 {
color: #0056b3;
}
form {
margin-bottom: 20px;
}
label {
font-weight: bold;
}
input[type="text"] {
padding: 10px;
margin: 10px 0;
width: calc(100% - 24px);
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 10px 20px;
background-color: #0056b3;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #004494;
}
.forecast {
margin-top: 20px;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
padding: 10px;
text-align: left;
border-bottom: 1px solid #ddd;
}
th {
background-color: #0056b3;
color: white;
}
.date-row {
background-color: #f0f8ff;
font-weight: bold;
}
#map {
height: 500px;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<h1>7-Day Wind Forecast</h1>
<form id="forecastForm">
<label for="city">City:</label>
<input type="text" id="city" name="city" required>
<br>
<label for="state">Province/State:</label>
<input type="text" id="state" name="state" required>
<br>
<label for="country">Country:</label>
<input type="text" id="country" name="country" required>
<br>
<button type="submit">Get Forecast</button>
</form>
<div class="forecast" id="forecast"></div>
<div id="map"></div>
</div>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet-velocity/dist/leaflet-velocity.min.js"></script>
<script>
let map, windLayer;
document.addEventListener('DOMContentLoaded', (event) => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
getCityName(lat, lon);
initializeMap(lat, lon);
});
} else {
alert('Geolocation is not supported by this browser.');
}
});
document.getElementById('forecastForm').addEventListener('submit', function(event) {
event.preventDefault();
const city = document.getElementById('city').value;
const state = document.getElementById('state').value;
const country = document.getElementById('country').value;
getForecast(city, state, country);
});
async function getCityName(lat, lon) {
const apiKey = 'INSERT_YOUR_OPENWEATHERMAP_API_KEY_HERE';
const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${apiKey}`;
const response = await fetch(url);
const data = await response.json();
if (data.name) {
document.getElementById('city').value = data.name;
document.getElementById('country').value = data.sys.country;
// Note: OpenWeatherMap does not directly provide state/province information in its API response.
} else {
alert('Unable to retrieve city name');
}
}
async function getForecast(city, state, country) {
const apiKey = 'INSERT_YOUR_OPENWEATHERMAP_API_KEY_HERE';
const url = `https://api.openweathermap.org/data/2.5/forecast?q=${city},${state},${country}&appid=${apiKey}&units=metric`;
const response = await fetch(url);
const data = await response.json();
if (data.cod !== '200') {
document.getElementById('forecast').innerHTML = `Error: ${data.message}`;
return;
}
const forecastElement = document.getElementById('forecast');
forecastElement.innerHTML = '<table><thead><tr><th>Date</th><th>Time</th><th>Wind Speed (km/h)</th><th>Wind Direction</th></tr></thead><tbody></tbody></table>';
const forecastTableBody = forecastElement.querySelector('tbody');
const forecastData = {};
data.list.forEach(item => {
const date = item.dt_txt.split(' ')[0];
if (!forecastData[date]) {
forecastData[date] = [];
}
forecastData[date].push({
time: formatTime(item.dt_txt),
windSpeed: Math.round(item.wind.speed * 3.6), // Convert m/s to km/h and round to nearest whole number
windDeg: degreesToDirection(item.wind.deg)
});
});
for (const [date, forecasts] of Object.entries(forecastData)) {
const dateRow = document.createElement('tr');
dateRow.className = 'date-row';
const dateCell = document.createElement('td');
dateCell.colSpan = 4;
dateCell.innerText = formatDate(date);
dateRow.appendChild(dateCell);
forecastTableBody.appendChild(dateRow);
forecasts.forEach(forecast => {
const forecastRow = document.createElement('tr');
forecastRow.innerHTML = `<td></td><td>${forecast.time}</td><td>${forecast.windSpeed}</td><td>${forecast.windDeg}</td>`;
forecastTableBody.appendChild(forecastRow);
});
}
// Update the wind layer with current wind data
updateWindLayer(data);
}
function formatDate(dateString) {
const date = new Date(dateString);
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
return date.toLocaleDateString(undefined, options);
}
function formatTime(dateTimeString) {
const date = new Date(dateTimeString);
const options = { hour: 'numeric', minute: 'numeric', hour12: true };
return date.toLocaleTimeString(undefined, options);
}
function degreesToDirection(degrees) {
const directions = ['North', 'NNE', 'NE', 'ENE', 'East', 'ESE', 'SE', 'SSE', 'South', 'SSW', 'SW', 'WSW', 'West', 'WNW', 'NW', 'NNW'];
const index = Math.round(degrees / 22.5) % 16;
return directions[index];
}
function initializeMap(lat, lon) {
map = L.map('map').setView([lat, lon], 10);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
}
function updateWindLayer(data) {
if (windLayer) {
map.removeLayer(windLayer);
}
const windData = data.list.map(item => ({
lat: data.city.coord.lat,
lon: data.city.coord.lon,
value: [
item.wind.speed,
item.wind.deg
]
}));
windLayer = L.velocityLayer({
displayValues: true,
displayOptions: {
velocityType: 'Global Wind',
displayPosition: 'bottomleft',
displayEmptyString: 'No wind data'
},
data: windData,
maxVelocity: 15
});
windLayer.addTo(map);
}
</script>
</body>
</html>