Archives par mot-clé : R

Traiter des images MODIS avec R pour calculer un NDVI

La Nasa propose depuis 1999 des images MODIS (Moderate-Resolution Imaging Spectroradiometer) à différentes résolutions spatiales et temporelles. Elles sont produites par deux satellites en orbite, Terra (1999) et Aqua  (2002), qui embarquent des capteurs pour le programme Earth Observing system.

Les instruments permettent d’enregistrer 36 bandes spectrales avec une fréquence de passage de 1 à 2 jours. La résolution des images diffère selon les bandes enregistrées et varie entre 0.25 et 1 km. Nous parlions il y a quelques jours du site reverb|echo de la Nasa, il se trouve qu’un certain nombre d’images sont disponibles sur le site.

Quelles données ?

Mais pour ça il faut savoir ce qu’on cherche, et la nomenclature des produits n’est pas vraiment transparente [1].  À titre d’exemple :

  • MOD9Q1 – Surface Reflectance 8-Day L3 Global 250m
  • MOD13Q1 – Vegetation Indices 16-Day L3 Global 250m
  • MOD11A2 – Land Surface Temperature/Emissivity 8-Day L3 Global 1km

Une fois qu’on en sait un peu plus sur le type de produit que l’on veut utiliser, il va falloir le télécharger et le traiter. Dans un post précédent, j’expliquais comment configurer sa machine pour utiliser wget. Si vous optez pour cette solution, il vous faudra utiliser le MRT pour reprojeter et assembler vos images. L’interface est assez intuitive et on peut faire du traitement de masse.

Mais je suis tombé aussi ce matin sur les logs de release d’un package R que je me suis empressé de tester : MODIStsp. Si vous avez déjà regardé MRT, MODISStsp n’est qu’un moyen de rester dans R pour télécharger les images. On pourra aussi regarder du côté du package MODIS qui lui n’intègre pas d’interface graphique.

Bon mais on parlait de NDVI dans le titre !

Traiter les images NDVI : MOD13Q1

En cherchant comment traiter les images MODIS, je suis tombé sur des ressources intéressantes. Notamment une page qui vous prend par la main pour traiter les données MODIS (MOD13Q1) dans R[2]. Je vous propose donc de faire un petit point pas à pas !

J’ai téléchargé et projeté les données grâce au package MODISStsp. J’ai donc un dossier qui contient les fichiers hrf, mais aussi un autre qui contient les fichiers tiff produits par le package.

Or quand on ouvre les données (dans Qgis), les gammes de valeurs ne correspondent pas à celles attendues pour du NDVI! On devrait avoir des valeurs entre -1 et 1 !

 

Freq. pour la tuille 16 – 17/01/2016

Il va falloir retravailler le raster pour obtenir les bonnes valeurs . Heureusement « the office of outer space affaire » nous donne la marche à suivre dans R[3]. Je vous propose donc ici un script commenté et customisé pour l’occasion.

library(raster)  
library(sp)
library(doParallel)
library(rgdal)
library(magrittr)

rm(list = ls()) ##clear env.

#create stack from tif NDVI files
path.v = "~/Documents/futurSahel/MOD13Q1_TS/VI_16Days_250m_v6/NDVI/"
l.files = list.files(path.v, pattern = ".tif")


my.stack = stack(paste0(path.v,l.files)) ##create raster stack of files in a directory
# load borders
border = shapefile("~/Documents/futurSahel/Senegal_gadm.org/SEN_adm0.shp") #ToDo: insert link to the shapefile with the country borders


## We use doParallel and magrittr packages to pipe different actions (crop and mask)
registerDoParallel(6) #we will use 6 parrallel thread
result = foreach(i = 1:dim(my.stack)[3],.packages='raster',.inorder=T) %dopar% {
  my.stack[[i]] %>% 
    crop(border) %>%
    mask(border)
}
endCluster()
ndvi.stack = stack(result)

ndvi.stack = ndvi.stack*0.0001 #rescaling of MODIS data
ndvi.stack[ndvi.stack ==-0.3]=NA #Fill value(-0,3) in NA
ndvi.stack[ndvi.stack<(-0.2)]=NA # as valid range is -0.2 -1 , all values smaller than -0,2 are masked out
names(ndvi.stack) = seq.POSIXt(from = ISOdate(2016,1,17), by = "16 day", length.out = 23) # atribut name as date for each layer

my_palette = colorRampPalette(c("red", "yellow", "lightgreen")) #Create a color palette for our values
## Plot X maps in the same layout
spplot(ndvi.stack, layout=c(4, 6),
       col.regions = my_palette(16))

Ce qui nous donne pour les 23 pas de temps étudiés l’image suivante. On voit bien reverdir la partie supérieure de la carte entre juillet et octobre en 2016.

Indice NDVI à partir des données MODIS MOD13Q1 sur le Sénégal pour 2016

Pour avoir un ordre d’idée, traiter 23 images et produire le graphe, en parallélisant une partie, me prend 11 min .

Des ressources :

[1]Type d’images disponible : https://modis.gsfc.nasa.gov/data/dataprod/

[2]http://www.un-spider.org/advisory-support/recommended-practices/recommended-practice-drought-monitoring/step-by-step/R

[3]http://www.un-spider.org/sites/default/files/Skript%20VCI%20final.R

GRASS-GIS 7 et R

Contexte

Avec @fabio_zottele, nous nous sommes replongés ce weekend sur un travail un peu vieux. Celui-ci remonte à 5 ans, et consiste à proposer un algorithme basé sur des librairies/logiciels libres afin de détecter les terrasses viticoles. Ce travail avait initialement été développé sur R gdal et grass 6.3. pour une petite zone de la val di Cembra.

Notre objectif est aujourd’hui de systématiser l’algorithme et de vérifier que l’évolution des technologies et des algorithmes sur lesquels nous nous étions basés produit toujours le résultat attendu.

Installation de GRASS7Grass-GIS

La première chose à faire est de compiler GRASS-GIS en version 7, car les dépôts ne sont pas encore à jour sur Fedora. Vous pouvez trouver toute la documentation sur le wiki de grass.

On pourra commencer par télécharger le weekly snapshot du projet , et installer les dépendances qui vont bien :

sudo dnf install gcc gcc-c++ bison flex ncurses-devel proj-epsg proj-nad xml2 \
proj-devel gdal gdal-devel gdal-python sqlite-devel mesa-libGL-devel \
fftw-devel mesa-libGLU-devel libXmu-devel libX11-devel geos geos-devel \
libtiff-devel lesstif-devel python-devel numpy wxPython wxGTK-devel \
python-dateutil python-imaging python-matplotlib-wx subversion doxygen python-sphinx \
netcdf-devel postgresql-devel lapack lapack-devel blas blas-devel atlas atlas-devel

On peut ensuite aller compiler les sources :

cd ~/Téléchargement/grass7.0.svn/
./configure \
  --with-cxx \
  --with-gdal=/usr/bin/gdal-config \
  --with-proj --with-proj-share=/usr/share/proj \
  --with-python=/usr/bin/python-config \
  --with-geos \
  --with-sqlite \
  --with-nls \
  --with-wxwidgets=/usr/bin/wx-config \
  --with-fftw \
  --with-cairo --with-cairo-ldflags=-lfontconfig \
  --with-freetype --with-freetype-includes=/usr/include/freetype2 \
  --enable-largefile \
  --without-odbc \
  --with-ffmpeg \
  --with-ffmpeg-includes="/usr/include/ffmpeg /usr/include/ffmpeg/libav* /usr/include/ffmpeg/libpostproc /usr/include/ffmpeg/libswscale" \
  --with-blas --with-blas-includes=/usr/include/atlas-x86_64-base/ \
  --with-lapack --with-lapack-includes=/usr/include/atlas-x86_64-base/ \
make -j4 #pour compiler sur 4 thread
sudo make install

Et nous voilà avec une belle installation de grass7. Je vous encourage à faire un tour du propriétaire parce qu’un travail formidable a été fait ! Bravo à l’équipe de dev!

Comment se passe la communication avec R ?

RlogoEt bien figurez-vous qu’il y a le package qui va bien 😀 : rgrass7 qui s’installe comme d’habitude dans R avec :

install.packages(« rgrass7 », dependences = TRUE)

Mais l’utilisation diffère un peu de son grand frère. En effet, on peut désormais spécifier l’emplacement de votre GRASS7 fraichement compilé. On procèdera donc de la manière suivante :

remove(list=ls())
## Configuration Parametrs:
gisBaseLocation = "/opt/grass" #where the GRASS executables are
library(rgrass7) #load lib in R
initGRASS(gisBase=gisBaseLocation, override=TRUE) #Run GRASS in & Cancel previous running GRASS instance in R

L’exécution se fait ensuite avec une seule et même commande R à laquelle on passera en paramètre la commande GRASS

execGRASS(cmd= "g.remove", flags=c("f", "b"), parameters= list(type="raster", pattern="*"))

Ici on exécute donc dans R une commande GRASS qui va permettre de supprimer tous les rasters de la base de données GRASS.

Pour prendre un autre exemple :

execGRASS(cmd= "r.param.scale", flags= c("overwrite", "verbose"), parameters= list(input="DTM",output="CURVATURE", size=5, method="profc", zscale=2.0))

Ici on exécutera la commande r.param.scale  en spécifiant toutes les options.

Quand on veut ensuite sortir les résultats de GRASS pour les manipuler dans R, la méthode n’a pas beaucoup changé :

param.scale = raster(readRAST("CURVATURE"))

Ici on utilise la fonction raster du package éponyme pour convertir en raster les données en sortie de la fonction readRAST du package rgrass7.

Pour le plaisir des yeux

Voilà donc à partir de données LIDAR à 1m la proportion de surface avec des terrasses à l’échelle tu Trentino !

mappaEroica
Proportion de surfaces agricoles terrassées par tuile de données LIDAR à l’échelle de la région Trentino

Les coopératives viticoles en France

Grâce au blog de R. Schirmer, j’ai découvert au début de l’été le site de l’observatoire de la viticulture française. Ce site permet d’avoir accès à une documentation très fournie (chiffres à la clef) sur des sujet aussi variés que :

  • les surfaces plantées en vigne
  • les surfaces par cépage dominant
  • les volumes vinifiés par les coopératives ou les caves particulières par commune
  • etc.

Comme je suis en plein travail sur le poids du système coopératif sur le cru Banyuls (dans les PO), j’ai regardé les données auxquelles je pouvais accéder sur le site de l’observatoire. J’ai été enchanté de découvrir dans la rubrique vinification des données diachroniques (entre 2007 et 2013) sur les quantités totales livrées aux coopératives ou vignifiées par des caves particulières, mais aussi type de vin (AOP rouge/rosé, AOP blanc, IGP rouge/rosé, IGP blanc, et sans IGP).

Une véritable mine d’or donc ! Hier soir, prenant mon courage à bras le corps, je me suis lancé dans la récupération des données, et ce sur plusieurs années (2010 et 2013). Un travail long et fastidieux (qui aurait pu être simplifié si les possibilités de téléchargement des données avait été optimisées, mais bon quand on veut, on peut !).

Voilà donc les deux premières sorties graphiques :

  • ggplot_coop_2010_203Sur ces deux premières cartes on peut essayer de jouer au jeu des 7 erreurs :
  • Les bouches ont légèrement reculé
  • Le Haut-Rhin et le  Bas-Rhin sont entrés en course avec des volumes non négligeables
  • Les volumes ont un peu augmenté dans les Pyrénées orientales

Si ensuite on s’intéresse à l’évolution des volumes apportés aux coopératives et vinifiés par des caves particulières entre 2010 et 2013, on produit alors les cartes suivantes :

ggplot_variation_2010_203La première chose qu’on peut noter est la différence d’ordre de grandeur entre les volumes gagnés (ou perdus) par les caves coopératives et ceux générés par les caves particulières. On peut observer deux petites choses. Les volumes produits aussi bien par les coopératives que par les caves particulières entre 2010 et 2013 sont en réduction en Gironde et en augmentation pour le département de l’Hérault. La progression semble également positive pour les départements du Bas Rhin et du Haut Rhin.

Vous pouvez retrouver le matériel et la méthode sur github

Ampélographie et cépages mondiaux : morceaux choisis de géographie viticole

Genèse

J’essaie de reconstruire petit à petit sur les ruines de l’ancien blog, réutiliser une belle pierre pour en faire un appui de fenêtre, et essayer de conserver une trace des travaux qui ne servent à rien, mais qui me tiennent à cœur malgré tout.

Je me suis donc lancé ce soir sur les traces d’un vieux billet perdu à tout jamais (même sur archive.org). Un billet qui avait commencé sur un air de défi pour moi suite à une belle news de portail SIG.

En janvier 2014 donc Francois-Nicolas ROBINNE publiait un petit article pour signaler l’existence d’une base de données construite et mise à disposition par l’université d’Adélaïde, en Australie.

Cette base de données reprend, par pays les surfaces plantées pour 1200 cépages (connus et moins connus). Or, quand on parle d’informations et de pays, un géographe a envie de faire des cartes. En prenant au mot la remarque François-Nicolas je vous propose donc quelques cartes des cépages mondiaux et moins mondiaux…

Morceaux choisis de géographie viticole

La Douce Noire (le Corbeau)

répartition de la Douce Noire dans le monde en 2010
Répartition de la Douce Noire dans le monde en 2010

La douce noire (le nom que lui préfèrent les Savoyards) aussi appelée corbeau (dans les registres officiels), a été réautorisée à la culture dans toute la France en 2009 . C’est un raisin de cuve noir, qui était jadis largement cultivé dans le massif du mont Blanc (connu en Italie sous le nom Dolcetto negro). Comme on le voit sur la carte, il est largement cultivé en Argentine, mais commence à être réintroduit en France grâce aux efforts du Centre d’Ampélographie Alpine (et particulièrement R. Raffin et M. Grisard). Il est particulièrement intéressant en ces temps de changement climatique, car il produit un vin peu alcooleux. En Savoie, il était généralement mélangé dans les parcelles avec du Persan et de la Mondeuse qui sont deux cépages de seconde époque (ce qui permet une vendange simultanée).

Selon l’inventaire des cépages de 1957 que j’avais étudié et cartographié pendant un stage au Centre d’Ampélographie Alpine il en restait 499ha en Savoie.

Le Gewurztraminer (ou traminer aromatico)

répartition du Gewurztraminer a travers le monde
répartition du Gewurztraminer à travers le monde

Le 2nd cépage sur lequel je voudrais m’arrêter est le Gewurztraminer ou Traminer aromatico pour les Italiens. Car si ce cépage est bien connu en France en particulier à cause de l’AOC alsacienne, c’est à nos voisins italiens que je dois l’une des plus belles réussites. Je travaille dans la vraie vie avec la fondazion E.Mach dans le Trentino en Italie. Et il se trouve qu’on cultive très largement le Traminer aromatico dans cette région. Pour les besoins de ma thèse j’ai donc fait quelques séjours prolongés. Le contexte du Val Di Cembra ou de l’Alto Adige sont particulièrement propices à ce cépage rose.

Si d’autres cépages vous intéressent, les scripts R et les (82) cartes sont sur github. Vous pouvez jouer avec les scripts et si, comme L. Jegou, vous voulez éviter cet horrible mercator, vous pouvez forker et jouer avec la fonction coord_map() de ggplot2 (Attention les surprises! la simplification de polygones a été fait avec les pieds)

Terroir congress, 2014, Tokaj, Hungary

Du 7 au 10 juillet 2014 s’est déroulé en Hongrie le bien connu (dans le milieu autorisé) congrès terroir. Cet évènement a regroupé, comme tous les deux ans, près de 200 chercheurs du monde entier pendant quelques jours dans la petite ville hongroise de Tokaj, pour échanger autour de cette notion (ô combien complexe) du terroir.

Les échanges que j’ai eu lors de ce congrès m’ont donné envie, une fois de retour en France, de revisiter les données produites par mon petit script qui moissonne, depuis plusieurs mois, les tweets parlant de terroir.

L’information d’un découpage mondial ?

Je ne reviendrai pas sur la procédure que j’ai déjà expliquée dans un article de geotribu. J’ai effectué une classification univariée des résultats par pays pour essayer de me faire une idée de l’internationalisation du terme.

classificationAvec une classification automatique de jenks sur 5 classes, voilà les résultats. On constate qu’une très grande majorité des pays ne parle pas de « terroir »… Et au final parmi ceux qui en parlent, on peut constater de grands écarts entre les pays.

