###############################################################################
##                  TP : Itinéraires grandes villes                          ##
###############################################################################

import matplotlib.pyplot as plt
import sqlite3 as lt            # Bibliothèque pour les requêtes SQL
import numpy as np
dbh=lt.connect('dots.db')
cur=dbh.cursor()


## Tracé de la carte de France et Fonction Calcul  -  Code fourni

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()


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

def Calcul(D,C1,C2):
    lon1,lon2,lat1,lat2=D[C1][0],D[C2][0],D[C1][1],D[C2][1]
    lon1,lon2=lon1*np.pi/180,lon2*np.pi/180     # Longitudes
    lat1,lat2=lat1*np.pi/180,lat2*np.pi/180     # Latitudes
    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        # On retourne la distance

## Question 4 - Dictionnaire des communes

def Dict_Communes(Pop_min):         # Transforme la liste en dictionnaire
    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          # Pour toutes les villes de + de Pop_min habitants
    return reduction_agglo(Dico)    # Pour uniquement les principales villes
                                    #   des grandes agglomerations

## Question 5 - Tracé de la carte des communes

def Trace_Carte(Pop_min):
    Dico=Dict_Communes(Pop_min)     # On récupère le dictionnaire des grandes
                                    #   villes (agglomérations réduites)
    L_lon,L_lat=[],[]      # On initialise les listes des coordonnées géo.
    for ville in Dico:                  # En parcourant le dictionnaire
        L_lon.append(Dico[ville][0])    #   on remplit les listes des
        L_lat.append(Dico[ville][1])    #   coordonées géographqiues
    carteFrance()                   # On trace la carte des départements
    plt.plot(L_lon,L_lat,'ro')    # On la complète avec les villes

## Question 7 - Réduction des agglomérations

def reduction_agglo(D_com):     # D_com : Dico de toutes les grandes villes
    Dcopie=D_com.copy()         # On fait une copie du dictionnaire D_com
    for Com1 in D_com:          # On parcours tous les couples (Com1,Com2)
        for Com2 in D_com:      #  possibles du dictionnaire original
            d=Calcul(D_com,Com1,Com2)  # On calcule la distance
            if d<15 and Com1!=Com2:      # Si 2 villes différentes sont
                                         #   distantes de moins de 15 km
                if D_com[Com1][2]<D_com[Com2][2]:   # On détermine la
                    petite=Com1                     #   plus petite dans
                else:                               #   le dictionnaire
                    petite=Com2                     #   original D_com
                if petite in Dcopie:     # On la retire de la copie du
                    Dcopie.pop(petite)   #   dictionnaire original
    return Dcopie                        # On retourne la copie réduite

## Question 9 - Construction du Graphe des étapes de moins de autonomie km

# def Constr_graphe(Pop_min,autonomie):

















## Question 10 - Tracé d'une étape entre deux villes

# def Trace_etape(D_com,C1,C2):




## Question 11 - Tracé du graphe sur la carte

# def Trace_graphe(Pop_min,autonomie):

