diff --git a/atlas/atlasRoutes.py b/atlas/atlasRoutes.py index 680c1f1c..f0d46561 100644 --- a/atlas/atlasRoutes.py +++ b/atlas/atlasRoutes.py @@ -298,7 +298,7 @@ def ficheArea(id_area): connection, id_area ) nb_organism = vmOrganismsRepository.get_nb_organism_on_area(connection, id_area) - infosCommune = vmAreasRepository.get_infos_area(connection, id_area) + infos_area = vmAreasRepository.get_infos_area(connection, id_area) area = tAreasRepository.getAreaFromIdArea(connection, id_area) if current_app.config["AFFICHAGE_MAILLE"]: @@ -314,6 +314,19 @@ def ficheArea(id_area): observers = vmObservationsRepository.getObserversArea(connection, id_area) + biodiversity_values_chart = vmAreasRepository.get_nb_species_by_taxonimy_group( + connection, id_area + ) + observations_values_chart = vmAreasRepository.get_nb_observations_by_taxonimy_group( + connection, id_area + ) + biodiversity_organism_values_chart = vmOrganismsRepository.get_nb_species_by_organism_on_area( + connection, id_area + ) + observations_organism_values_chart = ( + vmOrganismsRepository.get_nb_observations_by_organism_on_area(connection, id_area) + ) + session.close() connection.close() @@ -328,7 +341,11 @@ def ficheArea(id_area): id_area=id_area, taxonProPatri=taxon_pro_patri, nb_organism=nb_organism, - infosCommune=infosCommune, + infos_area=infos_area, + biodiversity_values_chart=biodiversity_values_chart, + observations_values_chart=observations_values_chart, + biodiversity_organism_values_chart=biodiversity_organism_values_chart, + observations_organism_values_chart=observations_organism_values_chart, ) diff --git a/atlas/configuration/config_schema.py b/atlas/configuration/config_schema.py index e1e292cd..c2f96807 100644 --- a/atlas/configuration/config_schema.py +++ b/atlas/configuration/config_schema.py @@ -131,14 +131,23 @@ class Meta: AFFICHAGE_LOGOS_HOME = fields.Boolean(load_default=True) AFFICHAGE_FOOTER = fields.Boolean(load_default=True) AFFICHAGE_RGPD = fields.Boolean(load_default=True) + OREJIME_APPS = fields.List(fields.Dict(), load_default=[]) AFFICHAGE_STAT_GLOBALES = fields.Boolean(load_default=True) AFFICHAGE_DERNIERES_OBS = fields.Boolean(load_default=True) + AFFICHAGE_TERRITOIRE_OBS = fields.Boolean(load_default=False) AFFICHAGE_EN_CE_MOMENT = fields.Boolean(load_default=True) AFFICHAGE_RANG_STAT = fields.Boolean(load_default=True) AFFICHAGE_NOUVELLES_ESPECES = fields.Boolean(load_default=True) AFFICHAGE_RECHERCHE_AVANCEE = fields.Boolean(load_default=False) AFFICHAGE_GRAPH_ALTITUDES = fields.Boolean(load_default=True) - AFFICHAGE_GRAPH_PHENOLOGIE = fields.Boolean(load_default=True) + AFFICHAGE_GRAPH_PHENOLOGIE = fields.Boolean(load_default=False) + AFFICHAGE_GRAPH_PROVENANCE_DONNEE = fields.Boolean(load_default=False) + AFFICHAGE_GRAPH_AREA_GENERAL_PRESENTATION = fields.Boolean(load_default=False) + AFFICHAGE_GRAPH_AREA_OBS_ESPECES = fields.Boolean(load_default=False) + AFFICHAGE_GRAPH_AREA_PROVENANCE_DONNEE = fields.Boolean(load_default=False) + COLOR_STACKED_BAR_CHARTS = fields.List( + fields.String(), load_default=["#E1CE7A", "#FBFFB9", "#FDD692"] + ) RANG_STAT = fields.List( fields.Dict, @@ -195,6 +204,7 @@ class Meta: ) AFFICHAGE_MAILLE = fields.Boolean(load_default=False) + TYPES_TERRITOIRE = fields.List(fields.String(), load_default=["COM"]) ZOOM_LEVEL_POINT = fields.Integer(load_default=11) LIMIT_CLUSTER_POINT = fields.Integer(load_default=1000) NB_DAY_LAST_OBS = fields.String(load_default="7") diff --git a/atlas/messages.pot b/atlas/messages.pot index dac997b1..07823db9 100644 --- a/atlas/messages.pot +++ b/atlas/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2025-01-09 21:50+0100\n" +"POT-Creation-Date: 2025-01-21 16:02+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -49,10 +49,6 @@ msgstr "" msgid "personal_data" msgstr "" -#: atlas/static/custom/templates/footer.html:12 -msgid "preferences_cookies" -msgstr "" - #: atlas/static/custom/templates/footer.html:18 #: atlas/static/custom/templates/footer.html.sample:17 msgid "atlas.fauna.flora" @@ -117,8 +113,11 @@ msgid "search.species" msgstr "" #: atlas/static/custom/templates/navbar.html:47 -#: atlas/static/custom/templates/navbar.html.sample:47 #: atlas/templates/home/globalStats.html:55 +msgid "search.area" +msgstr "" + +#: atlas/static/custom/templates/navbar.html.sample:47 msgid "search.zone" msgstr "" @@ -127,12 +126,34 @@ msgstr "" msgid "atlas.presentation" msgstr "" -#: atlas/templates/areaSheet/_main.html:63 +#: atlas/templates/areaSheet/_main.html:73 msgid "last.obs.zone" msgstr "" +#: atlas/templates/areaSheet/moreZoneInfo.html:5 +msgid "general_presentation" +msgstr "" + +#: atlas/templates/areaSheet/moreZoneInfo.html:7 +msgid "observations_and_species" +msgstr "" + +#: atlas/templates/areaSheet/moreZoneInfo.html:8 +msgid "data_sources" +msgstr "" + +#: atlas/templates/areaSheet/moreZoneInfo.html:19 +#: atlas/templates/areaSheet/moreZoneInfo.html:35 +msgid "Biodiversity" +msgstr "" + +#: atlas/templates/areaSheet/moreZoneInfo.html:26 +#: atlas/templates/areaSheet/moreZoneInfo.html:42 +msgid "Observations" +msgstr "" + #: atlas/templates/areaSheet/surrounding_areas.html:10 -msgid "associate.zone" +msgid "associate.area" msgstr "" #: atlas/templates/areaSheet/surrounding_areas.html:23 @@ -197,7 +218,7 @@ msgid "check.species.sheet" msgstr "" #: atlas/templates/core/extended_areas_search.html:13 -msgid "search.other.zones.type" +msgid "search.other.areas.type" msgstr "" #: atlas/templates/core/listTaxons.html:14 @@ -217,7 +238,7 @@ msgid "this.taxon.has.a.protected.status" msgstr "" #: atlas/templates/core/listTaxons.html:80 -#: atlas/templates/core/statHierarchy.html:7 +#: atlas/templates/core/statHierarchy.html:8 #: atlas/templates/organismSheet/topSpecies.html:61 #: atlas/templates/speciesSheet/map.html:15 #: atlas/templates/speciesSheet/otherInformations.html:144 @@ -225,7 +246,7 @@ msgid "observation" msgstr "" #: atlas/templates/core/listTaxons.html:81 -#: atlas/templates/core/statHierarchy.html:7 +#: atlas/templates/core/statHierarchy.html:8 #: atlas/templates/core/tabTaxons.html:19 #: atlas/templates/home/globalStats.html:16 #: atlas/templates/organismSheet/statsInfos.html:11 @@ -255,46 +276,46 @@ msgstr "" msgid "gallery.title" msgstr "" -#: atlas/templates/core/statHierarchy.html:12 +#: atlas/templates/core/statHierarchy.html:13 #: atlas/templates/home/globalStats.html:28 #: atlas/templates/home/taxoRank.html:32 #: atlas/templates/organismSheet/statsInfos.html:21 msgid "species" msgstr "" -#: atlas/templates/core/statHierarchy.html:17 +#: atlas/templates/core/statHierarchy.html:18 #: atlas/templates/speciesSheet/map.html:25 #: atlas/templates/speciesSheet/otherInformations.html:28 msgid "observers" msgstr "" -#: atlas/templates/core/statHierarchy.html:17 +#: atlas/templates/core/statHierarchy.html:18 #: atlas/templates/speciesSheet/map.html:25 #: atlas/templates/speciesSheet/otherInformations.html:28 msgid "observer" msgstr "" -#: atlas/templates/core/statHierarchy.html:23 +#: atlas/templates/core/statHierarchy.html:24 msgid "sources" msgstr "" -#: atlas/templates/core/statHierarchy.html:23 +#: atlas/templates/core/statHierarchy.html:24 msgid "source" msgstr "" -#: atlas/templates/core/statHierarchy.html:28 +#: atlas/templates/core/statHierarchy.html:29 msgid "first_observation" msgstr "" -#: atlas/templates/core/statHierarchy.html:33 +#: atlas/templates/core/statHierarchy.html:34 msgid "last_observation" msgstr "" -#: atlas/templates/core/statHierarchy.html:38 +#: atlas/templates/core/statHierarchy.html:39 msgid "protected_species" msgstr "" -#: atlas/templates/core/statHierarchy.html:44 +#: atlas/templates/core/statHierarchy.html:45 msgid "patrimonial_species" msgstr "" @@ -339,10 +360,9 @@ msgid "home.seelatestobs" msgstr "" #: atlas/templates/home/globalStats.html:47 -#: atlas/templates/speciesSheet/map.html:20 #: atlas/templates/speciesSheet/otherInformations.html:10 #: atlas/templates/speciesSheet/otherInformations.html:14 -msgid "municipalities" +msgid "territories" msgstr "" #: atlas/templates/home/globalStats.html:67 @@ -482,7 +502,7 @@ msgstr "" #: atlas/templates/speciesSheet/map.html:20 #: atlas/templates/speciesSheet/otherInformations.html:10 #: atlas/templates/speciesSheet/otherInformations.html:14 -msgid "municipality" +msgid "territory" msgstr "" #: atlas/templates/speciesSheet/map.html:29 diff --git a/atlas/modeles/repositories/tAreasRepository.py b/atlas/modeles/repositories/tAreasRepository.py index edbaae93..f76d3346 100644 --- a/atlas/modeles/repositories/tAreasRepository.py +++ b/atlas/modeles/repositories/tAreasRepository.py @@ -5,6 +5,7 @@ from sqlalchemy import distinct from sqlalchemy.sql import text from sqlalchemy.sql.expression import func +from flask import current_app from atlas.modeles.entities.vmAreas import VmAreas @@ -73,10 +74,14 @@ def getAreasObservationsChilds(connection, cd_ref): FROM atlas.vm_observations AS obs JOIN atlas.vm_l_areas AS area ON st_intersects(obs.the_geom_point, area.the_geom) - WHERE obs.cd_ref = ANY(:taxonsList) + WHERE obs.cd_ref = ANY(:taxonsList) AND area.id_type IN + (SELECT id_type FROM atlas.vm_bib_areas_types + WHERE type_code = ANY(:list_id_type)) ORDER BY area.area_name ASC """ - results = connection.execute(text(sql), taxonsList=taxons) + results = connection.execute( + text(sql), taxonsList=taxons, list_id_type=current_app.config["TYPE_TERRITOIRE"] + ) municipalities = list() for r in results: municipality = {"id_area": r.id_area, "area_name": r.area_name} diff --git a/atlas/modeles/repositories/tZonesRepository.py b/atlas/modeles/repositories/tZonesRepository.py deleted file mode 100644 index 5717f876..00000000 --- a/atlas/modeles/repositories/tZonesRepository.py +++ /dev/null @@ -1,40 +0,0 @@ - - -def get_infos_zone(connection, id_zone): - """ - Get zone info: - yearmin: fisrt observation year - yearmax: last observation year - id_parent: id parent zone - area_name: name parent zone - area_type_name: type parent zone - """ - sql = """ -SELECT - MIN(extract(YEAR FROM o.dateobs)) AS yearmin, - MAX(extract(YEAR FROM o.dateobs)) AS yearmax, - z.id_parent, - (SELECT area_name FROM atlas.zoning WHERE id_zone = z.id_parent) AS area_parent_name, - (SELECT type.type_name - FROM atlas.zoning AS zone - JOIN ref_geo.bib_areas_types type - ON type.id_type = zone.id_zoning_type - WHERE zone.id_zone = z.id_parent) AS area_parent_type_name -FROM atlas.vm_observations o - JOIN atlas.zoning z ON z.id_zone = o.id_zone -WHERE o.id_zone = :id_zone -GROUP BY z.id_parent - """ - - result = connection.execute(text(sql), id_zone=id_zone) - info_zone = dict() - for r in result: - info_zone = { - "yearmin": r.yearmin, - "yearmax": r.yearmax, - "id_parent": r.id_parent, - "parent_name": r.area_parent_name, - "parent_type_name": r.area_parent_type_name, - } - - return info_zone diff --git a/atlas/modeles/repositories/vmAreasRepository.py b/atlas/modeles/repositories/vmAreasRepository.py index c5811118..9f0d40de 100644 --- a/atlas/modeles/repositories/vmAreasRepository.py +++ b/atlas/modeles/repositories/vmAreasRepository.py @@ -44,101 +44,6 @@ def get_id_area(session, type_code, area_code): except Exception as e: current_app.logger.error(" error {}".format(e)) -# -# def last_observations_area_maille(session, myLimit, idArea): -# """Fonction a priori non utilisée à supprimer""" -# q_last_obs = ( -# session.query( -# # VmObservations.cd_ref.label("cd_ref"), -# # VmObservations.dateobs.label("dateobs"), -# # VmTaxons.lb_nom.label("lb_nom"), -# # VmTaxons.nom_vern.label("nom_vern"), -# # VmObservations.the_geom_point.label("the_geom_point"), -# VmObservations.cd_ref, -# VmObservations.dateobs, -# VmTaxons.lb_nom, -# VmTaxons.nom_vern, -# VmObservations.the_geom_point, -# ) -# .join( -# VmCorAreaObservation, -# VmObservations.id_observation == VmCorAreaObservation.id_observation, -# ) -# .join(VmAreas, VmAreas.id_area == VmCorAreaObservation.id_area) -# .join(VmTaxons, VmTaxons.cd_ref == VmObservations.cd_ref) -# .filter(VmAreas.id_area == idArea) -# .order_by(VmObservations.dateobs.desc()) -# .limit(myLimit) -# .subquery() -# ) -# current_app.logger.debug( -# " subquery q_last_obs: {}".format(q_last_obs) -# ) -# -# q_mailles_obs = ( -# session.query( -# TGrid.id_maille, -# q_last_obs.c.lb_nom, -# q_last_obs.c.cd_ref, -# q_last_obs.c.nom_vern, -# func.st_asgeojson(TGrid.the_geom).label("geojson_maille"), -# ) -# .join(q_last_obs, q_last_obs.c.the_geom_point.st_intersects(TGrid.the_geom)) -# .group_by( -# q_last_obs.c.lb_nom, -# q_last_obs.c.cd_ref, -# q_last_obs.c.nom_vern, -# TGrid.id_maille, -# TGrid.the_geom, -# ) -# ) -# -# current_app.logger.debug( -# " query q_mailles_obs: {}".format(q_mailles_obs) -# ) -# current_app.logger.debug( -# " start query: {}".format(datetime.now()) -# ) -# result = q_mailles_obs.all() -# current_app.logger.debug( -# " start loop: {}".format(datetime.now()) -# ) -# obsList = list() -# for o in result: -# if o.nom_vern: -# taxon = o.nom_vern + " | " + o.lb_nom + "" -# else: -# taxon = "" + o.lb_nom + "" -# temp = { -# "cd_ref": o.cd_ref, -# "taxon": taxon, -# "geojson_maille": json.loads(o.geojson_maille), -# "id_maille": o.id_maille, -# } -# obsList.append(temp) -# current_app.logger.debug(" end loop: {}".format(datetime.now())) -# return obsList - -# -# def get_observers_area(session, idArea): -# q_list_observers = ( -# session.query( -# func.trim(func.unnest(func.string_to_array(VmObservations.observateurs, ","))).label( -# "observateurs" -# ) -# ) -# .join( -# VmCorAreaObservation, -# VmObservations.id_observation == VmCorAreaObservation.id_observation, -# ) -# .filter(VmCorAreaObservation.id_area == idArea) -# ).subquery() -# -# query = session.query(q_list_observers.c.observateurs).group_by( -# q_list_observers.c.observateurs -# ) -# return query.all() - def search_area_by_type(session, search, type_code, limit=50): query = ( @@ -157,7 +62,7 @@ def search_area_by_type(session, search, type_code, limit=50): ), ) ) - print(limit) + query = query.limit(limit) current_app.logger.debug(" query {}".format(query)) @@ -167,62 +72,6 @@ def search_area_by_type(session, search, type_code, limit=50): areaList.append(temp) return areaList -# -# def get_areas_observations(session, id_area): -# query = ( -# session.query( -# VmObservations.id_observation, -# VmTaxref.nom_vern, -# VmTaxref.lb_nom, -# VmTaxref.group2_inpn, -# VmObservations.dateobs, -# VmObservations.observateurs, -# func.st_asgeojson(VmObservations.the_geom_point).label("geometry"), -# ) -# .join(VmTaxref, VmTaxref.cd_nom == VmObservations.cd_ref) -# .join( -# VmCorAreaObservation, -# VmObservations.id_observation == VmCorAreaObservation.id_observation, -# ) -# .filter(VmCorAreaObservation.id_area == id_area) -# ).all() -# result = [] -# for r in query: -# temp = r._asdict() -# temp["geometry"] = json.loads(r.geometry or "{}") -# temp["dateobs"] = str(r.dateobs) -# temp["group2_inpn"] = utils.deleteAccent(r.group2_inpn) -# result.append(temp) -# return result - - -# def get_areas_observations_by_cdnom(session, id_area): -# req = ( -# session.query( -# VmObservations.id_observation, -# VmTaxref.nom_vern, -# VmTaxref.lb_nom, -# VmTaxref.group2_inpn, -# VmObservations.dateobs, -# VmObservations.observateurs, -# func.st_asgeojson(VmObservations.the_geom_point).label("geometry"), -# ) -# .join(VmTaxref, VmTaxref.cd_nom == VmObservations.cd_ref) -# .join( -# VmCorAreaObservation, -# VmObservations.id_observation == VmCorAreaObservation.id_observation, -# ) -# .filter(VmCorAreaObservation.id_area == id_area) -# ).all() -# result = [] -# for r in req: -# temp = r._asdict() -# temp["geometry"] = json.loads(r.geometry or "{}") -# temp["dateobs"] = str(r.dateobs) -# temp["group2_inpn"] = utils.deleteAccent(r.group2_inpn) -# result.append(temp) -# return result - def get_areas_grid_observations_by_cdnom(session, id_area, cd_nom): query = ( @@ -251,59 +100,6 @@ def get_areas_grid_observations_by_cdnom(session, id_area, cd_nom): return tabObs -def get_area_taxa(session, id_area): - query = ( - session.query( - VmTaxons.cd_ref, - VmTaxons.nom_vern, - VmTaxons.nom_complet_html, - VmTaxons.group2_inpn, - VmTaxons.patrimonial, - VmTaxons.protection_stricte, - VmMedias.url, - VmMedias.chemin, - func.count(VmObservations.id_observation).label("nb_obs"), - func.max(func.extract("year", VmObservations.dateobs)).label("last_obs"), - ) - .join(VmTaxons, VmTaxons.cd_ref == VmObservations.cd_ref) - .join( - VmCorAreaObservation, - VmObservations.id_observation == VmCorAreaObservation.id_observation, - ) - .outerjoin( - VmMedias, - and_( - VmMedias.cd_ref == VmObservations.cd_ref, - VmMedias.id_type == current_app.config["ATTR_MAIN_PHOTO"], - ), - ) - .filter(VmCorAreaObservation.id_area == id_area) - .group_by( - VmTaxons.cd_ref, - VmTaxons.nom_vern, - VmTaxons.nom_complet_html, - VmTaxons.group2_inpn, - VmTaxons.patrimonial, - VmTaxons.protection_stricte, - VmMedias.url, - VmMedias.chemin, - ) - .order_by(-func.count(VmObservations.id_observation)) - ) - current_app.logger.debug(" QUERY: {}".format(query)) - current_app.logger.debug(" start loop: {}".format(datetime.now())) - result = [] - nbObsTotal = 0 - for r in query.all(): - temp = r._asdict() - temp["group2_inpn"] = utils.deleteAccent(r.group2_inpn) - temp["path"] = utils.findPath(r) - nbObsTotal = nbObsTotal + r.nb_obs - result.append(temp) - current_app.logger.debug(" end loop: {}".format(datetime.now())) - return {"taxons": result, "nbObsTotal": nbObsTotal} - - def get_surrounding_areas(session, id_area): subquery = session.query(VmAreas.the_geom).filter(VmAreas.id_area == id_area).subquery() @@ -321,6 +117,7 @@ def get_surrounding_areas(session, id_area): return query.all() + def get_infos_area(connection, id_area): """ Get area info: @@ -333,17 +130,19 @@ def get_infos_area(connection, id_area): sql = """ SELECT MIN(extract(YEAR FROM o.dateobs)) AS yearmin, - MAX(extract(YEAR FROM o.dateobs)) AS yearmax - -- z.id_parent, - -- (SELECT area_name FROM atlas.vm_l_areas WHERE id_area = z.id_parent) AS area_parent_name, - -- (SELECT type.type_name - -- FROM atlas.vm_l_areas AS area - -- JOIN ref_geo.bib_areas_types type - -- ON type.id_type = area.id_zoning_type - -- WHERE area.id_area = z.id_parent) AS area_parent_type_name -FROM atlas.vm_observations o JOIN atlas.vm_l_areas z ON z.id_area = o.id_area -WHERE o.id_area = :id_area ---GROUP BY z.id_parent + MAX(extract(YEAR FROM o.dateobs)) AS yearmax, + area.description, + ca.id_area_group AS id_parent, + (SELECT area_name FROM atlas.vm_l_areas WHERE id_area = ca.id_area_group) AS area_parent_name, + (SELECT type.type_name + FROM atlas.vm_l_areas l + JOIN atlas.vm_bib_areas_types type ON type.id_type = l.id_type + WHERE l.id_area = ca.id_area_group) AS area_parent_type_name +FROM atlas.vm_observations o + JOIN atlas.vm_l_areas area ON st_intersects(o.the_geom_point, area.the_geom) + JOIN atlas.vm_cor_areas ca ON ca.id_area = area.id_area +WHERE area.id_area = :id_area +GROUP BY area.description,ca.id_area_group; """ result = connection.execute(text(sql), id_area=id_area) @@ -352,9 +151,60 @@ def get_infos_area(connection, id_area): info_area = { "yearmin": r.yearmin, "yearmax": r.yearmax, - # "id_parent": r.id_parent, - # "parent_name": r.area_parent_name, - # "parent_type_name": r.area_parent_type_name, + "description": r.description, + "id_parent": r.id_parent, + "parent_name": r.area_parent_name, + "parent_type_name": r.area_parent_type_name, } return info_area + + +def get_nb_species_by_taxonimy_group(connection, id_area): + """ + Get number of species by taxonimy group: + """ + sql = """ + SELECT + COUNT(DISTINCT o.cd_ref) AS nb_species, + t.group2_inpn, + COUNT(DISTINCT case t.patrimonial when 'oui' then t.cd_ref else null end) AS nb_patrominal, + (SELECT COUNT(*) + FROM atlas.vm_taxons taxon + WHERE taxon.group2_inpn = t.group2_inpn) AS nb_species_in_teritory + from atlas.vm_observations o + JOIN atlas.vm_l_areas area ON st_intersects(o.the_geom_point, area.the_geom) + FULL JOIN atlas.vm_taxons t ON t.cd_ref = o.cd_ref +WHERE area.id_area = :id_area +GROUP BY t.group2_inpn + """ + + result = connection.execute(text(sql), id_area=id_area) + info_chart = dict() + for r in result: + info_chart[r.group2_inpn] = { + "nb_species": r.nb_species - r.nb_patrominal, + "nb_patrimonial": r.nb_patrominal, + "nb_species_in_teritory": r.nb_species_in_teritory - r.nb_species, + } + return info_chart + + +def get_nb_observations_by_taxonimy_group(connection, id_area): + """ + Get number of species by taxonimy group: + """ + sql = """ +SELECT COUNT(o.id_observation) AS nb_observations, t.group2_inpn +from atlas.vm_observations o +JOIN atlas.vm_taxons t ON t.cd_ref = o.cd_ref +JOIN atlas.vm_l_areas area ON st_intersects(o.the_geom_point, area.the_geom) +WHERE area.id_area = :id_area +GROUP BY t.group2_inpn, area.id_area + """ + + result = connection.execute(text(sql), id_area=id_area) + info_chart = dict() + for r in result: + info_chart[r.group2_inpn] = r.nb_observations + return info_chart diff --git a/atlas/modeles/repositories/vmOrganismsRepository.py b/atlas/modeles/repositories/vmOrganismsRepository.py index 72492219..bd2a21ba 100644 --- a/atlas/modeles/repositories/vmOrganismsRepository.py +++ b/atlas/modeles/repositories/vmOrganismsRepository.py @@ -91,13 +91,55 @@ def getTaxonRepartitionOrganism(connection, id_organism): def get_nb_organism_on_area(connection, id_area): - sql = """SELECT DISTINCT COUNT(cto.nom_organism) AS nb_organism -FROM atlas.vm_observations o -JOIN atlas.vm_cor_taxon_organism cto ON cto.cd_ref = o.cd_ref -WHERE o.id_area = :id_area + sql = """SELECT COUNT(DISTINCT cto.nom_organism) AS nb_organism +FROM atlas.vm_observations obs + JOIN gn_meta.cor_dataset_actor AS rcda + ON obs.id_dataset = rcda.id_dataset + JOIN atlas.vm_cor_taxon_organism cto ON rcda.id_organism = cto.id_organism + JOIN atlas.vm_l_areas area ON st_intersects(obs.the_geom_point, area.the_geom) +WHERE area.id_area = :id_area; """ res = connection.execute(text(sql), id_area=id_area) result = dict() for r in res: result = r.nb_organism return result + + +def get_nb_species_by_organism_on_area(connection, id_area): + sql = """ +SELECT COUNT(DISTINCT obs.cd_ref) AS nb_species, cto.nom_organism +FROM atlas.vm_observations obs + JOIN gn_meta.cor_dataset_actor AS rcda + ON obs.id_dataset = rcda.id_dataset + JOIN atlas.vm_cor_taxon_organism cto ON rcda.id_organism = cto.id_organism + JOIN atlas.vm_l_areas area ON st_intersects(obs.the_geom_point, area.the_geom) +WHERE area.id_area = :id_area +GROUP BY cto.nom_organism +ORDER BY cto.nom_organism; + """ + result = connection.execute(text(sql), id_area=id_area) + list_species_by_organism = list() + for r in result: + temp = {"nb": r.nb_species, "label": r.nom_organism} + list_species_by_organism.append(temp) + return list_species_by_organism + + +def get_nb_observations_by_organism_on_area(connection, id_area): + sql = """ +SELECT COUNT(obs.id_observation) AS nb_observations, b.nom_organisme +FROM atlas.vm_observations obs + JOIN gn_meta.cor_dataset_actor AS rcda ON obs.id_dataset = rcda.id_dataset + JOIN utilisateurs.bib_organismes b ON b.id_organisme = rcda.id_organism + JOIN atlas.vm_l_areas area ON st_intersects(obs.the_geom_point, area.the_geom) +WHERE area.id_area = :id_area +GROUP BY b.nom_organisme +ORDER BY b.nom_organisme; + """ + result = connection.execute(text(sql), id_area=id_area) + list_observations_by_organism = list() + for r in result: + temp = {"nb": r.nb_observations, "label": r.nom_organisme} + list_observations_by_organism.append(temp) + return list_observations_by_organism diff --git a/atlas/static/chart.js b/atlas/static/chart.js index 57b54678..8fa18421 100644 --- a/atlas/static/chart.js +++ b/atlas/static/chart.js @@ -40,16 +40,201 @@ genericChart = function (element, labels, values) { maintainAspectRatio: false, plugins: { legend: { - position: 'top', - display: false + position: 'top', + display: false }, } } }); }; -var monthChartElement = document.getElementById('monthChart'); -const monthChart = genericChart(monthChartElement, months_name, getChartDatas(months_value, 'value')); +pieChartConfig = function (element, data) { + return new Chart(element, { + type: 'doughnut', + data: data, + options: { + responsive: true, + cutout: "30%", + maintainAspectRatio: false, + plugins: { + legend: { + position: 'top', + }, + title: { + display: false, + text: 'Graphique des provenances de données' + } + } + } + }) +} + +function formatPieData(data) { + let labels = [] + let data_count = [] + Object.keys(data).forEach(key => { + labels.push(key) + data_count.push(data[key]) + }) + + return { + labels: labels, + datasets: [ + { + label: 'Dataset 1', + data: data_count, + backgroundColor: configuration.COLOR_PIE_CHARTS, + hoverOffset: 25 + } + ] + } +} + +function stackedBarChartConfig(element, data) { + return new Chart(element, { + type: 'bar', + data: data, + options: { + plugins: { + title: { + display: false + }, + }, + responsive: true, + maintainAspectRatio: true, + interaction: { + intersect: false, + }, + scales: { + x: { + stacked: true, + }, + y: { + stacked: true + } + }, + borderRadius: '5', + barThickness: '20', + indexAxis: 'y', + } + }); +} + +function formatStackedBarChart(values, element) { + const labels = [] + const nb_species = [] + const nb_patrimonial = [] + const nb_species_in_teritory = [] + Object.keys(values).forEach(key => { + labels.push(key) + nb_species.push(values[key].nb_species) + nb_patrimonial.push(values[key].nb_patrimonial) + nb_species_in_teritory.push(values[key].nb_species_in_teritory) + }) + const data = { + labels: labels, + datasets: [ + { + label: "Espèces", + data: nb_species, + backgroundColor: [configuration.COLOR_STACKED_BAR_CHARTS[0]], + stack: "0", + }, + { + label: "Patrimonial", + data: nb_patrimonial, + backgroundColor: [configuration.COLOR_STACKED_BAR_CHARTS[1]], + stack: "0", + }, + { + label: "Nombre d'espèces total sur le territoire", + data: nb_species_in_teritory, + backgroundColor: [configuration.COLOR_STACKED_BAR_CHARTS[2]], + stack: "0", + } + ] + }; + + return data +} + +function barChartConfig(element, data) { + return new Chart(element, { + type: 'bar', + data: data, + options: { + plugins: { + title: { + display: false + }, + }, + responsive: true, + maintainAspectRatio: true, + borderRadius: '5', + barThickness: '20', + indexAxis: 'x', + } + }); +} + +function formatBarChart(values, element, dataName) { + const labels = [] + const nb_elem = [] + values.forEach(value => { + labels.push(value.label) + nb_elem.push(value.nb) + }) + + const data = { + labels: labels, + datasets: [ + { + label: dataName, + data: nb_elem, + backgroundColor: chartMainColor, + stack: "0", + } + ] + }; + + return data +} + +var monthChartElement = document.getElementById('monthChart'); +if (monthChartElement) { + const monthChart = genericChart(monthChartElement, months_name, getChartDatas(months_value, 'value')); +} var altiChartElement = document.getElementById('altiChart'); -const altiChart = genericChart(altiChartElement, getChartDatas(dataset, 'altitude'), getChartDatas(dataset, 'value')); +if (altiChartElement) { + const altiChart = genericChart(altiChartElement, getChartDatas(dataset, 'altitude'), getChartDatas(dataset, 'value')); +} + +const dataSourceChartElement = document.getElementById('organismChart'); +if (dataSourceChartElement) { + const organismChart = pieChartConfig(dataSourceChartElement, formatPieData(data_source_values, dataSourceChartElement)); +} + +// Onglet observations et espèces + +const biodiversityChartElement = document.getElementById('biodiversityChart'); +if (biodiversityChartElement) { + const organismChart = stackedBarChartConfig(biodiversityChartElement, formatStackedBarChart(biodiversity_values_chart, biodiversityChartElement)); +} + +const observationsChartElement = document.getElementById('observationsChart'); +if (observationsChartElement) { + const organismChart = pieChartConfig(observationsChartElement, formatPieData(observations_values_chart, observationsChartElement)); +} + +// Onglet provenance des données + +const biodiversityByTerritoryChartElement = document.getElementById('biodiversity_by_territoryChart'); +if (biodiversityByTerritoryChartElement) { + const organismChart = barChartConfig(biodiversityByTerritoryChartElement, formatBarChart(biodiversity_organism_values_chart, biodiversityByTerritoryChartElement, "Espèces")); +} + +const observationsByTerritoryChartElement = document.getElementById('observations_by_territoryChart'); +if (observationsByTerritoryChartElement) { + const organismChart = barChartConfig(observationsByTerritoryChartElement, formatBarChart(observations_organism_values_chart, observationsByTerritoryChartElement, "Observations")); +} diff --git a/atlas/static/css/territorySheet.css b/atlas/static/css/territorySheet.css index 43b98fa0..e887a78f 100644 --- a/atlas/static/css/territorySheet.css +++ b/atlas/static/css/territorySheet.css @@ -1,3 +1,34 @@ +.card.container { + align-items: center; + padding: 1rem; + max-width: 100%; + &.stat_card { + align-items: center; + } + &.info_card { + align-items: self-start; + } + .tab-content { + padding: 1rem; + width: 100%; + + #observations_and_species.active { + text-align: center; + display: flex; + flex-wrap: wrap; + justify-content: space-around; + } + + #data_sources.active { + text-align: center; + display: flex; + flex-wrap: wrap; + justify-content: space-around; + } + } +} + + img.patrimonial_img { width: 1rem; } @@ -6,6 +37,10 @@ img.patrimonial_img { width: 100%; justify-items: center; padding: 1rem; + +} +.specie_list_map_block { + min-height: 50%; } .specie_list_map_block { diff --git a/atlas/templates/areaSheet/_main.html b/atlas/templates/areaSheet/_main.html index e225c4ac..ddd57492 100644 --- a/atlas/templates/areaSheet/_main.html +++ b/atlas/templates/areaSheet/_main.html @@ -10,6 +10,8 @@ {% endblock %} {% block additionalHeaderAssets %} + + {# Ajoutez ici les assets complémentaires qui seront dans le bloc #} @@ -30,11 +32,17 @@ var observations = {{observations|tojson}}; var areaInfos = {{ areaInfos | tojson }}; var url_limit_territory = "{{url_for('static', filename='custom/territoire.json') }}"; + var biodiversity_values_chart = {{ biodiversity_values_chart | tojson}}; + var observations_values_chart = {{ observations_values_chart | tojson}}; + var biodiversity_organism_values_chart = {{ biodiversity_organism_values_chart | tojson}}; + var observations_organism_values_chart = {{ observations_organism_values_chart | tojson}}; + + {% endblock %} @@ -44,11 +52,15 @@
-

