Skip to content

Commit 840a78e

Browse files
committed
add performance methode to get observations on territory sheet
1 parent 5f4955c commit 840a78e

File tree

7 files changed

+130
-85
lines changed

7 files changed

+130
-85
lines changed

atlas/atlasAPI.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# -*- coding:utf-8 -*-
2+
import json
23

34
from flask import jsonify, Blueprint, request, current_app
45

@@ -131,6 +132,23 @@ def getObservationsAreaTaxonMailleAPI(id_area, cd_ref):
131132
return jsonify(observations)
132133

133134

135+
@api.route("/area/<int(signed=True):id_area>", methods=["GET"])
136+
def get_observations_area_api(id_area):
137+
connection = db.engine.connect()
138+
139+
if current_app.config["AFFICHAGE_MAILLE"]:
140+
observations = vmObservationsMaillesRepository.lastObservationsAreaMaille(
141+
connection, current_app.config["NB_LAST_OBS"], str(id_area)
142+
)
143+
else:
144+
observations = vmObservationsRepository.lastObservationsArea(
145+
connection, current_app.config["NB_LAST_OBS"], id_area
146+
)
147+
148+
connection.close()
149+
return jsonify(observations)
150+
151+
134152
@api.route("/photoGroup/<group>", methods=["GET"])
135153
def getPhotosGroup(group):
136154
connection = db.engine.connect()

atlas/atlasRoutes.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,6 @@ def ficheArea(id_area):
314314
session = db.session
315315
connection = db.engine.connect()
316316

317-
if current_app.config["AFFICHAGE_MAILLE"]:
318-
observations = vmObservationsMaillesRepository.lastObservationsAreaMaille(
319-
connection, current_app.config["NB_LAST_OBS"], str(id_area)
320-
)
321-
else:
322-
observations = vmObservationsRepository.lastObservationsArea(
323-
connection, current_app.config["NB_LAST_OBS"], id_area
324-
)
325-
326317
listTaxons = vmTaxonsRepository.getTaxonsAreas(connection, id_area)
327318
area = vmAreasRepository.getAreaFromIdArea(connection, id_area)
328319
stats_area = vmAreasRepository.getStatsByArea(connection, id_area)
@@ -335,7 +326,6 @@ def ficheArea(id_area):
335326
listTaxons=listTaxons,
336327
stats_area=stats_area,
337328
areaInfos=area,
338-
observations=observations,
339329
DISPLAY_EYE_ON_LIST=True,
340330
id_area=id_area,
341331
)

atlas/modeles/repositories/vmObservationsMaillesRepository.py

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -118,43 +118,38 @@ def lastObservationsMailles(connection, mylimit, idPhoto):
118118

119119
def lastObservationsAreaMaille(connection, obs_limit, id_area):
120120
sql = """
121-
WITH obs_in_area AS (
122-
SELECT
123-
obs.id_observation,
124-
obs.cd_ref,
125-
date_part('year', obs.dateobs) AS annee
126-
FROM atlas.vm_observations obs
127-
JOIN atlas.vm_cor_area_synthese AS cas ON cas.id_synthese = obs.id_observation
128-
WHERE cas.id_area = :idAreaCode
129-
)
121+
WITH obs_in_area AS (
130122
SELECT
131-
obs_in_area.id_observation,
132-
obs_in_area.cd_ref,
133-
COALESCE(t.nom_vern || ' | ', '') || t.lb_nom AS display_name,
134-
obs_in_area.annee,
135-
obs.type_code,
136-
obs.id_maille,
137-
vla.area_geojson AS geojson_4326
138-
FROM obs_in_area
139-
JOIN atlas.vm_observations_mailles obs ON obs_in_area.id_observation = ANY(obs.id_observations)
140-
JOIN atlas.vm_l_areas vla ON vla.id_area=obs.id_maille
141-
JOIN atlas.vm_taxons AS t ON t.cd_ref = obs_in_area.cd_ref
142-
ORDER BY annee DESC
143-
LIMIT :obsLimit;
123+
obs.id_observation,
124+
obs.cd_ref,
125+
date_part('year', obs.dateobs) AS annee
126+
FROM atlas.vm_observations obs
127+
JOIN atlas.vm_cor_area_synthese AS cas ON cas.id_synthese = obs.id_observation
128+
WHERE cas.id_area = :idAreaCode
129+
)
130+
SELECT
131+
json_build_object(
132+
'type', 'FeatureCollection',
133+
'features', json_agg(ST_AsGeoJSON(features.*)::json)
134+
) AS observations_features
135+
FROM (
136+
SELECT
137+
COUNT(obs_in_area.id_observation) AS nb_observations,
138+
COUNT(DISTINCT obs_in_area.cd_ref) AS nb_cd_ref,
139+
json_agg(DISTINCT jsonb_build_object(
140+
'name', (COALESCE(t.nom_vern || ' | ', '') || t.lb_nom),
141+
'cdRef', t.cd_ref)) AS taxons,
142+
obs.type_code,
143+
obs.id_maille,
144+
vla.the_geom
145+
FROM obs_in_area
146+
JOIN atlas.vm_observations_mailles obs ON obs_in_area.id_observation = ANY(obs.id_observations)
147+
JOIN atlas.vm_l_areas vla ON vla.id_area=obs.id_maille
148+
JOIN atlas.vm_taxons AS t ON t.cd_ref = obs_in_area.cd_ref
149+
GROUP BY obs.type_code, obs.id_maille, vla.the_geom) AS features
144150
"""
145-
results = connection.execute(text(sql), idAreaCode=id_area, obsLimit=obs_limit)
146-
observations = list()
147-
for r in results:
148-
infos = {
149-
"cd_ref": r.cd_ref,
150-
"taxon": r.display_name,
151-
"geojson_maille": json.loads(r.geojson_4326),
152-
"id_maille": r.id_maille,
153-
"id_observation": r.id_observation,
154-
"type_code": r.type_code,
155-
}
156-
observations.append(infos)
157-
return observations
151+
query = connection.execute(text(sql), idAreaCode=id_area, obsLimit=obs_limit)
152+
return dict(query.all()[0])
158153

