Skip to content

Commit

Permalink
Add sterf protocole with export + synthese (#56)
Browse files Browse the repository at this point in the history
* Add sterf  protocole
* ignore DS_Store

---------

Co-authored-by: Amandine <[email protected]>
  • Loading branch information
DonovanMaillard and amandine-sahl authored Nov 25, 2024
1 parent e66f92d commit f6024d1
Show file tree
Hide file tree
Showing 11 changed files with 397 additions and 1 deletion.
Binary file removed .DS_Store
Binary file not shown.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.vscode
custom.json
custom.json

.DS_Store
15 changes: 15 additions & 0 deletions sterf/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"tree": {
"module": {
"site": {
"visit": {
"observation": null
}
}
}
},
"data": {
"nomenclature": ["TYPE_SITE", "METH_DETERMIN"],
"user": ["__CODE_LIST_INVENTOR", "__CODE_LIST_OBSERVER"]
}
}
64 changes: 64 additions & 0 deletions sterf/exports/csv/export_csv.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
------- Export des observations STERF ----------
DROP VIEW IF EXISTS gn_monitoring.v_export_sterf_standard;
CREATE OR REPLACE VIEW gn_monitoring.v_export_sterf_standard AS
SELECT
-- identifiant unique
o.uuid_observation AS uuid_observation,
-- Site et variables associées
s.base_site_name AS nom_transect,
st_astext(s.geom) AS wkt_transect,
st_x(st_centroid(s.geom_local)) AS x_centroid_local,
st_y(st_centroid(s.geom_local)) AS y_centroid_local,
s.altitude_min AS altitude_min,
s.altitude_max AS altitude_max,
com.communes,
nullif(sc.data::json ->> 'tirage_site', 'null') AS tirage_site,
nullif(sc.data::json ->> 'habitat_1', 'null') AS habitat_1,
nullif(sc.data::json ->> 'habitat_2', 'null') AS habitat_2,
nullif(sc.data::json ->> 'habitat_3', 'null') AS habitat_3,
nullif(sc.data::json ->> 'habitat_4', 'null') AS habitat_4,
-- Informations sur la visite
v.id_dataset,
d.dataset_name AS jeu_de_donnees,
v.uuid_base_visit AS uuid_visite,
v.visit_date_min AS date_visite,
nullif(vc.data::json ->> 'duration', 'null') AS duree_parcours,
obs.observers,
nullif(vc.data::json ->> 'start_time', 'null') AS heure_debut,
nullif(vc.data::json ->> 'meteo_cond', 'null') AS conditions_meteo,
nullif(vc.data::json ->> 'temperature', 'null') AS temperature,
nullif(vc.data::json ->> 'vent', 'null') AS vent,
nullif(vc.data::json ->> 'ennuagement', 'null') AS ennuagement,
v.comments AS commentaire_visite,
-- Informations sur l'observation
o.cd_nom AS cd_nom,
t.lb_nom AS nom_latin,
t.nom_vern AS nom_francais,
r.prenom_role||' '||r.nom_role AS determinateur,
nullif(oc.data::json ->> 'count_min', 'null') AS count_min,
nullif(oc.data::json ->> 'count_max', 'null') AS count_max,
ref_nomenclatures.get_nomenclature_label(nullif(json_extract_path(oc.data::json,'id_nomenclature_determination_method')::text,'null')::integer, 'fr') AS methode_determ,
o.comments AS commentaire_obs
FROM gn_monitoring.t_observations o
JOIN gn_monitoring.t_observation_complements oc ON oc.id_observation = o.id_observation
JOIN gn_monitoring.t_base_visits v ON o.id_base_visit = v.id_base_visit
JOIN gn_monitoring.t_visit_complements vc ON v.id_base_visit = vc.id_base_visit
JOIN gn_monitoring.t_base_sites s ON s.id_base_site = v.id_base_site
JOIN gn_monitoring.t_site_complements sc ON sc.id_base_site = s.id_base_site
JOIN gn_commons.t_modules m ON m.id_module = v.id_module
JOIN taxonomie.taxref t ON t.cd_nom = o.cd_nom
LEFT JOIN gn_meta.t_datasets d ON d.id_dataset=v.id_dataset
LEFT JOIN LATERAL (select string_agg(la.area_name, ', ') AS communes
FROM ref_geo.l_areas la
JOIN ref_geo.bib_areas_types bat ON la.id_type = bat.id_type
JOIN gn_monitoring.cor_site_area csa ON csa.id_area = la.id_area
WHERE bat.type_code='COM'
AND csa.id_base_site = s.id_base_site) AS com ON true
LEFT JOIN LATERAL ( SELECT array_agg(r.id_role) AS ids_observers,
string_agg(concat(r.nom_role, ' ', r.prenom_role, ' (',org.nom_organisme,') '), ' ; '::text) AS observers
FROM gn_monitoring.cor_visit_observer cvo
JOIN utilisateurs.t_roles r ON r.id_role = cvo.id_role
LEFT JOIN utilisateurs.bib_organismes org ON org.id_organisme =r.id_organisme
WHERE cvo.id_base_visit = v.id_base_visit) obs ON true
LEFT JOIN utilisateurs.t_roles r ON nullif(json_extract_path(oc.data::json,'determiner')::text,'null')::integer = r.id_role
WHERE m.module_code = 'sterf';
Binary file added sterf/img.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions sterf/module.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"module_label":"Suivi Temporel des Rhopalocères de France",
"module_desc":"Module de saisie du protocole STERF",
"export_csv": [
{ "label": "Format observations CSV", "type":"csv" , "method": "standard" }
]
}
18 changes: 18 additions & 0 deletions sterf/nomenclature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"types": [
{
"mnemonique": "TYPE_SITE",
"label_default": "Type de sites",
"definition_default": "Nomenclature des types de sites suivi dans gn_monitoring."
}
],
"nomenclatures": [
{
"type": "TYPE_SITE",
"cd_nomenclature": "STERF",
"mnemonique": "Site_STERF",
"label_default": "Site STERF",
"definition_default": "Site de relevé du protocole STERF"
}
]
}
58 changes: 58 additions & 0 deletions sterf/observation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"display_properties": [
"cd_nom",
"id_nomenclature_determination_method",
"determiner",
"count_min",
"count_max",
"comments"
],
"display_list": [
"cd_nom",
"id_nomenclature_determination_method",
"count_min",
"count_max"
],
"keep": [
"determiner",
"id_nomenclature_determination_method"
],
"specific": {
"determiner": {
"type_widget": "datalist",
"attribut_label": "Déterminateur",
"api": "users/menu/__MODULE.ID_LIST_OBSERVER",
"application": "GeoNature",
"keyValue": "id_role",
"keyLabel": "nom_complet",
"type_util": "user",
"required": true
},
"id_nomenclature_determination_method": {
"type_widget": "datalist",
"attribut_label": "Méthode de détermination",
"api": "nomenclatures/nomenclature/METH_DETERMIN",
"application": "GeoNature",
"keyValue": "id_nomenclature",
"keyLabel": "label_fr",
"data_path": "values",
"type_util": "nomenclature",
"required": false,
"default": {
"cd_nomenclature": "67"
}
},
"count_min": {
"type_widget": "number",
"attribut_label": "Effectif minimal dénombré",
"required": true,
"min": 1
},
"count_max": {
"type_widget": "number",
"attribut_label": "Effectif maximal dénombré",
"required": true,
"min": "({value}) => value.count_min "
}
}
}
102 changes: 102 additions & 0 deletions sterf/site.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@

{
"genre":"M",
"geometry_type": "LineString",
"label": "Transect",
"label_list": "Transects",
"map_label_field_name": "base_site_name",
"display_properties": [
"base_site_name",
"id_inventor",
"first_use_date",
"last_visit",
"nb_visits",
"tirage_site",
"habitat_1",
"habitat_2",
"habitat_3",
"habitat_4"
],
"display_list": [
"base_site_name",
"first_use_date",
"last_visit",
"nb_visits"
],
"keep": [
"id_inventor",
"tirage_site"
],
"specific": {
"id_nomenclature_type_site": {
"type_widget": "nomenclature",
"attribut_label": "Type site",
"code_nomenclature_type": "TYPE_SITE",
"type_util": "nomenclature",
"required": true,
"value": {
"code_nomenclature_type": "TYPE_SITE",
"cd_nomenclature": "STERF"
},
"hidden": true
},
"tirage_site": {
"type_widget": "select",
"attribut_label": "Modalité de sélection du site *",
"required": true,
"values": ["Tiré aléatoirement", "Choisi"],
"value":"Choisi"
},
"habitat_1": {
"type_widget": "select",
"attribut_label": "Habitat (subdivision 1) *",
"required": true,
"values": ["A. Forêt (arbres > 5m de hauteur)","B. Buissons ou jeune forêt (<5m de hauteur)","C. Pelouses, marais et landes","D. Milieux agricoles","E. Milieux bâtis ou urbanisés","G. Rochers terrestres ou côtiers"]
},
"habitat_2": {
"type_widget": "select",
"required": false,
"attribut_label": "Habitat (subdivision 2)",
"values": [
"({value}) => {",
" if (value.habitat_1 == 'A. Forêt (arbres > 5m de hauteur)') { return [ 'a. Feuillus exclusifs','b. Mixte dom. Feuillus (< 10% conifères)','c. Mixte dom. conifères (< 10% feuillus)','d. Conifères exclusifs','e. Mixte' ] }",
" if (value.habitat_1 == 'B. Buissons ou jeune forêt (<5m de hauteur)') { return [ 'a. Feuillus exclusifs','b. Mixte dom. feuillus (< 10% conifères)','c. Mixte dom. conifères (< 10% feuillus)','d. Conifères exclusifs','e. Mixte' ] }",
" if (value.habitat_1 == 'C. Pelouses, marais et landes') { return [ 'a. Pelouse calcaire sèche','b. Lande herbacée','c. Lande à bruyères','d. Autres pelouses sèches','e. Pelouse d altitude', 'f. Pelouse humide naturelle', 'g. Pelouse inondée/marais pâturé', 'h. Tourbière', 'i. Roselière', 'j. Marais salant (halophile)', 'k. Autres zones humides ouvertes' ] }",
" if (value.habitat_1 == 'D. Milieux agricoles') { return [ 'a. Prairie cultivée','b. Prairie non cultivée','c. Prairie / cultures mixtes','d. Grandes cultures','e. Vergers / vignes / cultures maraîchères','f. Autres types de cultures' ] }",
" if (value.habitat_1 == 'E. Milieux bâtis ou urbanisés') { return [ 'a Zone urbaine résidentielle','b Zone urbaine industrielle','c Zone suburbaine résidentielle','d Zone suburbaine industrelle','e Zone rurale' ] }",
" else { return [ 'a. Falaise','b. Eboulis, pente rocheuse','c. Carrière','d. Autres sols rocheux' ]} ",
"}"
]
},
"habitat_3": {
"type_widget": "select",
"required": false,
"attribut_label": "Habitat (subdivision 3)",
"values": [
"({value}) => {",
" if (value.habitat_1 == 'A. Forêt (arbres > 5m de hauteur)') { return [ '1. Sous-bois dense','2. Sous-bois clair','3. Clairière et lisière','4. Parc (arbres épars et prairies)' ] }",
" if (value.habitat_1 == 'B. Buissons ou jeune forêt (<5m de hauteur)') { return [ '1. Forêt de régénération ou taillis','2. Buissons calcicoles','3. Lande arbustive non calcicole','4. Garrigue (calcaire) (Méditerr)','5. Maquis (non calcaire) (Méditerr)','6. Buissons de zones humides' ] }",
" if (value.habitat_1 == 'C. Pelouses, marais et landes') { return [ '1. Entouré de haies avec arbres','2. Entouré de haies de buissons','3. Entouré de ligne d arbres sans haie','4. Avec buissons épars','5. Sans buissons épars','6. Groupes isolés de 1-10 arbres','7. Autres limites de terrain (digue, fossé, mur, ...)' ] }",
" if (value.habitat_1 == 'D. Milieux agricoles') { return [ '1. Entouré de haies avec arbres','2. Entouré de haies de buissons','3. Entouré de ligne d arbres sans haie','4. Entouré de bandes herbeuses','5. Avec des groupes isolés de 1-10 arbres','6. Autre limite de terrain (digue, fossé, mur, ...)' ] }",
" if (value.habitat_1 == 'E. Milieux bâtis ou urbanisés') { return [ '1. Zones bâties prédominantes','2. Jardin','3. Parc public, zone de loisirs','4. Bord d une route (< 50 m)','5. Bord d un chemin de fer (< 50 m)','6. Décharge d’ordures' ] }",
" else { return [ '1. En montagne','2. En bord de mer','3. En bord de lac ou de rivière','4. Autre' ]} ",
"}"
]
},
"habitat_4": {
"type_widget": "select",
"required": false,
"attribut_label": "Habitat (subdivision 4)",
"values": [
"({value}) => {",
" if (value.habitat_1 == 'A. Forêt (arbres > 5m de hauteur)') { return [ 'a. Non perturbé','b. Peu exploité','c. Fortement exploité','d. Pâturé' ] }",
" if (value.habitat_1 == 'B. Buissons ou jeune forêt (<5m de hauteur)') { return [ 'a. Non perturbé','b. Peu exploité','c. Fortement exploité','d. Pâturé' ] }",
" if (value.habitat_1 == 'C. Pelouses, marais et landes') { return [ 'a. Non perturbé/non exploité','b. Fauché','c. Pâturé' ] }",
" if (value.habitat_1 == 'D. Milieux agricoles') { return [ 'a. Non exploité (jachère)','b. Fauché','c. Pâturé','d. Céréales','e. Arbres fruitiers','f. Autres cultures' ] }",
" if (value.habitat_1 == 'E. Milieux bâtis ou urbanisés') { return [ 'a. Avec peu d espaces verts (< 25 %)','b. Avec des espaces verts surtout composés de pelouses','c. Avec des espaces verts buissonants (parterres, friches)','d. Avec des espaces verts fortement arborés','e. Avec un (des) potager(s)' ] }",
" else { return [ 'a. A dominante calcaire avec végétation herbacée rase','b. A dominante calcaire avec végétation herbacée haute','c. A dominante calcaire avec végétation buissonnante','d. A dominante non calcaire avec végétation herbacée rase','e. A dominante non calcaire avec végétation herbacée haute','f. A dominante non calcaire avec végétation buissonnante' ]} ",
"}"
]
}
}
}
67 changes: 67 additions & 0 deletions sterf/synthese.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
-- #############################
-- Création d'une vue
-- permettant la remonté des données
-- STERF dans la synthèse
-- #############################
DROP VIEW IF EXISTS gn_monitoring.v_synthese_sterf;

-- gn_monitoring.v_synthese_sterf
CREATE OR REPLACE VIEW gn_monitoring.v_synthese_sterf
AS WITH source AS (
SELECT t_sources.id_source
FROM gn_synthese.t_sources
WHERE t_sources.name_source::text = concat('MONITORING_', upper('sterf'::text))
LIMIT 1
)
SELECT o.uuid_observation AS unique_id_sinp,
v.uuid_base_visit AS unique_id_sinp_grp,
( SELECT source.id_source
FROM source) AS id_source,
o.id_observation AS entity_source_pk_value,
v.id_dataset,
ref_nomenclatures.get_id_nomenclature('METH_OBS'::character varying, '0'::character varying) AS id_nomenclature_obs_meth,
ref_nomenclatures.get_id_nomenclature('STADE_VIE'::character varying, '15'::character varying) AS id_nomenclature_life_stage,
ref_nomenclatures.get_id_nomenclature('SEXE'::character varying, '6'::character varying) AS id_nomenclature_sex,
ref_nomenclatures.get_id_nomenclature('OBJ_DENBR'::character varying, 'IND'::character varying) AS id_nomenclature_obj_count,
ref_nomenclatures.get_id_nomenclature('TYP_DENBR'::character varying, 'Co'::character varying) AS id_nomenclature_type_count,
ref_nomenclatures.get_id_nomenclature('STATUT_OBS'::character varying, 'Pr'::character varying) AS id_nomenclature_observation_status,
ref_nomenclatures.get_id_nomenclature('STATUT_SOURCE'::character varying, 'Te'::character varying) AS id_nomenclature_source_status,
ref_nomenclatures.get_id_nomenclature('TYP_INF_GEO'::character varying, '1'::character varying) AS id_nomenclature_info_geo_type,
ref_nomenclatures.get_id_nomenclature('ETA_BIO'::character varying, '2'::character varying) AS id_nomenclature_bio_condition,
((oc.data::json #> '{count_min}'::text[])::text)::integer AS count_min,
((oc.data::json #> '{count_max}'::text[])::text)::integer AS count_max,
o.id_observation,
o.cd_nom,
t.nom_complet AS nom_cite,
alt.altitude_min,
alt.altitude_max,
s.geom AS the_geom_4326,
st_centroid(s.geom) AS the_geom_point,
s.geom_local AS the_geom_local,
v.visit_date_min AS date_min,
v.visit_date_max AS date_max,
obs.observers,
s.id_digitiser,
((oc.data::json #> '{id_nomenclature_determination_method}'::text[])::text)::integer AS id_nomenclature_determination_method,
v.id_module,
v.comments AS comment_context,
o.comments AS comment_description,
obs.ids_observers,
v.id_base_site,
v.id_base_visit,
jsonb_build_object('nom_site', s.base_site_name, 'code_site', s.base_site_code, 'habitat_1', NULLIF(replace((sc.data::json -> 'habitat_1'::text)::text, '"'::text, ''::text), 'null'::text), 'habitat_2', NULLIF(replace((sc.data::json -> 'habitat_2'::text)::text, '"'::text, ''::text), 'null'::text), 'habitat_3', NULLIF(replace((sc.data::json -> 'habitat_3'::text)::text, '"'::text, ''::text), 'null'::text), 'habitat_4', NULLIF(replace((sc.data::json -> 'habitat_4'::text)::text, '"'::text, ''::text), 'null'::text), 'vent', NULLIF(replace((vc.data::json -> 'vent'::text)::text, '"'::text, ''::text), 'null'::text), 'ennuagement', NULLIF(replace((vc.data::json -> 'ennuagement'::text)::text, '"'::text, ''::text), 'null'::text), 'temperature', NULLIF(replace((vc.data::json -> 'temperature'::text)::text, '"'::text, ''::text), 'null'::text), 'meteo_favorable', NULLIF(replace((vc.data::json -> 'meteo_cond'::text)::text, '"'::text, ''::text), 'null'::text), 'duree_transect', NULLIF(replace((vc.data::json -> 'duration'::text)::text, '"'::text, ''::text), 'null'::text), 'heure_debut', NULLIF(replace((vc.data::json -> 'start_time'::text)::text, '"'::text, ''::text), 'null'::text)) AS additional_data
FROM gn_monitoring.t_base_visits v
JOIN gn_monitoring.t_visit_complements vc ON v.id_base_visit = vc.id_base_visit
JOIN gn_monitoring.t_base_sites s ON s.id_base_site = v.id_base_site
JOIN gn_monitoring.t_site_complements sc ON s.id_base_site = sc.id_base_site
JOIN gn_commons.t_modules m ON m.id_module = v.id_module
JOIN gn_monitoring.t_observations o ON o.id_base_visit = v.id_base_visit
JOIN gn_monitoring.t_observation_complements oc ON oc.id_observation = o.id_observation
JOIN taxonomie.taxref t ON t.cd_nom = o.cd_nom
LEFT JOIN LATERAL ( SELECT array_agg(r.id_role) AS ids_observers,
string_agg(concat(r.nom_role, ' ', r.prenom_role), ' ; '::text) AS observers
FROM gn_monitoring.cor_visit_observer cvo
JOIN utilisateurs.t_roles r ON r.id_role = cvo.id_role
WHERE cvo.id_base_visit = v.id_base_visit) obs ON true
LEFT JOIN LATERAL ref_geo.fct_get_altitude_intersection(s.geom_local) alt(altitude_min, altitude_max) ON true
WHERE m.module_code::text = 'sterf'::text;
Loading

0 comments on commit f6024d1

Please sign in to comment.