Skip to content

Instantly share code, notes, and snippets.

@thejeshgn
Last active September 11, 2024 09:04
Show Gist options
  • Save thejeshgn/7dad83f4278ef11c9d4ca4a4647c67c0 to your computer and use it in GitHub Desktop.
Save thejeshgn/7dad83f4278ef11c9d4ca4a4647c67c0 to your computer and use it in GitHub Desktop.
// bangalore https://thejeshgn-imd_distrcitwise_warnings.web.val.run/?lat=12.9796&lon=77.5906
// lalitpur up https://thejeshgn-imd_distrcitwise_warnings.web.val.run/?lat=24.6936599&lon=78.412621
// vishisha MP https://thejeshgn-imd_distrcitwise_warnings.web.val.run/?lat=23.5210259&lon=77.809569
export default async function(req: Request): Promise<Response> {
const url = new URL(req.url);
const lat = parseFloat(url.searchParams.get("lat") || "12.9796");
const lon = parseFloat(url.searchParams.get("lon") || "77.5906");
const format = url.searchParams.get("format") || "html";
// 1 degree of latitude is roughly 111 kilometers
const latOffset = 0.0045; // ~500 meters
// Adjust the longitude offset by the latitude's cosine to account for the Earth's curvature
const lonOffset = latOffset / Math.cos(lat * (Math.PI / 180));
const minLat = lat - latOffset;
const minLon = lon - lonOffset;
const maxLat = lat + latOffset;
const maxLon = lon + lonOffset;
const bbox = minLon + "," + minLat + "," + maxLon + "," + maxLat;
// crude hack but works for now
const now = new Date();
const utcOffset = 5.5 * 60; // IST is UTC+5:30
const istDate = new Date(now.getTime() + utcOffset * 60 * 1000);
// const today = istDate.toISOString();
const today = istDate.toISOString().replace("Z", "+05:30");
const osmand_web = "http://osmand.net/go.html?z=16&lat=" + lat + "&lon=" + lon;
const gmaps_poi = "https://www.google.com/maps?&hl=en&t=m&z=12&ll=" + lat + "," + lon + "&q=" + lat + "," + lon;
const osm = "http://www.openstreetmap.org/?&zoom=16&layers=M&mlat=" + lat + "&mlon=" + lon;
const geo_uri = "geo:" + lat + "," + lon;
const dist_nowcast_warnings =
"https://reactjs.imd.gov.in/geoserver/imd/wms?service=WMS&request=GetMap&layers=imd%3ANowcast_StateDistrict_Merged&styles=&format=image%2Fsvg&transparent=true&version=1.1.1&width=256&height=256&srs=EPSG%3A4326&bbox="
+ bbox;
// env=day:Day1_Color
const dist_warnings_today =
"https://reactjs.imd.gov.in/geoserver/imd/wms?service=WMS&request=GetMap&layers=imd%3AWarnings_StateDistrict_Merged&styles=&format=image%2Fsvg&transparent=true&version=1.1.1&env=day%3ADay1_Color&width=256&height=256&srs=EPSG%3A4326&bbox="
+ bbox;
// env=day:Day2_Color
const dist_warnings_today_plus_1 =
"https://reactjs.imd.gov.in/geoserver/imd/wms?service=WMS&request=GetMap&layers=imd%3AWarnings_StateDistrict_Merged&styles=&format=image%2Fsvg&transparent=true&version=1.1.1&env=day%3ADay2_Color&width=256&height=256&srs=EPSG%3A4326&bbox="
+ bbox;
// env=day:Day3_Color
const dist_warnings_today_plus_2 =
"https://reactjs.imd.gov.in/geoserver/imd/wms?service=WMS&request=GetMap&layers=imd%3AWarnings_StateDistrict_Merged&styles=&format=image%2Fsvg&transparent=true&version=1.1.1&env=day%3ADay3_Color&width=256&height=256&srs=EPSG%3A4326&bbox="
+ bbox;
// env=day:Day4_Color
const dist_warnings_today_plus_3 =
"https://reactjs.imd.gov.in/geoserver/imd/wms?service=WMS&request=GetMap&layers=imd%3AWarnings_StateDistrict_Merged&styles=&format=image%2Fsvg&transparent=true&version=1.1.1&env=day%3ADay4_Color&width=256&height=256&srs=EPSG%3A4326&bbox="
+ bbox;
// env=day:Day5_Color
const dist_warnings_today_plus_4 =
"https://reactjs.imd.gov.in/geoserver/imd/wms?service=WMS&request=GetMap&layers=imd%3AWarnings_StateDistrict_Merged&styles=&format=image%2Fsvg&transparent=true&version=1.1.1&env=day%3ADay5_Color&width=256&height=256&srs=EPSG%3A4326&bbox="
+ bbox;
/*
//extract color from SVGs
svgElement = document.querySelector('svg');
shapeElement = svgElement.querySelector('g')
rect = shapeElement.querySelector('g')
fillColor = rect.getAttribute('fill');
*/
const r = {
"today": today,
"lat": lat,
"lon": lon,
"bbox": bbox,
"osmand_web": osmand_web,
"gmaps_poi": gmaps_poi,
"osm": osm,
"geo_uri": geo_uri,
"dist_nowcast_warnings": dist_nowcast_warnings,
"dist_warnings_today": dist_warnings_today,
"dist_warnings_today_plus_1": dist_warnings_today_plus_1,
"dist_warnings_today_plus_2": dist_warnings_today_plus_2,
"dist_warnings_today_plus_3": dist_warnings_today_plus_3,
"dist_warnings_today_plus_4": dist_warnings_today_plus_4,
};
if (format == "json") {
return Response.json(r);
} else {
const bboxHtml = `
<html>
<body>
<h1>IMD Warnings</h1>
<p>Center: (${lat}, ${lon})</p>
<p>
<a target="_blank" href="${osmand_web}" >OSMAnd Web</a>,&nbsp;
<a target="_blank" href="${gmaps_poi}">GMaps</a>,&nbsp;
<a target="_blank" href="${osm}">OSM Web</a>,&nbsp;
<a target="_blank" href="${geo_uri}">Geo URL</a>
</p>
<p>BBox: ${bbox}</p>
<ul>
<li>Min Lon: ${minLon}</li>
<li>Min Lat: ${minLat}</li>
<li>Max Lon: ${maxLon}</li>
<li>Max Lat: ${maxLat}</li>
</ul>
<table border=0>
<tr>
<td>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg color-interpolation="auto" color-rendering="auto" fill="black" fill-opacity="1" width="100" height="35">
<title>No Warning - Green</title>
<rect x="10" y="10" width="100" height="20" fill="rgb(7,140,3)" stroke="rgb(7,140,3)" />
</svg>
</td>
<td>
No Warning - Green
</td>
</tr>
<tr>
<td>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg color-interpolation="auto" color-rendering="auto" fill="black" fill-opacity="1" width="100" height="35">
<title>Watch - Yellow</title>
<rect x="10" y="10" width="100" height="20" fill="rgb(242,226,5)" stroke="rgb(242,226,5)" />
</svg>
</td>
<td>
Watch - Yellow
</td>
</tr>
<tr >
<td>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg color-interpolation="auto" color-rendering="auto" fill="black" fill-opacity="1" width="100" height="35">
<title>Alert - Orange</title>
<rect x="10" y="10" width="100" height="20" fill="rgb(242,135,5)" stroke="rgb(242,135,5)" />
</svg>
</td>
<td>
Alert - Orange
</td>
</tr>
<tr>
<td>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg color-interpolation="auto" color-rendering="auto" fill="black" fill-opacity="1" width="100" height="35">
<title>Warning - Red</title>
<rect x="10" y="10" width="100" height="20" fill="rgb(242,5,5)" stroke="rgb(242,5,5)" />
</svg>
</td>
<td>
Warning - Red
</td>
</tr>
</table>
<h1>Warnings - ${today}</h1>
<table border=1>
<tr>
<td> Nowcast </td>
<td> Today </td>
<td> Today + 1 </td>
<td> Today + 2 </td>
<td> Today + 3 </td>
<td> Today + 4 </td>
</tr>
<tr>
<td><img src="${dist_nowcast_warnings}" width="128px" height="128px"/> </td>
<td><img src="${dist_warnings_today}" width="128px" height="128px"/> </td>
<td><img src="${dist_warnings_today_plus_1}" width="128px" height="128px"/> </td>
<td><img src="${dist_warnings_today_plus_2}" width="128px" height="128px"/> </td>
<td><img src="${dist_warnings_today_plus_3}" width="128px" height="128px"/> </td>
<td><img src="${dist_warnings_today_plus_4}" width="128px" height="128px"/> </td>
</tr>
</table>
<h3> URL Format </h3>
<pre>
https://thejeshgn-imd_distrcitwise_warnings.web.val.run/?lat=12.9796&lon=77.5906&format=html
</pre>
where
<ul>
<li>lat = latitude
<li>lon = longitude
<li>format = html or json
<li>defaults : If no lat or lon given, it will take bangalore's.
<li>defaults : If no format is given then it is html
</ul>
<br>Data Credit : <a href="https://mausam.imd.gov.in/responsive/subDivisionWiseWarningGIS.php">IMD</a>
<br> Made by <a href="https://thejeshgn.com">Thejesh GN</a> and details are in a <a href="https://thejeshgn.com/2024/09/11/simple-imd-alerts/">blog</a> post.
</body>
</html>
`;
return new Response(bboxHtml, {
headers: { "Content-Type": "text/html" },
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment