Archives de l’auteur : Mathieu

Intégration en ligne de commande d’une série de raster dans la base de données

Nous avons téléchargé les données de précipitation du projet worldclim : http://www.worldclim.org/data/v1_4/tiles/cur/prec_16_tif.zip

Cette archive contient un raster par mois.

Pour intégrer ces images à la base de données PostGIS en tuiles de 100×100 pixels, nous allons utiliser la commande suivante :

raster2pgsql -s 4326 -C -I -r -M -F -t 100×100 prec1_16.tif raster.prec1_16 | psql -h localhost -d rastest -U dba

Pour automatiser ce traitement sur les 12 fichiers, nous avons recyclé une ligne de commande déjà utilisée pour intégrer les shp de la bd_topo à la base de données :

for /R %F IN (*.tif) DO raster2pgsql -s 4326 -C -I -r -M -F -t 100×100 %~nF.tif raster.%~nF | psql -h localhost -d rastest -U dba

 

Interroger un fichier plat pour alimenter la base de données avec les Foreign Data Wrapper

Intégrer la dernière version de TAXREF à la base de données grace aux « Foreign Data Wrapper »

  • Mise à jour du 6 novembre 2018 pour conformité avec TAXREF v12 (changement de nom du fichier source 🙂 )
  • Mise à jour du 19 janvier 2018 pour conformité avec TAXREF v11
  • Mise à jour du 28 juin 2017 avec ajout des colonnes sa & ta (TAXREF v10)
  • Mise à jour du 4 juillet 2016 avec ajout de la colonne cd_sup (TAXREF v9)

Téléchargement de taxref :

https://inpn.mnhn.fr/telechargement/referentielEspece/taxref/12.0/menu#

CREATE EXTENSION file_fdw;

CREATE SERVER inpn FOREIGN DATA WRAPPER file_fdw;

CREATE SCHEMA fdw;

CREATE FOREIGN TABLE fdw.taxref_v12 (regne character varying, phylum character varying, classe character varying, ordre character varying, 
famille character varying, sous_famille character varying, tribu character varying, group1_inpn character varying, group2_inpn character varying, 
cd_nom character varying, cd_taxsup character varying, cd_sup character varying, cd_ref character varying, rang character varying, 
lb_nom character varying, lb_auteur character varying, nom_complet character varying, nom_complet_html character varying, nom_valide character varying,
nom_vern character varying, nom_vern_eng character varying, habitat character varying, fr character varying, gf character varying, 
mar character varying, gua character varying, sm character varying, sb character varying, spm character varying, may character varying, 
epa character varying, reu character varying, sa character varying, ta character varying, taaf character varying,
pf character varying, nc character varying, wf character varying, cli character varying, url character varying) SERVER inpn
OPTIONS (format 'csv', header 'true', filename '/tmp/TAXREFv12.txt', delimiter E'\t', null '');

Et voilà; nous pouvons faire une requête SQL sur notre fichier txt!

SELECT * FROM fdw.taxref_v12 WHERE ordre ILIKE 'ODONATA' limit 10;

Le fichier doit être lisible par postgres.

Un problème d’encodage a été rencontré sur les versions de TAXREF antérieures à la v10 de 2016, il a été résolu avec la commande

iconv -f LATIN1 -t UTF8 TAXREFv10.txt > TAXREFv10_utf8.txt

Les perspectives sont très intéressantes :

  • moissonnage des données externes (cas d’une base de données partenaire mysql)
  • interrogation de services web (json, xml)
  • et pourquoi pas des connecteurs vers les formats de fichier SIG ?

Ressources :

 

Lister les types enum d’une base de données

Comment lister les tyopes enum utilisé dans ma base de données, dans quel schéma sont-ils définis et qsuelles sont les valeurs de leurs différenst éléments ?

Avec PostgreSQL 9.x :

SELECT nspname AS schema, typname AS nom , string_agg(enumlabel::text, ', '::text) AS definition
  FROM pg_enum JOIN pg_type ON enumtypid = pg_type.oid
  JOIN pg_namespace ON pg_type.typnamespace = pg_namespace.oid
 WHERE typcategory = 'E'
 GROUP BY nspname, typname
 ORDER BY 1,2

Avec PostgreSQL 8.5 :

SELECT nspname AS schema, typname AS nom , array_to_string(array_agg(enumlabel::text),', ') AS definition
  FROM pg_enum JOIN pg_type ON enumtypid = pg_type.oid
  JOIN pg_namespace ON pg_type.typnamespace = pg_namespace.oid
 WHERE typcategory = 'E'
 GROUP BY nspname, typname
 ORDER BY 1,2

