diff --git a/VERSION b/VERSION index 89a27f7737..97041a78cf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.0.beta6.dev0 +2.0.0-rc.1 diff --git a/backend/geonature/core/gn_synthese/routes.py b/backend/geonature/core/gn_synthese/routes.py index 5a47af36ce..7b9a20aad5 100644 --- a/backend/geonature/core/gn_synthese/routes.py +++ b/backend/geonature/core/gn_synthese/routes.py @@ -271,13 +271,14 @@ def get_status(info_role): filters = dict(request.args) - q = DB.session.query(distinct(VSyntheseForWebApp.cd_nom), Taxref, TaxrefProtectionArticles).join( + q = (DB.session.query(distinct(VSyntheseForWebApp.cd_nom), Taxref, TaxrefProtectionArticles) + .join( Taxref, Taxref.cd_nom == VSyntheseForWebApp.cd_nom ).join( TaxrefProtectionEspeces, TaxrefProtectionEspeces.cd_nom == VSyntheseForWebApp.cd_nom ).join( TaxrefProtectionArticles, TaxrefProtectionArticles.cd_protection == TaxrefProtectionEspeces.cd_protection - ) + )) allowed_datasets = TDatasets.get_user_datasets(info_role) q = synthese_query.filter_query_all_filters(VSyntheseForWebApp, q, filters, info_role, allowed_datasets) diff --git a/backend/geonature/core/gn_synthese/utils/query.py b/backend/geonature/core/gn_synthese/utils/query.py index 1153d358dd..70026d990c 100644 --- a/backend/geonature/core/gn_synthese/utils/query.py +++ b/backend/geonature/core/gn_synthese/utils/query.py @@ -151,7 +151,7 @@ def filter_query_all_filters(model, q, filters, user, allowed_datasets): # if the geom is a circle if 'radius' in filters: radius = filters.pop('radius')[0] - geom_wkt = circle_from_point(geom_wkt, radius) + geom_wkt = circle_from_point(geom_wkt, float(radius)) geom_wkb = from_shape(geom_wkt, srid=4326) q = q.filter(model.the_geom_4326.ST_Intersects(geom_wkb)) filters.pop('geoIntersection') diff --git a/config/default_config.toml.example b/config/default_config.toml.example index 51e0651297..d3c7cd6175 100644 --- a/config/default_config.toml.example +++ b/config/default_config.toml.example @@ -12,13 +12,14 @@ DEBUG = true URL_APPLICATION = 'http://url.com/geonature' # Replace my_url.com by your domain or IP API_ENDPOINT = 'http://url.com/geonature/api' # Replace my_url.com by your domain or IP API_TAXHUB ='http://127.0.0.1:5000/api/' -ID_APPLICATION_GEONATURE = 14 # id_application of GeoNature in UsersHub +ID_APPLICATION_GEONATURE = 3 # id_application of GeoNature in UsersHub SESSION_TYPE = 'filesystem' SECRET_KEY = 'super secret key' COOKIE_EXPIRATION = 7200 COOKIE_AUTORENEW = true TRAP_ALL_EXCEPTIONS = false -HTTPS = false +# code EPSG des geom local de la BDD +LOCAL_SRID = # MTD XML_NAMESPACE = "{http://inpn.mnhn.fr/mtd}" @@ -41,6 +42,9 @@ CAS_URL_VALIDATION = 'https://preprod-inpn.mnhn.fr/auth/serviceValidate' ID = 'mon_id' PASSWORD = 'mon_pass' +[BDD] +id_area_type_municipality = 25 + [RIGHTS] NOTHING = 0 MY_DATA = 1 @@ -49,8 +53,11 @@ CAS_URL_VALIDATION = 'https://preprod-inpn.mnhn.fr/auth/serviceValidate' # Front end configuration [FRONTEND] +# passe le frontend en mode production (message de la console moins parlant en développement) PROD_MOD = false +# Affiche me composant 'custom/components/footer' sur la page d'accueil DISPLAY_FOOTER = false +# Passe le frontend en mode multilingue MULTILINGUAL = false [MAILERROR] @@ -67,15 +74,10 @@ MULTILINGUAL = false # Liste des entités géographiques sur lesquels les filtres # géographiques de la synthese s'appuient (id_area = id de l'entité géo, table ref_geo.bib_areas_types) AREA_FILTERS = [ - { label = "Zone natural 2000", id_type = 201 }, - { label = "Secteurs", id_type = 202 } + { label = "Communes", id_type = 25 }, ] # Colonne à afficher par défaut sur la liste des resultats de la synthese - # 'prop' corespond au nom de la colonne tel qu'il est écrit en BDD - # champs disponible de la table synthese : 'date_min', 'date_max', 'observers', 'id_synthese', 'altitude_min', 'altitude_max' - # champs disponible de la table taxon: 'nom_valide', 'cd_nom', 'lb_nom', 'nom_vern' - # champs disponible de la table t_dataset: 'dataset_name - # champs disponible de la table gn_synthese.t_sources: 'name_source' + # 'prop' corespond au nom de la colonne tel qu'il est écrit en BDD (gn_synthese.v_synthese_for_web_app) LIST_COLUMNS_FRONTEND = [ { prop = "nom_vern_or_lb_nom", name = "Taxon" }, @@ -83,15 +85,23 @@ MULTILINGUAL = false { prop = "observateurs", name = "Observateurs" }, { prop = "dataset_name", name = "Jeu de données" } ] + # id_attribut taxhub pour l'affichage dans la modale du détail d'une observation et dans les filtres taxonomique avancés - ID_ATTRIBUT_TAXHUB = [1, 2] # Colonne de la table gn_synthese.synthese que l'on veut masquer dans les filtres du formulaire 'occurrence avancé'. Par défaut, c'est un tableau vide. Exemple: EXCLUDED_COLUMNS = ['non_digital_proof'] pour enlever le filtre 'preuve non numérique' - - EXCLUDED_COLUMNS = [] - + # Affiche ou masque l'arbre de recherche taxonomique (recherche taxonommique avancé) + # Cette fonctionnalité n'est actuallement pas stable sur un grand nombre de taxon, passer à false si le temps de chargement est trop long + DISPLAY_TAXON_TREE = true + # Active le fait de rechercher sur le nom d'observateur en ILIKE sur les portée 1 et 2 du CRUVED + CRUVED_SEARCH_WITH_OBSERVER_AS_TXT = false + # Nombre d'observation maximum à afficher sur la carte après une recherche + NB_MAX_OBS_MAP = 10000 + # Nombre des dernières observations affichées par défaut quand on arrive sur la synthese + NB_LAST_OBS = 100 + # Nombre max d'observation dans les exports + NB_MAX_OBS_EXPORT = 40000 # Champs à afficher dans l'export [EXPORT_COLUMNS] [EXPORT_COLUMNS.SYNTHESE_COLUMNS] = [ @@ -137,9 +147,3 @@ MULTILINGUAL = false 'nom_valide' ] -default_maplist_columns = [ - { prop = "taxons", name = "Taxon" }, - { prop = "date_min", name = "Date début" }, - { prop = "observateurs", name = "Observateurs" }, - { prop = "dataset_name", name = "Jeu de données" } -] diff --git a/contrib/occtax/data/exports_occtax.sql b/contrib/occtax/data/exports_occtax.sql index d960c6a21f..7ffea6fce8 100644 --- a/contrib/occtax/data/exports_occtax.sql +++ b/contrib/occtax/data/exports_occtax.sql @@ -49,8 +49,8 @@ CREATE OR REPLACE VIEW pr_occtax.export_occtax_sinp AS ccc.count_min AS "denbrMin", ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_obj_count) AS "objDenbr", ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_type_count) AS "typDenbr", - COALESCE(string_agg((r.nom_role::text || ' '::text) || r.prenom_role::text, ','::text), rel.observers_txt::text) AS "obsId", - COALESCE(string_agg(r.organisme::text, ','::text), o.nom_organisme::text, 'NSP'::text) AS "obsNomOrg", + COALESCE(string_agg(DISTINCT(r.nom_role::text || ' '::text) || r.prenom_role::text, ','::text), rel.observers_txt::text) AS "obsId", + COALESCE(string_agg(DISTINCT r.organisme::text, ','::text), o.nom_organisme::text, 'NSP'::text) AS "obsNomOrg", COALESCE(occ.determiner, 'Inconnu'::character varying) AS "detId", 'NSP'::text AS "detNomOrg", 'NSP'::text AS "orgGestDat", @@ -104,8 +104,8 @@ CREATE OR REPLACE VIEW pr_occtax.export_occtax_dlb AS ccc.count_min AS "denbrMin", ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_obj_count) AS "objDenbr", ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_type_count) AS "typDenbr", - COALESCE(string_agg((r.nom_role::text || ' '::text) || r.prenom_role::text, ','::text), rel.observers_txt::text) AS "obsId", - COALESCE(string_agg(r.organisme::text, ','::text), o.nom_organisme::text, 'NSP'::text) AS "obsNomOrg", + COALESCE(string_agg(DISTINCT(r.nom_role::text || ' '::text) || r.prenom_role::text, ','::text), rel.observers_txt::text) AS "obsId", + COALESCE(string_agg(DISTINCT r.organisme::text, ','::text), o.nom_organisme::text, 'NSP'::text) AS "obsNomOrg", COALESCE(occ.determiner, 'Inconnu'::character varying) AS "detId", 'NSP'::text AS "detNomOrg", 'NSP'::text AS "orgGestDat", diff --git a/contrib/occtax/data/migration_2.0.0beta5toV2.sql b/contrib/occtax/data/migration_2.0.0beta5toV2.sql index d4f209989d..275792d247 100644 --- a/contrib/occtax/data/migration_2.0.0beta5toV2.sql +++ b/contrib/occtax/data/migration_2.0.0beta5toV2.sql @@ -197,8 +197,8 @@ VALUES( releve.geom_4326, ST_CENTROID(releve.geom_4326), releve.geom_local, - (to_char(releve.date_min, 'DD/MM/YYYY') || ' ' || to_char(releve.date_min, 'hh:mm:ss'))::timestamp, - (to_char(releve.date_max, 'DD/MM/YYYY') || ' ' || to_char(releve.date_max, 'hh:mm:ss'))::timestamp, + (to_char(releve.date_min, 'DD/MM/YYYY') || ' ' || '00:00:00')::timestamp, + (to_char(releve.date_max, 'DD/MM/YYYY') || ' ' || '00:00:00')::timestamp, validation.validator_full_name, validation.validation_comment, COALESCE (myobservers.observers_name, releve.observers_txt), @@ -216,10 +216,6 @@ $BODY$ COST 100; - - - - ---------------------- --FUNCTIONS TRIGGERS-- ---------------------- @@ -350,7 +346,7 @@ BEGIN sample_number_proof = NEW.sample_number_proof, digital_proof = NEW.digital_proof, non_digital_proof = NEW.non_digital_proof, - comments = CONCAT('Relevé : ',COALESCE(releve.comment, '-' ), ' Occurrence: ', COALESCE(NEW.comment, '-' )), + comments = CONCAT('Relevé : ',COALESCE(releve.comment, '- ' ), ' Occurrence: ', COALESCE(NEW.comment, '-' )), last_action = 'U' WHERE unique_id_sinp IN (SELECT unique_id_sinp_occtax FROM pr_occtax.cor_counting_occtax WHERE id_occurrence_occtax = NEW.id_occurrence_occtax); @@ -395,6 +391,7 @@ LANGUAGE plpgsql VOLATILE COST 100; +-- UPDATE Releve -- UPDATE Releve CREATE OR REPLACE FUNCTION pr_occtax.fct_tri_synthese_update_releve() RETURNS trigger AS @@ -413,6 +410,8 @@ BEGIN ELSE theobservers:= NEW.observers_txt; END IF; + + --mise à jour en synthese des informations correspondant au relevé uniquement UPDATE gn_synthese.synthese SET id_dataset = NEW.id_dataset, @@ -420,8 +419,8 @@ BEGIN id_digitiser = NEW.id_digitiser, id_nomenclature_obs_technique = NEW.id_nomenclature_obs_technique, id_nomenclature_grp_typ = NEW.id_nomenclature_grp_typ, - date_min = (to_char(NEW.date_min, 'DD/MM/YYYY') || ' ' || COALESCE(to_char(NEW.hour_min, 'hh:mm:ss'), '00:00:00'))::timestamp, - date_max = (to_char(NEW.date_max, 'DD/MM/YYYY') || ' ' || COALESCE(to_char(NEW.hour_max, 'hh:mm:ss'), '00:00:00'))::timestamp, + date_min = (to_char(NEW.date_min, 'DD/MM/YYYY') || ' ' || '00:00:00')::timestamp, + date_max = (to_char(NEW.date_max, 'DD/MM/YYYY') || ' ' || '00:00:00')::timestamp, altitude_min = NEW.altitude_min, altitude_max = NEW.altitude_max, the_geom_4326 = NEW.geom_4326, @@ -433,7 +432,7 @@ BEGIN FOR theoccurrence IN SELECT * FROM pr_occtax.t_occurrences_occtax WHERE id_releve_occtax = NEW.id_releve_occtax LOOP UPDATE gn_synthese.synthese SET - comments = CONCAT('Relevé: ',COALESCE(NEW.comment, '-'), 'Occurrence: ', COALESCE(theoccurrence.comment, '-')) + comments = CONCAT('Relevé: ',COALESCE(NEW.comment, '- '), 'Occurrence: ', COALESCE(theoccurrence.comment, '-')) WHERE unique_id_sinp IN (SELECT unnest(pr_occtax.get_unique_id_sinp_from_id_releve(NEW.id_releve_occtax::integer))); END LOOP; END IF; @@ -444,9 +443,6 @@ $BODY$ COST 100; - - - -- suppression d'un relevé CREATE OR REPLACE FUNCTION pr_occtax.fct_tri_synthese_delete_releve() RETURNS trigger AS @@ -467,7 +463,7 @@ CREATE OR REPLACE FUNCTION pr_occtax.fct_tri_synthese_insert_cor_role_releve() RETURNS trigger AS $BODY$ DECLARE - uuids_counting integer; + uuids_counting uuid[]; BEGIN -- récupération des id_counting à partir de l'id_releve SELECT INTO uuids_counting pr_occtax.get_unique_id_sinp_from_id_releve(NEW.id_releve_occtax::integer); @@ -664,6 +660,182 @@ CREATE TRIGGER tri_delete_synthese_cor_role_releves_occtax FOR EACH ROW EXECUTE PROCEDURE pr_occtax.fct_tri_synthese_delete_cor_role_releve(); +--------- +--VIEWS-- +--------- +DROP VIEW IF EXISTS v_releve_occtax; +CREATE OR REPLACE VIEW pr_occtax.v_releve_occtax AS + SELECT rel.id_releve_occtax, + rel.id_dataset, + rel.id_digitiser, + rel.date_min, + rel.date_max, + rel.altitude_min, + rel.altitude_max, + rel.meta_device_entry, + rel.comment, + rel.geom_4326, + rel."precision", + occ.id_occurrence_occtax, + occ.cd_nom, + occ.nom_cite, + t.lb_nom, + t.nom_valide, + t.nom_vern, + (((t.nom_complet_html::text || ' '::text) || rel.date_min::date) || '
'::text) || string_agg(DISTINCT(obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text) AS leaflet_popup, + COALESCE ( string_agg(DISTINCT(obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text),rel.observers_txt) AS observateurs + FROM pr_occtax.t_releves_occtax rel + LEFT JOIN pr_occtax.t_occurrences_occtax occ ON rel.id_releve_occtax = occ.id_releve_occtax + LEFT JOIN taxonomie.taxref t ON occ.cd_nom = t.cd_nom + LEFT JOIN pr_occtax.cor_role_releves_occtax cor_role ON cor_role.id_releve_occtax = rel.id_releve_occtax + LEFT JOIN utilisateurs.t_roles obs ON cor_role.id_role = obs.id_role + GROUP BY rel.id_releve_occtax, rel.id_dataset, rel.id_digitiser, rel.date_min, rel.date_max, rel.altitude_min, rel.altitude_max, rel.meta_device_entry, rel.comment, rel.geom_4326, rel."precision", t.cd_nom, occ.nom_cite, occ.id_occurrence_occtax, t.lb_nom, t.nom_valide, t.nom_complet_html, t.nom_vern; + +--Vue représentant l'ensemble des relevés du protocole occtax pour la représentation du module carte liste +CREATE OR REPLACE VIEW pr_occtax.v_releve_list AS + SELECT rel.id_releve_occtax, + rel.id_dataset, + rel.id_digitiser, + rel.date_min, + rel.date_max, + rel.altitude_min, + rel.altitude_max, + rel.meta_device_entry, + rel.comment, + rel.geom_4326, + rel."precision", + dataset.dataset_name, + string_agg(DISTINCT t.nom_valide::text, ','::text) AS taxons, + (((string_agg(DISTINCT t.nom_valide::text, ','::text) || '
'::text) || rel.date_min::date) || '
'::text) || COALESCE(string_agg(DISTINCT(obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text), rel.observers_txt::text) AS leaflet_popup, + COALESCE(string_agg(DISTINCT(obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text), rel.observers_txt::text) AS observateurs + FROM pr_occtax.t_releves_occtax rel + LEFT JOIN pr_occtax.t_occurrences_occtax occ ON rel.id_releve_occtax = occ.id_releve_occtax + LEFT JOIN taxonomie.taxref t ON occ.cd_nom = t.cd_nom + LEFT JOIN pr_occtax.cor_role_releves_occtax cor_role ON cor_role.id_releve_occtax = rel.id_releve_occtax + LEFT JOIN utilisateurs.t_roles obs ON cor_role.id_role = obs.id_role + LEFT JOIN gn_meta.t_datasets dataset ON dataset.id_dataset = rel.id_dataset + GROUP BY dataset.dataset_name, rel.id_releve_occtax, rel.id_dataset, rel.id_digitiser, rel.date_min, rel.date_max, rel.altitude_min, rel.altitude_max, rel.meta_device_entry; + +CREATE OR REPLACE VIEW pr_occtax.export_occtax_sinp AS + SELECT ccc.unique_id_sinp_occtax AS "permId", + ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_observation_status) AS "statObs", + occ.nom_cite AS "nomCite", + rel.date_min AS "dateDebut", + rel.date_max AS "dateFin", + rel.hour_min AS "heureDebut", + rel.hour_max AS "heureFin", + rel.altitude_max AS "altMax", + rel.altitude_min AS "altMin", + occ.cd_nom AS "cdNom", + taxonomie.find_cdref(occ.cd_nom) AS "cdRef", + gn_commons.get_default_parameter('taxref_version'::text, NULL::integer) AS "versionTAXREF", + rel.date_min AS datedet, + occ.comment, + 'NSP'::text AS "dSPublique", + d.unique_dataset_id AS "jddMetadonneeDEEId", + ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_source_status) AS "statSource", + '0'::text AS "diffusionNiveauPrecision", + ccc.unique_id_sinp_occtax AS "idOrigine", + d.dataset_name AS "jddCode", + d.unique_dataset_id AS "jddId", + NULL::text AS "refBiblio", + ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_obs_meth) AS "obsMeth", + ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_bio_condition) AS "ocEtatBio", + COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_naturalness), '0'::text::character varying) AS "ocNat", + ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_sex) AS "ocSex", + ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_life_stage) AS "ocStade", + '0'::text AS "ocBiogeo", + COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_bio_status), '0'::text::character varying) AS "ocStatBio", + COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_exist_proof), '0'::text::character varying) AS "preuveOui", + ref_nomenclatures.get_nomenclature_label(occ.id_nomenclature_determination_method, 'fr'::character varying) AS "ocMethDet", + occ.digital_proof AS "preuvNum", + occ.non_digital_proof AS "preuvNoNum", + rel.comment AS "obsCtx", + rel.unique_id_sinp_grp AS "permIdGrp", + 'Relevé'::text AS "methGrp", + 'OBS'::text AS "typGrp", + ccc.count_max AS "denbrMax", + ccc.count_min AS "denbrMin", + ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_obj_count) AS "objDenbr", + ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_type_count) AS "typDenbr", + COALESCE(string_agg(DISTINCT (r.nom_role::text || ' '::text) || r.prenom_role::text, ','::text), rel.observers_txt::text) AS "obsId", + COALESCE(string_agg(DISTINCT r.organisme::text, ','::text), o.nom_organisme::text, 'NSP'::text) AS "obsNomOrg", + COALESCE(occ.determiner, 'Inconnu'::character varying) AS "detId", + 'NSP'::text AS "detNomOrg", + 'NSP'::text AS "orgGestDat", + st_astext(rel.geom_4326) AS "WKT", + 'In'::text AS "natObjGeo" + FROM pr_occtax.t_releves_occtax rel + LEFT JOIN pr_occtax.t_occurrences_occtax occ ON rel.id_releve_occtax = occ.id_releve_occtax + LEFT JOIN pr_occtax.cor_counting_occtax ccc ON ccc.id_occurrence_occtax = occ.id_occurrence_occtax + LEFT JOIN taxonomie.taxref tax ON tax.cd_nom = occ.cd_nom + LEFT JOIN gn_meta.t_datasets d ON d.id_dataset = rel.id_dataset + LEFT JOIN pr_occtax.cor_role_releves_occtax cr ON cr.id_releve_occtax = rel.id_releve_occtax + LEFT JOIN utilisateurs.t_roles r ON r.id_role = cr.id_role + LEFT JOIN utilisateurs.bib_organismes o ON o.id_organisme = r.id_organisme + GROUP BY ccc.unique_id_sinp_occtax, d.unique_dataset_id, occ.id_nomenclature_bio_condition, occ.id_nomenclature_naturalness, ccc.id_nomenclature_sex, ccc.id_nomenclature_life_stage, occ.id_nomenclature_bio_status, occ.id_nomenclature_exist_proof, occ.id_nomenclature_determination_method, rel.unique_id_sinp_grp, d.id_nomenclature_source_status, occ.id_nomenclature_blurring, occ.id_nomenclature_diffusion_level, 'Pr'::text, occ.nom_cite, rel.date_min, rel.date_max, rel.hour_min, rel.hour_max, rel.altitude_max, rel.altitude_min, occ.cd_nom, occ.id_nomenclature_observation_status, (taxonomie.find_cdref(occ.cd_nom)), (gn_commons.get_default_parameter('taxref_version'::text, NULL::integer)), rel.comment, 'Ac'::text, rel.id_dataset, NULL::text, (ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_source_status)), ccc.id_counting_occtax, d.dataset_name, occ.determiner, occ.comment, (ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_obs_meth)), (ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_bio_condition)), (COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_naturalness), '0'::text::character varying)), (ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_sex)), (ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_life_stage)), '0'::text, (COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_bio_status), '0'::text::character varying)), (COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_exist_proof), '0'::text::character varying)), (ref_nomenclatures.get_nomenclature_label(occ.id_nomenclature_determination_method, 'fr'::character varying)), occ.digital_proof, occ.non_digital_proof, 'Relevé'::text, 'OBS'::text, ccc.count_max, ccc.count_min, (ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_obj_count)), (ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_type_count)), rel.observers_txt, 'NSP'::text, o.nom_organisme, (st_astext(rel.geom_4326)), 'In'::text; + +CREATE OR REPLACE VIEW pr_occtax.export_occtax_dlb AS + SELECT ccc.unique_id_sinp_occtax AS "permId", + ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_observation_status) AS "statObs", + occ.nom_cite AS "nomCite", + to_char(rel.date_min, 'DD/MM/YYYY'::text) AS "dateDebut", + to_char(rel.date_max, 'DD/MM/YYYY'::text) AS "dateFin", + rel.hour_min AS "heureDebut", + rel.hour_max AS "heureFin", + rel.altitude_max AS "altMax", + rel.altitude_min AS "altMin", + occ.cd_nom AS "cdNom", + taxonomie.find_cdref(occ.cd_nom) AS "cdRef", + to_char(rel.date_min, 'DD/MM/YYYY'::text) AS "dateDet", + occ.comment, + 'NSP'::text AS "dSPublique", + ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_source_status) AS "statSource", + ccc.unique_id_sinp_occtax AS "idOrigine", + d.unique_dataset_id AS "jddId", + NULL::text AS "refBiblio", + ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_obs_meth) AS "obsMeth", + ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_bio_condition) AS "ocEtatBio", + COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_naturalness), '0'::text::character varying) AS "ocNat", + ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_sex) AS "ocSex", + ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_life_stage) AS "ocStade", + '0'::text AS "ocBiogeo", + COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_bio_status), '0'::text::character varying) AS "ocStatBio", + COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_exist_proof), '0'::text::character varying) AS "preuveOui", + ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_determination_method) AS "ocMethDet", + occ.digital_proof AS "preuvNum", + occ.non_digital_proof AS "preuvNoNum", + rel.comment AS "obsCtx", + rel.unique_id_sinp_grp AS "permIdGrp", + 'Relevé'::text AS "methGrp", + 'OBS'::text AS "typGrp", + ccc.count_max AS "denbrMax", + ccc.count_min AS "denbrMin", + ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_obj_count) AS "objDenbr", + ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_type_count) AS "typDenbr", + COALESCE(string_agg(DISTINCT (r.nom_role::text || ' '::text) || r.prenom_role::text, ','::text), rel.observers_txt::text) AS "obsId", + COALESCE(string_agg(DISTINCT r.organisme::text, ','::text), o.nom_organisme::text, 'NSP'::text) AS "obsNomOrg", + COALESCE(occ.determiner, 'Inconnu'::character varying) AS "detId", + 'NSP'::text AS "detNomOrg", + 'NSP'::text AS "orgGestDat", + st_astext(rel.geom_4326) AS "WKT", + 'In'::text AS "natObjGeo", + rel.date_min, + rel.date_max, + rel.id_dataset, + rel.id_releve_occtax, + occ.id_occurrence_occtax, + rel.id_digitiser, + rel.geom_4326 + FROM pr_occtax.t_releves_occtax rel + LEFT JOIN pr_occtax.t_occurrences_occtax occ ON rel.id_releve_occtax = occ.id_releve_occtax + LEFT JOIN pr_occtax.cor_counting_occtax ccc ON ccc.id_occurrence_occtax = occ.id_occurrence_occtax + LEFT JOIN taxonomie.taxref tax ON tax.cd_nom = occ.cd_nom + LEFT JOIN gn_meta.t_datasets d ON d.id_dataset = rel.id_dataset + LEFT JOIN pr_occtax.cor_role_releves_occtax cr ON cr.id_releve_occtax = rel.id_releve_occtax + LEFT JOIN utilisateurs.t_roles r ON r.id_role = cr.id_role + LEFT JOIN utilisateurs.bib_organismes o ON o.id_organisme = r.id_organisme + GROUP BY rel.date_min, rel.date_max, rel.id_dataset, rel.unique_id_sinp_grp, occ.id_occurrence_occtax, rel.id_digitiser, rel.geom_4326, ccc.unique_id_sinp_occtax, d.unique_dataset_id, occ.id_nomenclature_bio_condition, occ.id_nomenclature_naturalness, ccc.id_nomenclature_sex, ccc.id_nomenclature_life_stage, occ.id_nomenclature_bio_status, occ.id_nomenclature_exist_proof, occ.id_nomenclature_determination_method, rel.id_releve_occtax, d.id_nomenclature_source_status, occ.id_nomenclature_blurring, occ.id_nomenclature_diffusion_level, 'Pr'::text, occ.nom_cite, rel.hour_min, rel.hour_max, rel.altitude_max, rel.altitude_min, occ.cd_nom, occ.id_nomenclature_observation_status, (taxonomie.find_cdref(occ.cd_nom)), rel.comment, 'Ac'::text, NULL::text, (ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_source_status)), ccc.id_counting_occtax, d.dataset_name, occ.determiner, occ.comment, (ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_obs_meth)), (ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_bio_condition)), (COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_naturalness), '0'::text::character varying)), (ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_sex)), (ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_life_stage)), '0'::text, (COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_bio_status), '0'::text::character varying)), (COALESCE(ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_exist_proof), '0'::text::character varying)), (ref_nomenclatures.get_cd_nomenclature(occ.id_nomenclature_determination_method)), occ.digital_proof, occ.non_digital_proof, 'Relevé'::text, 'OBS'::text, ccc.count_max, ccc.count_min, (ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_obj_count)), (ref_nomenclatures.get_cd_nomenclature(ccc.id_nomenclature_type_count)), rel.observers_txt, 'NSP'::text, o.nom_organisme, (st_astext(rel.geom_4326)), 'In'::text; -------------------- -- ASSOCIATED DATA-- diff --git a/contrib/occtax/data/occtax.sql b/contrib/occtax/data/occtax.sql index 0a3bafe298..783db9fc41 100644 --- a/contrib/occtax/data/occtax.sql +++ b/contrib/occtax/data/occtax.sql @@ -237,8 +237,8 @@ VALUES( releve.geom_4326, ST_CENTROID(releve.geom_4326), releve.geom_local, - (to_char(releve.date_min, 'DD/MM/YYYY') || ' ' || to_char(releve.date_min, 'hh:mm:ss'))::timestamp, - (to_char(releve.date_max, 'DD/MM/YYYY') || ' ' || to_char(releve.date_max, 'hh:mm:ss'))::timestamp, + (to_char(releve.date_min, 'DD/MM/YYYY') || ' ' || '00:00:00')::timestamp, + (to_char(releve.date_max, 'DD/MM/YYYY') || ' ' || '00:00:00')::timestamp, validation.validator_full_name, validation.validation_comment, COALESCE (myobservers.observers_name, releve.observers_txt), @@ -641,7 +641,6 @@ $BODY$ COST 100; - -- DELETE counting CREATE OR REPLACE FUNCTION pr_occtax.fct_tri_synthese_delete_counting() RETURNS trigger AS @@ -656,7 +655,6 @@ $BODY$ LANGUAGE plpgsql VOLATILE COST 100; - -- DELETE counting CREATE OR REPLACE FUNCTION pr_occtax.fct_tri_delete_counting() RETURNS trigger AS @@ -675,7 +673,6 @@ $BODY$ LANGUAGE plpgsql VOLATILE COST 100; - -- UPDATE counting CREATE OR REPLACE FUNCTION pr_occtax.fct_tri_synthese_update_counting() RETURNS trigger AS @@ -718,7 +715,6 @@ DECLARE BEGIN -- récupération du releve pour le commentaire à concatener SELECT INTO releve * FROM pr_occtax.t_releves_occtax WHERE id_releve_occtax = NEW.id_releve_occtax; - UPDATE gn_synthese.synthese SET id_nomenclature_obs_meth = NEW.id_nomenclature_obs_meth, id_nomenclature_bio_condition = NEW.id_nomenclature_bio_condition, @@ -740,7 +736,6 @@ BEGIN comments = CONCAT('Relevé : ',COALESCE(releve.comment, '-' ), ' Occurrence: ', COALESCE(NEW.comment, '-' )), last_action = 'U' WHERE unique_id_sinp IN (SELECT unique_id_sinp_occtax FROM pr_occtax.cor_counting_occtax WHERE id_occurrence_occtax = NEW.id_occurrence_occtax); - RETURN NULL; END; $BODY$ @@ -800,6 +795,7 @@ BEGIN ELSE theobservers:= NEW.observers_txt; END IF; + --mise à jour en synthese des informations correspondant au relevé uniquement UPDATE gn_synthese.synthese SET id_dataset = NEW.id_dataset, @@ -807,8 +803,8 @@ BEGIN id_digitiser = NEW.id_digitiser, id_nomenclature_obs_technique = NEW.id_nomenclature_obs_technique, id_nomenclature_grp_typ = NEW.id_nomenclature_grp_typ, - date_min = (to_char(NEW.date_min, 'DD/MM/YYYY') || ' ' || COALESCE(to_char(NEW.hour_min, 'hh:mm:ss'), '00:00:00'))::timestamp, - date_max = (to_char(NEW.date_max, 'DD/MM/YYYY') || ' ' || COALESCE(to_char(NEW.hour_max, 'hh:mm:ss'), '00:00:00'))::timestamp, + date_min = (to_char(NEW.date_min, 'DD/MM/YYYY') || ' ' || '00:00:00')::timestamp, + date_max = (to_char(NEW.date_max, 'DD/MM/YYYY') || ' ' || '00:00:00')::timestamp, altitude_min = NEW.altitude_min, altitude_max = NEW.altitude_max, the_geom_4326 = NEW.geom_4326, @@ -820,7 +816,7 @@ BEGIN FOR theoccurrence IN SELECT * FROM pr_occtax.t_occurrences_occtax WHERE id_releve_occtax = NEW.id_releve_occtax LOOP UPDATE gn_synthese.synthese SET - comments = CONCAT('Relevé: ',COALESCE(NEW.comment, '-'), 'Occurrence: ', COALESCE(theoccurrence.comment, '-')) + comments = CONCAT('Relevé: ',COALESCE(NEW.comment, '- '), 'Occurrence: ', COALESCE(theoccurrence.comment, '-')) WHERE unique_id_sinp IN (SELECT unnest(pr_occtax.get_unique_id_sinp_from_id_releve(NEW.id_releve_occtax::integer))); END LOOP; END IF; @@ -831,9 +827,6 @@ $BODY$ COST 100; - - - -- suppression d'un relevé CREATE OR REPLACE FUNCTION pr_occtax.fct_tri_synthese_delete_releve() RETURNS trigger AS @@ -854,7 +847,7 @@ CREATE OR REPLACE FUNCTION pr_occtax.fct_tri_synthese_insert_cor_role_releve() RETURNS trigger AS $BODY$ DECLARE - uuids_counting integer; + uuids_counting uuid[]; BEGIN -- récupération des id_counting à partir de l'id_releve SELECT INTO uuids_counting pr_occtax.get_unique_id_sinp_from_id_releve(NEW.id_releve_occtax::integer); @@ -927,8 +920,6 @@ COST 100; ------------ --TRIGGERS-- ------------ - - CREATE TRIGGER tri_insert_default_validation_status AFTER INSERT ON cor_counting_occtax @@ -1052,9 +1043,6 @@ CREATE TRIGGER tri_delete_synthese_cor_role_releves_occtax EXECUTE PROCEDURE pr_occtax.fct_tri_synthese_delete_cor_role_releve(); - - - ------------ --VIEWS-- ------------ @@ -1078,8 +1066,8 @@ CREATE OR REPLACE VIEW pr_occtax.v_releve_occtax AS t.lb_nom, t.nom_valide, t.nom_vern, - (((t.nom_complet_html::text || ' '::text) || rel.date_min::date) || '
'::text) || string_agg((obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text) AS leaflet_popup, - COALESCE ( string_agg((obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text),rel.observers_txt) AS observateurs + (((t.nom_complet_html::text || ' '::text) || rel.date_min::date) || '
'::text) || string_agg(DISTINCT(obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text) AS leaflet_popup, + COALESCE ( string_agg(DISTINCT(obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text),rel.observers_txt) AS observateurs FROM pr_occtax.t_releves_occtax rel LEFT JOIN pr_occtax.t_occurrences_occtax occ ON rel.id_releve_occtax = occ.id_releve_occtax LEFT JOIN taxonomie.taxref t ON occ.cd_nom = t.cd_nom @@ -1103,9 +1091,9 @@ CREATE OR REPLACE VIEW pr_occtax.v_releve_list AS rel.geom_4326, rel."precision", dataset.dataset_name, - string_agg(t.nom_valide::text, ','::text) AS taxons, - (((string_agg(t.nom_valide::text, ','::text) || '
'::text) || rel.date_min::date) || '
'::text) || COALESCE(string_agg((obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text), rel.observers_txt::text) AS leaflet_popup, - COALESCE(string_agg((obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text), rel.observers_txt::text) AS observateurs + string_agg(DISTINCT t.nom_valide::text, ','::text) AS taxons, + (((string_agg(DISTINCT t.nom_valide::text, ','::text) || '
'::text) || rel.date_min::date) || '
'::text) || COALESCE(string_agg(DISTINCT(obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text), rel.observers_txt::text) AS leaflet_popup, + COALESCE(string_agg(DISTINCT(obs.nom_role::text || ' '::text) || obs.prenom_role::text, ', '::text), rel.observers_txt::text) AS observateurs FROM pr_occtax.t_releves_occtax rel LEFT JOIN pr_occtax.t_occurrences_occtax occ ON rel.id_releve_occtax = occ.id_releve_occtax LEFT JOIN taxonomie.taxref t ON occ.cd_nom = t.cd_nom @@ -1114,6 +1102,7 @@ CREATE OR REPLACE VIEW pr_occtax.v_releve_list AS LEFT JOIN gn_meta.t_datasets dataset ON dataset.id_dataset = rel.id_dataset GROUP BY dataset.dataset_name, rel.id_releve_occtax, rel.id_dataset, rel.id_digitiser, rel.date_min, rel.date_max, rel.altitude_min, rel.altitude_max, rel.meta_device_entry; + -------------------- -- ASSOCIATED DATA-- -------------------- diff --git a/contrib/occtax/frontend/app/occtax-map-form/form/occtax-form.component.ts b/contrib/occtax/frontend/app/occtax-map-form/form/occtax-form.component.ts index 0d8c8aa4a0..d32301344d 100644 --- a/contrib/occtax/frontend/app/occtax-map-form/form/occtax-form.component.ts +++ b/contrib/occtax/frontend/app/occtax-map-form/form/occtax-form.component.ts @@ -33,7 +33,7 @@ export class OcctaxFormComponent implements OnInit { private router: Router, private occtaxService: OcctaxService, private _commonService: CommonService - ) {} + ) { } ngOnInit() { // set show occurrence to false: @@ -214,6 +214,7 @@ export class OcctaxFormComponent implements OnInit { } else { console.error(error.error.message); this._commonService.translateToaster("error", "ErrorMessage"); + this.disabledAfterPost = false; } } ); diff --git a/contrib/occtax/frontend/app/occtax-map-form/form/occtax-form.service.ts b/contrib/occtax/frontend/app/occtax-map-form/form/occtax-form.service.ts index f85e0ae97f..7b514e5a9f 100644 --- a/contrib/occtax/frontend/app/occtax-map-form/form/occtax-form.service.ts +++ b/contrib/occtax/frontend/app/occtax-map-form/form/occtax-form.service.ts @@ -135,6 +135,10 @@ export class OcctaxFormService { (releveForm.controls.properties as FormGroup).get("date_max"), (releveForm.controls.properties as FormGroup).get("hour_min"), (releveForm.controls.properties as FormGroup).get("hour_max") + ), + this._formService.altitudeValidator( + (releveForm.controls.properties as FormGroup).get("altitude_min"), + (releveForm.controls.properties as FormGroup).get("altitude_max"), ) ]); return releveForm; diff --git a/contrib/occtax/frontend/app/occtax-map-form/form/releve/releve.component.html b/contrib/occtax/frontend/app/occtax-map-form/form/releve/releve.component.html index a861c0f64b..f6168ee635 100644 --- a/contrib/occtax/frontend/app/occtax-map-form/form/releve/releve.component.html +++ b/contrib/occtax/frontend/app/occtax-map-form/form/releve/releve.component.html @@ -51,6 +51,7 @@ {{ 'Releve.DateMaxError' | translate }} +
@@ -94,12 +95,16 @@
+
+ + {{ 'Releve.AltitudeError' | translate }} +
diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index 4e552fc1de..03bb2d8522 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -2,7 +2,7 @@ CHANGELOG ========= -2.0.0-rc.1 (unreleased) +2.0.0-rc.1 (2018-09-21) ----------------------- La version 2 de GeoNature est une refonte complète de l'application. @@ -12,7 +12,7 @@ La version 2 de GeoNature est une refonte complète de l'application. * Refonte de la base de données pour la rendre plus standarde, plus générique et modulaire * Refonte ergonomique pour moderniser l'application -Présentation et suivi du projet : https://github.com/PnX-SI/GeoNature/issues/168 +Présentation et suivi des développements : https://github.com/PnX-SI/GeoNature/issues/168 **Accueil** @@ -156,7 +156,7 @@ Pour les utilisateurs utilisant la version 2.0.0.beta5 : geonature generate_frontend_modules_route geonature frontend_build -* Exécuter l'update de la BDD GeoNature (``data/migrations/2.0.0beta5to2.0.0.sql``) ainsi que celui du sous-module Nomenclature (https://github.com/PnX-SI/Nomenclature-api-module/blob/1.2.1/data/update1.1.0to1.2.1.sql) +* Exécuter l'update de la BDD GeoNature (``data/migrations/2.0.0beta5to2.0.0.sql``), celui de Occtax (``contrib/occtax/data/migration_2.0.0beta5toV2.sql``) ainsi que celui du sous-module Nomenclature (https://github.com/PnX-SI/Nomenclature-api-module/blob/1.2.1/data/update1.1.0to1.2.1.sql) 2.0.0.beta5 (2018-07-16) diff --git a/docs/admin-manual.rst b/docs/admin-manual.rst index b8caa2e492..ed63397aba 100644 --- a/docs/admin-manual.rst +++ b/docs/admin-manual.rst @@ -112,62 +112,106 @@ La base de données contient de nombreuses fonctions. | | | | d'une observation avec tous les zonages| +--------------------------------------+-------------------------------+----------------------+----------------------------------------+ +**ref_geo** + +.. code:: sql + + ref_geo.fct_get_altitude_intersection(IN mygeom geometry) + -- Fonction qui retourne l'altitude min et max de la géométrie passée en paramètre + +.. code:: sql + + ref_geo.fct_get_area_intersection( + IN mygeom geometry, + IN myidtype integer DEFAULT NULL::integer) + RETURNS TABLE(id_area integer, id_type integer, area_code character varying, area_name character varying) + -- Fonction qui retourne un tableau des zonages (id_area) intersectant la géométrie passée en paramètre + +.. code:: sql + + ref_geo.get_id_area_type(mytype character varying) RETURNS integer + --Function which return the id_type_area from the type_code of an area type + **pr_occtax** -pr_occtax.get_id_counting_from_id_releve(my_id_releve integer) RETURNS integer[] --- Function which return the id_countings in an array (table pr_occtax.cor_counting_occtax) from the id_releve(integer) +.. code:: sql + + pr_occtax.get_id_counting_from_id_releve(my_id_releve integer) RETURNS integer[] + -- Function which return the id_countings in an array (table pr_occtax.cor_counting_occtax) from the id_releve(integer) + +.. code:: sql -get_default_nomenclature_value(mytype character varying, myidorganism integer DEFAULT 0, myregne character varying(20) DEFAULT '0', mygroup2inpn character varying(255) DEFAULT '0') RETURNS integer ---Function that return the default nomenclature id with wanteds nomenclature type, organism id, regne, group2_inpn ---Return -1 if nothing matche with given parameters + get_default_nomenclature_value(mytype character varying, myidorganism integer DEFAULT 0, myregne character varying(20) DEFAULT '0', mygroup2inpn character varying(255) DEFAULT '0') RETURNS integer + --Function that return the default nomenclature id with wanteds nomenclature type, organism id, regne, group2_inp --Return -1 if nothing matche with given parameters -pr_occtax.insert_in_synthese(my_id_counting integer) RETURNS integer[] +.. code:: sql + + pr_occtax.insert_in_synthese(my_id_counting integer) RETURNS integer[] **ref_nomenclatures** -get_id_nomenclature_type(mytype character varying) RETURNS integer ---Function which return the id_type from the mnemonique of a nomenclature type +.. code:: sql + + get_id_nomenclature_type(mytype character varying) RETURNS integer + --Function which return the id_type from the mnemonique of a nomenclature type + +.. code:: sql + + get_default_nomenclature_value(mytype character varying, myidorganism integer DEFAULT 0) RETURNS integer + --Function that return the default nomenclature id with wanteds nomenclature type (mnemonique), organism id + --Return -1 if nothing matche with given parameters + +.. code:: sql + + check_nomenclature_type_by_mnemonique(id integer , mytype character varying) RETURNS boolean + --Function that checks if an id_nomenclature matches with wanted nomenclature type (use mnemonique type) + +.. code:: sql + + check_nomenclature_type_by_cd_nomenclature(mycdnomenclature character varying , mytype character varying) + --Function that checks if an id_nomenclature matches with wanted nomenclature type (use mnemonique type) + +.. code:: sql + + check_nomenclature_type_by_id(id integer, myidtype integer) RETURNS boolean + --Function that checks if an id_nomenclature matches with wanted nomenclature type (use id_type) + +.. code:: sql -get_default_nomenclature_value(mytype character varying, myidorganism integer DEFAULT 0) RETURNS integer ---Function that return the default nomenclature id with wanteds nomenclature type (mnemonique), organism id ---Return -1 if nothing matche with given parameters + get_id_nomenclature( + mytype character varying, + mycdnomenclature character varying) + RETURNS integer + --Function which return the id_nomenclature from an mnemonique_type and an cd_nomenclature -check_nomenclature_type_by_mnemonique(id integer , mytype character varying) RETURNS boolean ---Function that checks if an id_nomenclature matches with wanted nomenclature type (use mnemonique type) +.. code:: sql -check_nomenclature_type_by_cd_nomenclature(mycdnomenclature character varying , mytype character varying) ---Function that checks if an id_nomenclature matches with wanted nomenclature type (use mnemonique type) + get_nomenclature_label( + myidnomenclature integer, + mylanguage character varying + ) + RETURNS character varying + --Function which return the label from the id_nomenclature and the language -check_nomenclature_type_by_id(id integer, myidtype integer) RETURNS boolean ---Function that checks if an id_nomenclature matches with wanted nomenclature type (use id_type) +.. code:: sql -get_id_nomenclature( -mytype character varying, -mycdnomenclature character varying) -RETURNS integer ---Function which return the id_nomenclature from an mnemonique_type and an cd_nomenclature + get_cd_nomenclature(myidnomenclature integer) RETURNS character varying + --Function which return the cd_nomenclature from an id_nomenclature -get_nomenclature_label( -myidnomenclature integer, -mylanguage character varying -) -RETURNS character varying ---Function which return the label from the id_nomenclature and the language +.. code:: sql -get_cd_nomenclature(myidnomenclature integer) -RETURNS character varying ---Function which return the cd_nomenclature from an id_nomenclature + get_filtered_nomenclature(mytype character varying, myregne character varying, mygroup character varying) + RETURNS SETOF integer + --Function that returns a list of id_nomenclature depending on regne and/or group2_inpn sent with parameters. -get_filtered_nomenclature(mytype character varying, myregne character varying, mygroup character varying) -RETURNS SETOF integer ---Function that returns a list of id_nomenclature depending on regne and/or group2_inpn sent with parameters. +.. code:: sql -calculate_sensitivity( -mycdnom integer, -mynomenclatureid integer) -RETURNS integer ---Function to return id_nomenclature depending on observation sensitivity ---USAGE : SELECT ref_nomenclatures.calculate_sensitivity(240,21); + calculate_sensitivity( + mycdnom integer, + mynomenclatureid integer) + RETURNS integer + --Function to return id_nomenclature depending on observation sensitivity + --USAGE : SELECT ref_nomenclatures.calculate_sensitivity(240,21); A compléter... A voir si on mentionne les triggers ou pas... @@ -460,7 +504,7 @@ GeoNature est fourni avec des données géographiques de base sur la métropôle Si vous souhaitez modifier le MNT pour mettre celui de votre territoire : * Videz le contenu de la table ``ref_geo.dem_vector`` -* Uploadez le fichier du MNT du serveur +* Uploadez le fichier du MNT sur le serveur * Suivez la procédure de chargement du MNT en l'adaptant : https://github.com/PnX-SI/GeoNature/blob/master/install/install_db.sh#L295-L299 TODO : Procédure à améliorer et simplifier : https://github.com/PnX-SI/GeoNature/issues/235 diff --git a/docs/development.rst b/docs/development.rst index 72d539f8c9..e55bd067c4 100644 --- a/docs/development.rst +++ b/docs/development.rst @@ -587,6 +587,8 @@ Ces composants peuvent être considérés comme des "dump components" ou "presen :``layerDrawed``: Output renvoyant le geojson de l'objet dessiné. + :``layerDeleted``: + Output renvoyant les layers sont supprimées. - **GPSComponent** Affiche une modale permettant de renseigner les coordonnées d'une observation, puis affiche un marker à la position renseignée. Ce composant hérite du composant MarkerComponent: il dispose donc des mêmes inputs et outputs. diff --git a/frontend/src/app/GN2CommonModule/form/form.service.ts b/frontend/src/app/GN2CommonModule/form/form.service.ts index 0ba8be2d2b..881edadb64 100644 --- a/frontend/src/app/GN2CommonModule/form/form.service.ts +++ b/frontend/src/app/GN2CommonModule/form/form.service.ts @@ -4,7 +4,7 @@ import { FormGroup } from '@angular/forms/src/model'; @Injectable() export class FormService { - constructor() {} + constructor() { } dateValidator(dateMinControl: AbstractControl, dateMaxControl: AbstractControl): ValidatorFn { return (formGroup: FormGroup): { [key: string]: boolean } => { @@ -25,6 +25,20 @@ export class FormService { }; } + altitudeValidator(altiMinControl: AbstractControl, altMaxControl: AbstractControl): ValidatorFn { + return (formGroup: FormGroup): { [key: string]: boolean } => { + const altMin = altiMinControl.value; + const altMax = altMaxControl.value; + if (altMin && altMax && (altMin > altMax)) { + return { + invalidAlt: true + }; + } else { + return null; + } + }; + } + hourAndDateValidator( dateMinControl: AbstractControl, dateMaxControl: AbstractControl, @@ -40,8 +54,8 @@ export class FormService { ); return invalidHour ? { - invalidHour: true - } + invalidHour: true + } : null; }; } diff --git a/frontend/src/app/GN2CommonModule/form/multiselect/multiselect.component.ts b/frontend/src/app/GN2CommonModule/form/multiselect/multiselect.component.ts index 9eada5e8ba..3943fe3c45 100644 --- a/frontend/src/app/GN2CommonModule/form/multiselect/multiselect.component.ts +++ b/frontend/src/app/GN2CommonModule/form/multiselect/multiselect.component.ts @@ -19,6 +19,7 @@ export class MultiSelectComponent implements OnInit, OnChanges { public selectedItems = []; public searchControl = new FormControl(); public formControlValue = []; + public savedValues = []; @Input() parentFormControl: FormControl; // value of the dropddown @@ -41,7 +42,7 @@ export class MultiSelectComponent implements OnInit, OnChanges { @Output() onSearch = new EventEmitter(); @Output() onChange = new EventEmitter(); @Output() onDelete = new EventEmitter(); - constructor(private _translate: TranslateService) {} + constructor(private _translate: TranslateService) { } // Component to generate a custom multiselect input with a search bar (which can be disabled) // you can pass whatever callback to the onSearch output, to trigger database research or simple search on an array @@ -82,6 +83,7 @@ export class MultiSelectComponent implements OnInit, OnChanges { if (value === null) { this.selectedItems = []; this.formControlValue = []; + this.values = this.savedValues; } else { if (this.selectedItems.length === 0) { value.forEach(item => { @@ -153,6 +155,7 @@ export class MultiSelectComponent implements OnInit, OnChanges { ngOnChanges(changes) { if (changes.values && changes.values.currentValue) { + this.savedValues = changes.values.currentValue; // remove doublon in the dropdown lists if (this.formControlValue) { this.values = changes.values.currentValue.filter(v => { diff --git a/frontend/src/app/GN2CommonModule/map/leaflet-draw.options.ts b/frontend/src/app/GN2CommonModule/map/leaflet-draw.options.ts index 7f115c9442..25570d2f62 100644 --- a/frontend/src/app/GN2CommonModule/map/leaflet-draw.options.ts +++ b/frontend/src/app/GN2CommonModule/map/leaflet-draw.options.ts @@ -1,22 +1,22 @@ export const leafletDrawOption: any = { - position: 'topleft', - draw: { - polyline: true, - circle: false, // Turns off this drawing tool - circlemarker: false, - rectangle: false, - marker: false, - polygon: { - allowIntersection: false, // Restricts shapes to simple polygons - drawError: { - color: '#e1e100', // Color the shape will turn when intersects - message: 'Intersection forbidden !' // Message that will show when intersect - }, - }, - + position: 'topleft', + draw: { + polyline: true, + circle: false, // Turns off this drawing tool + circlemarker: false, + rectangle: false, + marker: false, + polygon: { + allowIntersection: false, // Restricts shapes to simple polygons + drawError: { + color: '#e1e100', // Color the shape will turn when intersects + message: 'Intersection forbidden !' // Message that will show when intersect }, - edit: { - remove: false, - moveMarker: true - } + }, + + }, + edit: { + remove: false, + moveMarker: true + } }; diff --git a/frontend/src/app/GN2CommonModule/map/leaflet-draw/leaflet-draw.component.ts b/frontend/src/app/GN2CommonModule/map/leaflet-draw/leaflet-draw.component.ts index 4dc75772b2..37913cde26 100644 --- a/frontend/src/app/GN2CommonModule/map/leaflet-draw/leaflet-draw.component.ts +++ b/frontend/src/app/GN2CommonModule/map/leaflet-draw/leaflet-draw.component.ts @@ -22,8 +22,9 @@ export class LeafletDrawComponent implements OnInit, OnChanges { @Input() options = leafletDrawOption; @Input() zoomLevel = MAP_CONFIG.ZOOM_LEVEL_RELEVE; @Output() layerDrawed = new EventEmitter(); + @Output() layerDeleted = new EventEmitter(); - constructor(public mapservice: MapService, private _commonService: CommonService) {} + constructor(public mapservice: MapService, private _commonService: CommonService) { } ngOnInit() { this.map = this.mapservice.map; @@ -85,6 +86,11 @@ export class LeafletDrawComponent implements OnInit, OnChanges { // output this.layerDrawed.emit(geojson); }); + + // on layer deleted + this.map.on(this._Le.Draw.Event.DELETED, (e) => { + this.layerDeleted.emit(); + }); } loadDrawfromGeoJson(geojson) { diff --git a/frontend/src/app/syntheseModule/services/data.service.ts b/frontend/src/app/syntheseModule/services/data.service.ts index c5c2af9ecd..f26bb6a07b 100644 --- a/frontend/src/app/syntheseModule/services/data.service.ts +++ b/frontend/src/app/syntheseModule/services/data.service.ts @@ -100,7 +100,7 @@ export class DataService { let date = new Date(); // FIXME: const DATE_FORMAT, FILENAME_FORMAT // FIXME: (format, mimetype, extension) - const extension = format !== 'shp' ? format : 'zip'; + const extension = format === 'shapefile' ? '.zip' : format; this.saveBlob(this._blob, `${filename}${date.toISOString()}.${extension}`); this.isDownloading = false; subscription.unsubscribe(); diff --git a/frontend/src/app/syntheseModule/services/form.service.ts b/frontend/src/app/syntheseModule/services/form.service.ts index 1cadd4dd56..9c34e8e71d 100644 --- a/frontend/src/app/syntheseModule/services/form.service.ts +++ b/frontend/src/app/syntheseModule/services/form.service.ts @@ -67,6 +67,7 @@ export class SyntheseFormService { const updatedParams = {}; // tslint:disable-next-line:forin for (let key in params) { + console.log(params[key]) if ((key === 'date_min' && params.date_min) || (key === 'date_max' && params.date_max)) { updatedParams[key] = this._dateParser.format(params[key]); } else if ( @@ -74,9 +75,8 @@ export class SyntheseFormService { (key === 'period_start' && params.period_start) ) { updatedParams[key] = this._periodFormatter.format(params[key]); - } else if (params['geoIntersection']) { + } else if (key === 'geoIntersection' && params['geoIntersection']) { updatedParams['geoIntersection'] = stringify(params['geoIntersection']); - // if other key an value not null or undefined } else if (params[key]) { // if its an Array push only if > 0 if (Array.isArray(params[key]) && params[key].length > 0) { diff --git a/frontend/src/app/syntheseModule/synthese-results/synthese-carte/synthese-carte.component.html b/frontend/src/app/syntheseModule/synthese-results/synthese-carte/synthese-carte.component.html index ea5ac80abb..91974cf710 100644 --- a/frontend/src/app/syntheseModule/synthese-results/synthese-carte/synthese-carte.component.html +++ b/frontend/src/app/syntheseModule/synthese-results/synthese-carte/synthese-carte.component.html @@ -7,6 +7,7 @@ + (layerDrawed)="bindGeojsonForm($event)" + (layerDeleted)="deleteControlValue()" > diff --git a/frontend/src/app/syntheseModule/synthese-results/synthese-carte/synthese-carte.component.ts b/frontend/src/app/syntheseModule/synthese-results/synthese-carte/synthese-carte.component.ts index 3fc7f249e3..8d53349caa 100644 --- a/frontend/src/app/syntheseModule/synthese-results/synthese-carte/synthese-carte.component.ts +++ b/frontend/src/app/syntheseModule/synthese-results/synthese-carte/synthese-carte.component.ts @@ -18,12 +18,13 @@ export class SyntheseCarteComponent implements OnInit, AfterViewInit { public mapListService: MapListService, private _ms: MapService, public formService: SyntheseFormService - ) {} + ) { } ngOnInit() { this.leafletDrawOptions.draw.rectangle = true; this.leafletDrawOptions.draw.circle = true; this.leafletDrawOptions.draw.polyline = false; + this.leafletDrawOptions.edit.remove = true; } ngAfterViewInit() { @@ -50,4 +51,10 @@ export class SyntheseCarteComponent implements OnInit, AfterViewInit { this.formService.searchForm.controls.radius.setValue(geojson.properties['radius']); this.formService.searchForm.controls.geoIntersection.setValue(geojson); } + + deleteControlValue() { + console.log('deleeeete') + this.formService.searchForm.controls.geoIntersection.reset(); + this.formService.searchForm.controls.radius.reset(); + } } diff --git a/frontend/src/app/syntheseModule/synthese-results/synthese-list/modal-download/modal-download.component.ts b/frontend/src/app/syntheseModule/synthese-results/synthese-list/modal-download/modal-download.component.ts index 5aad3b51ef..d3e300473d 100644 --- a/frontend/src/app/syntheseModule/synthese-results/synthese-list/modal-download/modal-download.component.ts +++ b/frontend/src/app/syntheseModule/synthese-results/synthese-list/modal-download/modal-download.component.ts @@ -19,13 +19,10 @@ export class SyntheseModalDownloadComponent implements OnInit { @Input() queryString: HttpParams; @Input() tooManyObs = false; - constructor(public activeModal: NgbActiveModal, private _dataService: DataService) {} + constructor(public activeModal: NgbActiveModal, private _dataService: DataService) { } ngOnInit() { this.progress$ = this._dataService.downloadProgress; - // this.progress$.subscribe( state => { - // (state === 100) ? this.done() : null; - // )}; this.progress$.subscribe(state => { if (state === 100) { this.done(); @@ -57,6 +54,7 @@ export class SyntheseModalDownloadComponent implements OnInit { downloadStatus() { this.downloading = true; this.progress(); + this.queryString = this.queryString.delete('limit'); const url = `${AppConfig.API_ENDPOINT}/synthese/statuts`; this._dataService.downloadData(url, 'csv', this.queryString, 'export_synthese_statuts'); } diff --git a/frontend/src/app/syntheseModule/synthese-search/synthese-search.component.html b/frontend/src/app/syntheseModule/synthese-search/synthese-search.component.html index d68fddc066..d8c940b638 100644 --- a/frontend/src/app/syntheseModule/synthese-search/synthese-search.component.html +++ b/frontend/src/app/syntheseModule/synthese-search/synthese-search.component.html @@ -134,7 +134,7 @@ - + {{formService.searchForm.value | json}} diff --git a/frontend/src/assets/i18n/en.json b/frontend/src/assets/i18n/en.json index 6656846def..0b21eda8c4 100644 --- a/frontend/src/assets/i18n/en.json +++ b/frontend/src/assets/i18n/en.json @@ -80,6 +80,7 @@ "Comment": "Comment", "SaveReleve": "Save releve", "DateMaxError": "Max date can't be inferior to the date min", + "AltitudeError": "Altitude max cannot be less than altitude min", "HourMaxError": "End hour can't be inferior to start hour", "SavedTaxon": "Saved taxon(s)", "InfoGeo": "Geographic informations of the releve", diff --git a/frontend/src/assets/i18n/fr.json b/frontend/src/assets/i18n/fr.json index 0e6bcaed68..e501ed1e23 100644 --- a/frontend/src/assets/i18n/fr.json +++ b/frontend/src/assets/i18n/fr.json @@ -81,6 +81,7 @@ "Comment": "Commentaire", "SaveReleve": "Enregistrer le relevé", "DateMaxError": "La date de début ne peut pas être superieure à la date de fin", + "AltitudeError": "L'altitude max ne peut être inférieure à l'altitude min", "HourMaxError": "L'heure de début ne peut pas être supérieure à l'heure de fin", "SavedTaxon": "Taxon(s) enregistré(s)", "InfoGeo": "Informations géographiques du relevé", diff --git a/install/install_all/install_all.ini b/install/install_all/install_all.ini index 6871aa89fd..84cd4923e7 100644 --- a/install/install_all/install_all.ini +++ b/install/install_all/install_all.ini @@ -29,7 +29,7 @@ usershub_release=1.3.2 ### CONFIGURATION GEONATURE ### -geonature_release=develop +geonature_release=2.0.0-rc.1 # Effacer la base de données GeoNature existante lors de l'installation drop_geonaturedb=false # Nom de la base de données GeoNature diff --git a/install/migration/migration.sh b/install/migration/migration.sh index 40ea376960..ae80e57af5 100755 --- a/install/migration/migration.sh +++ b/install/migration/migration.sh @@ -2,13 +2,14 @@ cp /home/$USER/geonature_old/config/settings.ini config/settings.ini +cp /home/$USER/geonature_old/config/geonature_config.toml config/geonature_config.toml cp /home/$USER/geonature_old/frontend/src/conf/map.config.ts frontend/src/conf/map.config.ts cp -r /home/$USER/geonature_old/frontend/src/custom/* frontend/src/custom/ cp -r /home/$USER/geonature_old/external_modules/* external_modules cp -r /home/$USER/geonature_old/frontend/src/external_assets/* frontend/src/external_assets/ -mkdir $geonature_dir/var -mkdir $geonature_dir/var/log +mkdir /home/$USER/geonature/var +mkdir /home/$USER/geonature/var/log # Création du répertoitre static et rapattriement des médias if [ ! -d 'backend/static/' ]