|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Anax\Models; |
|
4
|
|
|
|
|
5
|
|
|
class Forecaster |
|
6
|
|
|
{ |
|
7
|
|
|
protected $owmApiKey = ""; |
|
8
|
|
|
protected $geoApiKey = ""; |
|
9
|
|
|
|
|
10
|
|
|
protected $latitude = ""; |
|
11
|
|
|
protected $longitude = ""; |
|
12
|
|
|
protected $todaysWeather = array(); |
|
13
|
|
|
|
|
14
|
|
|
protected $dailyDate = []; |
|
15
|
|
|
protected $dailyDesc = []; |
|
16
|
|
|
protected $dailyTemp = []; |
|
17
|
|
|
protected $dailyWind = []; |
|
18
|
|
|
protected $historicalDate = []; |
|
19
|
|
|
protected $historicalDesc = []; |
|
20
|
|
|
protected $historicalTemp = []; |
|
21
|
|
|
protected $historicalWind = []; |
|
22
|
|
|
|
|
23
|
|
|
public function getWeather($inputLat, $inputLong) |
|
24
|
|
|
{ |
|
25
|
|
|
$this->latitude = $inputLat; |
|
26
|
|
|
$this->longitude = $inputLong; |
|
27
|
|
|
$owmApiKey = $this->owmApiKey; |
|
28
|
|
|
|
|
29
|
|
|
// Fetching epoch times for last 5 days |
|
30
|
|
|
$epochDays = array(); |
|
31
|
|
|
$epochDays[0] = strtotime("-5 days"); |
|
32
|
|
|
$epochDays[1] = strtotime("-4 days"); |
|
33
|
|
|
$epochDays[2] = strtotime("-3 days"); |
|
34
|
|
|
$epochDays[3] = strtotime("-2 days"); |
|
35
|
|
|
$epochDays[4] = strtotime("-1 days"); |
|
36
|
|
|
|
|
37
|
|
|
$url1 = "https://api.openweathermap.org/data/2.5/onecall?" |
|
38
|
|
|
. "lat=" . $inputLat . "&lon=" . $inputLong |
|
39
|
|
|
. "&exclude=minutely,hourly,alerts&" |
|
40
|
|
|
. "appid=" . $owmApiKey |
|
41
|
|
|
. "&units=metric&lang=se"; |
|
42
|
|
|
|
|
43
|
|
|
//Creating URLs for historical data |
|
44
|
|
|
$historicalUrls = array(); |
|
45
|
|
|
for ($i = 0; $i < 5; $i++) { |
|
46
|
|
|
$historicalUrls[$i] = "https://api.openweathermap.org/data/2.5/onecall/timemachine?" |
|
47
|
|
|
. "lat=" . $inputLat . "&lon=" . $inputLong |
|
48
|
|
|
. "&dt=" . $epochDays[$i] |
|
49
|
|
|
. "&appid=" . $owmApiKey |
|
50
|
|
|
. "&units=metric&lang=se"; |
|
51
|
|
|
} |
|
52
|
|
|
|
|
53
|
|
|
// Send request |
|
54
|
|
|
$urlReq1 = array($url1); |
|
55
|
|
|
$urls = array_merge($urlReq1, $historicalUrls); |
|
56
|
|
|
$urlCount = count($urls); |
|
57
|
|
|
|
|
58
|
|
|
$responseArr = array(); |
|
59
|
|
|
$master = curl_multi_init(); |
|
60
|
|
|
$running = 0; |
|
61
|
|
|
|
|
62
|
|
|
for ($i = 0; $i < $urlCount; $i++) { |
|
63
|
|
|
$url =$urls[$i]; |
|
64
|
|
|
$responseArr[$i] = curl_init($url); |
|
65
|
|
|
curl_setopt($responseArr[$i], CURLOPT_RETURNTRANSFER, true); |
|
66
|
|
|
curl_multi_add_handle($master, $responseArr[$i]); |
|
67
|
|
|
} |
|
68
|
|
|
|
|
69
|
|
|
do { |
|
70
|
|
|
curl_multi_exec($master, $running); |
|
71
|
|
|
} while ($running > 0); |
|
72
|
|
|
|
|
73
|
|
|
$results = array(); |
|
74
|
|
|
for ($i = 0; $i < $urlCount; $i++) { |
|
75
|
|
|
$results[$i] = curl_multi_getcontent($responseArr[$i]); |
|
76
|
|
|
$results[$i] = json_decode($results[$i]); |
|
77
|
|
|
} |
|
78
|
|
|
|
|
79
|
|
|
if (isset($results[0])) { |
|
80
|
|
|
// Handle response for request 1 |
|
81
|
|
|
|
|
82
|
|
|
// Current weather |
|
83
|
|
|
$this->todaysWeather["temperature"] = @$results[0]->current->temp; |
|
84
|
|
|
$this->todaysWeather["feelsLike"] = @$results[0]->current->feels_like; |
|
85
|
|
|
$this->todaysWeather["windSpeed"] = @$results[0]->current->wind_speed; |
|
86
|
|
|
|
|
87
|
|
|
$this->todaysWeather["weatherMain"] = @$results[0]->current->weather[0]->main; |
|
88
|
|
|
$this->todaysWeather["weatherDesc"] = @$results[0]->current->weather[0]->description; |
|
89
|
|
|
|
|
90
|
|
|
// Weather next 7 days |
|
91
|
|
|
$dailySize = @sizeof($results[0]->daily); |
|
92
|
|
|
for ($i = 1; $i < @$dailySize; $i++) { |
|
93
|
|
|
$this->dailyDate[$i] = $results[0]->daily[$i]->dt; |
|
94
|
|
|
$this->dailyDesc[$i] = $results[0]->daily[$i]->weather[0]->description; |
|
95
|
|
|
$this->dailyTemp[$i] = $results[0]->daily[$i]->temp->day; |
|
96
|
|
|
$this->dailyWind[$i] = $results[0]->daily[$i]->wind_speed; |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
// Weather last 5 days |
|
100
|
|
|
$resultSize = sizeof($results); |
|
101
|
|
|
for ($i = 1; $i < $resultSize; $i++) { |
|
102
|
|
|
$this->historicalDate[$i] = @$results[$i]->current->dt; |
|
103
|
|
|
$this->historicalDesc[$i] = @$results[$i]->current->weather[0]->description; |
|
104
|
|
|
$this->historicalTemp[$i] = @$results[$i]->current->temp; |
|
105
|
|
|
$this->historicalWind[$i] = @$results[$i]->current->wind_speed; |
|
106
|
|
|
} |
|
107
|
|
|
} |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
|
|
|
|
111
|
|
|
public function buildWeatherHtml() |
|
112
|
|
|
{ |
|
113
|
|
|
if (isset($this->todaysWeather["temperature"])) { |
|
114
|
|
|
$geoapifyApiKey = $this->geoApiKey; |
|
115
|
|
|
|
|
116
|
|
|
// Weather right now |
|
117
|
|
|
$lat = $this->latitude; |
|
118
|
|
|
$long = $this->longitude; |
|
119
|
|
|
$tmpr = $this->todaysWeather["temperature"]; |
|
120
|
|
|
$flike = $this->todaysWeather["feelsLike"]; |
|
121
|
|
|
$wSpeed = $this->todaysWeather["windSpeed"]; |
|
122
|
|
|
$wMain = $this->todaysWeather["weatherMain"]; |
|
123
|
|
|
$wDesc = $this->todaysWeather["weatherDesc"]; |
|
124
|
|
|
|
|
125
|
|
|
// Map image link |
|
126
|
|
|
$mapLink = "https://maps.geoapify.com/v1/staticmap?style=osm-carto&width=500&height=350¢er=" |
|
127
|
|
|
. "lonlat:" . $long . "," . $lat . "&zoom=16&apiKey=" . $geoapifyApiKey; |
|
128
|
|
|
|
|
129
|
|
|
// Coming weather next 7 days |
|
130
|
|
|
$comingWeatherTable = $this->genForecastTable(); |
|
131
|
|
|
|
|
132
|
|
|
// Weather past 5 days |
|
133
|
|
|
$histWeatherTbl = $this->genHistoricalTable(); |
|
134
|
|
|
|
|
135
|
|
|
// String to return *HTML |
|
136
|
|
|
$returnHtml = " |
|
137
|
|
|
<h5>Vädret just nu</h5> |
|
138
|
|
|
<p> |
|
139
|
|
|
Vädret vid koordinaterna (" . $lat . ", " . $long . ") |
|
140
|
|
|
är <br><br><b>" . $wMain . "</b> (<b>" . $wDesc . "</b>) |
|
141
|
|
|
</p> |
|
142
|
|
|
<br> |
|
143
|
|
|
<p> |
|
144
|
|
|
Temperaturen är <b>" . $tmpr ."°C</b>, och känns som <b>" . $flike . "°C</b>. |
|
145
|
|
|
</p> |
|
146
|
|
|
<p> |
|
147
|
|
|
Vindar blåser i upp emot <b>" . $wSpeed . "m/s</b>.</p> |
|
148
|
|
|
|
|
149
|
|
|
<h5>Karta</h5> |
|
150
|
|
|
<img src=" . $mapLink . " alt='Karta'> |
|
151
|
|
|
|
|
152
|
|
|
<h5>Vädret kommande vecka</h5> |
|
153
|
|
|
" . $comingWeatherTable . " |
|
154
|
|
|
|
|
155
|
|
|
<h5>Vädret tidigare 5 dagar</h5> |
|
156
|
|
|
" . $histWeatherTbl . " |
|
157
|
|
|
|
|
158
|
|
|
"; |
|
159
|
|
|
|
|
160
|
|
|
return $returnHtml; |
|
161
|
|
|
} |
|
162
|
|
|
return false; |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
private function genForecastTable() |
|
166
|
|
|
{ |
|
167
|
|
|
// Generates/returns table containing coming weather |
|
168
|
|
|
// Returned as string, HTML |
|
169
|
|
|
$htmlTable = "<table><thead><tr><th></th>"; //First cell is empty |
|
170
|
|
|
$dailyDateSize = sizeof($this->dailyDate); |
|
171
|
|
|
for ($i = 1; $i < $dailyDateSize; $i++) { |
|
172
|
|
|
$epochDate = $this->dailyDate[$i]; |
|
173
|
|
|
$day = date("D j", $epochDate); |
|
174
|
|
|
$htmlTable .= "<th>" . $day . "</th>"; |
|
175
|
|
|
} |
|
176
|
|
|
$htmlTable .= "</tr></thead><tbody><tr><td><b>Beskrivning</b></td>"; |
|
177
|
|
|
$dailyDescSize = sizeof($this->dailyDesc); |
|
178
|
|
|
for ($i = 1; $i < $dailyDescSize; $i++) { |
|
179
|
|
|
$htmlTable .= "<td>" . $this->dailyDesc[$i] . "</td>"; |
|
180
|
|
|
} |
|
181
|
|
|
$htmlTable .= "</tr><tr><td><b>Temperatur</b></td>"; |
|
182
|
|
|
$dailyTSize = sizeof($this->dailyTemp); |
|
183
|
|
|
for ($i = 1; $i < $dailyTSize; $i++) { |
|
184
|
|
|
$htmlTable .= "<td>" . $this->dailyTemp[$i] . "°C</td>"; |
|
185
|
|
|
} |
|
186
|
|
|
$htmlTable .= "</tr><tr><td><b>Vindhastighet</b></td>"; |
|
187
|
|
|
$dailyWSize = sizeof($this->dailyWind); |
|
188
|
|
|
for ($i = 1; $i < $dailyWSize; $i++) { |
|
189
|
|
|
$htmlTable .= "<td>" . $this->dailyWind[$i] . "m/s</td>"; |
|
190
|
|
|
} |
|
191
|
|
|
$htmlTable .= "</tr></tbody></table>"; |
|
192
|
|
|
return $htmlTable; |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
public function genHistoricalTable() |
|
196
|
|
|
{ |
|
197
|
|
|
// Generates/returns table containing historical weather |
|
198
|
|
|
// Returned as string, HTML |
|
199
|
|
|
$htmlTable = "<table><thead><tr><th></th>"; //First cell is empty |
|
200
|
|
|
$histDateSize = sizeof($this->historicalDate); |
|
201
|
|
|
for ($i = 1; $i < $histDateSize + 1; $i++) { |
|
202
|
|
|
$epochDate = $this->historicalDate[$i]; |
|
203
|
|
|
$day = date("D j", $epochDate); |
|
204
|
|
|
$htmlTable .= "<th>" . $day . "</th>"; |
|
205
|
|
|
} |
|
206
|
|
|
$htmlTable .= "</tr></thead><tbody><tr><td><b>Beskrivning</b></td>"; |
|
207
|
|
|
$histDescSize = sizeof($this->historicalDesc); |
|
208
|
|
|
for ($i = 1; $i < $histDescSize + 1; $i++) { |
|
209
|
|
|
$htmlTable .= "<td>" . $this->historicalDesc[$i] . "</td>"; |
|
210
|
|
|
} |
|
211
|
|
|
$htmlTable .= "</tr><tr><td><b>Temperatur</b></td>"; |
|
212
|
|
|
$dailyWSize = sizeof($this->historicalTemp); |
|
213
|
|
|
for ($i = 1; $i < $dailyWSize + 1; $i++) { |
|
214
|
|
|
$htmlTable .= "<td>" . $this->historicalTemp[$i] . "°C</td>"; |
|
215
|
|
|
} |
|
216
|
|
|
$htmlTable .= "</tr><tr><td><b>Vindhastighet</b></td>"; |
|
217
|
|
|
$dailyWSize = sizeof($this->historicalWind); |
|
218
|
|
|
for ($i = 1; $i < $dailyWSize + 1; $i++) { |
|
219
|
|
|
$htmlTable .= "<td>" . $this->historicalWind[$i] . "m/s</td>"; |
|
220
|
|
|
} |
|
221
|
|
|
$htmlTable .= "</tr></tbody></table>"; |
|
222
|
|
|
return $htmlTable; |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
// SET&GET FUNCS |
|
226
|
|
|
|
|
227
|
|
|
|
|
228
|
|
|
public function setApiKeys($geoInputKey, $owmInputKey) |
|
229
|
|
|
{ |
|
230
|
|
|
$this->geoApiKey = $geoInputKey; |
|
231
|
|
|
$this->owmApiKey = $owmInputKey; |
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
public function getLatLong() |
|
235
|
|
|
{ |
|
236
|
|
|
if ($this->latitude != "" && $this->longitude != "") { |
|
237
|
|
|
$returnArray = array(); |
|
238
|
|
|
$returnArray["lat"] = $this->latitude; |
|
239
|
|
|
$returnArray["long"] = $this->longitude; |
|
240
|
|
|
return $returnArray; |
|
241
|
|
|
} |
|
242
|
|
|
return false; |
|
243
|
|
|
} |
|
244
|
|
|
|
|
245
|
|
|
public function getCompleteFetchedData() |
|
246
|
|
|
{ |
|
247
|
|
|
if (isset($this->latitude) && |
|
248
|
|
|
isset($this->todaysWeather["temperature"])) { |
|
249
|
|
|
$currentArray = $this->todaysWeather; |
|
250
|
|
|
$dailyArray = array(); |
|
251
|
|
|
$historicalArray = array(); |
|
252
|
|
|
$returnArray = array(); |
|
253
|
|
|
|
|
254
|
|
|
$dailyDateSize = sizeof($this->dailyDate); |
|
255
|
|
|
for ($i = 1; $i < $dailyDateSize + 1; $i++) { |
|
256
|
|
|
$arrayIdx = "forecast_" . $i; |
|
257
|
|
|
$dailyArray[$arrayIdx]["date"] = $this->dailyDate[$i]; |
|
258
|
|
|
$dailyArray[$arrayIdx]["description"] = $this->dailyDesc[$i]; |
|
259
|
|
|
$dailyArray[$arrayIdx]["temperature"] = $this->dailyTemp[$i]; |
|
260
|
|
|
$dailyArray[$arrayIdx]["windspeed"] = $this->dailyWind[$i]; |
|
261
|
|
|
} |
|
262
|
|
|
$histDateSize = sizeof($this->historicalDate); |
|
263
|
|
|
for ($i = 1; $i < $histDateSize + 1; $i++) { |
|
264
|
|
|
$arrayIdx = "historical_" . $i; |
|
265
|
|
|
$historicalArray[$arrayIdx]["date"] = $this->historicalDate[$i]; |
|
266
|
|
|
$historicalArray[$arrayIdx]["description"] = $this->historicalDesc[$i]; |
|
267
|
|
|
$historicalArray[$arrayIdx]["temperature"] = $this->historicalTemp[$i]; |
|
268
|
|
|
$historicalArray[$arrayIdx]["windspeed"] = $this->historicalWind[$i]; |
|
269
|
|
|
} |
|
270
|
|
|
$returnArray[0] = $currentArray; |
|
271
|
|
|
$returnArray[1] = $dailyArray; |
|
272
|
|
|
$returnArray[2] = $historicalArray; |
|
273
|
|
|
return $returnArray; |
|
274
|
|
|
} |
|
275
|
|
|
return false; |
|
276
|
|
|
} |
|
277
|
|
|
} |
|
278
|
|
|
|