St_value() et géometries nulles

En voulant mettre à jour des données d'altitude d'une distribution de points, nous avons rencontré une erreur :

La requête suivante :

UPDATE export.tous_point_espece_selon_format_esri SET pente_mnt = ST_VALUE(rast, geometrie, true)
FROM raster.pente_mnt30
WHERE code_insee LIKE '30%' AND st_intersects(geometrie, rast)

retournait ceci :

ERREUR: syntaxe en entrée invalide pour l'entier : « NaN »
CONTEXTE : PL/pgSQL function "st_world2rastercoordx" lors de la conversion de la valeur de retour au type de retour de la fonction PL/pgSQL function "st_value" line 13 at RETURN

La solution est venue de la liste postgis-users et particulièrement de Bborie Park (http://postgis.17.n6.nabble.com/st-value-st-world2rastercoordx-error-td4999247.html).

Certaines geometries étaient nulles. Il faut donc ajouter cette condition à la claude WHERE (AND geometrie IS NOT NULL), ou corriger les données concernées.

Bborie a créé un ticket suite à ce problème pour tester dans la fonction l'existence de la géometrie.

PostGIS raster, suite

A vouloir aller trop vite on oublie de parcourir la documentation…

Lors d'un précédent article nous avons chargé "simplement" un raster dans la base de donnée pour l'exploiter ensuite.

Les requêtes fonctionnaient mais avec des temps de réponses qui rendent impossible une exploitation "en live " du MNT.

Après avoir posté sur la liste postgis-users au sujet d'une erreur rencontrée, on m'a conseillé de réaliser une jointure simple avec une condition de jointure (ST_Intersects(geometrie, rast)) plutôt qu'une jointure croisée.

Donc faire ceci :

UPDATE export.tous_point_espece_selon_format_esri SET altitude_mnt = ST_VALUE(rast, geometrie, true)
FROM raster.mnt30
WHERE code_insee LIKE '30%'
AND ST_Intersects(geometrie, rast)

plutôt que cela :

UPDATE export.tous_point_espece_selon_format_esri SET altitude_mnt = ST_VALUE(rast, geometrie, true)
FROM raster.mnt30
WHERE code_insee LIKE '30%'

Dans un premier temps cela n'a fait qu'augmenter le temps d'exécution de la requête déjà passablement longue.

Cela vient du fait que le raster a été initialement stocké comme une seule tuile (un table contenant une seule ligne).

Nous avons réintégré le raster à la base de donnée en le découpant en tuiles de 100×100 pixels avec cette commande :

raster2pgsql -s 2154 -C -I -r -M -F -t 100x100 DEPT30.asc raster.mnt30 | psql -h localhost -d odo_pap -U dba

Cela génère une table contenant environ 2400 lignes (tuiles) indexées.

Le résultat est sans appel, la mise à jour de l'altitude de 19000 données ponctuelles prend 31 secondes sur une machine de base contre plusieurs heures précédemment.

Liens utiles :

  • http://postgis.refractions.net/docs/using_raster.xml.html#RT_Raster_Loader
  • http://postgis.refractions.net/docs/RT_reference.html#Raster_Processing

Faciliter l’export des données et en garder la trace

Les demandes de données sont fréquentes et il est intéressant d'une part, de se faciliter la vie, et d'autre part de garder une trace de ces exports afin de valoriser le travail réalisé par les naturalistes et de les tenir informés de l'utilisation qui est faite de leurs données.

On créer pour cela deux tables :

  • une destinée à recueillir l'emprise des zones sur lesquelles des demandes de données sont réalisées
CREATE TABLE export.zone_export_donnee
(
  id_zone serial NOT NULL,
  motif character varying(200),
  date date NOT NULL DEFAULT ('now'::text)::date,
  geometrie geometry,
  id_structure integer,
  CONSTRAINT pk_zone_export PRIMARY KEY (id_zone ),
  CONSTRAINT enforce_dims_geometrie CHECK (st_ndims(geometrie) = 2),
  CONSTRAINT enforce_geotype_geometrie CHECK (geometrytype(geometrie) = 'MULTIPOLYGON'::text OR geometrie IS NULL),
  CONSTRAINT enforce_srid_geometrie CHECK (st_srid(geometrie) = 2154)
)
WITH (
  OIDS=FALSE
);
COMMENT ON TABLE export.zone_export_donnee
  IS 'Table utilisée dans un projet Qgis pour définir des emprises sur lesquelles exporter les données. Assure une traçabilité des export dans la table export.structure_a_recu_donnee';
  • la seconde pour garder la trace des envois
CREATE TABLE export.structure_a_recu_donnee
(
  date_export date NOT NULL,
  id_entite character varying NOT NULL,
  id_structure integer NOT NULL,
  CONSTRAINT structure_a_recu_ese_pk PRIMARY KEY (date_export , id_entite , id_structure ),
  CONSTRAINT id_structure_reference_structure FOREIGN KEY (id_structure)
      REFERENCES md.structure (id_structure) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
COMMENT ON TABLE export.structure_a_recu_donnee
  IS 'Trace l''ensemble des données envoyées à une structure, ainsi que la date d''envoi.';

Enfin, on crée un script (export_atlas_par_zone_export.sh) qui sera utilisé dans une action QGis :

mkdir -p "export"/$1/$3
cd "export"/$1/$3
pgsql2shp -f point_atlas_odopap_lr.shp -h adr.es.sse.ip -u nom_utilisateur -g geometrie nom_bdd "SELECT export.tous_point_espece_selon_format_esri.* FROM export.tous_point_espece_selon_format_esri, export.zone_export_donnee WHERE st_intersects(export.tous_point_espece_selon_format_esri.geometrie, export.zone_export_donnee.geometrie) AND id_zone='$2';"
psql -c "INSERT INTO export.structure_a_recu_donnee(date_export, id_entite, id_structure) SELECT current_date, id_entite, id_structure FROM export.tous_point_espece_selon_format_esri, export.zone_export_donnee WHERE st_intersects(export.tous_point_espece_selon_format_esri.geometrie, export.zone_export_donnee.geometrie) AND id_zone='$2'" -h adr.es.sse.ip -U nom_utilisateur nom_bdd 
echo "export terminé!"

L'action unix est créée comme ceci dans QGis :

./export_atlas_par_zone_export.sh %id_structure %id_zone %date

Premier contact avec postgis 2.0 et les raster

Nous venons d'installer postgis 2.0 sur la base de développement de l'atlas des papillons de jour et des libellules du Languedoc-Roussillon.

Cette fonctionalité des plus intéressantes nous intéresse particulièrement pour caractériser l'écologie des espèces et décrire leurs préférences écologiques.

Un premier test nous a conduit à importer dans la base de données le MNT du département de la lozère issu de la BD_TOPO de l'IGN et ensuite à afficher l'altitude des données de ce département.

Résultat concluant!

raster2pgsql -s 2154 mnt_48.asc raster.mnt48 > mnt48.sql
psql odo_pap -> i mnt48.sql
select ST_Value(rast, geometrie, true) from rater.mnt48, observation WHERE observation.codeçinsee LIKE '48%';

Voir  l'article "PostGIS raster, suite" pour comprendre les raisons du barré.

Ressources

Créer un site d’enquête participative avec Drupal version 7

Voilà quelques modules (Version 7 de Drupal) qui ont permis de réaliser le site Allo'Grenouille* (www.allo-grenouille.fr), enquête participative sur la répartition des grenouilles "vertes" de la Région Languedoc-Roussillon, visant à collecter des observations sonores (chants).

* Ce site a été élaboré dans le cadre du programme REPERE (Réseau d'Échange et de projets sur le Pilotage de la Recherche et l'Expertise) du projet MEDINA (Conservation de la biodiversité en région MEDiterranéenne: une INterface recherche – gestion pour identifier les enjeux et Alimenter le processus de décision).

 
MODULES FONCTIONS
›  Fonctions
Link

Ajouter un champ "lien" à un type de contenu.

Le widget "lien" est automatiquement défini.

PostGis Ajouter un champ "geospatial data" à un type de contenu, pour insérer une carte dans une page
Openlayers

Afficher les cartes Google maps (entre autres).

Il faut choisir ce widget pour le champ geospatial data. La gestion des cartes/couches/styles se fait alors dans Structure > Openlayers.

Submitted by

Gérer l'affichage des informations de publication (auteur et date).

La gestion se fait dans les paramètres de chaque type de contenu.

AddToAny

Ajouter un bloc "share" qui permet aux utilisateurs de partager un contenu sur les principaux réseaux sociaux.

La sélection des types de contenu pour lesquels on souhaite appliquer cette fonction se fait dans Configuration > Système > AddToAny OU dans la configuration du module.

FB like button

Insérer un bouton "J'aime" de Facebook à un contenu.

La sélection des types de contenu pour lesquels on souhaite appliquer cette fonction se fait dans Configuration > FB like button OU dans la configuration du module.

Rules (fonctionne avec Entity)

Définir des règles personnalisées: lier une action automatique (ici: affichage d'un message, redirection vers une page, envoi d'un mail automatique) avec un évènement (ici: création d'un contenu) et une condition (ici: type de contenu formulaire d'observation).

La gestion de ces règles se fait dans Configuration > Processus > Rules OU dans la configuration du module Rules.

Email field Ajouter un champ "email" à un type de contenu, qui crée un lien cliquable vers la messagerie automatique définie sur l'ordinateur de l'utilisateur.
Apparence
Colorbox

Afficher une image en overlay/pop-up pour la mettre en évidence et la voir en plus grand.

La gestion des styles personnalisés se fait dans Configuration > Média > Styles d'images, et la sélection du style dans la configuration du module. La gestion de l'application et le paramétrage du format Colorbox à des champs de types de contenu se font dans Gérer l'affichage dans les paramètres du type de contenu concerné, et dans les paramètres du champ dans les vues.

Fieldgroup

Ordonner les champs au sein d'une page / d'un type de contenu: onglets, accordéons,…

Dans les paramètres Gérer les champs du type de contenu, créer une arborescence en utilisant la fonction "Ajouter un nouveau groupe".

Date pop-up (fonctionne avec Calendar)

Sélectionner une date dans un calendrier mensuel au sein d'un formulaire de contribution.

Il faut choisir le widget pop-up calendar pour ce champ date. NB: ce module (et donc la date) est en anglais.

 

Image block Créer un bloc avec une image pour contenu
Automatic nodetitles

Maquer le champ "titre" et générer un nom automatique pour les contenus créés.

Par défaut: Nom du type de contenu et numéro de création. L'application de cette fonction s'active/se désactive dans les paramètres du type de contenu.

Exclude node title

Supprimer les titres de certains noeuds.

La sélection des noeuds se fait dans Configuration > Rédaction de contenu > Exclude Node Title.

Administration
Administration menu

Activer une toolbar d'administration qui permet d'afficher l'arborescence interne au survol, et donc d'accéder plus rapidement au menu souhaité.

Une fois ce module activé, on peut désactiver le module Toolbar contenu dans le Coeur de Drupal.

CKEditor

Mettre en forme un texte (formats filtred HTML ou full HTML) au lieu de rester en texte brut. Fonctions: liens, couleurs, alignement, insertion d'image dans le corps du texte à partir du file browser, etc.

Le type de champ à choisir pour appliquer cet assistant est "Texte long et résumé".

Module filter Organiser les modules selon leur type (automatique) pour faciliter leur recherche.
IMCE (fonctionne avec CKEditor)

Explorer le serveur FTP (file browser) pour insérer un fichier dans un contenu.

La gestion des profils d'utilisateurs et des droits pour le file browser d'IMCE se fait dans Configuration > Média > IMCE OU dans la configuration du module.

Sécurité
Captcha

Dispositif anti-spam pour s'assurer que la personne qui transmet est humaine. Générer automatique une image ou un texte à valider.

Les champs auxquels on souhaite appliquer cette fonction se fait dans Configuration > Personnes > Captcha OU dans la configuration du module.

Médias
Média

Télécharger des médias et les gérer.

La configuration de cette fonction se fait dans Configuration > Média >Types de fichier.

Audiofield

Ajouter un champ audio à un type de contenu.

Le widget à sélectionner est "Audio upload". Un player doit être associé à ce champ pour que la lecture soit possible.

JPlayer Lecteur audio personnalisable par la gestion des fichiers CSS.
JW player Lecteur vidéo.

 

Lancement de la seconde version de sig.cenlr.org

Le site sig.cenlr.org est devenue difficilement navigable.

Initialement utilisé comme un bloc-note ou un registre de notre travail géomaticien au sein du CEN L-R, le wiki mis en place en 2008 s'est étoffé, a beaucoup grossi. Ce nouveau site s'appelle si.cenlr.org, pour garder l'ancien site accessible et pour mieux correspondre au contenu qui ne concerne pas que la partie géographique du SI.

L'organisation du contenu y ait peu évidente et il devient difficile de parcourir le site. Par ailleurs, la forme utilisée rend peu compte de son dynamisme et des fréquents ajouts de contenu.

Ce site est mis en oeuvre avec de drupal, sur une base de données postgresql.

Petit à petit, nous allons tenter de migrer le contenu du wiki (sig.cenlr.org) vers ce site.

Bonne visite