map_twitterSur cette carte (dans une projection funky (mapproj: gilbert)), on observe tout de suite que la notion de terroir est plutôt un terme utilisé par les « vieux » pays producteurs, mais pas seulement. C’est sans doute une question d’adoption du langage. En effet, les États-Unis sont dans la classe qui mobilise le plus d’utilisation (entre 21 et 34 % des tweets avec le mot « terroir ») et la France est juste derrière dans la classe 16 à 21%.

Les autres pays producteurs de vin en Europe (en particulier l’Italie et l’Espagne) sont plus loin derrière et partagent la même classe que les pays d’Amérique latine (entre 1 et 5% des tweets).

Échelle géographique nationale ?

On s’interroge ensuite tout naturellement sur la pertinence de raisonner à l’échelle nationale, et ainsi donner autant de points aux USA qu’à un pays européen. Il faut donc trouver un moyen de s’abstraire des limites géographiques.

L’exercice n’est pas trop compliqué dans la mesure où la donnée que nous récoltons est sous forme de points géoréférencés. La question reste l’échelle d’agrégation pour garder du sens. map_twitter_hexa

Avec cette agrégation par hexagones, on peut voir qu’il y a des inégalités spatiales dans l’utilisation du mot « terroir », et cela au sein même d’un territoire national ! Pour garder l’exemple des États-Unis, le centre du pays disparaît au profit des côtes Est et Ouest qui représentent de véritables « hotSpots » de l’utilisation du mot.

On pourrait rapprocher l’utilisation de ce mot aux zones urbaines (avec en Europe, un beau Hotspot parisien), ce qui représenterait un beau paradoxe. Peut-être parlons-nous volontiers de terroir dans un bar à vin parisien que sur les terrains viticoles de Bourgogne ou d’ailleurs :-)!

Sur ce, je vous laisse avec en prime de petites images des visites de terrain sur le vignoble de Tokaj.

 Des visites de terrain

Disznoko winnery

Une winnery historique où j’ai découvert le tokaj aszu, un vin produit à partir d’une double vinification. Des raisins botrytisés d’un côté et une vinification plus traditionnelle de l’autre. Les deux sont mélangés pendant quelques jours pour que les arômes des aszu passent dans le liquide et lui donnent des notes d’abricot, tintées de menthe !

L’occasion également de déguster un tokaj eszencia… essence même des raisin aszu récoltéd par gravité !

la cave de disznoko
La cave de disznoko
disznoko-celar
Dans les galeries de Disznoko

Nobilis winnery

DCIM102GOPRO
Dans la cave du domaine Nobilis

Un domaine familial de moins de 15ha d’où sortent des vins de tokaj fabuleux, dommage qu’ils soient compliqués à trouver en France … avis aux cavistes. Il y a quelque chose à faire ici :-). Une dégustation verticale, des comparaisons de millésimes surprenants !

PS : Pour ceux que ça intéresse, vous pouvez retrouver la présentation ( disponible sur gitHub) que j’ai faite lors de l’introduction à la session 4 du congrès. Il s’agissait de ré-explorer la pensée de Roger Dion par l’intermédiaire des SMA.

Election à Limoges : regrouper classifier !

Tout à commencer après les élections municipales, nous discutions avec @joelgombin de cartographie avec R et de résultats d’élection… dans ma naïveté je pensais qu’il existait un site regroupant tous les résultats des élections, un peu à la manière de cartelec. J’avais dans l’idée de proposer aux L1 de Géographie à Limoges dont je m’occupe de travailler sur la discrétisation univariée avec R sur ces données brûlantes d’actualité. Travail d’autant plus intéressant (à mon sens) que France3 Limousin proposait sur son site des cartes de ces résultats sans en préciser les modalités de création .

Retrouver et commenter la discrétisation des cartes de France3, un exercice intéressant si tant est que je puisse avoir accès aux données (électorales et spatiales). Pour les données spatiales, le site cartelec propose des fichiers spatiaux que je me suis empressé de découper à l’échelle de Limoges, et le site de la mairie propose un PDF des résultats par bureau de vote (parfait ça colle avec le shapefile).

Donc me voilà parti à scraper le PDF pour intégrer les données au shapefile de cartelec ! Et c’est en suite que les problèmes ont commencé !

