diff --git a/config/pmd-suppressions.properties b/config/pmd-suppressions.properties index a842bcf870af3d7390f1a423e46bb4230e25bbf3..98b2c2e8b44951290401f5501864707eaa916d91 100644 --- a/config/pmd-suppressions.properties +++ b/config/pmd-suppressions.properties @@ -9,6 +9,8 @@ fr.agrometinfo.www.shared.dto.IndicatorDTO_MapperImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.PeriodDTOBeanJsonDeserializerImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.PeriodDTOBeanJsonSerializerImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.PeriodDTO_MapperImpl=UnnecessaryImport +fr.agrometinfo.www.shared.dto.SimpleFeatureBeanJsonDeserializerImpl=UnnecessaryImport +fr.agrometinfo.www.shared.dto.SimpleFeatureBeanJsonSerializerImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.SummaryDTOBeanJsonDeserializerImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.SummaryDTOBeanJsonSerializerImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.SummaryDTO_MapperImpl=UnnecessaryImport diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/App.java b/www-client/src/main/java/fr/agrometinfo/www/client/App.java index f86a85a9a9ba97aad33f601be6426a1f2bb1f3b5..52b5c38e9e3db361c71151c3f14888464da2292e 100644 --- a/www-client/src/main/java/fr/agrometinfo/www/client/App.java +++ b/www-client/src/main/java/fr/agrometinfo/www/client/App.java @@ -1,6 +1,9 @@ package fr.agrometinfo.www.client; import org.dominokit.rest.DominoRestConfig; +import org.gwtproject.event.shared.Event; +import org.gwtproject.event.shared.EventBus; +import org.gwtproject.event.shared.SimpleEventBus; import org.pepstock.charba.client.Charba; import com.google.gwt.core.client.EntryPoint; @@ -17,6 +20,17 @@ import fr.agrometinfo.www.client.presenter.LoginPresenter; * @author Olivier Maury */ public class App implements EntryPoint { + /** + * Dispatches {@link Event}s to interested parties. + */ + private static final EventBus EVENT_BUS = new SimpleEventBus(); + + /** + * @return {@link Event}s dispatcher. + */ + public static EventBus getEventBus() { + return EVENT_BUS; + } private boolean isLoggedIn() { // fake check diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/event/FeatureSelectEvent.java b/www-client/src/main/java/fr/agrometinfo/www/client/event/FeatureSelectEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..ac12ef8c40908dc27bf35bc4fcdcfc974be73c45 --- /dev/null +++ b/www-client/src/main/java/fr/agrometinfo/www/client/event/FeatureSelectEvent.java @@ -0,0 +1,80 @@ +package fr.agrometinfo.www.client.event; + +import org.gwtproject.event.shared.Event; + +import fr.agrometinfo.www.shared.dto.FeatureLevel; + +/** + * Event when the user click on a geographic feature on the map. + * + * @author Olivier Maury + */ +public final class FeatureSelectEvent extends Event<FeatureSelectHandler> { + + /** + * Event type. + */ + public static final Type<FeatureSelectHandler> TYPE = new Type<>(); + + /** + * Builder. + * + * @param level Level of selected feature. + * @param id Id of selected feature. + * @return built event + */ + public static FeatureSelectEvent of(final FeatureLevel level, final String id) { + final FeatureSelectEvent event = new FeatureSelectEvent(); + event.setId(id); + event.setLevel(level); + return event; + } + + /** + * Id of selected feature. + */ + private String id; + + /** + * Level of selected feature. + */ + private FeatureLevel level; + + @Override + protected void dispatch(final FeatureSelectHandler handler) { + handler.onFeatureSelect(this); + } + + @Override + public Type<FeatureSelectHandler> getAssociatedType() { + return TYPE; + } + + /** + * @return Id of selected feature. + */ + public String getId() { + return id; + } + + /** + * @return Level of selected feature. + */ + public FeatureLevel getLevel() { + return level; + } + + /** + * @param value Id of selected feature. + */ + public void setId(final String value) { + this.id = value; + } + + /** + * @param value Level of selected feature. + */ + public void setLevel(final FeatureLevel value) { + this.level = value; + } +} diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/event/FeatureSelectHandler.java b/www-client/src/main/java/fr/agrometinfo/www/client/event/FeatureSelectHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..66f291038cccc344e91c2d418c0816a08309fcb3 --- /dev/null +++ b/www-client/src/main/java/fr/agrometinfo/www/client/event/FeatureSelectHandler.java @@ -0,0 +1,13 @@ +package fr.agrometinfo.www.client.event; + +/** + * Handler for {@link FeatureSelectEvent}. + * + * @author Olivier Maury + */ +public interface FeatureSelectHandler { + /** + * @param event event with feature selection + */ + void onFeatureSelect(FeatureSelectEvent event); +} diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/event/package-info.java b/www-client/src/main/java/fr/agrometinfo/www/client/event/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..a753af3c54f923fd1ed573f7f6ca95c90c4a5230 --- /dev/null +++ b/www-client/src/main/java/fr/agrometinfo/www/client/event/package-info.java @@ -0,0 +1,4 @@ +/** + * {@link org.gwtproject.event.shared.Event} implementations for the event bus. + */ +package fr.agrometinfo.www.client.event; diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppConstants.java b/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppConstants.java index 8ccc4f63c8de80ded669870e2ddc454481d01eae..1cc0025efdff093ca1972cf86fb334370dfa049b 100644 --- a/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppConstants.java +++ b/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppConstants.java @@ -87,6 +87,12 @@ public interface AppConstants extends com.google.gwt.i18n.client.ConstantsWithLo @DefaultStringValue("Compare two maps") String comparisonMap(); + /** + * @return translation + */ + @DefaultStringValue("period 1990 − 2020") + String comparisonPeriod(); + /** * @return translation */ diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppMessages.java b/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppMessages.java index 17d503884ce0a12a5210b1bd6214b8dab743e67c..c9ba9cef9a58929f59edfc34d482e16d9d67c3f6 100644 --- a/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppMessages.java +++ b/www-client/src/main/java/fr/agrometinfo/www/client/i18n/AppMessages.java @@ -27,6 +27,13 @@ public interface AppMessages extends Messages { @DefaultMessage("Average value for the indicator {0} ({1}) at {2} in {3}") String averageValue(String indicator, String period, String region, int year); + /** + * @param id cell id + * @return translation + */ + @DefaultMessage("Cell #{0}") + String cell(String id); + /** * @param indicator chosen indicator * @param period chosen period @@ -67,6 +74,20 @@ public interface AppMessages extends Messages { */ @DefaultMessage("{0} indicators.") @AlternateMessage({"=0", "No indicator.", // - "=1", "1 indicator."}) + "=1", "1 indicator."}) String nbOfIndicators(@PluralCount int nb); + + /** + * @param name + * @return translation + */ + @DefaultMessage("Petite Région Agricole \"{0}\"") + String pra(String name); + + /** + * @param name + * @return translation + */ + @DefaultMessage("Region \"{0}\"") + String region(String name); } diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/presenter/MapPresenter.java b/www-client/src/main/java/fr/agrometinfo/www/client/presenter/MapPresenter.java index f8e380b72065251a43106e6c587843989350931c..df4bc0b855ab2a6898b8a73100aec84fa9dd7358 100644 --- a/www-client/src/main/java/fr/agrometinfo/www/client/presenter/MapPresenter.java +++ b/www-client/src/main/java/fr/agrometinfo/www/client/presenter/MapPresenter.java @@ -8,10 +8,13 @@ import org.geojson.FeatureCollection; import com.google.gwt.core.client.GWT; import elemental2.dom.HTMLDivElement; +import fr.agrometinfo.www.client.App; +import fr.agrometinfo.www.client.event.FeatureSelectEvent; import fr.agrometinfo.www.client.util.ApplicationUtils; import fr.agrometinfo.www.client.view.BaseView; import fr.agrometinfo.www.client.view.MapView; import fr.agrometinfo.www.shared.dto.ChoiceDTO; +import fr.agrometinfo.www.shared.dto.FeatureLevel; import fr.agrometinfo.www.shared.dto.IndicatorDTO; import fr.agrometinfo.www.shared.service.IndicatorService; @@ -66,14 +69,18 @@ public final class MapPresenter implements Presenter { if (choice.getPeriod() != null) { request.addQueryParam("period", choice.getPeriod()); } - if (choice.getRegion() != null) { - request.addQueryParam("region", choice.getRegion()); + if (choice.getFeatureId() != null) { + request.addQueryParam("region", choice.getFeatureId()); } request.addQueryParam("year", String.valueOf(choice.getYear())); request.addQueryParam("comparison", String.valueOf(choice.getComparison())); request.onSuccess(response -> view.setGeoJson(response.getBodyAsString(), indicator)).send(); } + public void onFeatureSelect(final String id) { + App.getEventBus().fireEvent(FeatureSelectEvent.of(FeatureLevel.PRA, id)); + } + /** * @param mapContainer container for the map */ diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/presenter/RightPanelPresenter.java b/www-client/src/main/java/fr/agrometinfo/www/client/presenter/RightPanelPresenter.java index e472bc7cc8f685b44eec49339a1ae1b7f8982579..ebc372ae6358ac0264575460fded235e08962b26 100644 --- a/www-client/src/main/java/fr/agrometinfo/www/client/presenter/RightPanelPresenter.java +++ b/www-client/src/main/java/fr/agrometinfo/www/client/presenter/RightPanelPresenter.java @@ -6,6 +6,9 @@ import com.google.gwt.core.client.GWT; import elemental2.dom.DomGlobal; import elemental2.dom.HTMLElement; +import fr.agrometinfo.www.client.App; +import fr.agrometinfo.www.client.event.FeatureSelectEvent; +import fr.agrometinfo.www.client.event.FeatureSelectHandler; import fr.agrometinfo.www.client.view.BaseView; import fr.agrometinfo.www.client.view.LayoutView; import fr.agrometinfo.www.client.view.RightPanelView; @@ -19,7 +22,7 @@ import fr.agrometinfo.www.shared.service.IndicatorServiceFactory; * * @author Olivier Maury */ -public final class RightPanelPresenter implements Presenter { +public final class RightPanelPresenter implements FeatureSelectHandler, Presenter { /** * Related view interface. */ @@ -47,6 +50,11 @@ public final class RightPanelPresenter implements Presenter { void show(); } + /** + * Last choice. + */ + private ChoiceDTO currentChoice; + /** * Related view. */ @@ -65,18 +73,13 @@ public final class RightPanelPresenter implements Presenter { /** * Load indicator values on the panel. * - * @param choice user choice for the indicator values + * @param c user choice for the indicator values */ - public void loadValues(final ChoiceDTO choice) { - GWT.log("RightPanelPresenter.loadValues() " + choice); - Integer regionId; - try { - regionId = Integer.valueOf(choice.getRegion()); - } catch (final NumberFormatException e) { - regionId = null; - } + public void loadValues(final ChoiceDTO c) { + GWT.log("RightPanelPresenter.loadValues() " + c); + currentChoice = c; IndicatorServiceFactory.INSTANCE - .getSummary(choice.getIndicator(), choice.getPeriod(), regionId, choice.getYear()) // + .getSummary(c.getIndicator(), c.getPeriod(), c.getLevel(), c.getFeatureId(), c.getYear()) // .onSuccess(view::setSummary)// .onFailed(layoutView::failureNotification)// .send(); @@ -86,6 +89,22 @@ public final class RightPanelPresenter implements Presenter { } } + @Override + public void onFeatureSelect(final FeatureSelectEvent event) { + if (currentChoice == null) { + return; + } + final ChoiceDTO choice = new ChoiceDTO(); + choice.setComparison(currentChoice.getComparison()); + choice.setIndicator(currentChoice.getIndicator()); + choice.setPeriod(currentChoice.getPeriod()); + choice.setFeatureId(event.getId()); + choice.setLevel(event.getLevel()); + choice.setYear(currentChoice.getYear()); + loadValues(choice); + view.show(); + } + /** * @param mapContainer container for the map */ @@ -103,6 +122,7 @@ public final class RightPanelPresenter implements Presenter { @Override public void start() { GWT.log("RightPanelPresenter.start()"); + App.getEventBus().addHandler(FeatureSelectEvent.TYPE, this); view = new RightPanelView(layoutView, container); view.setPresenter(this); view.init(); diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/view/LayoutView.java b/www-client/src/main/java/fr/agrometinfo/www/client/view/LayoutView.java index 8c172b605baf37ab0f792de2bcc4f89f4a3f8de8..1da2a2252c0643e3e97dc62d29a90eb456d52344 100644 --- a/www-client/src/main/java/fr/agrometinfo/www/client/view/LayoutView.java +++ b/www-client/src/main/java/fr/agrometinfo/www/client/view/LayoutView.java @@ -53,6 +53,7 @@ import fr.agrometinfo.www.client.presenter.RightPanelPresenter; import fr.agrometinfo.www.client.ui.AgroclimAppsMenu; import fr.agrometinfo.www.client.ui.HTMLSelectElementBuilder; import fr.agrometinfo.www.shared.dto.ChoiceDTO; +import fr.agrometinfo.www.shared.dto.FeatureLevel; import fr.agrometinfo.www.shared.dto.IndicatorDTO; import fr.agrometinfo.www.shared.dto.PeriodDTO; @@ -203,6 +204,7 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen public void init() { GWT.log("initLayout()"); DomGlobal.console.info("initLayout()"); + choice.setLevel(FeatureLevel.REGION); layout = Layout.create("AgroMetInfo").show(); final EmptyContentBuilder<HTMLImageElement> logoElem = Elements.img("app/img/logo_etat-agrometinfo.svg"); layout.setLogo(logoElem); @@ -432,9 +434,9 @@ public final class LayoutView extends AbstractBaseView<LayoutPresenter> implemen private void onRegionChange(final String newValue) { if (newValue.length() > 2) { - choice.setRegion(null); + choice.setFeatureId(null); } else { - choice.setRegion(newValue); + choice.setFeatureId(newValue); } onChoiceChange(); } diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/view/MapView.java b/www-client/src/main/java/fr/agrometinfo/www/client/view/MapView.java index a8790e816aadb898813d394243aafe71f14262e5..883662ffbd4364c88a8e1ef45fca5715bad00341 100644 --- a/www-client/src/main/java/fr/agrometinfo/www/client/view/MapView.java +++ b/www-client/src/main/java/fr/agrometinfo/www/client/view/MapView.java @@ -32,8 +32,11 @@ import ol.OLFactory; import ol.View; import ol.ViewOptions; import ol.color.Color; +import ol.events.condition.Condition; import ol.format.GeoJson; import ol.format.GeoJsonFeatureOptions; +import ol.interaction.Select; +import ol.interaction.SelectOptions; import ol.layer.Base; import ol.layer.Group; import ol.layer.LayerGroupOptions; @@ -240,11 +243,27 @@ public final class MapView extends HtmlContentBuilder<HTMLElement> implements Ma super(element.element()); } + /** + * Mouse click interaction to select a cell. + */ + private void addClickInteractions() { + final SelectOptions selectOptions = new SelectOptions(); + selectOptions.setCondition(Condition.getClick()); + selectOptions.setMulti(false); + final Style style = createCellStyle(Color.getColorFromString("blue"), new Color(255, 0, 0, 0.5f)); + selectOptions.setStyle((f, r) -> new Style[] {style}); + + // create a select interaction + final Select selectFeature = new Select(selectOptions); + map.addInteraction(selectFeature); + + selectFeature.on("select", event -> onFeatureClick(selectFeature.getFeatures())); + } + private Feature[] colorizeFeatures(final Feature[] features) { for (final Feature f : features) { final Double value = getValue(f); final String color = "#" + ColorSequenceManager.getColorForValue(colorIntervals, value); - // GWT.log("Feature #" + f.getId() + ", value=" + value + ", color=" + color); final Color foreground = Color.getColorFromString(color); final Style style = createCellStyle(foreground, foreground); f.setStyle(style); @@ -298,6 +317,14 @@ public final class MapView extends HtmlContentBuilder<HTMLElement> implements Ma // add some interactions removeContextMenuRightClick(); + addClickInteractions(); + } + + private void onFeatureClick(final Collection<Feature> features) { + if (features == null || features.isEmpty()) { + return; + } + this.getPresenter().onFeatureSelect(features.item(0).getId()); } /** diff --git a/www-client/src/main/java/fr/agrometinfo/www/client/view/RightPanelView.java b/www-client/src/main/java/fr/agrometinfo/www/client/view/RightPanelView.java index 9184a0e5a1b3ea0f7e0dc2d7b9b0f2726cd63eb9..c57161110ee629e0206f987b8700e95b1a41aa3e 100644 --- a/www-client/src/main/java/fr/agrometinfo/www/client/view/RightPanelView.java +++ b/www-client/src/main/java/fr/agrometinfo/www/client/view/RightPanelView.java @@ -8,6 +8,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import org.dominokit.domino.ui.button.Button; import org.dominokit.domino.ui.cards.Card; import org.dominokit.domino.ui.grid.Column; import org.dominokit.domino.ui.grid.Row; @@ -15,7 +16,9 @@ import org.dominokit.domino.ui.icons.Icons; import org.dominokit.domino.ui.notifications.Notification; import org.dominokit.domino.ui.utils.DominoElement; import org.dominokit.domino.ui.utils.TextNode; +import org.jboss.elemento.Elements; import org.jboss.elemento.EventType; +import org.jboss.elemento.HtmlContentBuilder; import org.pepstock.charba.client.AbstractChart; import org.pepstock.charba.client.BarChart; import org.pepstock.charba.client.IsChart; @@ -44,9 +47,12 @@ import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; import com.google.gwt.i18n.client.NumberFormat; +import elemental2.dom.EventListener; import elemental2.dom.HTMLDivElement; import elemental2.dom.HTMLElement; +import elemental2.dom.HTMLHeadingElement; import elemental2.dom.Node; +import fr.agrometinfo.www.client.event.FeatureSelectEvent; import fr.agrometinfo.www.client.i18n.AppConstants; import fr.agrometinfo.www.client.i18n.AppMessages; import fr.agrometinfo.www.client.presenter.RightPanelPresenter; @@ -137,14 +143,19 @@ public final class RightPanelView implements RightPanelPresenter.View { private final Card averageCard = Card.create(); /** - * Container for bar chart displaying monthly values. + * Back link. */ - private final DominoElement<HTMLDivElement> barChartContainer = DominoElement.div(); + private final Button backBtn = Button.create(Icons.ALL.arrow_back()); /** - * Container for bar chart displaying daily values. + * Event listener for click on {@link RightPanelView#backBtn}. */ - private final DominoElement<HTMLDivElement> lineChartContainer = DominoElement.div(); + private EventListener backBtnClickListener = null; + + /** + * Container for bar chart displaying monthly values. + */ + private final DominoElement<HTMLDivElement> barChartContainer = DominoElement.div(); /** * Card for the daily comparison value for the user choice. @@ -156,16 +167,30 @@ public final class RightPanelView implements RightPanelPresenter.View { */ private final DominoElement<HTMLElement> container; + /** + * Panel header. + */ + private final HtmlContentBuilder<HTMLHeadingElement> header = Elements.h(3); + /** * Layout handling the panel. */ private final LayoutView layoutView; + /** + * Container for bar chart displaying daily values. + */ + private final DominoElement<HTMLDivElement> lineChartContainer = DominoElement.div(); + + /** + * Related presenter. + */ + private RightPanelPresenter presenter; + /** * Values according to user's choice. */ private SummaryDTO summary; - /** * Constructor. * @@ -176,6 +201,7 @@ public final class RightPanelView implements RightPanelPresenter.View { layoutView = view; container = div; } + private void createBarChart(final Map<String, Float> monthlyValues) { GWT.log("RightPanelView.createBarChart() " + monthlyValues.size()); final BarChart chart = new BarChart(); @@ -258,12 +284,21 @@ public final class RightPanelView implements RightPanelPresenter.View { @Override public void init() { - container.add(a() // - .on(EventType.click, e -> hide()) // - .add(Icons.CONTENT_ICONS.clear().clickable())); + backBtn.style().setDisplay("none"); + + container.add(DominoElement.div() // + .add(backBtn)// + .add(a() // + .on(EventType.click, e -> hide()) // + .css("float-right") // + .add(Icons.CONTENT_ICONS.clear().clickable())) // + ); + + container.add(header); averageCard.addHeaderAction(Icons.ACTION_ICONS.info_outline(), e -> this.showDescription(false)); comparisonCard.addHeaderAction(Icons.ACTION_ICONS.info_outline(), e -> this.showDescription(true)); + comparisonCard.setDescription(CSTS.comparisonPeriod()); container.add(Row.create() // .addColumn(Column.span6().add(averageCard)) // @@ -279,30 +314,67 @@ public final class RightPanelView implements RightPanelPresenter.View { @Override public void setPresenter(final RightPanelPresenter p) { - // Do nothing + presenter = p; } @Override public void setSummary(final SummaryDTO data) { GWT.log("RightPanelView.setSummary()"); summary = data; - String region = data.getRegion(); - if (region == null || region.isEmpty()) { - region = CSTS.metropolitanFrance(); + + final String featureName = data.getFeatureName(); + final String title; + if (featureName == null || featureName.isEmpty()) { + title = CSTS.metropolitanFrance(); + } else { + switch (data.getChoice().getLevel()) { + case CELL: + title = MSGS.cell(featureName); + break; + case PRA: + title = MSGS.pra(featureName); + break; + case REGION: + title = MSGS.region(featureName); + break; + default: + throw new UnsupportedOperationException("Level not handled: " + data.getChoice().getLevel()); + + } + } + if (data.getParentFeature() != null) { + backBtn.getTextSpan().textContent(data.getParentFeature().getName()); + if (backBtnClickListener != null) { + backBtn.removeEventListener(EventType.click, backBtnClickListener); + } + backBtnClickListener = e -> { + final FeatureSelectEvent event = new FeatureSelectEvent(); + event.setId(data.getParentFeature().getId()); + event.setLevel(data.getParentFeature().getLevel()); + presenter.onFeatureSelect(event); + }; + backBtn.addClickListener(backBtnClickListener); + backBtn.style().setDisplay("inline-block"); + } else { + backBtn.style().setDisplay("none"); } + final NumberFormat nf = NumberFormat.getFormat("0.#"); final DateTimeFormat df = DateTimeFormat.getFormat(PredefinedFormat.DATE_MEDIUM); + header.element().innerHTML = ""; + header.add(title); + header.add(Elements.br()); + header.add(Elements.small(df.format(data.getDate()))); + final IndicatorDTO indicator = data.getIndicator(); // Average averageCard.setTitle(indicator.getDescription()); - averageCard.setDescription(df.format(data.getDate())); averageCard.getBody().clearElement(); averageCard.getBody().appendChild(TextNode.of(nf.format(data.getAverageValue()) + " " + indicator.getUnit())); // Comparison comparisonCard.setTitle(CSTS.normalComparison()); - comparisonCard.setDescription(df.format(data.getDate())); comparisonCard.getBody().clearElement(); comparisonCard.getBody() .appendChild(TextNode.of(nf.format(data.getComparedValue()) + " " + indicator.getUnit())); @@ -319,7 +391,7 @@ public final class RightPanelView implements RightPanelPresenter.View { private void showDescription(final boolean comparison) { final IndicatorDTO indicator = summary.getIndicator(); - String region = summary.getRegion(); + String region = summary.getFeatureName(); if (region == null) { region = CSTS.metropolitanFrance(); } diff --git a/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppConstants_fr.properties b/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppConstants_fr.properties index 319a98a56acb5b52c16dd433d4dc6cdd379ef9ab..06f764da5451bec616e5b5d3a91ffb882bf187ac 100644 --- a/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppConstants_fr.properties +++ b/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppConstants_fr.properties @@ -12,6 +12,7 @@ chooseRegion= Choisir une région chooseYear= Choisir une année close = Fermer comparisonMap = Carte comparative +comparisonPeriod = Période 1990 − 2020 contactDataGathering = Les informations recueillies à partir de ce formulaire sont nécessaires au traitement de votre message par l’équipe d’AgroMetInfo. contactEmailField= Adresse courriel contactMessageField= Votre message diff --git a/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppMessages_fr.properties b/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppMessages_fr.properties index bec7c84280060eefc05e4fb2dfbcda779962e0a8..67b0d6fcbd1f00092399339387f7937a7bef7365 100644 --- a/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppMessages_fr.properties +++ b/www-client/src/main/resources/fr/agrometinfo/www/client/i18n/AppMessages_fr.properties @@ -1,6 +1,7 @@ # Ce fichier est encodé en UTF-8. account = Compte de {0} ({1}) averageValue = Valeur moyenne de l’indicateur {0} ({1}) en {2} sur {3} +cell = Maille n°{0} comparedValue = Écart moyen de la valeur de l’indicateur {0} ({1}) en {2} sur {3} failureStatusCode = Code d’état HTTP : {0} nbOfIndicatorPeriods[\=0] = Aucune période. @@ -11,3 +12,5 @@ nbOfIndicators[\=0] = Aucun indicateur. nbOfIndicators[\=1] = Un indicateur. nbOfIndicators[one] = Un indicateur. nbOfIndicators = {0} indicateurs. +pra = Petite région agricole «\u00A0{0}\u00A0» +region = Région «\u00A0{0}\u00A0» diff --git a/www-client/src/main/resources/fr/agrometinfo/www/client/public/style.css b/www-client/src/main/resources/fr/agrometinfo/www/client/public/style.css index f15f6865f460d07957a031f579ba80566a49d571..0de56fbf3c9f4c2a86ddaeb1234f952b6e0c4cf0 100644 --- a/www-client/src/main/resources/fr/agrometinfo/www/client/public/style.css +++ b/www-client/src/main/resources/fr/agrometinfo/www/client/public/style.css @@ -107,6 +107,9 @@ select { padding-bottom: 6px; padding-top: 6px; } +.float-right { + float: right; +} div.idp { padding: 0.5em; } diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDao.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDao.java index 3ca7b5f944e808eb903c51a5ddb46af762e0b64a..0fdbd0ff9c538328475ec860261397d46c979a4d 100644 --- a/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDao.java +++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDao.java @@ -5,6 +5,7 @@ import java.util.List; import fr.agrometinfo.www.server.model.Indicator; import fr.agrometinfo.www.server.model.MonthlyValue; +import fr.agrometinfo.www.server.model.Pra; import fr.agrometinfo.www.server.model.Region; /** @@ -22,13 +23,23 @@ public interface MonthlyValueDao { */ List<MonthlyValue> find(Indicator indicator, LocalDate date); + /** + * Last 12 monthly values for the indicator and all cells of a PRA. + * + * @param indicator indicator + * @param date date for the value last date + * @param pra PRA + * @return values + */ + List<MonthlyValue> find(Indicator indicator, LocalDate date, Pra pra); + /** * Last 12 monthly values for the indicator and all cells of a region. * * @param indicator indicator - * @param region region * @param date date for the value last date + * @param region region * @return values */ - List<MonthlyValue> find(Indicator indicator, Region region, LocalDate date); + List<MonthlyValue> find(Indicator indicator, LocalDate date, Region region); } diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernate.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernate.java index 54c3632c8f8efe69291fe88a7a0b1bd62808dcd6..b6ebd909487fba7e26091dfe994eb086c4768c35 100644 --- a/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernate.java +++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernate.java @@ -6,6 +6,7 @@ import java.util.Map; import fr.agrometinfo.www.server.model.Indicator; import fr.agrometinfo.www.server.model.MonthlyValue; +import fr.agrometinfo.www.server.model.Pra; import fr.agrometinfo.www.server.model.Region; import jakarta.enterprise.context.ApplicationScoped; @@ -43,23 +44,43 @@ public class MonthlyValueDaoHibernate extends DaoHibernate<MonthlyValue> impleme } @Override - public final List<MonthlyValue> find(final Indicator indicator, final Region region, final LocalDate date) { + public final List<MonthlyValue> find(final Indicator indicator, final LocalDate date, final Pra pra) { final var jpql = """ SELECT new fr.agrometinfo.www.server.model.MonthlyValue( EXTRACT(YEAR FROM t.date) AS year, EXTRACT(MONTH FROM t.date) AS month, """ + indicator.getAggregationType() + """ (t.computedValue) AS value) - FROM DailyValue AS t + FROM PraDailyValue AS t WHERE t.indicator=:indicator AND t.date BETWEEN :startdate AND :enddate AND - t.cell.department.region=:region AND + t.pra=:pra AND t.computedValue IS NOT NULL GROUP BY year, month ORDER BY year ASC, month ASC"""; return super.findAllByJPQL(jpql, - Map.of("indicator", indicator, "startdate", date.minusYears(1), "enddate", date, "region", region), + Map.of("indicator", indicator, "startdate", date.minusYears(1), "enddate", date, "pra", pra), MonthlyValue.class); } + @Override + public final List<MonthlyValue> find(final Indicator indicator, final LocalDate date, final Region region) { + final var jpql = """ + SELECT new fr.agrometinfo.www.server.model.MonthlyValue( + EXTRACT(YEAR FROM t.date) AS year, + EXTRACT(MONTH FROM t.date) AS month, + """ + indicator.getAggregationType() + """ + (t.computedValue) AS value) + FROM DailyValue AS t + WHERE t.indicator=:indicator AND + t.date BETWEEN :startdate AND :enddate AND + t.cell.department.region=:region AND + t.computedValue IS NOT NULL + GROUP BY year, month + ORDER BY year ASC, month ASC"""; + return super.findAllByJPQL(jpql, + Map.of("indicator", indicator, "startdate", date.minusYears(1), "enddate", date, "region", region), + MonthlyValue.class); + } + } diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDailyValueDao.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDailyValueDao.java index cfb65a06c6ad487f6f16bd8b84a25179acc6f9d7..f83e54db558409eced8cd690ad8bb335f1daa1b2 100644 --- a/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDailyValueDao.java +++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDailyValueDao.java @@ -6,6 +6,7 @@ import java.util.Map; import fr.agrometinfo.www.server.model.DailyValue; import fr.agrometinfo.www.server.model.Indicator; +import fr.agrometinfo.www.server.model.Pra; import fr.agrometinfo.www.server.model.PraDailyValue; import fr.agrometinfo.www.server.model.Region; @@ -25,6 +26,16 @@ public interface PraDailyValueDao { */ List<PraDailyValue> find(Indicator indicator, LocalDate date); + /** + * Value for the indicator, the day and the PRA. + * + * @param indicator indicator + * @param date date for the value + * @param pra PRA + * @return value + */ + PraDailyValue find(Indicator indicator, LocalDate date, Pra pra); + /** * Values for the indicator, the day and all PRAs of a region. * @@ -85,6 +96,17 @@ public interface PraDailyValueDao { */ Map<LocalDate, Float> findDailyValues(Indicator indicator, LocalDate start, LocalDate end); + /** + * Daily values for the indicator between 2 dates for a PRA. + * + * @param indicator indicator + * @param start period start + * @param end period end + * @param pra related PRA + * @return values + */ + Map<LocalDate, Float> findDailyValues(Indicator indicator, LocalDate start, LocalDate end, Pra pra); + /** * Daily values for the indicator between 2 dates for a region. * diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDailyValueDaoHibernate.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDailyValueDaoHibernate.java index bf92ef42e8e2569923298c34bdd1b26d285515a9..defb11275b98fa6b600ff1e3f4a9de654398d786 100644 --- a/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDailyValueDaoHibernate.java +++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDailyValueDaoHibernate.java @@ -6,6 +6,7 @@ import java.util.Map; import java.util.stream.Collectors; import fr.agrometinfo.www.server.model.Indicator; +import fr.agrometinfo.www.server.model.Pra; import fr.agrometinfo.www.server.model.PraDailyValue; import fr.agrometinfo.www.server.model.Region; import jakarta.enterprise.context.ApplicationScoped; @@ -33,6 +34,12 @@ public class PraDailyValueDaoHibernate extends DaoHibernate<PraDailyValue> imple return super.findAllByJPQL(jpql, Map.of("indicator", indicator, "date", date), PraDailyValue.class); } + @Override + public final PraDailyValue find(final Indicator indicator, final LocalDate date, final Pra pra) { + final var jpql = "SELECT t FROM PraDailyValue t WHERE t.indicator=:indicator AND t.date=:date AND t.pra=:pra"; + return super.findOneByJPQL(jpql, Map.of("indicator", indicator, "date", date, "pra", pra), PraDailyValue.class); + } + @Override public final List<PraDailyValue> find(final Indicator indicator, final Region region, final LocalDate date) { final var jpql = """ @@ -73,8 +80,8 @@ public class PraDailyValueDaoHibernate extends DaoHibernate<PraDailyValue> imple } @Override - public final Double findAverageComputedValue(final Indicator indicator, final LocalDate date, - final Integer regionId) { + public final Double findAverageComputedValue(final Indicator indicator, + final LocalDate date, final Integer regionId) { final var jpql = """ SELECT AVG(t.computedValue) FROM PraDailyValue AS t @@ -101,6 +108,24 @@ public class PraDailyValueDaoHibernate extends DaoHibernate<PraDailyValue> imple return findDailyValues(jpql, params); } + @Override + public final Map<LocalDate, Float> findDailyValues(final Indicator indicator, final LocalDate start, + final LocalDate end, final Pra pra) { + final var jpql = """ + SELECT t.date AS date, AVG(t.computedValue) AS value + FROM PraDailyValue AS t + WHERE t.indicator=:indicator AND t.date BETWEEN :start AND :end AND t.pra=:pra + GROUP BY t.date + ORDER BY t.date ASC + """; + final Map<String, Object> params = Map.of(// + "indicator", indicator, // + "pra", pra, // + "start", start, // + "end", end); + return findDailyValues(jpql, params); + } + @Override public final Map<LocalDate, Float> findDailyValues(final Indicator indicator, final LocalDate start, final LocalDate end, final Region region) { diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDao.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDao.java index d50f658038b5074e79a2c0188bd6a4c47f374c29..535111221a01560af923567de9be4f8831fcf91c 100644 --- a/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDao.java +++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDao.java @@ -20,4 +20,10 @@ public interface PraDao { * @return all PRAs */ List<Pra> findAll(); + + /** + * @param code PRA code + * @return found PRA + */ + Pra findByCode(String code); } diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDaoHibernate.java b/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDaoHibernate.java index 48ed4f94e570daf609227b68f21fd0b8ca243e6a..52d56deb249dda82f83a7d948e9b5200c5e9af5a 100644 --- a/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDaoHibernate.java +++ b/www-server/src/main/java/fr/agrometinfo/www/server/dao/PraDaoHibernate.java @@ -1,5 +1,7 @@ package fr.agrometinfo.www.server.dao; +import java.util.Map; + import fr.agrometinfo.www.server.model.Pra; import jakarta.enterprise.context.ApplicationScoped; @@ -18,4 +20,10 @@ public class PraDaoHibernate extends DaoHibernate<Pra> implements PraDao { super(Pra.class); } + @Override + public final Pra findByCode(final String code) { + final var jpql = "SELECT t FROM Pra t WHERE t.code=:code"; + return super.findOneByJPQL(jpql, Map.of("code", code), Pra.class); + } + } diff --git a/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java b/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java index 6441181c194576f7829b51eaf6bfb9275092c648..0003b7d49e2d4dbf84806b0ea24d24da3987eb2a 100644 --- a/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java +++ b/www-server/src/main/java/fr/agrometinfo/www/server/rs/IndicatorResource.java @@ -21,17 +21,21 @@ import fr.agrometinfo.www.server.dao.CellDao; import fr.agrometinfo.www.server.dao.IndicatorDao; import fr.agrometinfo.www.server.dao.MonthlyValueDao; import fr.agrometinfo.www.server.dao.PraDailyValueDao; +import fr.agrometinfo.www.server.dao.PraDao; import fr.agrometinfo.www.server.dao.RegionDao; import fr.agrometinfo.www.server.model.Indicator; import fr.agrometinfo.www.server.model.MonthlyValue; +import fr.agrometinfo.www.server.model.Pra; import fr.agrometinfo.www.server.model.PraDailyValue; import fr.agrometinfo.www.server.model.Region; import fr.agrometinfo.www.server.util.DateUtils; import fr.agrometinfo.www.server.util.LocaleUtils; import fr.agrometinfo.www.shared.dto.ChoiceDTO; import fr.agrometinfo.www.shared.dto.ErrorResponseDTO; +import fr.agrometinfo.www.shared.dto.FeatureLevel; import fr.agrometinfo.www.shared.dto.IndicatorDTO; import fr.agrometinfo.www.shared.dto.PeriodDTO; +import fr.agrometinfo.www.shared.dto.SimpleFeature; import fr.agrometinfo.www.shared.dto.SummaryDTO; import fr.agrometinfo.www.shared.service.IndicatorService; import jakarta.annotation.PostConstruct; @@ -139,6 +143,12 @@ public class IndicatorResource implements IndicatorService { @Inject private MonthlyValueDao monthlyValueDao; + /** + * DAO for {@link Pra}. + */ + @Inject + private PraDao praDao; + /** * DAO for {@link Region}. */ @@ -215,7 +225,8 @@ public class IndicatorResource implements IndicatorService { @Produces(MediaType.APPLICATION_JSON) @Override public SummaryDTO getSummary(@QueryParam(value = "indicator") final String indicatorUid, - @QueryParam(value = "period") final String periodCode, @QueryParam(value = "region") final Integer regionId, + @QueryParam(value = "period") final String periodCode, + @QueryParam(value = "level") final FeatureLevel level, @QueryParam(value = "id") final String id, @QueryParam(value = "year") final Integer year) { checkRequired(indicatorUid, "indicator"); checkRequired(periodCode, "period"); @@ -242,26 +253,49 @@ public class IndicatorResource implements IndicatorService { final Map<Date, Float> dailyValues = new TreeMap<>(); final Map<String, Float> monthlyValues; final LocalDate yearAgo = date.minusYears(1); - final Region region; + final SimpleFeature parentFeature; + final String featureName; + Integer regionId; + try { + regionId = Integer.valueOf(id); + } catch (final NumberFormatException e) { + regionId = null; + } if (regionId == null) { - region = null; + featureName = null; averageValue = praDailyValueDao.findAverageComputedValue(indicator, date); comparedValue = praDailyValueDao.findAverageComparedValue(indicator, date); tmpDailyValues = praDailyValueDao.findDailyValues(indicator, yearAgo, date); monthlyValues = toMonthlyValues(monthlyValueDao.find(indicator, date), i18n); + parentFeature = null; + } else if (level == FeatureLevel.PRA) { + final Pra pra = praDao.findByCode(id); + final PraDailyValue value = praDailyValueDao.find(indicator, date, pra); + averageValue = value.getComputedValue().doubleValue(); + comparedValue = value.getComparedValue().doubleValue(); + tmpDailyValues = praDailyValueDao.findDailyValues(indicator, yearAgo, date, pra); + monthlyValues = toMonthlyValues(monthlyValueDao.find(indicator, date, pra), i18n); + featureName = pra.getName(); + parentFeature = new SimpleFeature(); + parentFeature.setId(String.valueOf(pra.getDepartment().getRegion().getId())); + parentFeature.setLevel(FeatureLevel.REGION); + parentFeature.setName(pra.getDepartment().getRegion().getName()); } else { - region = regionDao.find(regionId); + final Region region = regionDao.find(regionId); averageValue = praDailyValueDao.findAverageComputedValue(indicator, date, regionId); comparedValue = praDailyValueDao.findAverageComparedValue(indicator, date, regionId); tmpDailyValues = praDailyValueDao.findDailyValues(indicator, yearAgo, date, region); - monthlyValues = toMonthlyValues(monthlyValueDao.find(indicator, region, date), i18n); + monthlyValues = toMonthlyValues(monthlyValueDao.find(indicator, date, region), i18n); + featureName = region.getName(); + parentFeature = null; } tmpDailyValues.forEach((d, v) -> dailyValues.put(DateUtils.toDate(d), v)); final var choice = new ChoiceDTO(); choice.setIndicator(indicatorUid); + choice.setLevel(level); choice.setPeriod(periodCode); - choice.setRegion(String.valueOf(regionId)); + choice.setFeatureId(String.valueOf(regionId)); choice.setYear(year); final var dto = new SummaryDTO(); if (averageValue != null) { @@ -273,12 +307,13 @@ public class IndicatorResource implements IndicatorService { } dto.setDate(Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant())); dto.setDailyValues(dailyValues); + if (featureName != null) { + dto.setFeatureName(featureName); + } dto.setIndicator(toDTO(indicator, locale)); dto.setMonthlyValues(monthlyValues); + dto.setParentFeature(parentFeature); dto.setPeriod(getTranslation(indicator.getPeriod().getNames(), locale)); - if (region != null) { - dto.setRegion(region.getName()); - } return dto; } diff --git a/www-server/src/test/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernateTest.java b/www-server/src/test/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernateTest.java index 930520312ac8cf67cba9de48f7ac4e6f879b4db4..3056f0bd7ba53a93d20648aac237de37b1852e17 100644 --- a/www-server/src/test/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernateTest.java +++ b/www-server/src/test/java/fr/agrometinfo/www/server/dao/MonthlyValueDaoHibernateTest.java @@ -31,7 +31,7 @@ class MonthlyValueDaoHibernateTest { final var indicator = indicatorDao.findByCodeAndPeriod("rainsum", "year"); final var date = dailyValueDao.findLastDate(indicator, 2023); final var region = dailyValueDao.findRegions().get(0); - final var actual = dao.find(indicator, region, date); + final var actual = dao.find(indicator, date, region); assertNotNull(actual); assertEquals(1, actual.size()); final Float expected = 22.F; diff --git a/www-server/src/test/java/fr/agrometinfo/www/server/dao/PraDaoHibernateTest.java b/www-server/src/test/java/fr/agrometinfo/www/server/dao/PraDaoHibernateTest.java index d295365e178d0d776e91a93509a4433599897e27..6eaac6a03e6917bc19bc19cd7a78a0d675f5732f 100644 --- a/www-server/src/test/java/fr/agrometinfo/www/server/dao/PraDaoHibernateTest.java +++ b/www-server/src/test/java/fr/agrometinfo/www/server/dao/PraDaoHibernateTest.java @@ -39,4 +39,12 @@ public class PraDaoHibernateTest { final int expected = 42; assertEquals(expected, first.getCoordinates().length); } + + @Test + void findByCode() { + final var code = "01195"; + final var actual = dao.findByCode(code); + assertNotNull(actual); + assertEquals(code, actual.getCode()); + } } diff --git a/www-server/src/test/java/fr/agrometinfo/www/server/rs/IndicatorResourceTest.java b/www-server/src/test/java/fr/agrometinfo/www/server/rs/IndicatorResourceTest.java index daa30b08e7889009f22bbb33a77adcb5b7385e18..9df22fa4a58e3011a73732b39986fe9d5069ead8 100644 --- a/www-server/src/test/java/fr/agrometinfo/www/server/rs/IndicatorResourceTest.java +++ b/www-server/src/test/java/fr/agrometinfo/www/server/rs/IndicatorResourceTest.java @@ -17,6 +17,8 @@ import fr.agrometinfo.www.server.dao.MonthlyValueDao; import fr.agrometinfo.www.server.dao.MonthlyValueDaoHibernate; import fr.agrometinfo.www.server.dao.PraDailyValueDao; import fr.agrometinfo.www.server.dao.PraDailyValueDaoHibernate; +import fr.agrometinfo.www.server.dao.PraDao; +import fr.agrometinfo.www.server.dao.PraDaoHibernate; import fr.agrometinfo.www.server.dao.RegionDao; import fr.agrometinfo.www.server.dao.RegionDaoHibernate; import jakarta.ws.rs.core.Application; @@ -38,6 +40,7 @@ class IndicatorResourceTest extends JerseyTest { protected final Application configure() { final CellDao cellDao = new CellDaoHibernate(); final PraDailyValueDao praDailyValueDao = new PraDailyValueDaoHibernate(); + final PraDao praDao = new PraDaoHibernate(); final IndicatorDao indicatorDao = new IndicatorDaoHibernate(); final MonthlyValueDao monthlyValueDao = new MonthlyValueDaoHibernate(); final RegionDao regionDao = new RegionDaoHibernate(); @@ -46,6 +49,7 @@ class IndicatorResourceTest extends JerseyTest { public void configure() { bind(cellDao).to(CellDao.class); bind(praDailyValueDao).to(PraDailyValueDao.class); + bind(praDao).to(PraDao.class); bind(indicatorDao).to(IndicatorDao.class); bind(monthlyValueDao).to(MonthlyValueDao.class); bind(regionDao).to(RegionDao.class); diff --git a/www-shared/config/pmd-suppressions.properties b/www-shared/config/pmd-suppressions.properties index 86faec274b17c99d94ed5ed9b248e28b029259af..0864a4a508a06646cdc83d76eb2c76a0623cfee0 100644 --- a/www-shared/config/pmd-suppressions.properties +++ b/www-shared/config/pmd-suppressions.properties @@ -9,6 +9,8 @@ fr.agrometinfo.www.shared.dto.IndicatorDTO_MapperImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.PeriodDTOBeanJsonDeserializerImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.PeriodDTOBeanJsonSerializerImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.PeriodDTO_MapperImpl=UnnecessaryImport +fr.agrometinfo.www.shared.dto.SimpleFeatureBeanJsonDeserializerImpl=UnnecessaryImport +fr.agrometinfo.www.shared.dto.SimpleFeatureBeanJsonSerializerImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.SummaryDTOBeanJsonDeserializerImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.SummaryDTOBeanJsonSerializerImpl=UnnecessaryImport fr.agrometinfo.www.shared.dto.SummaryDTO_MapperImpl=UnnecessaryImport diff --git a/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/ChoiceDTO.java b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/ChoiceDTO.java index 0794bbcb3deb6d530d51868afd77e9c64905eddb..b35993c6ec5882e6c3f94b7edcce15e49bb562e0 100644 --- a/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/ChoiceDTO.java +++ b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/ChoiceDTO.java @@ -28,9 +28,14 @@ public final class ChoiceDTO { private String period; /** - * Chosen region. + * ID of chosen feature (region in left panel, PRA on map). */ - private String region; + private String featureId; + + /** + * Level of chosen feature (region in left panel or PRA on map). + */ + private FeatureLevel level; /** * Chosen year. @@ -44,6 +49,13 @@ public final class ChoiceDTO { return Boolean.TRUE.equals(comparison); } + /** + * @return Id of chosen feature + */ + public String getFeatureId() { + return featureId; + } + /** * @return ID of chosen indicator. */ @@ -52,17 +64,17 @@ public final class ChoiceDTO { } /** - * @return Period code of chosen indicator. + * @return Level of chosen feature (region in left panel or PRA on map). */ - public String getPeriod() { - return period; + public FeatureLevel getLevel() { + return level; } /** - * @return Chosen region. + * @return Period code of chosen indicator. */ - public String getRegion() { - return region; + public String getPeriod() { + return period; } /** @@ -89,6 +101,13 @@ public final class ChoiceDTO { this.comparison = value; } + /** + * @param value ID of chosen feature (region in left panel or PRA on map). + */ + public void setFeatureId(final String value) { + this.featureId = value; + } + /** * @param value ID of chosen indicator. */ @@ -97,17 +116,17 @@ public final class ChoiceDTO { } /** - * @param value Period code of chosen indicator. + * @param value Level of chosen feature (region in left panel or PRA on map). */ - public void setPeriod(final String value) { - this.period = value; + public void setLevel(final FeatureLevel value) { + this.level = value; } /** - * @param value Chosen region. + * @param value Period code of chosen indicator. */ - public void setRegion(final String value) { - this.region = value; + public void setPeriod(final String value) { + this.period = value; } /** @@ -119,8 +138,8 @@ public final class ChoiceDTO { @Override public String toString() { - return "ChoiceDTO [comparison=" + comparison + ", indicator=" + indicator + ", period=" + period + ", region=" - + region + ", year=" + year + "]"; + return "ChoiceDTO [comparison=" + comparison + ", indicator=" + indicator + ", period=" + period + + ", featureId=" + featureId + ", level=" + level + ", year=" + year + "]"; } } diff --git a/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/FeatureLevel.java b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/FeatureLevel.java new file mode 100644 index 0000000000000000000000000000000000000000..d5ab4681cc75da83faa8ed4af542836f685f4647 --- /dev/null +++ b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/FeatureLevel.java @@ -0,0 +1,22 @@ +package fr.agrometinfo.www.shared.dto; + +/** + * Level of selected feature. + * + * @author Olivier Maury + */ +public enum FeatureLevel { + /** + * SAFRAN cell. + */ + CELL, + /** + * Petite Région Agricole. + */ + PRA, + /** + * Region. + */ + REGION; +} + diff --git a/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/SimpleFeature.java b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/SimpleFeature.java new file mode 100644 index 0000000000000000000000000000000000000000..0f7d4b37a33dfca5a8303663fa6530a1f73cee2c --- /dev/null +++ b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/SimpleFeature.java @@ -0,0 +1,63 @@ +package fr.agrometinfo.www.shared.dto; + +/** + * A geographic object. + * + * @author Olivier Maury + */ +public class SimpleFeature { + /** + * Unique identifier. + */ + private String id; + /** + * Display name. + */ + private String name; + /** + * Level. + */ + private FeatureLevel level; + + /** + * @return Unique identifier. + */ + public final String getId() { + return id; + } + + /** + * @return Level. + */ + public final FeatureLevel getLevel() { + return level; + } + + /** + * @return Display name. + */ + public final String getName() { + return name; + } + + /** + * @param value Unique identifier. + */ + public final void setId(final String value) { + this.id = value; + } + + /** + * @param value Level. + */ + public final void setLevel(final FeatureLevel value) { + this.level = value; + } + + /** + * @param value Display name. + */ + public final void setName(final String value) { + this.name = value; + } +} diff --git a/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/SummaryDTO.java b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/SummaryDTO.java index 913c23dc01c8f02ca332cda272862ef3b05b3563..a6ba9f0d5072bf27fc58d93614b74facb2f8424c 100644 --- a/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/SummaryDTO.java +++ b/www-shared/src/main/java/fr/agrometinfo/www/shared/dto/SummaryDTO.java @@ -16,23 +16,32 @@ public class SummaryDTO { * Average daily value of the indicator for the user choice. */ private Float averageValue; - /** - * Average daily comparison value of the indicator for the user choice. - */ - private Float comparedValue; + /** * User choice. */ private ChoiceDTO choice; + + /** + * Average daily comparison value of the indicator for the user choice. + */ + private Float comparedValue; + /** * Last daily values for the indicator. */ private Map<Date, Float> dailyValues; + /** * Date of the last simulation. */ private Date date; + /** + * Feature name (region, PRA, cell). + */ + private String featureName; + /** * Chosen indicator. */ @@ -44,19 +53,22 @@ public class SummaryDTO { private Map<String, Float> monthlyValues; /** - * Period name. + * The parent feature if exists. */ - private String period; + private SimpleFeature parentFeature; + /** - * Region name. + * Period name. */ - private String region; + private String period; + /** * @return Average daily value of the indicator for the user choice. */ public final Float getAverageValue() { return averageValue; } + /** * @return User choice. */ @@ -85,6 +97,13 @@ public class SummaryDTO { return date; } + /** + * @return Feature name. + */ + public final String getFeatureName() { + return featureName; + } + /** * @return Chosen indicator. */ @@ -100,17 +119,17 @@ public class SummaryDTO { } /** - * @return period name + * @return The parent feature if exists. */ - public String getPeriod() { - return period; + public final SimpleFeature getParentFeature() { + return parentFeature; } /** - * @return Region name. + * @return period name */ - public final String getRegion() { - return region; + public String getPeriod() { + return period; } /** @@ -148,6 +167,13 @@ public class SummaryDTO { this.date = value; } + /** + * @param name Feature name. + */ + public final void setFeatureName(final String name) { + this.featureName = name; + } + /** * @param value Chosen indicator. */ @@ -163,16 +189,16 @@ public class SummaryDTO { } /** - * @param name period name + * @param feature The parent feature or null. */ - public final void setPeriod(final String name) { - this.period = name; + public final void setParentFeature(final SimpleFeature feature) { + this.parentFeature = feature; } /** - * @param name Region name. + * @param name period name */ - public final void setRegion(final String name) { - this.region = name; + public final void setPeriod(final String name) { + this.period = name; } } diff --git a/www-shared/src/main/java/fr/agrometinfo/www/shared/service/IndicatorService.java b/www-shared/src/main/java/fr/agrometinfo/www/shared/service/IndicatorService.java index 58cefcad7637affdd3ce5eaae0b8adb78bda166e..cd3d6330c1f610e12e98cc02f29725d339d4a84a 100644 --- a/www-shared/src/main/java/fr/agrometinfo/www/shared/service/IndicatorService.java +++ b/www-shared/src/main/java/fr/agrometinfo/www/shared/service/IndicatorService.java @@ -10,6 +10,7 @@ import javax.ws.rs.QueryParam; import org.dominokit.rest.shared.request.service.annotations.RequestFactory; import org.geojson.FeatureCollection; +import fr.agrometinfo.www.shared.dto.FeatureLevel; import fr.agrometinfo.www.shared.dto.PeriodDTO; import fr.agrometinfo.www.shared.dto.SummaryDTO; @@ -63,20 +64,21 @@ public interface IndicatorService { Map<String, String> getRegions(); /** - * @param indicator indicator coe + * @param indicator indicator code * @param period period code - * @param region region ID + * @param level feature level + * @param id feature ID * @param year year * @return indicator summary for the user choice. */ @GET @Path(PATH_SUMMARY) SummaryDTO getSummary(@QueryParam(value = "indicator") String indicator, - @QueryParam(value = "period") String period, @QueryParam(value = "region") Integer region, - @QueryParam(value = "year") Integer year); + @QueryParam(value = "period") String period, @QueryParam(value = "level") FeatureLevel level, + @QueryParam(value = "id") String id, @QueryParam(value = "year") Integer year); /** - * @param indicator indicator coe + * @param indicator indicator code * @param period period code * @param region region ID * @param year year