{{ areaInfos.typeName }} - {{ areaInfos.areaName }}

{% include 'templates/core/statHierarchy.html' %}
+ {% if configuration.AFFICHAGE_GRAPH_AREA_GENERAL_PRESENTATION or configuration.AFFICHAGE_GRAPH_AREA_OBS_ESPECES or configuration.AFFICHAGE_GRAPH_AREA_PROVENANCE_DONNEE %} +
+ {% include 'templates/areaSheet/moreZoneInfo.html' %} +
+ {% endif %}
-
+
diff --git a/atlas/templates/areaSheet/moreZoneInfo.html b/atlas/templates/areaSheet/moreZoneInfo.html new file mode 100644 index 00000000..e56894cc --- /dev/null +++ b/atlas/templates/areaSheet/moreZoneInfo.html @@ -0,0 +1,67 @@ +{% block moreZoneInfos %} +
+ + +
+ {% if configuration.AFFICHAGE_GRAPH_AREA_GENERAL_PRESENTATION%} +
+ {% if infos_area.description %} + {{ infos_area.description | safe }} + {% else %} + {{ _('not.resigned.for.the.moment') }} + {% endif %} +
+ {% endif %} + {% if configuration.AFFICHAGE_GRAPH_AREA_OBS_ESPECES%} +
+
+

{{ _('Biodiversity') }}

+
Nombre d'espèces par groupe taxonomique
+
+ +
+
+
+

{{ _('Observations') }}

+
Nombre d'observations par groupe taxonomique
+
+ +
+
+
+ {% endif %} + {% if configuration.AFFICHAGE_GRAPH_AREA_PROVENANCE_DONNEE%} +
+
+

{{ _('Biodiversity') }}

+
Nombre d'espèces sur le territoire par source de données
+
+ +
+
+
+

{{ _('Observations') }}

+
Nombre d'observations sur le territoire par source de données
+
+ +
+
+
+ {% endif %} +
+
+{% endblock %} + diff --git a/atlas/templates/core/statHierarchy.html b/atlas/templates/core/statHierarchy.html index f4c7effe..ef6a6723 100644 --- a/atlas/templates/core/statHierarchy.html +++ b/atlas/templates/core/statHierarchy.html @@ -25,32 +25,32 @@

{{ areaInfos.typeName }} - {{ areaInfos.areaName }}

-
{{ infosCommune.yearmin }} +
{{ infos_area.yearmin }}
{{ _('first_observation')|lower }}
-
{{ infosCommune.yearmax}} +
{{ infos_area.yearmax}}
{{ _('last_observation')|lower }}
-
+

{{ taxonProPatri.nbTaxonPatri }}
{{ _('protected_species')|lower }}
{% if configuration.DISPLAY_PATRIMONIALITE %} -
+

{{ taxonProPatri.nbTaxonPro }}
{{ _('patrimonial_species')|lower }}
{% endif %} - {% if infosCommune.id_parent %} -
+ {% if infos_area.id_parent %} +
-
{{ infosCommune.parent_type_name }} -
{{ infosCommune.parent_name }} +
{{ infos_area.parent_type_name }} +
{{ infos_area.parent_name }}
{% endif %}
diff --git a/atlas/templates/home/globalStats.html b/atlas/templates/home/globalStats.html index d102b170..5436874c 100644 --- a/atlas/templates/home/globalStats.html +++ b/atlas/templates/home/globalStats.html @@ -44,7 +44,7 @@

- {{ _('municipalities') }}

+ {{ _('territories') }}