diff --git a/app/Archive.py b/app/Archive.py index 98b0806c88ed61d5e887f0f518876f809a50e9ec..7e0d42b3e2626a7d02969af3bc2afe5aaaeb8ed5 100644 --- a/app/Archive.py +++ b/app/Archive.py @@ -6,20 +6,24 @@ import math, subprocess import urllib.request import zipfile import requests +import datetime import configparser +from urllib.parse import urlencode from osgeo import gdal, ogr, osr import numpy as np from uuid import uuid4 from collections import defaultdict, UserDict -import app.Satellites as Satellites import app.Outils as Outils import app.Constantes as Constantes id_tuile = re.compile("T[0-9]+[A-Z]+") date_tuile = re.compile("[SENTINEL.+?_]([0-9]*?)-") +def str2bool(v): + return v.lower() in (["false"]) + class Archive(): """ Classe pour lister, télécharger les archives via site Theia selon un shapefile représentant la zone d'étude. @@ -52,82 +56,70 @@ class Archive(): :type seuil: Entier """ - def __init__(self, capteur, bandes, niveau, emprise, zone_etude, sortie, annee_debut, annee_fin, seuil): + # def __init__(self, capteur, bandes, niveau, emprise, zone_etude, sortie, annee_debut, annee_fin, seuil): + def __init__(self, config): """ Créé une instance de la classe 'Archive'. """ - self._capteur = capteur - self.niveau = niveau - - if bandes == "RGB" : - self.extent_img = Satellites.SATELLITE[self._capteur][niveau][:-1] - else : - self.extent_img = Satellites.SATELLITE[self._capteur][niveau] - - if self.niveau == "LEVEL2A" : - self.nuage = Satellites.SATELLITE[self._capteur]["NUAGE"] - else : - self.nuage = None - - self.liste_annees = [] - - for i in range(annee_debut, annee_fin) : - self.liste_annees.append(i) - - self.liste_annees.append(annee_fin) - - self.emprise = emprise - self.zone_etude = zone_etude - self.dossier_sortie = sortie - self.seuil_nuage = seuil - - self.liste_archive = [] - self.logger = Outils.Log("log", "Archive") - self.serveur = Satellites.SATELLITE[self._capteur]["serveur"] - self.resto = Satellites.SATELLITE[self._capteur]["resto"] - self.token_type = Satellites.SATELLITE[self._capteur]["token_type"] + Outils.get_variable(self, config) + self.liste_archive = [] self.url = '' - def utm_to_latlng(self, zone, easting, northing): - """ - Méthode pour convertir la projection UTM en coordonnées géographique + def vector_projection_with_epsg(self, chemin_vecteur, output_path, epsg=32631): - :param zone: Zone en projection UTM. - :type zone: Entier + driver = ogr.GetDriverByName('ESRI Shapefile') - :param easting: Coordonnées UTM en x. - :type easting: Flottant + projection_reference = osr.SpatialReference() + projection_reference.ImportFromEPSG(epsg) - :param northing: Coordonnées UTM en y. - :type northing: Flottant + shapefile = driver.Open(chemin_vecteur) + layer = shapefile.GetLayer() + projection_vector = layer.GetSpatialRef() - :param northernHemisphere: Vrai si la zone se situe dans l'hémisphère Nord, faux sinon. - :type northernHemisphere: Booléen + transformation = osr.CoordinateTransformation(projection_vector, projection_reference) - :returns: Tuple d'entiers représentant la longitude et la latitude. - """ + vecteur_reproj = output_path + + if os.path.exists(vecteur_reproj): + driver.DeleteDataSource(vecteur_reproj) - systeme_utm = osr.SpatialReference() + outDataSet = driver.CreateDataSource(vecteur_reproj) + outLayer = outDataSet.CreateLayer(layer.GetName(), projection_reference, geom_type=layer.GetLayerDefn().GetGeomType()) - # Initialise le système de coordonnées géographique vers Lat/Long - systeme_utm.SetWellKnownGeogCS("WGS84") - systeme_utm.SetUTM(zone, northing > 0) + # add fields + inLayerDefn = layer.GetLayerDefn() + for i in range(0, inLayerDefn.GetFieldCount()): + fieldDefn = inLayerDefn.GetFieldDefn(i) + outLayer.CreateField(fieldDefn) - # Duplique UNIQUEMENT le système de coordonnées géographique - systeme_lat_long = systeme_utm.CloneGeogCS() + outLayerDefn = outLayer.GetLayerDefn() - # Creation de méthode de conversion - # (<de>, <vers>) - convertion_utm = osr.CoordinateTransformation(systeme_utm, systeme_lat_long) + inFeature = layer.GetNextFeature() - # Renvoie lon, lat, altitude - longitude, latitude, altitude = convertion_utm.TransformPoint(easting, northing, 0) + while inFeature: + # get the input geometry + geom = inFeature.GetGeometryRef() + # reproject the geometry + geom.Transform(transformation) + # create a new feature + outFeature = ogr.Feature(outLayerDefn) + # set the geometry and attribute + outFeature.SetGeometry(geom) + for i in range(0, outLayerDefn.GetFieldCount()): + outFeature.SetField(outLayerDefn.GetFieldDefn(i).GetNameRef(), inFeature.GetField(i)) + # add the feature to the shapefile + outLayer.CreateFeature(outFeature) + # dereference the features and get the next input feature + outFeature = None + inFeature = layer.GetNextFeature() - return (longitude, latitude) + # Save and close the shapefiles + inDataSet = None + outDataSet = None def coord_box_dd(self): """ @@ -144,8 +136,8 @@ class Archive(): if os.path.exists(utm_outfile): os.remove(utm_outfile) - process_tocall = ['ogr2ogr', '-f', 'Esri Shapefile', '-t_srs', 'EPSG:32631', utm_outfile, self.emprise] - subprocess.call(process_tocall) + # wgs84 : 4326 + self.vector_projection_with_epsg(self.emprise, utm_outfile, epsg=4326) # To get shapefile extent # Avec import ogr @@ -164,15 +156,17 @@ class Archive(): ## Close source data data_source.Destroy() - # Coordinates min in decimal degrees - LL_min = self.utm_to_latlng(31, extent_[0], extent_[2]) + area_coord_corner = str(extent_[2]) + ',' + str(extent_[0]) + ',' + str(extent_[3]) + ',' + str(extent_[1]) - # Coordinates max in decimal degrees - LL_max = self.utm_to_latlng(31, extent_[1], extent_[3]) + return "{},{},{},{}".format(extent_[2], extent_[0], extent_[3], extent_[1]) - area_coord_corner = str(LL_min[0]) + ',' + str(LL_min[1]) + ',' + str(LL_max[0]) + ',' + str(LL_max[1]) + def listing_by_tile(self): + + for tuile in self.liste_tuiles : - return area_coord_corner + self.requete['location'] = tuile + + print(urlencode(self.requete)) def listing(self): """ @@ -181,15 +175,33 @@ class Archive(): nbImage = 0 + if hasattr(self, 'liste_tuiles'): + self.listing_by_tile() + + # print(urlencode(self.requete)) + # print(self.coord_box_dd()) + self.requete['box'] = self.coord_box_dd() + + # sys.exit(1) + self.liste_annees = ["2019"] + self.niveau = 'LEVEL2A' # Boucle sur les annees - self.logger.info("Images availables") + # self.logger.info("Images availables") for annee in self.liste_annees: self.logger.info("=============== {0} ===============".format(annee)) - self.url = "{0}/{1}/api/collections/{2}/search.json?lang=fr&processingLevel={3}&_pretty=true&q={4}&box={5}&maxRecord=500".format(self.serveur, self.resto, self._capteur, self.niveau, annee, self.coord_box_dd()) + + if self.emprise : + # self.url = "{0}/{1}/api/collections/{2}/search.json?lang=fr&processingLevel={3}&_pretty=true&q={4}&box={5}&maxRecord=500".format(self.serveur, self.resto, self.capteur, self.niveau, annee, self.coord_box_dd()) + self.url = "{0}/{1}/api/collections/{2}/search.json?{3}".format(self.serveur, self.resto, self.capteur, urlencode(self.requete)) + else : + self.url = "{0}/{1}/api/collections/{2}/search.json?lang=fr&processingLevel={3}&_pretty=true&q={4}&location={5}&maxRecord=500".format(self.serveur, self.resto, self.capteur, self.niveau, annee, self.liste_tuiles[0]) + # S'il existe une autre image, suivante = vrai, faux sinon suivante = True + print(self.url) + # Tant qu'il existe une image à traiter while suivante: @@ -212,7 +224,7 @@ class Archive(): link_archive = data_Dict['features'][d]['properties']['services']['download']['url'].replace("\\", "") url_archive = link_archive.replace(self.resto, "rocket/#") archive_download = url_archive.replace("/download", "") # Url de l'archive à télécharger - out_archive = "{0}/{1}.tgz".format(self.dossier_sortie, name_archive)# Nom de sortie de l'archive + out_archive = "{0}/{1}.zip".format(self.dossier_sortie, name_archive) # Nom de sortie de l'archive if "SENTINEL2X" not in out_archive or self.niveau == "LEVEL3A": self.liste_archive.append([archive_download, out_archive, feature_id]) @@ -239,7 +251,7 @@ class Archive(): self.logger.info("{0} image(s) correspondent aux critères.".format(len(self.liste_archive))) - def download_auto(self, identifiant, mdp, proxy="", extraction=True, groupe="Date"): + def download_auto(self): """ Méthode pour télécharger les archives sur le site Theia. @@ -256,17 +268,18 @@ class Archive(): # Url pour obtenir l'authentification url = "{0}/services/authenticate/".format(self.serveur) + # Dictionnaire contenant les informations du proxy s'il existe proxyDict = { - "http" : "{0}".format(proxy), \ - "https" : "{0}".format(proxy), \ - "ftp" : "{0}".format(proxy) \ + "http" : "{0}".format(self.proxy), \ + "https" : "{0}".format(self.proxy), \ + "ftp" : "{0}".format(self.proxy) \ } # Dictionnaire contenant les informations d'authentification payload = { - 'ident' : "{0}".format(identifiant),\ - 'pass' : "{0}".format(mdp) + 'ident' : "{0}".format(self.id),\ + 'pass' : "{0}".format(self.mdp) } # Requête pour obtenir le jeton d'identification @@ -331,7 +344,6 @@ class Archive(): else : sauvegarde[str(date)] = {} sauvegarde[str(date)][nom_image] = "False" - sauvegarde[str(date)]["NDVI"] = "False" if date in dico_date.keys() : dico_date[date].append(l) @@ -352,17 +364,18 @@ class Archive(): self.logger.info("Requête pour l'archive : {0}".format(img[1].split("/")[-1])) # Url de l'archive - url = "{0}/{1}/collections/{2}/{3}/download/?issuerId=theia".format(self.serveur, self.resto, self._capteur, img[2]) + url = "{0}/{1}/collections/{2}/{3}/download/?issuerId=theia".format(self.serveur, self.resto, self.capteur, img[2]) self.logger.debug("url : {}".format(url)) + # Requête pour récupérer l'archive reponse = requests.get(url, headers=head, proxies=proxyDict) - if extraction : + if self.extraction : # Ajout de l'archive à la liste liste_content.append(reponse.content) del reponse else : - if groupe == "Tuile" : + if self.groupe == "Tuile" : dossier_archive = "{0}/{1}/Archive".format(self.dossier_sortie, id_tuile.search(img[1]).group(0)) else: dossier_archive = "{0}/{1}/Archive".format(self.dossier_sortie, cle[:4]) @@ -371,10 +384,11 @@ class Archive(): if not os.path.exists(dossier_archive): os.makedirs(dossier_archive) + print("{0}/{1}".format(dossier_archive, img[1].split("/")[-1])) with open("{0}/{1}".format(dossier_archive, img[1].split("/")[-1]), "wb") as fichier: fichier.write(reponse.content) - if extraction : + if self.extraction : # Traitement des images (fusion, découpage selon la zone d'étude ...) self.traitement_images(cle, liste_content) del liste_content @@ -499,6 +513,7 @@ class Archive(): # Pour chaque archive for idx, content in enumerate(liste_content) : + # Lecture de l'archive tzip = zipfile.ZipFile(io.BytesIO(content)) @@ -518,6 +533,8 @@ class Archive(): mmap_name = "/vsimem/"+uuid4().hex liste_mem.append(mmap_name) gdal.FileFromMemBuffer(mmap_name, tzip.read(img)) + print(mmap_name) + sys.exit(1) liste_bandes.append(gdal.Open(mmap_name)) # On fusionne les différentes bandes en une seule image diff --git a/app/Outils.py b/app/Outils.py index f78a986bd522feb96441f617c276fe3312f65b1d..3923982741d22de5cf3f8283e28f7a3c3f56c00d 100644 --- a/app/Outils.py +++ b/app/Outils.py @@ -1,6 +1,7 @@ #!/bin/env python3 # -*- coding: utf-8 -*- +import sys import argparse import logging from logging.handlers import RotatingFileHandler @@ -9,6 +10,10 @@ from contextlib import contextmanager import inspect from osgeo import gdal import app.Constantes as Constantes +import configparser +import ast +from datetime import datetime +import app.Satellites as Satellites class Fusion(argparse.Action): def __init__(self, option_strings, dest, nargs=None, **kwargs): @@ -77,25 +82,25 @@ class TimeoutException(Exception): pass @contextmanager def limitation_temporelle(secondes): - - def signal_handler(signum, frame): - raise TimeoutException - signal.signal(signal.SIGALRM, signal_handler) - signal.alarm(secondes) + def signal_handler(signum, frame): + raise TimeoutException - try: - yield - finally: - signal.alarm(0) + signal.signal(signal.SIGALRM, signal_handler) + signal.alarm(secondes) + + try: + yield + finally: + signal.alarm(0) # Utilisation : # # try: -# with limitation_temporelle(temps_en_seconde): -# appel_fonction() +# with limitation_temporelle(temps_en_seconde): +# appel_fonction() # except TimeoutException: -# pass +# pass def clip(image, cut, form="Mem", dst="", type_sortie=gdal.GDT_Float32, nodata="NaN"): """ @@ -118,4 +123,124 @@ def clip(image, cut, form="Mem", dst="", type_sortie=gdal.GDT_Float32, nodata="N option_clip = gdal.WarpOptions(cropToCutline=True,\ cutlineDSName=cut, outputType=type_sortie , format=form, dstNodata=nodata) - return gdal.Warp(dst, image, options=option_clip) \ No newline at end of file + return gdal.Warp(dst, image, options=option_clip) + + +def checkDate(date): + + d = date.split('-') + + try: + if not date : + + annee = datetime.now().year + + if datetime.now().month < 10 : + mois = "0{}".format(datetime.now().month) + else : + mois = datetime.now().month + + if datetime.now().day < 10 : + jour = "0{}".format(datetime.now().day) + else : + jour = datetime.now().day + + elif len(d) == 1 : + annee = d[0] + mois = "01" + jour = "01" + elif len(d) == 2 : + annee = d[0] + mois = d[1] + jour = "01" + elif len(d) == 3 : + annee = d[0] + mois = d[1] + jour = d[2] + + datetime(int(annee), int(mois), int(jour)) + return "{annee}-{mois}-{jour}".format(annee=annee, mois=mois, jour=jour) + except ValueError: + print("Format invalide") + sys.exit(1) + except IndexError: + print("La date doit être au format 'AAAA-MM-JJ', 'AAAA-MM' ou 'AAAA'") + sys.exit(1) + + +def get_variable(self, config): + """ + Récupération des variables dans le fichier de configuration + """ + + configfile = configparser.ConfigParser() + configfile.read(config) + + self.requete = dict() + self.requete["lang"] = "fr" + self.requete["_pretty"] = "true" + self.requete["maxRecord"] = 500 + + # Capteur utilisé + self.capteur = configfile["satellite"]["capteur"] + self.bandes = configfile["satellite"]["bandes"] + self.requete["processingLevel"] = configfile["satellite"]["processingLevel"] + + # Dossier contenant les résultats + self.dossier_sortie = configfile["sortie"]["chemin"] + + try: + if str2bool(configfile["sortie"]["extraction"]): + self.extraction = False + else : + self.extraction = True + except : + self.extraction = True + + self.groupe = configfile["sortie"]["groupe"] + + # Date de début et de fin de la recherche + try: + # self.date_debut = configfile["donnees"]["date_debut"] + self.requete["startDate"] = checkDate(configfile["donnees"]["date_debut"]) + except Exception as e: + raise "L'année de départ est requise." + + self.requete["completionDate"] = checkDate(configfile["donnees"]["date_fin"]) + + self.seuil_nuage = float(configfile["donnees"]["seuil_nuage"])/100.0 if configfile["donnees"]["seuil_nuage"] else 0.0 + + # Emprise et zone de l'étude + self.emprise = configfile["donnees"]["chemin_emprise"] + + if self.emprise : + self.zone_etude = configfile["donnees"]["chemin_zone_etude"] + if not self.zone_etude : + self.zone_etude = self.emprise + else : + try: + self.liste_tuiles = list(ast.literal_eval(configfile["donnees"]["liste_tuiles"])) + except Exception as e: + raise "Aucune emprise ni aucune tuile n'a été renseigné." + + + self.nombre_image = configfile["donnees"]["nombre_image"] + + # Identifiant, mot de passe et proxy pour le téléchargement des images Théia + self.id = configfile["theia"]["identifiant"] + self.mdp = configfile["theia"]["mdp"] + self.proxy = configfile["theia"]["proxy"] + + if self.bandes == "RGB" : + self.extent_img = Satellites.SATELLITE[self.capteur][self.requete["processingLevel"]][:-1] + else : + self.extent_img = Satellites.SATELLITE[self.capteur][self.requete["processingLevel"]] + + if self.requete["processingLevel"] == "LEVEL2A" : + self.nuage = Satellites.SATELLITE[self.capteur]["NUAGE"] + else : + self.nuage = None + + self.serveur = Satellites.SATELLITE[self.capteur]["serveur"] + self.resto = Satellites.SATELLITE[self.capteur]["resto"] + self.token_type = Satellites.SATELLITE[self.capteur]["token_type"] diff --git a/app/Processing.py b/app/Processing.py deleted file mode 100644 index c9dd1db42912757bf500cdb097127691b4b414b7..0000000000000000000000000000000000000000 --- a/app/Processing.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -import os -import configparser -import datetime -import glob -from osgeo import gdal - -import otbApplication as otb - -from app import Archive - -def str2bool(v): - return v.lower() in ("true") - -class Processing(object): - - def __init__(self): - pass - - def i_download(self): - """ - Méthode pour télécharger les images sur le site Theia Land. - """ - - if not self.annee_fin : - self.annee_fin = datetime.datetime.now().year - - self.check_download = Archive.Archive(self.capteur, self.bandes, self.niveau, self.emprise, self.zone_etude,\ - self.resultats, self.annee_debut, int(self.annee_fin), self.seuil_nuage) - self.check_download.listing() - self.check_download.download_auto(self.id, self.mdp, self.proxy, extraction=self.extraction, groupe=self.groupe) - - self.liste_dossier = dict() - - for annee in os.listdir(self.resultats): - with open("{}/{}/dates.txt".format(self.resultats, annee), "w") as fichier : - for image in sorted(glob.glob("{}/{}/Images/*".format(self.resultats, annee))) : - fichier.write("{}\n".format(os.path.basename(image)[:-4])) - - self.liste_dossier[annee] = sorted([x for x in glob.glob("{}/{}/Images/*".format(self.resultats, annee)) if x.endswith(".tif")]) - - def otbPhenologie(self): - """ - Appel le module OTB : 'SigmoFitting' sur l'image composée de l'empilement des NDVI - """ - - otb_Phenologie = otb.Registry.CreateApplication("SigmoFitting") - otb_Phenologie.SetParameterString("mode", "metrics") - - for annee in self.liste_dossier : - otb_Phenologie.SetParameterString("in", "{}/{}/NDVI/stack_ndvi.tif".format(self.resultats, annee)) - otb_Phenologie.SetParameterString("dates", "{}/{}/dates.txt".format(self.resultats, annee)) - otb_Phenologie.SetParameterString("out", "{}/{}/metrics.tif".format(self.resultats, annee)) - - otb_Phenologie.ExecuteAndWriteOutput() - - def calcul_ndvi(self): - """ - Méthode effectuant le calcul du NDVI via le module OTB : 'RadiometricIndices' - """ - - options_vrt = gdal.ParseCommandLine('-resolution highest -separate') - - otb_NDVI = otb.Registry.CreateApplication("RadiometricIndices") - otb_NDVI.SetParameterInt("channels.blue", 1) - otb_NDVI.SetParameterInt("channels.green", 2) - otb_NDVI.SetParameterInt("channels.red", 3) - otb_NDVI.SetParameterInt("channels.nir", 4) - otb_NDVI.SetParameterStringList("list", ["Vegetation:NDVI"]) - - sauvegarde = configparser.ConfigParser() - - for annee in self.liste_dossier : - - sauvegarde.read("{}/{}/sauvegarde.ini".format(self.resultats, annee)) - dossier_NDVI = "{}/{}/NDVI".format(self.resultats, annee) - - if not os.path.exists(dossier_NDVI) : - os.makedirs(dossier_NDVI) - - for img in self.liste_dossier[annee] : - - chemin_ndvi = "{}/ndvi_{}".format(dossier_NDVI, os.path.basename(img)) - - if not str2bool(sauvegarde[os.path.basename(img)[:-4]]["NDVI"]): - otb_NDVI.SetParameterString("in", img) - otb_NDVI.SetParameterString("out", chemin_ndvi) - otb_NDVI.ExecuteAndWriteOutput() - sauvegarde[os.path.basename(img)[:-4]]["NDVI"] = "True" - - liste_ndvi = sorted([x for x in glob.glob("{}/*".format(dossier_NDVI)) if x.endswith(".tif") and "stack" not in x]) - vrt = gdal.BuildVRT("", liste_ndvi, options=options_vrt) - gdal.Translate("{}/{}/NDVI/stack_ndvi.tif".format(self.resultats, annee), vrt) - - with open("{}/{}/sauvegarde.ini".format(self.resultats, annee), 'w') as configfile: - sauvegarde.write(configfile) - - def i_images_processing(self): - """ - Calul le ndvi, fusionnne en une seule image puis lance le module OTBPhenology - """ - self.calcul_ndvi() - self.otbPhenologie() diff --git a/config.ini b/config.ini deleted file mode 100644 index 87b04152743b8ce3d21535e9f273cf74c7e3c5ac..0000000000000000000000000000000000000000 --- a/config.ini +++ /dev/null @@ -1,55 +0,0 @@ -[donnees] -# chemin/vers/shapefile/emprise -chemin_emprise = - -# chemin/vers/shapefile/zone_etude -# Si vide, zone d'étude = emprise -chemin_zone_etude = - -# Année à partir de laquelle les images ont été prises -annee_debut = - -# Année limite d'acquisition des images -# Si vide, l'année de fin correspond à l'année actuelle -annee_fin = - -# Pourcentage maximal d'ennuagement -seuil_nuage = 5.0 - -[sortie] -# chemin/dossier/resultats -chemin = - -# Manière de regrouper les images/archives -# Possibilités :- Date (Regroupe les images selon leurs date d'acquisition) -# - Tuile (Regroupe les images en fonction de la tuile sentinel2 auquelle elles correspondent ) -groupe = Date - -# Vrai si extraction des images des archives, faux si téléchagement de celles-ci -extraction = True - -[theia] -# Identifiant Theia-land -identifiant = - -# Mot de passe Theia-land -mdp = - -# Proxy de connection si nécessaire -proxy = - -[satellite] -# Type du satellite source -# Possibilités :- SENTINEL2 -# - LANDSAT8 -capteur = SENTINEL2 - -# Niveau de traitement des images satellites -# Possibilités :- LEVEL2A (Acquisition standard) -# - LEVEL3A (Synthèse mensuelle) -processingLevel= LEVEL2A - -# Bandes d'intêrets -# Possibilités :- RGB (Bandes Rouge, Verte, Bleue) -# - RGBI (Bandes Rouge, Verte, Bleue + Proche Infra-rouge) -bandes = RGB diff --git a/install.sh b/install.sh deleted file mode 100755 index aed9b9feb111350c3355318cda268f6a8b3fab4f..0000000000000000000000000000000000000000 --- a/install.sh +++ /dev/null @@ -1,117 +0,0 @@ -#!/bin/bash -# ========================================= -# Script d'installation -# ========================================= - -function erreur { - echo "Usage : $0 [--libs --maj --compil --all]" - echo "--libs : Installation des bibliothèques python" - echo "--maj : Téléchargement des fichiers sources pour OTB" - echo "--compil : Compilation d'OTB" - echo "--all : Téléchargement des sources et des bibliothèques python puis compilation d'OTB" - exit -} - -function confirme { - read -r -p "${1}Êtes-vous sûr de vouloir continuer ? [O/N] " response - if [[ $response == "o" || $response = "O" || $response == "y" || $response = "Y" ]]; then - echo -e "${ROUGE}\e[1mLauching generation in $prefix_dir\e[0m" - else - exit - fi -} - -set -e - -#Couleur 'Rouge' pour le terminal -ROUGE='\033[0;31m' - -# Dossier courant du script -CMD="$(readlink -e "${BASH_SOURCE[0]}")" -SH_DIR="$(dirname "$CMD")" -prefix_dir=$SH_DIR - -if [ ! -z $CXX ]; then - echo "Version du compilateur : $CXX" -else - CXX=`type -p g++` -fi - -CXXVersion=`${CXX} -dumpversion` -version_compilateur="5.0.0" - -if [ "$(printf '%s\n' "$version_compilateur" "$CXXVersion" | sort -V | head -n1)" = "$CXXVersion" ]; then - echo "Gcc version too old" - echo "Actual: ${CXXVersion}" - echo "Needed: ${version_compilateur}" - exit -fi - -# Erreur si manque ou mauvais argument -if [[ "$#" != "1" ]]; then - erreur -fi - -if [[ "$1" != "--libs" ]] && [[ "$1" != "--maj" ]] && [[ "$1" != "--compil" ]] && [[ "$1" != "--all" ]]; then - erreur -fi - -if [[ "$1" == "--libs" ]]; then - echo "Installation des bibliothèques python3" - sudo apt-get update - sudo apt-get install aptitude -y - sudo aptitude install python3-pip -y - sudo pip3 install -r "dépendances.txt" -fi - - -echo $prefix_dir/OTB - -if [[ "$1" != "--libs" ]]; then - - echo "Installation de la bibliothèque OTB dans : ${prefix_dir}" - confirme - - #---------------------------------------- - # Récupération des sources - if [[ "$1" == "--maj" ]] || [[ "$1" == "--all" ]]; then - # Clonage du repertoire OTB - if [ -d "OTB" ]; then - echo "Le répertoire OTB existe déjà ." - else - echo "Clonage OTB ..." - mkdir -p $prefix_dir/OTB - cd $prefix_dir/OTB - git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git - fi - fi - - #---------------------------------------- - # Compilation - if [[ "$1" != "--compil" ]] || [[ "$1" == "--all" ]] ; then - - sudo aptitude install make cmake-curses-gui build-essential libtool automake git libbz2-dev python-dev libboost-dev libboost-filesystem-dev libboost-serialization-dev libboost-system-dev zlib1g-dev libcurl4-gnutls-dev swig libgdal-dev - - - echo "Compilation d'OTB ..." - cd $prefix_dir/ - - mkdir -p build - mkdir -p build - cd build - - # Compilation d'OTB - cmake -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_CXX_FLAGS:STRING=-std=c++14 -DUSE_SYSTEM_BOOST=ON -DUSE_SYSTEM_CURL=ON -DUSE_SYSTEM_ZLIB=ON -DUSE_SYSTEM_GDAL=ON -DCMAKE_BUILD_TYPE=Release -DOTB_WRAP_PYTHON3:BOOL=ON -DGDAL_SB_EXTRA_OPTIONS:STRING="--with-python" -DCMAKE_INSTALL_PREFIX=$prefix_dir/OTB/install/ -DOTB_USE_QWT=OFF -DOTB_USE_GLEW=OFF -DOTB_USE_GLFW=OFF -DOTB_USE_GLUT=OFF -DOTB_USE_OPENGL=OFF -DOTB_USE_QT=OFF -DOTB_USE_QWT=OFF $prefix_dir/OTB/otb/SuperBuild/ - make --jobs=12 - - # Compilation des modules - cd $prefix_dir/OTB/build/OTB/build - - cmake -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_CXX_FLAGS:STRING=-std=c++14 -DModule_OTBPhenology:BOOL=ON -DModule_OTBTemporalGapFilling:BOOL=ON $prefix_dir/OTB/otb - make --jobs=12 - make install - fi - - echo "Installation terminée." - -fi diff --git a/main.py b/main.py index d69c70dfb28507e3ac56f5d7eb74596e8f9f7596..5de8db025ef2377d2371972355efdeeb527d1750 100644 --- a/main.py +++ b/main.py @@ -2,73 +2,21 @@ # -*- coding: utf-8 -*- import sys, time - -from osgeo import ogr - import configparser -from app.Processing import Processing -import app.Constantes as Constantes -import app.Outils as Outils - -def str2bool(v): - return v.lower() in (["false"]) - -class Telechargement(Processing): +import argparse - def __init__(self, parent=None): - super(Processing, self).__init__() - Processing.__init__(self) - - self.logger = Outils.Log("log", "Téléchargement") - - self.get_variable() - - def get_variable(self): - """ - Récupération des variables dans le fichier de configuration - """ - - configfile = configparser.ConfigParser() - configfile.read("config.ini") - - # Capteur utilisé - self.capteur = configfile["satellite"]["capteur"] - self.niveau = configfile["satellite"]["processingLevel"] - self.bandes = configfile["satellite"]["bandes"] - - # Dossier contenant les résultats - self.resultats = configfile["sortie"]["chemin"] - - try: - if str2bool(configfile["sortie"]["extraction"]): - self.extraction = False - else : - self.extraction = True - except : - self.extraction = True - - self.groupe = configfile["sortie"]["groupe"] - - # Date de début et de fin de la recherche - try: - self.annee_debut = int(configfile["donnees"]["annee_debut"]) - except Exception as e: - raise "L'année de départ est requise." +from app.Archive import Archive +import app.Constantes as Constantes - self.annee_fin = configfile["donnees"]["annee_fin"] - self.seuil_nuage = float(configfile["donnees"]["seuil_nuage"])/100.0 if configfile["donnees"]["seuil_nuage"] else 0.0 +from app.Outils import Log - # Emprise et zone de l'étude - self.emprise = configfile["donnees"]["chemin_emprise"] - self.zone_etude = configfile["donnees"]["chemin_zone_etude"] +class Telechargement(object): - if not self.zone_etude : - self.zone_etude = self.emprise + def __init__(self, config): + super(Telechargement, self).__init__() - # Identifiant, mot de passe et proxy pour le téléchargement des images Théia - self.id = configfile["theia"]["identifiant"] - self.mdp = configfile["theia"]["mdp"] - self.proxy = configfile["theia"]["proxy"] + self.logger = Log("log", "Téléchargement") + self.config = config def run(self): """ @@ -77,11 +25,9 @@ class Telechargement(Processing): # Début du processus debut = time.time() - # Recherche de nouvelles images non traitées et téléchargement de celles-ci le cas échéant - self.i_download() - - # Traitement des images - self.i_images_processing() + prog = Archive(self.config) + prog.listing() + prog.download_auto() # Fin du processus fin = time.time() @@ -92,5 +38,9 @@ class Telechargement(Processing): if __name__ == "__main__": - app = Telechargement() + parser = argparse.ArgumentParser() + parser.add_argument("-config", dest="config", help="Chemin du fichier de config", required=True) + args = parser.parse_args() + + app = Telechargement(args.config) sys.exit(app.run()) diff --git a/prepare_env.sh b/prepare_env.sh deleted file mode 100755 index 52d66be4f8e6bd77546010f3c5d94ec37ef4f72c..0000000000000000000000000000000000000000 --- a/prepare_env.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -# Dossier courant du script. -CMD="$(readlink -e "${BASH_SOURCE[0]}")" -SH_DIR="$(dirname "$CMD")" -prefix_dir=$SH_DIR - - -export PATH=$PATH:$prefix_dir/OTB/install/bin -export PYTHONPATH=$prefix_dir/OTB/install/lib/otb/python3 -export ITK_AUTOLOAD_PATH=$prefix_dir/OTB/install/lib/otb/applications \ No newline at end of file