Skip to content

Commit c9710c3

Browse files
author
Tom Klíma
committed
added Air Pollution API
1 parent a72a13f commit c9710c3

File tree

4 files changed

+227
-1
lines changed

4 files changed

+227
-1
lines changed

Cmfcmf/OpenWeatherMap.php

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@
1818

1919
namespace Cmfcmf;
2020

21+
use Cmfcmf\OpenWeatherMap\AirPollution;
2122
use Cmfcmf\OpenWeatherMap\CurrentWeather;
22-
use Cmfcmf\OpenWeatherMap\UVIndex;
2323
use Cmfcmf\OpenWeatherMap\CurrentWeatherGroup;
2424
use Cmfcmf\OpenWeatherMap\Exception as OWMException;
25+
use Cmfcmf\OpenWeatherMap\UVIndex;
2526
use Cmfcmf\OpenWeatherMap\WeatherForecast;
2627
use Psr\Cache\CacheItemPoolInterface;
2728
use Psr\Http\Client\ClientInterface;
@@ -67,6 +68,11 @@ class OpenWeatherMap
6768
*/
6869
private $uvIndexUrl = 'https://api.openweathermap.org/data/2.5/uvi';
6970

71+
/**
72+
* @var string The basic api url to fetch air pollution data from.
73+
*/
74+
private $airPollutionUrl = 'https://api.openweathermap.org/pollution/v1/co';
75+
7076
/**
7177
* @var CacheItemPoolInterface|null $cache The cache to use.
7278
*/
@@ -336,6 +342,31 @@ public function getHistoricUVIndex($lat, $lon, $start, $end)
336342
}, $data);
337343
}
338344

345+
/**
346+
* Returns atmosferic pollution by Carbon Monoxie
347+
*
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"
351+
*
352+
* @return AirPollution
353+
*
354+
* @api
355+
* @throws \Exception
356+
*/
357+
public function getAirPollution($lat, $lon, $dateTime = null)
358+
{
359+
if ($dateTime === null) {
360+
$dateTime = 'current';
361+
}
362+
363+
$answer = $this->getRawAirPollutionData($lat, $lon, $dateTime);
364+
365+
$json = $this->parseJson($answer);
366+
367+
return new AirPollution($json);
368+
}
369+
339370
/**
340371
* Directly returns the xml/json/html string returned by OpenWeatherMap for the current weather.
341372
*
@@ -471,6 +502,20 @@ public function getRawUVIndexData($mode, $lat, $lon, $cnt = null, $start = null,
471502
return $this->cacheOrFetchResult($url);
472503
}
473504

505+
/**
506+
* @param $lat
507+
* @param $lon
508+
* @param $dateTime
509+
* @return bool|string Returns the fetched data.
510+
* @throws OWMException
511+
*/
512+
public function getRawAirPollutionData($lat, $lon, $dateTime)
513+
{
514+
$url = $this->buildAirPollutionUrl($lat, $lon, $dateTime, $this->airPollutionUrl);
515+
516+
return $this->cacheOrFetchResult($url);
517+
}
518+
474519
/**
475520
* Returns whether or not the last result was fetched from the cache.
476521
*
@@ -505,6 +550,9 @@ private function cacheOrFetchResult($url)
505550
$response = $this->httpClient->sendRequest($this->httpRequestFactory->createRequest("GET", $url));
506551
$result = $response->getBody()->getContents();
507552
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.');
555+
}
508556
throw new OWMException('OpenWeatherMap returned a response with status code ' . $response->getStatusCode() . ' and the following content '. $result);
509557
}
510558

@@ -606,6 +654,21 @@ private function buildQueryUrlParameter($query)
606654
}
607655
}
608656

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+
609672
/**
610673
* @param string $answer The content returned by OpenWeatherMap.
611674
*
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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;
20+
21+
use Cmfcmf\OpenWeatherMap\Util\Location;
22+
23+
/**
24+
* AirPollution class used to hold the air pollution and time of measurement
25+
*/
26+
class AirPollution
27+
{
28+
/**
29+
* @var \DateTime
30+
*/
31+
public $dateTime;
32+
33+
/**
34+
* @var Location
35+
*/
36+
public $location;
37+
38+
/**
39+
* @var AirPollutionData[]
40+
*/
41+
public $data;
42+
43+
/**
44+
* Create a new air pollution object.
45+
*
46+
* @param object $json
47+
*
48+
* @throws \Exception
49+
* @internal
50+
*/
51+
public function __construct($json)
52+
{
53+
$this->dateTime = new \DateTime($json->time, new \DateTimeZone('UTC'));
54+
$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);
72+
}
73+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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;
20+
21+
/**
22+
* AirPollution class used to hold the air pollution and time of measurement
23+
*/
24+
class AirPollutionData
25+
{
26+
/**
27+
* @var float measurement precision
28+
*/
29+
public $precision;
30+
31+
/**
32+
* @var float atmospheric pressure at the point of measurement in hPa
33+
*/
34+
public $pressure;
35+
36+
/**
37+
* @var float volume mixing ratio
38+
*/
39+
public $value;
40+
41+
/**
42+
* Create a new air pollution data object.
43+
*
44+
* @param object $json
45+
*
46+
* @internal
47+
*/
48+
public function __construct($json)
49+
{
50+
$this->precision = (float)$json->precision;
51+
$this->pressure = (float)$json->pressure;
52+
$this->value = (float)$json->value;
53+
}
54+
55+
/**
56+
* @return float
57+
*/
58+
public function getPrecision(): float
59+
{
60+
return $this->precision;
61+
}
62+
63+
/**
64+
* @return float
65+
*/
66+
public function getPressure(): float
67+
{
68+
return $this->pressure;
69+
}
70+
71+
/**
72+
* @return float
73+
*/
74+
public function getValue(): float
75+
{
76+
return $this->value;
77+
}
78+
79+
}

tests/OpenWeatherMapTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@ public function testGetDailyWeatherForecast()
167167

168168
$this->assertInstanceOf('\Cmfcmf\OpenWeatherMap\WeatherForecast', $dailyForecast);
169169
}
170+
171+
public function testGetAirPollution()
172+
{
173+
$airPollutionCurrent = $this->owm->getAirPollution(40, -74, null);
174+
175+
$this->assertInstanceOf(OpenWeatherMap\AirPollution::class, $airPollutionCurrent);
176+
177+
$airPollutionPast = $this->owm->getAirPollution(40, -74, new \DateTime('now - 2 months'));
178+
179+
$this->assertInstanceOf(OpenWeatherMap\AirPollution::class, $airPollutionPast);
180+
}
170181

171182
public function testWasCached()
172183
{

0 commit comments

Comments
 (0)