Completed
Push — master ( 237d29...caebd9 )
by Yannick
20:41
created

Weather   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 167
rs 8.64
c 0
b 0
f 0
wmc 47
lcom 0
cbo 1

4 Methods

Rating   Name   Duplication   Size   Complexity  
D buildcloudlayer() 0 52 19
C openweathermap() 0 40 13
B nomad_wind() 0 43 8
B oscar_wave() 0 27 7

How to fix   Complexity   

Complex Class

Complex classes like Weather often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Weather, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * This class is part of FlightAirmap. It's used to get weather data and create clouds
4
 *
5
 * Copyright (c) Ycarus (Yannick Chabanois) <[email protected]>
6
 * Licensed under AGPL license.
7
 * For more information see: https://www.flightairmap.com/
8
*/
9
require_once(dirname(__FILE__).'/class.Common.php');
10
class Weather {
11
	public function buildcloudlayer($metar) {
12
		//print_r($metar);
13
		$result = array();
14
		foreach($metar['cloud'] as $key => $data) {
15
			$alt_m = $metar['cloud'][$key]['level'];
16
			$alt_ft = $alt_m*3.28084;
17
			$pressure = $metar['QNH'];
18
			$cumulus_base = 122.0 * ($metar['temperature'] - $metar['dew']);
19
			$stratus_base = 100.0 * (100.0 * $metar['rh'])*0.3048;
20
			$coverage_norm = 0.0;
21
			if ($metar['cloud'][$key]['type'] == 'Few') {
22
				$coverage_norm = 2.0/8.0;
23
			} elseif ($metar['cloud'][$key]['type'] == 'Scattered') {
24
				$coverage_norm = 4.0/8.0;
25
			} elseif ($metar['cloud'][$key]['type'] == 'Broken') {
26
				$coverage_norm = 6.0/8.0;
27
			} elseif ($metar['cloud'][$key]['type'] == 'Overcast/Full cloud coverage') {
28
				$coverage_norm = 8.0/8.0;
29
			}
30
			$layer_type = 'nn';
0 ignored issues
show
Unused Code introduced by
$layer_type is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
31
			if ($metar['cloud'][$key]['significant'] == 'cirrus') {
32
				$layer_type = 'ci';
33
			} elseif ($alt_ft > 16500) {
34
				$layer_type = 'ci';
35
			} elseif ($alt_ft > 6500) {
36
				$layer_type = 'ac';
37
				if ($pressure < 1005.0 && $coverage_norm >= 0.5) {
38
					$layer_type = 'ns';
39
				}
40
			} else {
41
				if ($cumulus_base * 0.80 < $alt_m && $cumulus_base * 1.20 > $alt_m) {
42
					$layer_type = 'cu';
43
				} elseif ($stratus_base * 0.80 < $alt_m && $stratus_base * 1.40 > $alt_m) {
44
					$layer_type = 'st';
45
				} else {
46
					if ($alt_ft < 2000) {
47
						$layer_type = 'st';
48
					} elseif ($alt_ft < 4500) {
49
						$layer_type = 'cu';
50
					} else {
51
						$layer_type = 'sc';
52
					}
53
				}
54
			}
55
			//echo 'coverage norm : '.$coverage_norm.' - layer_type: '.$layer_type."\n";
56
			$result[] = array('cov' => $coverage_norm, 'type' => $layer_type,'alt' => $alt_m,'rh' => $metar['rh']);
57
		}
58
		if (count($result) < 2 && $metar['rh'] > 60) {
59
			$result[] = array('cov' => 0.75, 'type' => 'ci','alt' => 4000,'rh' => $metar['rh']);
60
		}
61
		return $result;
62
	}
63
	
64
	public function openweathermap($latitude,$longitude) {
65
		global $globalOpenWeatherMapKey;
66
		if ($globalOpenWeatherMapKey == '') return array();
67
		$Common = new Common();
68
		$url = 'http://api.openweathermap.org/data/2.5/weather?lat='.$latitude.'&lon='.$longitude.'&units=metric&appid='.$globalOpenWeatherMapKey;
69
		//echo $url."\n";
70
		$weatherdata = json_decode($Common->getData($url),true);
71
		if (!isset($weatherdata['main']['temp']) || !isset($weatherdata['weather'][0]['id'])) return array('clouds' => array(),'rain' => array());
72
		$dew = $weatherdata['main']['temp'] - ((100-$weatherdata['main']['humidity'])/5);
73
		$cumulus_base = 122.0 * ($weatherdata['main']['temp'] - $dew);
74
		$stratus_base = 100.0 * (100.0 * $weatherdata['main']['humidity'])*0.3048;
75
		$coverage_norm = 0.0;
76
		if ($weatherdata['weather'][0]['id'] == 801) {
77
			// few clouds
78
			$coverage_norm = 2.0/8.0;
79
		} elseif ($weatherdata['weather'][0]['id'] == 802) {
80
			//scattered cloud
81
			$coverage_norm = 4.0/8.0;
82
		} elseif ($weatherdata['weather'][0]['id'] == 803) {
83
			// broken clouds
84
			$coverage_norm = 6.0/8.0;
85
		} elseif ($weatherdata['weather'][0]['id'] == 804) {
86
			// overcast clouds
87
			$coverage_norm = 8.0/8.0;
88
		}
89
		$alt_m = 1000;
90
		if ($cumulus_base * 0.80 < $alt_m && $cumulus_base * 1.20 > $alt_m) {
91
			$layer_type = 'cu';
92
		} elseif ($stratus_base * 0.80 < $alt_m && $stratus_base * 1.40 > $alt_m) {
93
			$layer_type = 'st';
94
		} else {
95
			$layer_type = 'st';
96
		}
97
		$result = array();
98
		$result[] = array('cov' => $coverage_norm, 'type' => $layer_type,'alt' => $alt_m,'rh' => $weatherdata['main']['humidity']);
99
		if ($weatherdata['main']['humidity'] > 60) {
100
			$result[] = array('cov' => 0.75, 'type' => 'ci','alt' => 4000,'rh' => $weatherdata['main']['humidity']);
101
		}
102
		return array('clouds' => $result,'rain' => array('tmp' => $weatherdata['main']['temp'],'rh' => $weatherdata['main']['humidity']));
103
	}
104
	
105
	public function nomad_wind($hour = '') {
106
		global $globalWindsPath;
107
		if ($hour == '') $hour = date('G');
108
		if (isset($globalWindsPath) && $globalWindsPath != '') {
109
			$grib2json = $globalWindsPath['grib2json'];
110
			$windpathsrc = $globalWindsPath['source'];
111
			$windpathdest = $globalWindsPath['destination'];
112
		} else {
113
			$grib2json = dirname(__FILE__).'/libs/grib2json/bin/grib2json';
114
			$windpathsrc = dirname(__FILE__).'/../data/winds.gb2';
115
			$windpathdest = dirname(__FILE__).'/../data/winds.json';
116
		}
117
		
118
		// http://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_0p50.pl?file=gfs.t05z.pgrb2full.0p50.f000&lev_10_m_above_ground=on&lev_surface=on&var_TMP=on&var_UGRD=on&var_VGRD=on&leftlon=0&rightlon=360&toplat=90&bottomlat=-90&dir=/gfs.2017111717
119
		$resolution = '0.5';
120
		$baseurl = 'http://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_'.($resolution === '1' ? '1p00':'0p50').'.pl';
121
		$get = array('file' => 'gfs.t'.sprintf('%02d',(6*floor($hour/6))).($resolution === '1' ? 'z.pgrb2.1p00.f000' : 'z.pgrb2full.0p50.f000'),
122
			'lev_10_m_above_ground' => 'on',
123
			'lev_surface' => 'on',
124
			'var_TMP' => 'on',
125
			'var_UGRD' => 'on',
126
			'var_VGRD' => 'on',
127
			'leftlon' => 0,
128
			'rightlon' => 360,
129
			'toplat' => 90,
130
			'bottomlat' => -90,
131
			'dir' => '/gfs.'.date('Ymd').sprintf('%02d',(6*floor($hour/6)))
132
		);
133
		$url = $baseurl.'?'.http_build_query($get);
134
		//echo $url;
135
		$Common = new Common();
136
		$Common->download($url,$windpathsrc);
137
		// Check if the downloaded file is in GRIB format
138
		$file = fopen($windpathsrc,"r");
139
		$firc = fgetc($file);
140
		fclose($file);
141
		if ($firc == 'G') {
142
			system($grib2json.' --data --output '.$windpathdest.' --names --compact '.$windpathsrc);
143
		} else {
144
			// if not try previous run
145
			if ($hour == date('G')) $this->nomad_wind(date('G')-6);
146
		}
147
	}
148
149
	public function oscar_wave() {
150
		global $globalWavesPath, $globalPODACCuser,$globalPODACCpass;
151
		if ($globalPODACCuser == '' && $globalPODACCpass == '') return;
152
		if (isset($globalWavesPath) && $globalWavesPath != '') {
153
			$grib2json = $globalWavesPath['grib2json'];
154
			$wavepathsrc = $globalWavesPath['source'];
155
			$wavepathdest = $globalWavesPath['destination'];
156
		} else {
157
			$grib2json = dirname(__FILE__).'/libs/grib2json/bin/grib2json';
158
			$wavepathsrc = dirname(__FILE__).'/../data/waves.nc';
159
			$wavepathdest = dirname(__FILE__).'/../data/waves.json';
160
		}
161
		
162
		$url = 'https://podaac.jpl.nasa.gov/ws/search/granule/?datasetId=PODAAC-OSCAR-03D01&itemsPerPage=1&sortBy=timeDesc&format=atom&pretty=false';
163
		$Common = new Common();
164
		$auth = base64_encode("$globalPODACCuser:$globalPODACCpass");
165
		$oscarlst = $Common->getData($url);
166
		$oscarlst_xml = json_decode(json_encode(simplexml_load_string($oscarlst)),true);
167
		foreach ($oscarlst_xml['entry']['link'] as $oscarlnk) {
168
			if ($oscarlnk['@attributes']['type'] == 'application/x-netcdf') {
169
				$Common->download($oscarlnk['@attributes']['href'],$wavepathsrc.'.gz','',array("Authorization: BASIC $auth"));
0 ignored issues
show
Documentation introduced by
array("Authorization: BASIC {$auth}") is of type array<integer,?>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
170
				break;
171
			}
172
		}
173
		$Common->gunzip($wavepathsrc.'.gz');
174
		system($grib2json.' --data --output '.$wavepathdest.' --names --compact '.$wavepathsrc);
175
	}
176
}
177
/*
178
require_once('class.METAR.php');
179
$METAR = new METAR();
180
*/
181
/*
182
$themetar = $METAR->getMETAR('LFLL');
183
print_r($themetar);
184
$result = $METAR->parse($themetar[0]['metar']);
185
*/
186
/*
187
$result = $METAR->parse('LFLL 081330Z 01006KT 340V050 9999 FEW020 BKN080 07/01 Q1018 NOSIG');
188
print_r($result);
189
$Weather = new Weather();
190
//print_r($Weather->buildcloudlayer($result));
191
//print_r($Weather->buildcloud('46.3870','5.2941','2000','0.25'));
192
print_r($Weather->generateRandomPoint('46.3870','5.2941','2000'));
193
*/
194
/*
195
$Weather = new Weather();
196
$Weather->nomad_wind();
197
*/
198
/*
199
$Weather = new Weather();
200
$Weather->oscar_wave();
201
*/
202
/*
203
$Weather = new Weather();
204
print_r($Weather->openweathermap(0.0,-10.0));
205
*/
206
?>