def test_get_easting_northing_from_lat_long(): """Test lat_long_to_easting_northing.""" latitude = np.array([geo.rad(52, 39, 27.2531)]) longitude = np.array([geo.rad(1, 43, 4.5177)]) e = 651409.903 n = 313177.270 assert np.array(geo.get_easting_northing_from_lat_long(latitude, longitude, radians=True)) \ == approx(np.array((e,n)), rel=1.0e-5)
def __init__(self, postcode_file=None, risk_file=None, values_file=None): """ Reads postcode and flood risk files and provides a postcode locator service. Parameters --------- postcode_file : str, optional Filename of a .csv file containing geographic location data for postcodes. risk_file : str, optional Filename of a .csv file containing flood risk data. postcode_file : str, optional Filename of a .csv file containing property value data for postcodes. """ self.dfp = pd.read_csv(postcode_file) self.dff = pd.read_csv(risk_file) self.dfc = pd.read_csv(values_file) self.dfc['Postcode'] = self.dfc['Postcode'].str.replace(" ", "") self.dfp['Postcode'] = self.dfp['Postcode'].str.replace(" ", "") lat, lon = geo.WGS84toOSGB36(self.dfp.loc[:, 'Latitude'], self.dfp.loc[:, 'Longitude']) easting, northing = geo.get_easting_northing_from_lat_long(lat, lon) self.dfp['Easting'] = easting self.dfp['Northing'] = northing self.dfp = self.dfp.merge(self.dfc[['Postcode', 'Total Value']], how='left', left_on='Postcode', right_on='Postcode').fillna(0) self.dff['Numerical Risk'] = self.dff['prob_4band'].replace( ['High', 'Medium', 'Low', 'Very Low'], [4, 3, 2, 1]) self.dfp['Postcode'] = self.dfp['Postcode'].apply( lambda x: x[0:3] + " " + x[3:6] if len(x) == 6 else x) self.dfp['Postcode'] = self.dfp['Postcode'].apply( lambda x: x[0:2] + " " + x[4:6] if len(x) == 5 else x)
def historic_API(date, easting_lim, northing_lim, latlong=False): url = 'https://environment.data.gov.uk/flood-monitoring/archive/readings-full-' + date + '.csv' data_csv = pd.read_csv(url) df = pd.DataFrame(data=data_csv) df = df.groupby('parameter') df = df.get_group('rainfall') df = df.reset_index() if latlong == True: easting_lim, northing_lim = geo.get_easting_northing_from_lat_long( easting_lim, northing_lim) values = [] dates = [] stations = [] northing = [] easting = [] station_list = [] northeast = [] for row in range(0, len(df)): historic_values = df.loc[row, 'value'] historic_date = df.loc[row, 'dateTime'] station = df.loc[row, 'stationReference'] historic_values = pd.to_numeric(historic_values, errors='coerce') if isinstance(historic_values, float) == False: continue if station in station_list: stations.append(station) northing.append(northing[station_list.index(station)]) easting.append(easting[station_list.index(station)]) else: station_list.append(station) station_url = 'https://environment.data.gov.uk/flood-monitoring/id/stations?parameter=rainfall&stationReference=' + str( station) coordinates = requests.get(station_url) coordinates = json.loads(coordinates.text) north = coordinates.get('items')[0].get('northing') east = coordinates.get('items')[0].get('easting') stations.append(station) northing.append(north) easting.append(east) values.append(historic_values) dates.append(historic_date) historic_rain = pd.DataFrame({ 'dates': dates[:], 'station': stations[:], 'northing': northing[:], 'easting': easting[:], 'values': values[:] }) historic_rain['dates'] = historic_rain['dates'].map( lambda x: x.rstrip('Z')) # for line in historic_rain['dates']: # if ':01T' in historic_rain['dates']: # historic_rain['dates'][row] = historic_rain['dates'][row].str.replace(':01T', ':00T') historic_rain['date'], historic_rain['time'] = historic_rain[ 'dates'].str.split('T', 1).str # pattern = '*:01' # for line in historic_rain['time']: # if fnmatch(line, pattern): # historic_rain.dates.loc[row] = historic_rain.dates.loc[row].replace('*$.:01', ':00', regex=True) # # historic_rain['dates'][index=row] = historic_rain['dates'][index=row].replace(r'*$.:01', ':00') historic_rain = historic_rain.drop('dates', axis=1).drop( 'date', axis=1).sort_values(by='time', ascending=True) northeast = historic_rain.loc[(historic_rain.northing > northing_lim) & (historic_rain.easting > easting_lim)] northeast_averageT = northeast.groupby( 'time')['values'].mean().reset_index() northeast_average = northeast['values'].mean() southeast = historic_rain.loc[(historic_rain.northing < northing_lim) & (historic_rain.easting > easting_lim)] southeast_average = southeast['values'].mean() southeast_averageT = southeast.groupby( 'time')['values'].mean().reset_index() northwest = historic_rain.loc[(historic_rain.northing > northing_lim) & (historic_rain.easting < easting_lim)] northwest_average = northwest['values'].mean() northwest_averageT = northwest.groupby( 'time')['values'].mean().reset_index() southwest = historic_rain.loc[(historic_rain.northing < northing_lim) & (historic_rain.easting < easting_lim)] southwest_average = southwest['values'].mean() southwest_averageT = southwest.groupby( 'time')['values'].mean().reset_index() plt.figure(1) plt.title('Average rain per quadrant' + date) scale_ls = range(4) index_ls = ['NE', 'SE', 'NW', 'SW'] area_data = [ northeast_average, southeast_average, northwest_average, southwest_average ] plt.xticks(scale_ls, index_ls) plt.xlabel('Quadrant') plt.ylabel('Average Rainfall (mm)') plt.bar(scale_ls, area_data) plt.savefig('quadrant.png') plt.show() plt.subplots() plt.title('England Rainfall Against Time for ' + date) plt.subplot(2, 2, 1) plt.plot(northwest_averageT['time'], northwest_averageT['values']) plt.xlabel('Time') plt.xticks(np.arange(0, len(northwest_averageT), 4), rotation=30) plt.ylabel('Average Rainfall (mm)') plt.title('North West') plt.subplot(2, 2, 2) plt.plot(northeast_averageT['time'], northeast_averageT['values']) plt.xlabel('Time') plt.xticks(np.arange(0, len(northeast_averageT), 4), rotation=30) plt.ylabel('Average Rainfall (mm)') plt.title('North East') plt.subplot(223) plt.plot(southwest_averageT['time'], southwest_averageT['values']) plt.xlabel('Time') plt.xticks(np.arange(0, len(southwest_averageT), 4), rotation=30) plt.ylabel('Average Rainfall (mm)') plt.title('South West') plt.subplot(224) plt.plot(southeast_averageT['time'], southeast_averageT['values']) plt.xlabel('Time') plt.xticks(np.arange(0, len(southeast_averageT), 4), rotation=30) plt.ylabel('Average Rainfall (mm)') plt.title('South East') plt.subplots_adjust(left=0.1, bottom=0.05, top=0.9, right=0.95, hspace=0.5) plt.savefig('quadrant_detail.png') plt.show()
import json from flood_tool import Tool from flood_tool import geo from math import sqrt import numpy as np import csv with open('./flood_tool/resources/api_postcodes.csv', 'r') as f: reader = csv.reader(f) for row in reader: postcodes = row tool = Tool('./flood_tool/resources/postcodes.csv', './flood_tool/resources/flood_probability.csv', './flood_tool/resources/property_value.csv') lat_long = tool.get_lat_long(postcodes) E_N = np.array(geo.get_easting_northing_from_lat_long(lat_long[:, 0], lat_long[:,1])) url = 'https://environment.data.gov.uk/flood-monitoring/id/stations?parameter=rainfall' resp = requests.get(url) data = json.loads(resp.text) coord = data.get('items') for i in range(3): station = '' a = [] lat = lat_long[i, 0] long =lat_long[i, 1] prox_url = 'https://environment.data.gov.uk/flood-monitoring/id/stations?parameter=rainfall' + '&lat=' + str(lat) + '&long=' + str(long) + '&dist=10000' prox = requests.get(prox_url)
def get_Risk_Level(self, postcode, distance): """ Get an array of corresponding latitude, longitude and risk level from a sequence of postcodes and distance range around every postcode Parameters ---------- postcodes: sequence of strs Ordered collection of postcodes distance: a float number Returns ------- numpy.ndarray array of floats for the latitude, longitude and risk level """ # create class Tool to use functions in tool.py # for apply function in tool.py later files = tool.Tool( postcode_file='flood_tool/resources/postcodes.csv', risk_file='flood_tool/resources/flood_probability.csv', values_file='flood_tool/resources/property_value.csv') #set the range of postcode to define stations and get latitude, longitude lat_long = files.get_lat_long(postcode) latitude = lat_long[:, 0] longitude = lat_long[:, 1] #get rainfall value for input Postcode rainfall = np.array(self.get_all_station(latitude, longitude, distance)) #change numpy.array to 0 which is convenient to process later rainfall = np.nan_to_num(rainfall) EOS_NOS = geo.get_easting_northing_from_lat_long(latitude, longitude) prob_band = files.get_easting_northing_flood_probability( EOS_NOS[0], EOS_NOS[1]) dataset = pd.DataFrame({ 'Postcode': postcode, 'Latitude': latitude, 'Longitude': longitude, 'Value': rainfall, 'Probability Band': prob_band }) #replace the probability band to threshold value threshold_DF = dataset.replace({ 'High': 1.00, 'Medium': 1.25, 'Low': 1.5, 'Very Low': 1.75, 'Zero': 2.00, 'No Risk': 2.00 }) first_level = 0.2 second_level = 0.4 third_level = 0.6 def to_mark(diff): ''' get the corresponding risk level as str from the difference between threshold and rainfall value Parameters ---------- diff: a float number recording difference between threshold and rainfall value Returns ------- str: risk level ''' if diff < 0: result = 'No Risk' else: if diff < first_level: result = 'Low Risk' elif (diff >= first_level) & (diff < second_level): result = 'Medium Risk' elif (diff >= second_level) & (diff < third_level): result = 'High Risk' else: result = 'Dangerous' return result #comupute the difference between threshold and rainfall value diff_DF = threshold_DF.assign(diff=threshold_DF['Value'] - threshold_DF['Probability Band']) #change the difference to the corresponding risk level Risk_Ser = diff_DF['diff'].apply(to_mark) output = np.array(Risk_Ser) return latitude, longitude, output