Créer des cartes avec python facilement

Débuter

Pour créer des cartes facilement on peut utiliser la bibliothèque Folium.

Cette bibliothèque n'est pas présente par défaut dans winPython. -Vérifions :

In [1]:
import folium

Si vous n'avez pas de message d'erreur, la bibliothèque a dèjà été installée par un utilisateur de l'ordinateur. Vous pouvez passer à la cellule suivante.

Si vous avez eu un message d'erreur, il faut installer la bibliothèque folium dans winPython.

Pour cela, lancez le windows power shell python et écrire:

pip install folium

Quelques messages plus tard, c'est fini.

Nous aurons parfois besoin de trouver les latitudes et longitudes de lieus. Nous utiliserons openstreetmap.

À l'aide de la souris, faites un clic droit puis choisissez Afficher l'adresse et enfin copiez les coordonnées.

Créeons notre 1° carte

In [2]:
import folium
carte = folium.Map(location=[47.82813, -0.69801], zoom_start=16)
carte
Out[2]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Pour afficher un carte Folium dans Jupyter-notebook, on écrit juste son nom comme dernière instruction d'une cellule de code.

Mais on peut également enregistrer la carte dans un fichier html de son dossier personnel (au lycée c'est U://) avec la commande

macarte.save('U://macarte.html')
In [3]:
carte.save('macarte1.html') # Créer le fichier html dans le répertoire du notebook en cours

puis on visualise le fichier html dans un navigateur internet classique comme Firefox.

personnalisation

Une carte est constitué de couches (layers) et de styles (tiles).

Le style par défaut est OpenStreetMap, mais on peux utiliser d'autres styles

  • OpenStreetMap
  • Stamen Terrain
  • Stamen Watercolor
  • Stamen Toner
  • Mapbox Bright
  • Cartodb Positron
In [4]:
carte=folium.Map(
    location=[47.82813, -0.69801],
    tiles='Stamen Terrain',
    zoom_start=16
)
carte
Out[4]:
Make this Notebook Trusted to load map: File -> Trust Notebook

On peut même proposer plusieurs types de représentation sur une seule carte.

In [5]:
carte=folium.Map(
    location=[47.82813, -0.69801],
    zoom_start=10
)
folium.TileLayer('openstreetmap').add_to(carte)
folium.TileLayer('stamenterrain').add_to(carte)
folium.TileLayer('Cartodb Positron').add_to(carte)
folium.TileLayer('Stamen Toner').add_to(carte)
folium.TileLayer('Stamen Watercolor').add_to(carte)
folium.LayerControl().add_to(carte)
carte
Out[5]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Les marqueurs

Il existe différent marqueurs que l'on peut ajouter aux cartes.

Les icones

In [6]:
carte=folium.Map(
    location=[47.82813, -0.69801],
    tiles='Stamen Terrain',
    zoom_start=16
)

# Essayez de prévoir ce qu'un clic sur l'icône activera
folium.Marker(location=[47.82822,-0.69960], popup='<i>Bâtiment D</i>').add_to(carte)
folium.Marker(location=[47.82767,-0.69810], popup='<b>Salle de sport</b>').add_to(carte)
folium.Marker(location=[47.82776,-0.69935], popup='<b>La cantine</b>').add_to(carte)

carte
Out[6]:
Make this Notebook Trusted to load map: File -> Trust Notebook

On peux modifier l'apparance des marqueurs.

In [7]:
carte=folium.Map(
    location=[47.82813, -0.69801],
    zoom_start=16
)
folium.Marker(location=[47.82822,-0.69960],
              tooltip='Bâtiment D',  # Texte lors du survol
              popup='<b>Le Bâtiment des Mathématiques<b>',  #Texte lors d'un clic
             icon=folium.Icon() # icône par défaut
             ).add_to(carte)
folium.Marker(location=[47.82767,-0.69810],
              popup='<i>Salle de sport</i>', # Notez les balises html de mise en forme du texte
             icon=folium.Icon(color='green', icon='table-tennis') # Choix de la couleur et de l'icône
             ).add_to(carte)
folium.Marker(location=[47.82776,-0.69935],
              tooltip='là où je mange',
              popup='<u>La cantine</u>',
             icon=folium.Icon(color='red', icon='cutlery')
             ).add_to(carte)
display(carte)
Make this Notebook Trusted to load map: File -> Trust Notebook

On peut obtenir beaucoup d'informations sur les icônes avec la commande ci-dessous.

In [8]:
help(folium.Icon)
Help on class Icon in module folium.map:

class Icon(branca.element.MacroElement)
 |  Icon(color='blue', icon_color='white', icon='info-sign', angle=0, prefix='glyphicon', **kwargs)
 |  
 |  Creates an Icon object that will be rendered
 |  using Leaflet.awesome-markers.
 |  
 |  Parameters
 |  ----------
 |  color : str, default 'blue'
 |      The color of the marker. You can use:
 |  
 |          ['red', 'blue', 'green', 'purple', 'orange', 'darkred',
 |           'lightred', 'beige', 'darkblue', 'darkgreen', 'cadetblue',
 |           'darkpurple', 'white', 'pink', 'lightblue', 'lightgreen',
 |           'gray', 'black', 'lightgray']
 |  
 |  icon_color : str, default 'white'
 |      The color of the drawing on the marker. You can use colors above,
 |      or an html color code.
 |  icon : str, default 'info-sign'
 |      The name of the marker sign.
 |      See Font-Awesome website to choose yours.
 |      Warning : depending on the icon you choose you may need to adapt
 |      the `prefix` as well.
 |  angle : int, default 0
 |      The icon will be rotated by this amount of degrees.
 |  prefix : str, default 'glyphicon'
 |      The prefix states the source of the icon. 'fa' for font-awesome or
 |      'glyphicon' for bootstrap 3.
 |  
 |  https://github.com/lvoogdt/Leaflet.awesome-markers
 |  
 |  Method resolution order:
 |      Icon
 |      branca.element.MacroElement
 |      branca.element.Element
 |      builtins.object
 |  
 |  Methods defined here:
 |  
 |  __init__(self, color='blue', icon_color='white', icon='info-sign', angle=0, prefix='glyphicon', **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  color_options = {'beige', 'black', 'blue', 'cadetblue', 'darkblue', 'd...
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from branca.element.MacroElement:
 |  
 |  render(self, **kwargs)
 |      Renders the HTML representation of the element.
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from branca.element.Element:
 |  
 |  add_child(self, child, name=None, index=None)
 |      Add a child.
 |  
 |  add_children(self, child, name=None, index=None)
 |      Add a child.
 |  
 |  add_to(self, parent, name=None, index=None)
 |      Add element to a parent.
 |  
 |  get_bounds(self)
 |      Computes the bounds of the object and all it's children
 |      in the form [[lat_min, lon_min], [lat_max, lon_max]].
 |  
 |  get_name(self)
 |      Returns a string representation of the object.
 |      This string has to be unique and to be a python and
 |      javascript-compatible
 |      variable name.
 |  
 |  get_root(self)
 |      Returns the root of the elements tree.
 |  
 |  save(self, outfile, close_file=True, **kwargs)
 |      Saves an Element into a file.
 |      
 |      Parameters
 |      ----------
 |      outfile : str or file object
 |          The file (or filename) where you want to output the html.
 |      close_file : bool, default True
 |          Whether the file has to be closed after write.
 |  
 |  to_dict(self, depth=-1, ordered=True, **kwargs)
 |      Returns a dict representation of the object.
 |  
 |  to_json(self, depth=-1, **kwargs)
 |      Returns a JSON representation of the object.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from branca.element.Element:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)

Les cercles

Remarquez la différence entre les 2 types de cercle en zoomant.

In [9]:
carte=folium.Map(
    location=[47.82813, -0.69801],
    tiles='Cartodb Positron',
    zoom_start=16
)
folium.Circle(
    radius=30,
    location=[47.82767,-0.69810],
    popup='Salle des sport',
    color='crimson',
    fill=False,
).add_to(carte)

folium.CircleMarker(
    location=[47.82776,-0.69935],
    radius=40,
    popup='Cantine',
    color='#3186cc',
    fill=True,
    fill_color='#3186cc'
).add_to(carte)

display(carte)
Make this Notebook Trusted to load map: File -> Trust Notebook

Les polygones

On utilise une liste de coordonnées de points et on trace le polygone avec la méthode PolyLine.

In [10]:
carte=folium.Map(
    location=[47.82813, -0.6980],
    tiles='Open Street Map',
    zoom_start=16
)
folium.PolyLine(
    locations=[(47.82757,-0.69848),(47.82778,-0.69872),(47.82818,-0.69807),(47.82890,-0.69910),(47.82922,-0.70095),(47.82981,-0.70126),(47.83209,-0.70138),(47.83306,-0.70104),(47.83299,-0.70178)],
    tooltip='Le plus court chemin',
    popup='de la E02 au gymnase',
    weight=7,
    color='crimson',
).add_to(carte)

carte
Out[10]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [ ]:
 

Exercices

Aller sur le site http://argonautica.jason.oceanobs.com/html/argonautica/affiche_donnees_fr.html pour obtenir les coordonnées de déplacement d'un animal de votre choix.

Par exemple l'ours sakari

Reconstituer une carte :

  • centrée sur la moyenne des positions de l'animal
  • indiquant la trajectoire de l'animal
  • indiquant lors du survol d'un point avec la souris la date d'enregistrement de cette position.
In [ ]:
 
In [11]:
def lire(nom):
    """ Fonction qui lit le contenu d'un fichier et retourne la liste des coordonnées comme chaine de caractères """
    trajectoire = []
    with open(nom, 'r', encoding='utf-8') as fichier :#Ouvre le fichier en lecture 'r'= read
        for ligne in fichier:
            chaine=ligne.split()   # Place le contenu du fichier dans la chaine de caractère
            try :
                int(chaine[0])             # si le premier mot est le numéro de la balise
                trajectoire.append(chaine[2:])  # On enlève le numéro de la balise et la classe du relevé
            except:
                None
        return trajectoire             # Renvoie le contenu du fichier sous forme d'une chaine de caractères
In [12]:
trajectoire = lire('sakari.txt')
trajet = [(float(point [2]),float(point[3])) for point in trajectoire]
trajectoire = [(point[0]+' à '+point[1],float(point [2]),float(point[3])) for point in trajectoire]
In [13]:
def moyen(list_coord):
    x=0
    y=0
    for point in list_coord:
        x += point[0]
        y += point[1]
        n = len(list_coord)
    return [x/n, y/n]
In [14]:
carte = folium.Map(location=moyen(trajet), zoom_start=6)
folium.PolyLine(
    locations=trajet,
    weight=5,
    color='crimson',
).add_to(carte)
for position in trajectoire :
    folium.Circle(
    radius=15,
    location=[position[1],position[2]],
    tooltip=position[0],
    color='crimson',
    fill=False,
    ).add_to(carte)
carte
Out[14]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Travail à effectuer

Possibilité 1

Voici un site expliquant le calcul de la distance entre 2 points définis par leurs latitu et lon. http://www.movable-type.co.uk/scripts/latlong.html Calculez la vitesse moyenne de l'animal entre 2 positions enregistrée.

In [ ]:
 

Possibilité 2

  • Rendez-vous sur le site suivant.
  • Inspirez-vous en pour créer une carte autour de chez vous avec un minimum de 3 points caractèristiques.
  • Déposez le site obtenu sur dans l'espace prévu sur e-lyco.
In [ ]: