Skip to content

Commit 941af8d

Browse files
committed
Implement other air pollution apis
1 parent c9710c3 commit 941af8d

15 files changed

+381
-86
lines changed

Cmfcmf/OpenWeatherMap.php

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Cmfcmf\OpenWeatherMap\CurrentWeather;
2323
use Cmfcmf\OpenWeatherMap\CurrentWeatherGroup;
2424
use Cmfcmf\OpenWeatherMap\Exception as OWMException;
25+
use Cmfcmf\OpenWeatherMap\NotFoundException as OWMNotFoundException;
2526
use Cmfcmf\OpenWeatherMap\UVIndex;
2627
use Cmfcmf\OpenWeatherMap\WeatherForecast;
2728
use Psr\Cache\CacheItemPoolInterface;
@@ -71,7 +72,7 @@ class OpenWeatherMap
7172
/**
7273
* @var string The basic api url to fetch air pollution data from.
7374
*/
74-
private $airPollutionUrl = 'https://api.openweathermap.org/pollution/v1/co';
75+
private $airPollutionUrl = 'https://api.openweathermap.org/pollution/v1/';
7576

7677
/**
7778
* @var CacheItemPoolInterface|null $cache The cache to use.
@@ -343,28 +344,42 @@ public function getHistoricUVIndex($lat, $lon, $start, $end)
343344
}
344345

345346
/**
346-
* Returns atmosferic pollution by Carbon Monoxie
347+
* Returns air pollution data
347348
*
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.
351359
*
352-
* @return AirPollution
360+
* @throws OWMException|\Exception
353361
*
354362
* @api
355-
* @throws \Exception
356363
*/
357-
public function getAirPollution($lat, $lon, $dateTime = null)
364+
public function getAirPollution($type, $lat, $lon, $date = "current")
358365
{
359-
if ($dateTime === null) {
360-
$dateTime = 'current';
366+
$answer = $this->getRawAirPollutionData($type, $lat, $lon, $date);
367+
if ($answer === null) {
368+
return null;
361369
}
362-
363-
$answer = $this->getRawAirPollutionData($lat, $lon, $dateTime);
364-
365370
$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+
}
368383
}
369384

370385
/**
@@ -503,17 +518,37 @@ public function getRawUVIndexData($mode, $lat, $lon, $cnt = null, $start = null,
503518
}
504519

505520
/**
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
511535
*/
512-
public function getRawAirPollutionData($lat, $lon, $dateTime)
536+
public function getRawAirPollutionData($type, $lat, $lon, $date = "current")
513537
{
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+
}
517552
}
518553

519554
/**
@@ -550,10 +585,10 @@ private function cacheOrFetchResult($url)
550585
$response = $this->httpClient->sendRequest($this->httpRequestFactory->createRequest("GET", $url));
551586
$result = $response->getBody()->getContents();
552587
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();
555590
}
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 . '`');
557592
}
558593

559594
if ($this->cache !== null) {
@@ -654,21 +689,6 @@ private function buildQueryUrlParameter($query)
654689
}
655690
}
656691

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-
672692
/**
673693
* @param string $answer The content returned by OpenWeatherMap.
674694
*

Cmfcmf/OpenWeatherMap/AirPollution.php renamed to Cmfcmf/OpenWeatherMap/AirPollution/BaseAirPollution.php

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,58 +16,31 @@
1616
* @see https://OpenWeatherMap.org/appid
1717
*/
1818

19-
namespace Cmfcmf\OpenWeatherMap;
19+
namespace Cmfcmf\OpenWeatherMap\AirPollution;
2020

2121
use Cmfcmf\OpenWeatherMap\Util\Location;
2222

