import webbrowser
from os.path import abspath
import holoviews as hv
import pandas as pd
from holoviews import opts
hv.extension('bokeh')
from bokeh.sampledata.us_counties import data as counties

df = pd.read_csv('census_data_popl_2010.csv', encoding="ISO-8859-1")

df = pd.DataFrame(df,
                  columns=
                  ['Target Geo Id2',
                   'Geographic area.1',
                   'Density per square mile of land area - Population'])

df.rename(columns=
          {'Target Geo Id2': 'fips',
           'Geographic area.1': 'Hrabstwo',
           'Density per square mile of land area - Population':
               'Gęstość_zaludnienia'},
          inplace=True)

print(f"\nOryginalne dane na temat gęstości zaludnienia:\n {df.head()}")
print(f"Wymiary obiektu df = {df.shape}\n")

# Usuwa dane dotyczące jednostek innych niż hrabstwa z obiektu dataframe.
df = df[df['fips'] > 100]
print(f"Dane na temat gęstości zaludnienia po usunięciu wierszy "
      f"dotyczących jednostek innych niż hrabstwa:\n{df.head()}")
print(f"Wymiary obiektu df = {df.shape}\n")

# Tworzy kolumny z identyfikatorami stanów i hrabstw.
df['state_id'] = (df['fips'] // 1000).astype('int64')
df['cid'] = (df['fips'] % 1000).astype('int64')
print(f"Dane na temat gęstości zaludnienia z nowymi kolumnami "
      f"na identyfikatory: \n{df.head()}")
print(f"Wymiary obiektu df = {df.shape}\n")
print("Informacja na temat obiektu df:")
print(df.info())  # Wyświetla typy danych wszystkich kolumn.

# Sprawdza poprawność przetwarzania pięciocyfrowych kodów FIPS.
print("\nDane na temat gęstości zaludnienia z wiersza 500:")
print(df.loc[500])

# Tworzy słownik z krotki state_id i cid oraz danych dot. gęstości zaludnienia.
state_ids = df.state_id.tolist()
cids = df.cid.tolist()
den = df['Gęstość_zaludnienia'].tolist()

tuple_list = tuple(zip(state_ids, cids))
popl_dens_dict = dict(zip(tuple_list, den))

# Wyklucza stany i terytoria, które nie są częścią stanów kontynentalnych.
EXCLUDED = ('ak', 'hi', 'pr', 'gu', 'vi', 'mp', 'as')

counties = [dict(county, Gęstość_zaludnienia=popl_dens_dict[cid])
            for cid, county in counties.items()
            if county["state"] not in EXCLUDED]

choropleth = hv.Polygons(counties,
                         ['lons', 'lats'],
                         [('detailed name', 'Hrabstwo'),'Gęstość_zaludnienia'])

title = 'Gęstość zaludnienia na milę kwadratową obszaru lądowego ' \
        'wg spisu powszechnego z 2010 roku'
choropleth.opts(opts.Polygons(logz=True,
                              tools=['hover'],
                              xaxis=None, yaxis=None,
                              show_grid=False, show_frame=False,
                              width=1100, height=700,
                              colorbar=True, toolbar='above',
                              color_index='Gęstość_zaludnienia', cmap='Greys',
                              line_color=None,
                              title=title))

hv.save(choropleth, 'choropleth.html', backend='bokeh')
url = abspath('choropleth.html')
webbrowser.open(url)
