@@ -175,7 +175,11 @@ def get_pvgis_hourly(lat, lon, angle=0, aspect=0,
175
175
src = res .json ()
176
176
return _parse_pvgis_hourly_json (src )
177
177
elif outputformat == 'csv' :
178
- return _parse_pvgis_hourly_csv (src )
178
+ with io .StringIO (res .content .decode ('utf-8' )) as src :
179
+ return _parse_pvgis_hourly_csv (src )
180
+ elif outputformat == 'basic' :
181
+ with io .BytesIO (res .content ) as src :
182
+ return _parse_pvgis_hourly_basic (src )
179
183
else :
180
184
# this line is never reached because if outputformat is not valid then
181
185
# the response is HTTP/1.1 400 BAD REQUEST which is handled earlier
@@ -189,9 +193,69 @@ def _parse_pvgis_hourly_json(src):
189
193
data = pd .DataFrame (src ['outputs' ]['hourly' ])
190
194
data .index = pd .to_datetime (data ['time' ], format = '%Y%m%d:%H%M' , utc = True )
191
195
data = data .drop ('time' , axis = 1 )
196
+ data = data .astype (dtype = {'Int' : 'int' }) # The 'Int' column to be integer
192
197
return data , inputs , meta
193
198
194
199
200
+ def _parse_pvgis_hourly_basic (src ):
201
+ # Hourly data with outputformat='basic' does not include header or metadata
202
+ data = pd .read_csv (src , header = None , skiprows = 2 )
203
+ return data , None , None
204
+
205
+
206
+ def _parse_pvgis_hourly_csv (src ):
207
+ # The first 4 rows are latitude, longitude, elevation, radiation database
208
+ inputs = {}
209
+ # 'Latitude (decimal degrees): 45.000\r\n'
210
+ inputs ['latitude' ] = float (src .readline ().split (':' )[1 ])
211
+ # 'Longitude (decimal degrees): 8.000\r\n'
212
+ inputs ['longitude' ] = float (src .readline ().split (':' )[1 ])
213
+ # Elevation (m): 1389.0\r\n
214
+ inputs ['elevation' ] = float (src .readline ().split (':' )[1 ])
215
+ # 'Radiation database: \tPVGIS-SARAH\r\n'
216
+ inputs ['radiation_database' ] = str (src .readline ().split (':' )[1 ]
217
+ .replace ('\t ' , '' ).replace ('\n ' , '' ))
218
+
219
+ # Parse through the remaining metadata section (the number of lines for
220
+ # this section depends on the requested parameters)
221
+ while True :
222
+ line = src .readline ()
223
+ if line .startswith ('time,' ): # The data header starts with 'time,'
224
+ # The last line of the meta-data section contains the column names
225
+ names = line .replace ('\n ' , '' ).replace ('\r ' , '' ).split (',' )
226
+ break
227
+ # Only retrieve metadata from non-empty lines
228
+ elif (line != '\n ' ) & (line != '\r \n ' ):
229
+ inputs [line .split (':' )[0 ]] = str (line .split (':' )[1 ]
230
+ .replace ('\n ' , '' )
231
+ .replace ('\r ' , '' ).strip ())
232
+
233
+ # The data section covers a variable number of lines (depends on requested
234
+ # years) and ends with a blank line
235
+ data_lines = []
236
+ while True :
237
+ line = src .readline ()
238
+ if (line == '\n ' ) | (line == '\r \n ' ):
239
+ break
240
+ else :
241
+ data_lines .append (line .replace ('\n ' , '' ).replace ('\r ' , '' )
242
+ .split (',' ))
243
+
244
+ data = pd .DataFrame (data_lines , columns = names )
245
+ data .index = pd .to_datetime (data ['time' ], format = '%Y%m%d:%H%M' , utc = True )
246
+ data = data .drop ('time' , axis = 1 )
247
+ # All columns should have the dtype=float, except 'Int' which should be
248
+ # integer. It is necessary to convert to float, before converting to int
249
+ data = data .astype (float ).astype (dtype = {'Int' : 'int' })
250
+
251
+ # Generate metadata dictionary containing description of parameters
252
+ meta = {}
253
+ for line in src .readlines ():
254
+ if ':' in line :
255
+ meta [line .split (':' )[0 ]] = line .split (':' )[1 ].strip ()
256
+
257
+ return data , inputs , meta
258
+
195
259
def get_pvgis_tmy (lat , lon , outputformat = 'json' , usehorizon = True ,
196
260
userhorizon = None , startyear = None , endyear = None , url = URL ,
197
261
timeout = 30 ):
0 commit comments