23-
/**
24-
* AirPollution class used to hold the air pollution and time of measurement
25-
*/
26-
class AirPollution
23+
abstract class BaseAirPollution
2724
{
2825
/**
2926
* @var \DateTime
3027
*/
31-
public $dateTime;
28+
public $time;
3229

3330
/**
3431
* @var Location
3532
*/
3633
public $location;
3734

3835
/**
39-
* @var AirPollutionData[]
40-
*/
41-
public $data;
42-
43-
/**
44-
* Create a new air pollution object.
45-
*
4636
* @param object $json
4737
*
4838
* @throws \Exception
4939
* @internal
5040
*/
5141
public function __construct($json)
5242
{
53-
$this->dateTime = new \DateTime($json->time, new \DateTimeZone('UTC'));
43+
$this->time = new \DateTime($json->time, new \DateTimeZone('UTC'));
5444
$this->location = new Location($json->location->latitude, $json->location->longitude);
55-
$airPollutionData = [];
56-
foreach ($json->data as $measurement) {
57-
$airPollutionData[] = new AirPollutionData($measurement);
58-
}
59-
$this->data = $airPollutionData;
60-
}
61-
62-
/**
63-
* @return AirPollutionData|null
64-
*/
65-
public function getLastAirPollutionData()
66-
{
67-
if (count($this->data) === 0) {
68-
return null;
69-
}
70-
71-
return reset($this->data);
7245
}
7346
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/*
4+
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
5+
*
6+
* @license MIT
7+
*
8+
* Please see the LICENSE file distributed with this source code for further
9+
* information regarding copyright and licensing.
10+
*
11+
* Please visit the following links to read about the usage policies and the license of
12+
* OpenWeatherMap data before using this library:
13+
*
14+
* @see https://OpenWeatherMap.org/price
15+
* @see https://OpenWeatherMap.org/terms
16+
* @see https://OpenWeatherMap.org/appid
17+
*/
18+
19+
namespace Cmfcmf\OpenWeatherMap\AirPollution;
20+
21+
class COAirPollution extends PrecisionPressureValueAirPollution
22+
{
23+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
5+
*
6+
* @license MIT
7+
*
8+
* Please see the LICENSE file distributed with this source code for further
9+
* information regarding copyright and licensing.
10+
*
11+
* Please visit the following links to read about the usage policies and the license of
12+
* OpenWeatherMap data before using this library:
13+
*
14+
* @see https://OpenWeatherMap.org/price
15+
* @see https://OpenWeatherMap.org/terms
16+
* @see https://OpenWeatherMap.org/appid
17+
*/
18+
19+
namespace Cmfcmf\OpenWeatherMap\AirPollution;
20+
21+
use Cmfcmf\OpenWeatherMap\Util\Unit;
22+
23+
class NO2AirPollution extends BaseAirPollution
24+
{
25+
26+
/**
27+
* @var Unit
28+
*/
29+
public $value;
30+
31+
/**
32+
* @var Unit
33+
*/
34+
public $valueStratosphere;
35+
36+
/**
37+
* @var Unit
38+
*/
39+
public $valueTroposphere;
40+
41+
public function __construct($json)
42+
{
43+
parent::__construct($json);
44+
45+
$this->value = new Unit($json->data->no2->value, "g/m³", "", $json->data->no2->precision);
46+
$this->valueStratosphere = new Unit($json->data->no2_strat->value, "g/m³", "", $json->data->no2_strat->precision);
47+
$this->valueTroposphere = new Unit($json->data->no2_trop->value, "g/m³", "", $json->data->no2_trop->precision);
48+
}
49+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
/*
4+
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
5+
*
6+
* @license MIT
7+
*
8+
* Please see the LICENSE file distributed with this source code for further
9+
* information regarding copyright and licensing.
10+
*
11+
* Please visit the following links to read about the usage policies and the license of
12+
* OpenWeatherMap data before using this library:
13+
*
14+
* @see https://OpenWeatherMap.org/price
15+
* @see https://OpenWeatherMap.org/terms
16+
* @see https://OpenWeatherMap.org/appid
17+
*/
18+
19+
namespace Cmfcmf\OpenWeatherMap\AirPollution;
20+
21+
use Cmfcmf\OpenWeatherMap\Util\Unit;
22+
23+
class O3AirPollution extends BaseAirPollution
24+
{
25+
26+
/**
27+
* @var Unit
28+
*/
29+
public $value;
30+
31+
public function __construct($json)
32+
{
33+
parent::__construct($json);
34+
35+
$this->value = new Unit($json->data, "DU");
36+
}
37+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/*
4+
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
5+
*
6+
* @license MIT
7+
*
8+
* Please see the LICENSE file distributed with this source code for further
9+
* information regarding copyright and licensing.
10+
*
11+
* Please visit the following links to read about the usage policies and the license of
12+
* OpenWeatherMap data before using this library:
13+
*
14+
* @see https://OpenWeatherMap.org/price
15+
* @see https://OpenWeatherMap.org/terms
16+
* @see https://OpenWeatherMap.org/appid
17+
*/
18+
19+
namespace Cmfcmf\OpenWeatherMap\AirPollution;
20+
21+
use Cmfcmf\OpenWeatherMap\Util\Unit;
22+
23+
class PrecisionPressureValueAirPollution extends BaseAirPollution
24+
{
25+
26+
/**
27+
* @var object[]
28+
*/
29+
public $values;
30+
31+
public function __construct($json)
32+
{
33+
parent::__construct($json);
34+
35+
$this->values = [];
36+
foreach ($json->data as $data) {
37+
$this->values[] = [
38+
"value" => new Unit($data->value, "g/m³", "", $data->precision),
39+
"pressure" => new Unit($data->pressure, "hPa"),
40+
];
41+
}
42+
}
43+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/*
4+
* OpenWeatherMap-PHP-API — A PHP API to parse weather data from https://OpenWeatherMap.org.
5+
*
6+
* @license MIT
7+
*
8+
* Please see the LICENSE file distributed with this source code for further
9+
* information regarding copyright and licensing.
10+
*
11+
* Please visit the following links to read about the usage policies and the license of
12+
* OpenWeatherMap data before using this library:
13+
*
14+
* @see https://OpenWeatherMap.org/price
15+
* @see https://OpenWeatherMap.org/terms
16+
* @see https://OpenWeatherMap.org/appid
17+
*/
18+
19+
namespace Cmfcmf\OpenWeatherMap\AirPollution;
20+
21+
class SO2AirPollution extends PrecisionPressureValueAirPollution
22+
{
23+
}

0 commit comments

Comments
 (0)