159154

160155
# Use for API

atlas/modeles/repositories/vmObservationsRepository.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ def lastObservations(connection, mylimit, idPhoto):
7676
temp.pop("the_geom_point", None)
7777
temp["geojson_point"] = json.loads(o.geojson_point or "{}")
7878
temp["dateobs"] = o.dateobs
79-
temp["type_code"] = o.type_code
8079
temp["group2_inpn"] = utils.deleteAccent(o.group2_inpn)
8180
temp["pathImg"] = utils.findPath(o)
8281
obsList.append(temp)

atlas/static/mapAreas.js

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ var currentLayer;
99
// Current observation geoJson: type object
1010
var myGeoJson;
1111

12+
const id_area = document.location.pathname.split("/")[2]
13+
displayObs(id_area)
14+
15+
1216
// Display limit of the territory
1317
var areaLayer = L.geoJson(areaInfos.areaGeoJson, {
1418
style: function () {
@@ -30,12 +34,8 @@ bounds.extend(layerBounds);
3034
map.fitBounds(bounds);
3135
map.zoom = map.getZoom();
3236
// Display the 'x' last observations
33-
// MAILLE
34-
if (configuration.AFFICHAGE_MAILLE) {
35-
displayMailleLayerLastObs(observations);
36-
}
3737
// POINT
38-
else {
38+
if (!configuration.AFFICHAGE_MAILLE) {
3939
displayMarkerLayerPointLastObs(observations);
4040
}
4141

@@ -75,34 +75,53 @@ function displayObsGridBaseUrl() {
7575

7676
// display observation on click
7777
function displayObsTaxon(id_area, cd_ref) {
78-
$.ajax({
79-
url:
80-
configuration.URL_APPLICATION +
81-
"/api/observations/" +
82-
id_area +
83-
"/" +
84-
cd_ref,
85-
dataType: "json",
86-
beforeSend: function() {
87-
$("#loadingGif").show();
88-
$("#loadingGif").attr(
89-
"src",
90-
configuration.URL_APPLICATION + "/static/images/loading.svg"
91-
);
92-
}
93-
}).done(function(observations) {
94-
$("#loadingGif").hide();
95-
map.removeLayer(currentLayer);
96-
if (configuration.AFFICHAGE_MAILLE) {
97-
displayMailleLayerLastObs(observations);
98-
clearOverlays()
99-
} else {
78+
$.ajax({
79+
url:
80+
configuration.URL_APPLICATION +
81+
"/api/observations/" +
82+
id_area +
83+
"/" +
84+
cd_ref,
85+
dataType: "json",
86+
beforeSend: function() {
87+
$("#loadingGif").show();
88+
$("#loadingGif").attr(
89+
"src",
90+
configuration.URL_APPLICATION + "/static/images/loading.svg"
91+
);
92+
}
93+
}).done(function(observations) {
94+
$("#loadingGif").hide();
10095
map.removeLayer(currentLayer);
101-
displayMarkerLayerPointArea(observations);
102-
}
103-
});
96+
if (configuration.AFFICHAGE_MAILLE) {
97+
displayMailleLayerLastObs(observations);
98+
clearOverlays()
99+
} else {
100+
map.removeLayer(currentLayer);
101+
displayMarkerLayerPointArea(observations);
102+
}
103+
});
104104
}
105105

106+
function displayObs(areaCode) {
107+
$("#loaderSpinner").show();
108+
fetch(`/api/area/${areaCode}`)
109+
.then(data => {
110+
return data.json()
111+
})
112+
.then(observations => {
113+
if (configuration.AFFICHAGE_MAILLE) {
114+
displayMailleLayer(observations.observations_features);
115+
} else {
116+
displayMarkerLayerPointLastObs(observations)
117+
}
118+
$("#loaderSpinner").hide();
119+
})
120+
.catch(err => {
121+
console.error(err)
122+
$("#loaderSpinner").hide();
123+
})
124+
}
106125

107126
function displayObsTaxonMaille(areaCode, cd_ref) {
108127
$.ajax({

atlas/static/mapGenerator.js

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,7 @@ function generateGeojsonGridArea(observations) {
451451
}
452452

453453
function displayGridLayerArea(observations) {
454-
myGeoJson = generateGeojsonGridArea(observations);
455-
currentLayer = L.geoJson(myGeoJson, {
454+
currentLayer = L.geoJson(observations, {
456455
onEachFeature: onEachFeatureMaille,
457456
style: styleMaille,
458457
});
@@ -645,12 +644,17 @@ function buildSpeciesEntries(taxons) {
645644
return rows.join('\n');
646645
}
647646

648-
function onEachFeatureMailleLastObs(feature, layer) {
649-
title = `${feature.properties.taxons.length} espèces observées dans la maille &nbsp;: `;
650-
rows = buildSpeciesEntries(feature.properties.taxons);
651-
popupContent = `<b>${title}</b><ul>${rows}</ul>`;
647+
function createPopUp(feature, layer) {
648+
const title = `${feature.properties.taxons.length} espèces observées dans la maille &nbsp;: `;
649+
const rows = buildSpeciesEntries(feature.properties.taxons);
650+
const popupContent = `<b>${title}</b><ul>${rows}</ul>`;
652651

653652
layer.bindPopup(popupContent, { maxHeight: 300 });
653+
}
654+
655+
function onEachFeatureMailleLastObs(feature, layer) {
656+
createPopUp(feature, layer);
657+
654658

655659
addInFeatureGroup(feature, layer);
656660

@@ -808,6 +812,22 @@ function generateGeoJsonMailleLastObs(observations, isRefresh=false) {
808812
};
809813
}
810814

815+
function displayMailleLayer(observationsMaille) {
816+
// myGeoJson = observationsMaille;
817+
// Get all different type code
818+
Object.values(observationsMaille.features).forEach(elem => {
819+
if (!current_type_code.includes(elem.properties.type_code)) {
820+
current_type_code.push(elem.properties.type_code)
821+
}
822+
})
823+
createMailleSelector()
824+
currentLayer = L.geoJson(observationsMaille, {
825+
onEachFeature: onEachFeatureMailleLastObs,
826+
});
827+
828+
// ajout de la légende
829+
generateLegendMaille();
830+
}
811831

812832
function displayMailleLayerLastObs(observations, isRefresh=false) {
813833
const geojsonMaille = generateGeoJsonMailleLastObs(observations, isRefresh);

atlas/templates/areaSheet/_main.html

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
{# Ajoutez ici les assets complémentaires qui seront en bas de page #}
3030
<script type="text/javascript">
3131
var configuration = {{configuration|tojson}};
32-
var observations = {{observations|tojson}};
3332
var areaInfos = {{ areaInfos | tojson }};
3433
var url_limit_territory = "{{url_for('static', filename='custom/territoire.json') }}";
3534
const translations = {
@@ -66,8 +65,13 @@
6665
</div>
6766
<div class="col-12 col-xl-8 col-lg-7 col-md-6 d-flex flex-column m-0 p-0" style="min-height: 80vh;">
6867
<div class="bg-light p-2">
69-
<h5 id="titleMap"><i class="fa fa-map"></i> <i>{{ areaInfos.areaName }}</i> : {{ configuration.NB_LAST_OBS }} {{ _('last.obs.area') }}
70-
</h5>
68+
{% if configuration.AFFICHAGE_MAILLE %}
69+
<h5 id="titleMap"><i class="fa fa-map"></i> <i>{{ areaInfos.areaName }}</i> 
70+
</h5>
71+
{% else %}
72+
<h5 id="titleMap"><i class="fa fa-map"></i> <i>{{ areaInfos.areaName }}</i> : {{ configuration.NB_LAST_OBS }} {{ _('last.obs.area') }}
73+
</h5>
74+
{% endif %}
7175
</div>
7276
<div class="d-flex align-content-stretch bg-warning flex-grow-1">
7377
<div class="d-flex flex-grow-1">

0 commit comments

Comments
 (0)