Une fois la jointure réalisée, et grâce au package classInt on découvre les premiers résultats !

2nd tour des éléctions municipales à Limoges
2nd tour des élections municipales à Limoges. Les lignes verticales représentent les bornes de classes pour une classification par les quantiles

On pourra par exemple utiliser la syntaxe suivante :

classifQ=classIntervals(data$pct_GERARD,n=5,style="quantile")
pal1=c("#F0FFFF", "#003366") #définition des extrémités de la palette de couleurs
plot(classifQ,pal=pal1,
main="fréquence cumulée des votes FN \n 2nd tour à Limoges",
xlab="% de votes") #plot des effectifs cumulés

Effectuer une classification, qu’elle soit supervisée ou automatique, n’est jamais anodin. De cette étape dépend une très grande partie de l’information qui va être perçue par le lecteur.

Ainsi en utilisant une classification par quantiles, on obtient ce type de carte.

Cartographie des résultats du 2nd tour des municipales à Limoges par bureau de vote.
Cartographie des résultats du 2nd tour des municipales à Limoges par bureau de vote.

Ici on à utiliser ggplot2 avec la syntaxe suivante

##préparation de la legende
# Create labels from break values
brks=round(classifQ$brks,digits=2) ##definition des breaks
intLabels=matrix(1:(length(brks)-1))
for(j in 1:length(intLabels )){intLabels [j] = paste(as.character(brks[j]),"-",as.character(brks[j+1]))}
label_GERAD=intLabels

fn=ggplot()+
geom_polygon(data=bureau.df, aes(x=long,y=lat,group=group,fill=classif_GERARD))+
geom_path(data=bureau.df, aes(x=long,y=lat,group=group),color="grey30")+
scale_fill_brewer(type="seq", palette="YlGnBu",labels = label_GERAD)+
labs(title ="Classification de la proportion de votes GERARD (FN) \n
par la méthode des quantiles")+
theme_bw()+
coord_equal()
fn

On pourrait s’amuser à comparer le rendu en utilisant une classification par la méthode de Jenks (méthode des sauts naturels).

Cartographie des résultats du 2nd tour des municipales à Limoges par bureau de vote. Classification par la methode de Jenks
Cartographie des résultats du 2nd tour des municipales à Limoges par bureau de vote. Classification par la méthode de Jenks

On constate que la carte change d’allure. Si l’on s’intéresse à la carte de gauche représentant le vote FN à Limoges, certains bureaux de vote (sur la partie droite) qui étaient considérés comme appartenant à la classe la plus haute par une classification par les quantiles se retrouvent dans une classe plus intermédiaire avec une analyse par jenks…

La classification par Jenks me semble ici plus intéressante (je vous laisse vous reporter aux courbes de fréquences cumulées) car des « seuils » sont visibles sur les courbes.

Mais revenons au ce qui nous occupait. La cartographie proposée par France3, et des comparaisons. Le problème maintenant, vient de la résolution spatiale. En effet, elle n’est pas basée sur des résultats par bureau de vote, ce qui ne va pas nous aider à retrouver la méthode de classification !

C’est là qu’est intervenu F.Cerbelaud en effectuant un regroupement des résultats par bureau de vote en se basant visuellement sur la carte de France3.

Voici les nouvelles cartes produites quand on applique aux données une classification par la méthode de jenks (c’est la méthode de classification automatique qui donne les résultats les plus proches de la carte de France3)

Cartographie du 2nd tour des élections municipales à Limoges. Bureaux de votes regrouper selon la carte de FR3. Classification Jenks
Cartographie du 2nd tour des élections municipales à Limoges. Bureaux de vote regroupés selon la carte de France3. Classification Jenks

 

On voit très bien le type de changement de représentation qu’opèrent ces regroupement. Il est donc nécessaire, pour pouvoir comprendre une carte, de connaître la signification des regroupements d’entités spatiales (ici pour France3 des regroupements de bureau de vote) ainsi que le type de classification qui a été utilisé pour traiter les données. Quand on touche à des sujets aussi sensibles, une mise en contexte de l’objet cartographique ne me paraît pas ici superflu, car on voit très bien que chaque étape dans le traitement des données influence l’objet cartographique.

Vous pouvez télécharger les données spatiales ici