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
|
|
|
|