ソースを参照

Fixed /export method for 'timeseries' style

Method fixed for units without locations when sending data
Rename style name to timeseries
mkepka 3 年 前
コミット
c100b846b5

+ 25 - 8
src/main/java/cz/hsrs/db/util/ExportUtil.java

@@ -1,23 +1,24 @@
 package cz.hsrs.db.util;
 
+import static java.util.stream.Collectors.toList;
+
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Types;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
-import java.time.OffsetDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.*;
-import java.util.regex.Matcher;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 import java.util.regex.Pattern;
-import java.util.stream.Collectors;
 
 import cz.hsrs.db.model.Unit;
 import cz.hsrs.db.pool.SQLExecutor;
 
-import static java.util.stream.Collectors.toList;
-
 /**
  * 
  * @author mkepka
@@ -140,6 +141,17 @@ public class ExportUtil {
         return getObservationsBySensorByUnits(sensorId, unitIdsStr, groupId, fromTime, toTime, nullable);
     }
 
+    /**
+     * 
+     * @param sensorId
+     * @param unitIds
+     * @param groupId
+     * @param fromTime
+     * @param toTime
+     * @param nullable
+     * @return
+     * @throws SQLException
+     */
     public static String getObservationsBySensorByUnits(long sensorId, String unitIds, int groupId, LocalDateTime fromTime, LocalDateTime toTime, boolean nullable) throws SQLException {
         // long sensorId, int groupId, String fromTime, String toTime, boolean nullable
         if (!Pattern.compile("^[\\d,\\s]+$").matcher(unitIds).find()) {
@@ -154,7 +166,7 @@ public class ExportUtil {
         Map<Long, Location> unitToPosition = parseUnitPosition(unitRes);
 
         String sqlObsQuery = String.format("SELECT unit_id, time_stamp, observed_value FROM observations\n" +
-                "WHERE unit_id IN (%s) AND sensor_id = %d AND time_stamp >= '%s' AND time_stamp <= '%s' ORDER BY time_stamp;",
+                "WHERE unit_id IN (%s) AND sensor_id = %d AND time_stamp >= '%s' AND time_stamp < '%s' ORDER BY time_stamp;",
                 unitIds, sensorId, fromTime, toTime);
         ResultSet obsRes = SQLExecutor.getInstance().executeQuery(sqlObsQuery);
         Map<Long, Map<LocalDateTime, List<Double>>> unitToObs = parseUnitObservation(obsRes);
@@ -174,7 +186,12 @@ public class ExportUtil {
             long unitId = unitToEntry.getKey();
             Map<LocalDateTime, List<Double>> obsAtTimestamp = unitToEntry.getValue();
             Location unitLocation = unitToPosition.get(unitId);
-            csv.append(unitId).append(";").append(unitLocation.lon).append(";").append(unitLocation.lat);
+            if(unitLocation != null) {
+            	csv.append(unitId).append(";").append(unitLocation.lon).append(";").append(unitLocation.lat);
+            }
+            else {
+            	csv.append(unitId).append(";").append("").append(";").append("");
+            }
             for (LocalDateTime timestampColumn : timestampColumns) {
                 double val = obsAtTimestamp.getOrDefault(timestampColumn, Collections.emptyList()).stream().mapToDouble(d -> d).average().orElse(Double.NaN);
                 csv.append(";").append(Double.isNaN(val) ? "" : val);

+ 1 - 1
src/main/java/cz/hsrs/rest/ParamsList.java

@@ -52,7 +52,7 @@ public class ParamsList {
      * Values for parameters for REST services 
      */
     public static final String CROSS_TAB_STYLE = "crosstab";
-    public static final String REVERSE_TAB_STYLE = "reverse_crosstab";
+    public static final String TIMESERIES_STYLE = "timeseries";
     public static final String EXPORT_STYLE = "style";
     
 }

+ 15 - 9
src/main/java/cz/hsrs/rest/provider/ObservationRest.java

@@ -4,13 +4,14 @@
 package cz.hsrs.rest.provider;
 
 import java.sql.SQLException;
-import java.time.*;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.util.logging.Logger;
 
 import javax.naming.AuthenticationException;
 import javax.servlet.http.HttpServletRequest;
-import javax.validation.constraints.NotNull;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
@@ -54,6 +55,10 @@ public class ObservationRest {
      * /rest/observation/export?group_id=25&sensor_id=340340092&from_time=2021-05-30&to_time=2021-05-31&style=crosstab
      * /rest/observation/export?group_id=25&sensor_id=340340092&from_time=2021-05-30&to_time=2021-05-30+04:00:00&style=crosstab&nullable=false
      * /rest/observation/export?unit_id=1305167563044155,1305167563032199,1305167563051210&sensor_id=340340092&from_time=2021-05-30&to_time=2021-05-30+04:00:00&style=crosstab&nullable=false
+     * /rest/observation/export?group_id=25&sensor_id=340340092&from_time=2021-05-30&to_time=2021-05-31&style=timeseries
+     * /rest/observation/export?unit_id=1305167563044724,1305167563025379&sensor_id=340340092&from_time=2021-05-30&to_time=2021-05-31&style=timeseries
+     * /rest/observation/export?group_id=25&sensor_id=340340092&month_of_year=4&year=2021&style=timeseries
+     * 
      */
     @Path("/export")
     @GET
@@ -88,14 +93,13 @@ public class ObservationRest {
                 else {
                 	CSV = ExportUtil.getObservationsBySensorByGroupCross(sensorId, groupId, fromTime, toTime, nullable);
                 }
-            } else if(exportStyle.equalsIgnoreCase(ParamsList.REVERSE_TAB_STYLE)) {
+            } else if(exportStyle.equalsIgnoreCase(ParamsList.TIMESERIES_STYLE)) {
                 if (sensorId == null) {
                     return Response.status(HttpStatus.ORDINAL_400_Bad_Request)
-                            .entity(String.format("Request does not contain sensor id. Define: '%s'.", ParamsList.SENSOR_ID))
+                            .entity(String.format("Request does not contain sensor_id. Define: '%s'.", ParamsList.SENSOR_ID))
                             .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN)
                             .build();
                 }
-
                 LocalDateTime fromTimestamp;
                 LocalDateTime toTimestamp;
                 if (monthOfYear != null && monthOfYear > 0 && year != null && year > 0) {
@@ -103,7 +107,8 @@ public class ObservationRest {
                     fromTimestamp = LocalDateTime.of(date, LocalTime.MIN);
                     toTimestamp = fromTimestamp.plusMonths(1);
                 } else if (fromTime != null && toTime != null) {
-                    final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+                	final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+                	
                     fromTimestamp = LocalDateTime.parse(fromTime, formatter);
                     toTimestamp = LocalDateTime.parse(toTime, formatter);
                 } else {
@@ -135,7 +140,8 @@ public class ObservationRest {
                     .build();
         } catch (AuthenticationException e) {
         	return Response.status(HttpStatus.ORDINAL_401_Unauthorized)
-                    .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
+                    .entity(new ExceptionBean(e.getClass().getName(), e.getMessage()))
+                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
                     .build();
 		}
     }
@@ -147,14 +153,14 @@ public class ObservationRest {
     	JSONArray arr = new JSONArray();
     	/* crosstab style*/
     	JSONObject obj1 = new JSONObject();
-    	obj1.put("style_id", "crosstab");
+    	obj1.put("style_id", ParamsList.CROSS_TAB_STYLE);
     	obj1.put("style_name", "Cross table");
     	obj1.put("description", "Table with dates in rows and units/sensors in columns.");
     	arr.add(obj1);
     	
     	/* timeseries style*/
     	JSONObject obj2 = new JSONObject();
-    	obj2.put("style_id", "timeseries");
+    	obj2.put("style_id", ParamsList.TIMESERIES_STYLE);
     	obj2.put("style_name", "Time series table");
     	obj2.put("description", "Table with units in rows and dates in columns, available for one observed property.");
     	arr.add(obj2);