Add weather and reverse geocode APIs
parent
8fafdc80a6
commit
bcfec3e180
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
$output = [];
|
||||
|
||||
$lat = round($VARS["latitude"], 6);
|
||||
$lon = round($VARS["longitude"], 6);
|
||||
|
||||
$cacheresp = $memcache->get("gis.geocode.reverse.$lat,$lon");
|
||||
if ($cacheresp !== false) {
|
||||
exitWithJson(json_decode($cacheresp, true));
|
||||
}
|
||||
|
||||
$json = file_get_contents("http://www.mapquestapi.com/geocoding/v1/reverse?outFormat=json&thumbMaps=false&location=$lat,$lon&key=" . env("mapquest_key", ""));
|
||||
|
||||
$geocode = json_decode($json, TRUE);
|
||||
|
||||
$location = $geocode['results'][0]['locations'][0];
|
||||
|
||||
$output = [
|
||||
"status" => "OK",
|
||||
"address" => [
|
||||
"street" => $location['street'],
|
||||
"city" => $location['adminArea5'],
|
||||
"county" => $location['adminArea4'],
|
||||
"state" => $location['adminArea3'],
|
||||
"country" => $location['adminArea1'],
|
||||
"postalCode" => $location['postalCode']
|
||||
],
|
||||
"coords" => [
|
||||
$lat,
|
||||
$lon
|
||||
]
|
||||
];
|
||||
|
||||
$memcache->set("gis.geocode.reverse.$lat,$lon", json_encode($output));
|
||||
exitWithJson($output);
|
@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
|
||||
$output = [];
|
||||
|
||||
$lat = round($VARS["latitude"], 2);
|
||||
$lon = round($VARS["longitude"], 2);
|
||||
|
||||
if (empty($VARS["nocache"])) {
|
||||
$cacheresp = $memcache->get("gis.weather.$lat,$lon");
|
||||
if ($cacheresp !== false) {
|
||||
exitWithJson(json_decode($cacheresp, true));
|
||||
}
|
||||
}
|
||||
|
||||
$json = file_get_contents("https://api.openweathermap.org/data/2.5/onecall?lat=$lat&lon=$lon&units=imperial&appid=" . env("openweathermap_appid", ""));
|
||||
$weather = json_decode($json, TRUE);
|
||||
|
||||
$minutely = [];
|
||||
|
||||
foreach ($weather["minutely"] as $m) {
|
||||
$minutely[] = [
|
||||
"time" => $m["dt"],
|
||||
"precip" => round($m["precipitation"] / 25.4, 3)
|
||||
];
|
||||
}
|
||||
$hourly = [];
|
||||
$mintemp = false;
|
||||
$maxtemp = false;
|
||||
$maxwind = false;
|
||||
$precipchance = false;
|
||||
$preciptype = "";
|
||||
$maxcloudcover = false;
|
||||
$cloudcovers = []; // For calculating average
|
||||
$summaryicon = "clear";
|
||||
$oldicon = "clear";
|
||||
$nowicon = "clear";
|
||||
$lasttimestamp = time();
|
||||
|
||||
foreach ($weather["hourly"] as $w) {
|
||||
if ($w["dt"] > strtotime("now + " . env("weather_summary_hours", 8) . " hours")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$hourly[] = [
|
||||
"time" => $w["dt"],
|
||||
"temp" => $w["temp"],
|
||||
"feelslike" => $w["feels_like"],
|
||||
"windspeed" => $w["wind_speed"],
|
||||
"winddirection" => $w["wind_deg"],
|
||||
"precipchance" => $w["pop"]
|
||||
];
|
||||
|
||||
if ($mintemp === false) {
|
||||
$mintemp = $w["temp"];
|
||||
}
|
||||
if ($maxtemp === false) {
|
||||
$maxtemp = $w["temp"];
|
||||
}
|
||||
if ($maxwind === false) {
|
||||
$maxwind = $w["wind_speed"];
|
||||
}
|
||||
if ($precipchance === false) {
|
||||
$precipchance = $w["pop"];
|
||||
}
|
||||
if ($maxcloudcover === false) {
|
||||
$maxcloudcover = $w["clouds"];
|
||||
}
|
||||
$mintemp = min($w["temp"], $mintemp);
|
||||
$maxtemp = max($w["temp"], $maxtemp);
|
||||
$maxwind = max($w["wind_speed"], $maxwind);
|
||||
$precipchance = max($w["pop"], $precipchance);
|
||||
$maxcloudcover = max($w["clouds"], $maxcloudcover);
|
||||
$cloudcovers[] = $w["clouds"];
|
||||
$lasttimestamp = max($w["dt"], $lasttimestamp);
|
||||
}
|
||||
|
||||
$avgcloudcover = array_sum($cloudcovers) / count($cloudcovers);
|
||||
|
||||
if ($precipchance > 0.2) {
|
||||
$summaryicon = "rain";
|
||||
$oldicon = "rain";
|
||||
if ($maxtemp < 28) {
|
||||
$summaryicon = "snow";
|
||||
$oldicon = "snow";
|
||||
}
|
||||
} else if ($mintemp > 55 && $maxtemp > 85 && $avgcloudcover <= 25) {
|
||||
$summaryicon = "heat";
|
||||
} else if ($maxwind >= 20) {
|
||||
$summaryicon = "windy";
|
||||
$oldicon = "windy";
|
||||
} else if ($avgcloudcover >= 75 || $maxcloudcover >= 90) {
|
||||
$summaryicon = "cloudy";
|
||||
$oldicon = "cloudy";
|
||||
} else if ($avgcloudcover <= 15) {
|
||||
$summaryicon = "mostly-sunny";
|
||||
$oldicon = "partly-cloudy";
|
||||
} else if ($maxcloudcover >= 33) {
|
||||
$summaryicon = "partly-cloudy";
|
||||
$oldicon = "partly-cloudy";
|
||||
}
|
||||
|
||||
if (((string) $weather["current"]["weather"][0]["id"])[0] == "2") {
|
||||
$nowicon = "rain";
|
||||
} else if (((string) $weather["current"]["weather"][0]["id"])[0] == "3") {
|
||||
$nowicon = "rain";
|
||||
} else if (((string) $weather["current"]["weather"][0]["id"])[0] == "5") {
|
||||
$nowicon = "rain";
|
||||
} else if (((string) $weather["current"]["weather"][0]["id"])[0] == "6") {
|
||||
$nowicon = "snow";
|
||||
} else if (((string) $weather["current"]["weather"][0]["id"])[0] == "7") {
|
||||
$nowicon = "fog";
|
||||
if ($weather["current"]["weather"][0]["id"] == 781) {
|
||||
// Tornado!!!
|
||||
$nowicon = "hazard";
|
||||
}
|
||||
} else if ($weather["current"]["weather"][0]["id"] == 801) {
|
||||
$nowicon = "mostly-sunny";
|
||||
} else if ($weather["current"]["weather"][0]["id"] == 802) {
|
||||
$nowicon = "partly-cloudy";
|
||||
} else if ($weather["current"]["weather"][0]["id"] >= 803) {
|
||||
$nowicon = "cloudy";
|
||||
}
|
||||
if (($nowicon == "mostly-sunny" || $nowicon == "clear" || $nowicon == "partly-cloudy") && $weather["current"]["feels_like"] > 80) {
|
||||
$nowicon = "heat";
|
||||
}
|
||||
|
||||
$dailyforecast = [];
|
||||
|
||||
foreach ($weather["daily"] as $w) {
|
||||
$dailyforecast[] = [
|
||||
"date" => $w["dt"],
|
||||
"temp" => [
|
||||
"min" => $w["temp"]["min"],
|
||||
"max" => $w["temp"]["max"]
|
||||
],
|
||||
"precipitation" => [
|
||||
"chance" => empty($w["pop"]) ? 0 : $w["pop"]
|
||||
],
|
||||
"windspeed" => $w["wind_speed"],
|
||||
"uv_index" => round($w["uvi"], 1)
|
||||
];
|
||||
}
|
||||
|
||||
$reverse_geocode_url = ($_SERVER['SERVER_PORT'] == 443 ? "https://" : "http://") . $_SERVER['HTTP_HOST'] . str_replace("/gis/weather/", "/gis/geocode/reverse/", $_SERVER['REQUEST_URI']);
|
||||
$geocode = json_decode(file_get_contents($reverse_geocode_url), TRUE);
|
||||
|
||||
$location_name = "";
|
||||
|
||||
$epa_uv_index = null;
|
||||
|
||||
if ($geocode["status"] == "OK") {
|
||||
$location_name = implode(", ", [$geocode["address"]["city"], $geocode["address"]["state"]]);
|
||||
$city = $geocode["address"]["city"];
|
||||
$state = $geocode["address"]["state"];
|
||||
try {
|
||||
$epa_url = "https://enviro.epa.gov/enviro/efservice/getEnvirofactsUVHOURLY/CITY/$city/STATE/$state/JSON";
|
||||
|
||||
$epa_data = json_decode(ApiFetcher::get($epa_url), true);
|
||||
|
||||
// Find which returned result is closest to the current date and time
|
||||
$closest = $epa_data[0];
|
||||
foreach ($epa_data as $entry) {
|
||||
if (abs(time() - strtotime(str_replace("/", " ", $entry["DATE_TIME"]))) < abs(time() - strtotime(str_replace("/", " ", $closest["DATE_TIME"])))) {
|
||||
$closest = $entry;
|
||||
}
|
||||
}
|
||||
$epa_uv_index = min($closest["UV_VALUE"], 11);
|
||||
} catch (Exception $ex) {
|
||||
$epa_uv_index = null;
|
||||
}
|
||||
} else {
|
||||
$location_name = "Unknown";
|
||||
}
|
||||
|
||||
$output = [
|
||||
"status" => "OK",
|
||||
"summary" => [
|
||||
"icon" => $summaryicon,
|
||||
"temp" => [
|
||||
"min" => $mintemp,
|
||||
"max" => $maxtemp
|
||||
],
|
||||
"precipitation" => [
|
||||
"type" => $preciptype,
|
||||
"chance" => $precipchance
|
||||
],
|
||||
"windspeed" => $maxwind,
|
||||
"cloudcover" => $maxcloudcover,
|
||||
"cloudcover_avg" => $avgcloudcover,
|
||||
"forecast_hours" => env("weather_summary_hours", 8),
|
||||
"forecast_until" => $lasttimestamp
|
||||
],
|
||||
"now" => [
|
||||
"icon" => $nowicon,
|
||||
"temp" => $weather["current"]["temp"],
|
||||
"feelslike" => $weather["current"]["feels_like"],
|
||||
"uv_index" => (is_null($epa_uv_index) ? min(round($weather["current"]["uvi"], 1), 11) : $epa_uv_index),
|
||||
"windspeed" => $weather["current"]["wind_speed"],
|
||||
"winddirection" => $weather["current"]["wind_deg"]
|
||||
],
|
||||
"today" => [
|
||||
"minutely" => $minutely,
|
||||
"hourly" => $hourly
|
||||
],
|
||||
"forecast" => $dailyforecast,
|
||||
// From here to the next comment is deprecated
|
||||
"icon" => $oldicon,
|
||||
"temp" => [
|
||||
"min" => $mintemp,
|
||||
"max" => $maxtemp
|
||||
],
|
||||
"precipitation" => [
|
||||
"type" => $preciptype,
|
||||
"chance" => $precipchance
|
||||
],
|
||||
"windspeed" => $maxwind,
|
||||
"cloudcover" => $maxcloudcover,
|
||||
"cloudcover_avg" => $avgcloudcover,
|
||||
"forecast_hours" => env("weather_summary_hours", 8),
|
||||
"forecast_until" => $lasttimestamp,
|
||||
// the next comment
|
||||
"location_name" => $location_name,
|
||||
"latitude" => $lat,
|
||||
"longitude" => $lon,
|
||||
"source" => [
|
||||
"text" => "Data: OpenWeatherMap.org" . (is_null($epa_uv_index) ? "" : ", EPA"),
|
||||
"url" => "https://openweathermap.org"
|
||||
]
|
||||
];
|
||||
|
||||
$memcache->set("gis.weather.$lat,$lon", json_encode($output), 60 * 10);
|
||||
exitWithJson($output);
|
Loading…
Reference in New Issue