|
22 | 22 | use Cmfcmf\OpenWeatherMap\CurrentWeather; |
23 | 23 | use Cmfcmf\OpenWeatherMap\CurrentWeatherGroup; |
24 | 24 | use Cmfcmf\OpenWeatherMap\Exception as OWMException; |
| 25 | +use Cmfcmf\OpenWeatherMap\NotFoundException as OWMNotFoundException; |
25 | 26 | use Cmfcmf\OpenWeatherMap\UVIndex; |
26 | 27 | use Cmfcmf\OpenWeatherMap\WeatherForecast; |
27 | 28 | use Psr\Cache\CacheItemPoolInterface; |
@@ -71,7 +72,7 @@ class OpenWeatherMap |
71 | 72 | /** |
72 | 73 | * @var string The basic api url to fetch air pollution data from. |
73 | 74 | */ |
74 | | - private $airPollutionUrl = 'https://api.openweathermap.org/pollution/v1/co'; |
| 75 | + private $airPollutionUrl = 'https://api.openweathermap.org/pollution/v1/'; |
75 | 76 |
|
76 | 77 | /** |
77 | 78 | * @var CacheItemPoolInterface|null $cache The cache to use. |
@@ -343,28 +344,42 @@ public function getHistoricUVIndex($lat, $lon, $start, $end) |
343 | 344 | } |
344 | 345 |
|
345 | 346 | /** |
346 | | - * Returns atmosferic pollution by Carbon Monoxie |
| 347 | + * Returns air pollution data |
347 | 348 | * |
348 | | - * @param float $lat The location's latitude. |
349 | | - * @param float $lon The location's longitude. |
350 | | - * @param ?DateTime|string $dateTime Time of the measurement. Set null for "current" |
| 349 | + * @param string $type One of CO, O3, SO2, and NO2. |
| 350 | + * @param string $lat The location's latitude. |
| 351 | + * @param string $lon The location's longitude. |
| 352 | + * @param string $date The date to gather data from. If you omit this parameter or supply "current", returns current data. |
| 353 | + * |
| 354 | + * @return AirPollution\COAirPollution|AirPollution\NO2AirPollution|AirPollution\O3AirPollution|AirPollution\SO2AirPollution|null The air pollution data or null if no data was found. |
| 355 | + * |
| 356 | + * We use strings as $lat and $lon, since the exact number of digits in $lat and $lon determines the search range. |
| 357 | + * For example, there is a difference between using "1.5" and "1.5000". |
| 358 | + * We also use a string for $date, since it may either be "current" or an (abbreviated) ISO 8601 timestamp like 2016Z. |
351 | 359 | * |
352 | | - * @return AirPollution |
| 360 | + * @throws OWMException|\Exception |
353 | 361 | * |
354 | 362 | * @api |
355 | | - * @throws \Exception |
356 | 363 | */ |
357 | | - public function getAirPollution($lat, $lon, $dateTime = null) |
| 364 | + public function getAirPollution($type, $lat, $lon, $date = "current") |
358 | 365 | { |
359 | | - if ($dateTime === null) { |
360 | | - $dateTime = 'current'; |
| 366 | + $answer = $this->getRawAirPollutionData($type, $lat, $lon, $date); |
| 367 | + if ($answer === null) { |
| 368 | + return null; |
361 | 369 | } |
362 | | - |
363 | | - $answer = $this->getRawAirPollutionData($lat, $lon, $dateTime); |
364 | | - |
365 | 370 | $json = $this->parseJson($answer); |
366 | | - |
367 | | - return new AirPollution($json); |
| 371 | + switch ($type) { |
| 372 | + case "O3": |
| 373 | + return new AirPollution\O3AirPollution($json); |
| 374 | + case "NO2": |
| 375 | + return new AirPollution\NO2AirPollution($json); |
| 376 | + case "SO2": |
| 377 | + return new AirPollution\SO2AirPollution($json); |
| 378 | + case "CO": |
| 379 | + return new AirPollution\COAirPollution($json); |
| 380 | + default: |
| 381 | + throw new \LogicException(); |
| 382 | + } |
368 | 383 | } |
369 | 384 |
|
370 | 385 | /** |
@@ -503,17 +518,37 @@ public function getRawUVIndexData($mode, $lat, $lon, $cnt = null, $start = null, |
503 | 518 | } |
504 | 519 |
|
505 | 520 | /** |
506 | | - * @param $lat |
507 | | - * @param $lon |
508 | | - * @param $dateTime |
509 | | - * @return bool|string Returns the fetched data. |
510 | | - * @throws OWMException |
| 521 | + * Fetch raw air pollution data |
| 522 | + * |
| 523 | + * @param string $type One of CO, O3, SO2, and NO2. |
| 524 | + * @param string $lat The location's latitude. |
| 525 | + * @param string $lon The location's longitude. |
| 526 | + * @param string $date The date to gather data from. If you omit this parameter or supply "current", returns current data. |
| 527 | + * |
| 528 | + * @return string|null The air pollution data or null if no data was found. |
| 529 | + * |
| 530 | + * We use strings as $lat and $lon, since the exact number of digits in $lat and $lon determines the search range. |
| 531 | + * For example, there is a difference between using "1.5" and "1.5000". |
| 532 | + * We also use a string for $date, since it may either be "current" or an (abbreviated) ISO 8601 timestamp like 2016Z. |
| 533 | + * |
| 534 | + * @api |
511 | 535 | */ |
512 | | - public function getRawAirPollutionData($lat, $lon, $dateTime) |
| 536 | + public function getRawAirPollutionData($type, $lat, $lon, $date = "current") |
513 | 537 | { |
514 | | - $url = $this->buildAirPollutionUrl($lat, $lon, $dateTime, $this->airPollutionUrl); |
515 | | - |
516 | | - return $this->cacheOrFetchResult($url); |
| 538 | + if (!in_array($type, ["CO", "O3", "SO2", "NO2"])) { |
| 539 | + throw new \InvalidArgumentException('Invalid $type received.'); |
| 540 | + } |
| 541 | + if (!is_string($lat) || !is_string($lon) || !is_string($date)) { |
| 542 | + throw new \InvalidArgumentException('$lat, $lon and $date all must be strings.'); |
| 543 | + } |
| 544 | + |
| 545 | + $url = $this->airPollutionUrl . strtolower($type) . "/$lat,$lon/$date.json?appid=" . $this->apiKey; |
| 546 | + |
| 547 | + try { |
| 548 | + return $this->cacheOrFetchResult($url); |
| 549 | + } catch (OWMNotFoundException $e) { |
| 550 | + return null; |
| 551 | + } |
517 | 552 | } |
518 | 553 |
|
519 | 554 | /** |
@@ -550,10 +585,10 @@ private function cacheOrFetchResult($url) |
550 | 585 | $response = $this->httpClient->sendRequest($this->httpRequestFactory->createRequest("GET", $url)); |
551 | 586 | $result = $response->getBody()->getContents(); |
552 | 587 | if ($response->getStatusCode() !== 200) { |
553 | | - if ($result === '{"message":"not found"}' && $response->getStatusCode() === 404) { |
554 | | - throw new OWMException('OpenWeatherMap returned that air pollution data for this location cannot be found - try less precision location.'); |
| 588 | + if ($result === "{\"message\":\"not found\"}\n" && $response->getStatusCode() === 404) { |
| 589 | + throw new OWMNotFoundException(); |
555 | 590 | } |
556 | | - throw new OWMException('OpenWeatherMap returned a response with status code ' . $response->getStatusCode() . ' and the following content '. $result); |
| 591 | + throw new OWMException('OpenWeatherMap returned a response with status code ' . $response->getStatusCode() . ' and the following content `'. $result . '`'); |
557 | 592 | } |
558 | 593 |
|
559 | 594 | if ($this->cache !== null) { |
@@ -654,21 +689,6 @@ private function buildQueryUrlParameter($query) |
654 | 689 | } |
655 | 690 | } |
656 | 691 |
|
657 | | - /** |
658 | | - * Build the url to fetch air pollution data from. |
659 | | - * |
660 | | - * @param $lat |
661 | | - * @param $lon |
662 | | - * @param $dateTime |
663 | | - * @param string $url The url to prepend. |
664 | | - * |
665 | | - * @return string The fetched url |
666 | | - */ |
667 | | - private function buildAirPollutionUrl($lat, $lon, $dateTime, $url) |
668 | | - { |
669 | | - return $url."/$lat,$lon/$dateTime.json?appid=" . $this->apiKey; |
670 | | - } |
671 | | - |
672 | 692 | /** |
673 | 693 | * @param string $answer The content returned by OpenWeatherMap. |
674 | 694 | * |
|
0 commit comments