###############################################################################
##                  TP : Itinéraires grandes villes                          ##
###############################################################################

import matplotlib.pyplot as plt
import sqlite3 as lt
import numpy as np
dbh=lt.connect('dots.db')
cur=dbh.cursor()


## Tracé de la carte d'un département

def points(idd,nump):

    cur.execute("select contours_departements.x,contours_departements.y FROM departements join contours_departements on contours_departements.id_departement=departements.id where departements.id=? and contours_departements.numero_poly=?",(idd,nump))
    result=cur.fetchall()
    return result

def polygones(idd):
    cur.execute("select distinct numero_poly FROM contours_departements where id_departement=?",(idd,))
    result=cur.fetchall()
    return result

def liste_dep_plusieurs_polygones():
    cur.execute("select id,nom from departements")
    result=cur.fetchall()
    Resultat=[]
    for i in result:
        if i[0]!=1:
            Resultat.append(i[1])
    print("Résultat de la question 8")
    print(Resultat)

def carte_dep(idd):
    Liste_poly=polygones(idd)
    for k in Liste_poly:
        nump=k[0]
        X,Y=[],[]
        Liste=points(idd,nump)
        for i in Liste:
            X.append(i[0])
            Y.append(i[1])
        X.append(Liste[0][0])
        Y.append(Liste[0][1])
        plt.plot(X,Y,color='b')

def carteFrance():
    plt.axis('equal')
    plt.axes().set_aspect(1.5)
    for n in range(1,92):
        if n!=29 and n!=30:
            carte_dep(n)
    plt.grid()

## Liste des grandes villes

def Grandes_Communes(Pop_min):
    cur.execute("SELECT c.nom AS Nom , AVG(cc.x) AS Longitude , AVG(cc.y) AS Latitude , population FROM communes AS c JOIN contours_communes AS cc ON c.id=cc.id_commune WHERE population>=? and id_departement<>29 and id_departement<>30 GROUP BY cc.id_commune",(Pop_min,))
    result=cur.fetchall()
    return result

## Dictionnaire des communes

def Dict_Communes(Pop_min):
    L=Grandes_Communes(Pop_min)
    Dico=dict()
    for i in range(len(L)):
        Dico[L[i][0]]=(L[i][1],L[i][2],L[i][3])
    #return Dico
    return reduction_agglo(Dico)


## Calcul de la distance entre 2 communes

def Cal_dist(D,C1,C2):
    lon1,lon2,lat1,lat2=D[C1][0],D[C2][0],D[C1][1],D[C2][1]
    lon1,lon2,lat1,lat2=lon1*np.pi/180,lon2*np.pi/180,lat1*np.pi/180,lat2*np.pi/180
    d=2*6371*np.arcsin(np.sqrt((np.sin((lat2-lat1)/2))**2+np.cos(lat1)*np.cos(lat2)*(np.sin((lon2-lon1)/2))**2))
    return d

## Réduction des agglomérations

def reduction_agglo(D_com):
    D=D_com.copy()
    for Com1 in D_com:
        for Com2 in D_com:
            d=Cal_dist(D_com,Com1,Com2)
            if d<15 and Com1!=Com2:
                if D_com[Com1][2]<D_com[Com2][2]:
                    petite=Com1
                else:
                    petite=Com2
                if petite in D:
                    D.pop(petite)
    return D

## Tracé de la carte des communes

def Trace_Carte(Pop_min):
    Dico=Dict_Communes(Pop_min)
    L_lon,L_lat=[],[]
    for ville in Dico:
        L_lon.append(Dico[ville][0])
        L_lat.append(Dico[ville][1])
    carteFrance()
    plt.plot(L_lon,L_lat,'ro')


## Construction du Graphe

def Constr_graphe(Pop_min,autonomie):
    D_com=Dict_Communes(Pop_min)
    Graphe={}
    for com1 in D_com:
        Graphe[com1]={}
        for com2 in D_com:
            d=Cal_dist(D_com,com1,com2)
            if d<=autonomie and com1!=com2:
                Graphe[com1][com2]=d
    return Graphe,D_com


## Tracé du graphe sur la carte

def Trace_graphe(Pop_min,autonomie):
    Graphe,D_com=Constr_graphe(Pop_min,autonomie)
    Trace_Carte(Pop_min)
    Fait={}
    for ville in Graphe:
        for voisin in Graphe[ville]:
            if (voisin,ville) not in Fait:
                Lx=[D_com[ville][0],D_com[voisin][0]]
                Ly=[D_com[ville][1],D_com[voisin][1]]
                plt.plot(Lx,Ly,'--',color='g')
                Fait[ville,voisin]=''


## Codage de l'algorithme de Floy-Warshall

# def Constr_mat(Graphe_adj):













# def Ajout_ville(M,Ajout):










# def Floyd_Warshall(Graphe_adj):






## tracé de l'itinéraire le plus court

# def Itineraire(Pop_min,autonomie,Depart,Arrivee):










# def Trace_itineraire(Pop_min,autonomie,Depart,Arrivee):





