|
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