Parcourir la source

Fixing of service and adding Track services

Fixing of Export service, added service for List of export styles
Added Track service - listing of available dates, providing track in
GeoJSON format per unit
mkepka il y a 3 ans
Parent
commit
8011e6574b

+ 2 - 0
src/main/java/cz/hsrs/rest/ParamsList.java

@@ -50,4 +50,6 @@ public class ParamsList {
      * Values for parameters for REST services 
      */
     public static final String CROSS_TAB_STYLE = "crosstab";
+    public static final String EXPORT_STYLE = "style";
+    
 }

+ 29 - 1
src/main/java/cz/hsrs/rest/provider/ObservationRest.java

@@ -11,6 +11,7 @@ import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
@@ -25,6 +26,8 @@ import cz.hsrs.rest.ParamsList;
 import cz.hsrs.rest.beans.ExceptionBean;
 import cz.hsrs.rest.util.AuthUtil;
 import cz.hsrs.servlet.security.LoginUser;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
 
 /**
  * @author mkepka
@@ -57,7 +60,7 @@ public class ObservationRest {
             @QueryParam(ParamsList.GROUP_ID) Integer groupId,
             @QueryParam(ParamsList.FROM_TIME) String fromTime,
             @QueryParam(ParamsList.TO_TIME) String toTime,
-            @QueryParam("style") String exportStyle,
+            @QueryParam(ParamsList.EXPORT_STYLE) String exportStyle,
             @DefaultValue("true") @QueryParam("nullable") Boolean nullable,
             @Context HttpServletRequest req){
         try {
@@ -94,4 +97,29 @@ public class ObservationRest {
                     .build();
 		}
     }
+    
+    @Path("/exportstyle")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getExportStyles() {
+    	JSONArray arr = new JSONArray();
+    	/* crosstab style*/
+    	JSONObject obj1 = new JSONObject();
+    	obj1.put("style_id", "crosstab");
+    	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_name", "Time series table");
+    	obj2.put("description", "Table with units in rows and dates in columns, available for one observed property.");
+    	arr.add(obj2);
+    	
+        return Response.ok()
+                .entity(arr)
+                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
+                .build();
+    }
 }

+ 151 - 0
src/main/java/cz/hsrs/rest/provider/TrackRest.java

@@ -0,0 +1,151 @@
+/**
+ * 
+ */
+package cz.hsrs.rest.provider;
+
+import java.sql.SQLException;
+import java.text.ParseException;
+import java.util.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.mortbay.jetty.HttpStatus;
+
+import cz.hsrs.db.util.DateUtil;
+import cz.hsrs.rest.ParamsList;
+import cz.hsrs.rest.beans.ExceptionBean;
+import cz.hsrs.rest.util.TrackRestUtil;
+
+/**
+ * @author mkepka
+ *
+ */
+@Path("/track/")
+public class TrackRest {
+
+	public static Logger logger = Logger.getLogger("TrackRest");
+	
+    /**
+     * Empty constructor
+     */
+	public TrackRest() {
+		super();
+	}
+    
+	/**
+	 * /rest/track/dates?group_name=
+	 * /rest/track/dates?group_id=
+	 * /rest/track/dates?unit_id=
+	 * 
+	 * @param unitIds
+	 * @param groupId
+	 * @param req
+	 * @return
+	 */
+	@Path("/dates")
+    @GET
+	public Response getDatesOfTracks(
+			@QueryParam(ParamsList.UNIT_ID) String unitIds,
+			@QueryParam(ParamsList.GROUP_ID) Integer groupId,
+			@QueryParam(ParamsList.GROUP_NAME) String groupName,
+			@Context HttpServletRequest req){
+		try {
+			//LoginUser loggedUser = AuthUtil.getAuthenticatedLoginUser(req);
+			if(groupId == null) {
+				//groupId = UserUtil.getUserGroupId(loggedUser.getUserName());
+			}
+			String jsonTimes;
+			if(unitIds!= null && !unitIds.isEmpty()){
+				jsonTimes = TrackRestUtil.getDatesByUnits(unitIds);
+			}
+    		else if (groupId != null){
+    			jsonTimes = TrackRestUtil.getDatesByUnitsByGroup(groupId);
+    			
+    		}
+    		else if(groupName !=null && !groupName.isEmpty()) {
+    			jsonTimes = TrackRestUtil.getDatesByUnitsByGroup(groupName);
+    		}
+    		else {
+    			throw new SQLException("Wrong combination of parameters");
+    		}
+            return Response.ok()
+                    .entity(jsonTimes)
+                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
+                    .build();
+		} catch (SQLException e) {
+            return Response.status(HttpStatus.ORDINAL_500_Internal_Server_Error)
+                    .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
+                    .build();
+        }/* catch (AuthenticationException e) {
+        	return Response.status(HttpStatus.ORDINAL_401_Unauthorized)
+                    .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
+                    .build();
+		}*/
+	}
+	
+	/**
+	 * /rest/track/points
+	 * /rest/track/points?unit_id=352625691996753&from_time=2022-03-19 10:00:00&to_time=2022-03-29 12:00:00
+	 * @param unitId
+	 * @param fromTime
+	 * @param toTime
+	 * @param req
+	 * @return
+	 */
+	@Path("/points")
+    @GET
+	public Response getPointsOfTrack(
+			@QueryParam(ParamsList.UNIT_ID) Long unitId,
+			@QueryParam(ParamsList.SENSOR_ID) String sensorIds,
+			@QueryParam(ParamsList.FROM_TIME) String fromTime,
+			@QueryParam(ParamsList.TO_TIME) String toTime,
+			@Context HttpServletRequest req){
+		try {
+			//LoginUser loggedUser = AuthUtil.getAuthenticatedLoginUser(req);
+
+			if(fromTime != null && toTime != null) {
+				long weekInMilis = (7*24*60*60*1000);
+				if((DateUtil.parseTimestamp(toTime).getTime() - DateUtil.parseTimestamp(fromTime).getTime()) <= weekInMilis) {
+					String geoJson = TrackRestUtil.getTrackPoints(unitId, sensorIds, fromTime, toTime);
+					return Response.ok()
+		                .entity(geoJson)
+		                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
+		                .build();
+				}
+				else {
+					throw new SQLException("Too long interval for data selection");
+				}
+				
+			}
+			else if(fromTime != null && toTime == null){
+				String geoJson = TrackRestUtil.getTrackPoints(unitId, sensorIds, fromTime, toTime);
+				return Response.ok()
+	                .entity(geoJson)
+	                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
+	                .build();
+			}
+			else {
+				throw new SQLException("Wrong combination of parameters");
+			}
+		} catch (SQLException e) {
+			return Response.status(HttpStatus.ORDINAL_500_Internal_Server_Error)
+                .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
+                .build();
+		} catch (ParseException e) {
+			return Response.status(HttpStatus.ORDINAL_400_Bad_Request)
+	                .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
+	                .build();
+		}/* catch (AuthenticationException e) {
+        	return Response.status(HttpStatus.ORDINAL_401_Unauthorized)
+                    .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
+                    .build();
+		}*/
+	}
+}

+ 159 - 0
src/main/java/cz/hsrs/rest/util/TrackRestUtil.java

@@ -0,0 +1,159 @@
+/**
+ * 
+ */
+package cz.hsrs.rest.util;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import cz.hsrs.db.pool.SQLExecutor;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+/**
+ * @author mkepka
+ *
+ */
+public class TrackRestUtil {
+
+	/**
+	 * Function selects days of stored positions for given list of units
+	 * @param unitIds - list of unit IDs separated by commas
+	 * @return JSON Array as String containing arrays of active days for each unit in group
+	 * @throws SQLException 
+	 */
+	public static String getDatesByUnits(String unitIds) throws SQLException {
+		String query = "SELECT t.unit_id, t.description, json_agg(t.date_trunc) FROM"
+				+ " (SELECT u.unit_id, u.description, date_trunc('day', up.time_stamp)::date"
+					+ " FROM public.units_positions up, units u"
+					+ " WHERE u.unit_id IN ("+unitIds+") AND u.unit_id = up.unit_id"
+					+ " GROUP BY u.unit_id, date_trunc ORDER BY u.unit_id, date_trunc) t"
+				+ " GROUP BY t.unit_id, t.description;";
+		ResultSet res = SQLExecutor.getInstance().executeQuery(query);
+		JSONArray units = new JSONArray();
+		if(res != null) {
+			while(res.next()) {
+				JSONObject unit = new JSONObject();
+				unit.element("unit_id", res.getLong("unit_id"));
+				unit.element("unit_description", res.getString("description"));
+				unit.element("dates", res.getString("json_agg"));
+				units.add(unit);
+			}
+		}
+		return units.toString();
+	}
+
+	/**
+	 * Function selects days of stored positions for units in given group 
+	 * @param groupId - ID of group for selecting list of units
+	 * @return JSON Array as String containing arrays of active days for each unit in group
+	 * @throws SQLException
+	 */
+	public static String getDatesByUnitsByGroup(int groupId) throws SQLException {
+		String query = "SELECT t.unit_id, t.description, json_agg(t.date_trunc) FROM"
+				+ " (SELECT u.unit_id, u.description, date_trunc('day', up.time_stamp)::date"
+				+ " FROM public.units_positions up, units u"
+				+ " WHERE u.unit_id IN ("
+				+ "SELECT unit_id FROM units_to_groups WHERE group_id = "+groupId+")"
+				+ " GROUP BY u.unit_id, date_trunc ORDER BY u.unit_id, date_trunc) t"
+				+ " GROUP BY t.unit_id, t.description;";
+		ResultSet res = SQLExecutor.getInstance().executeQuery(query);
+		JSONArray units = new JSONArray();
+		if(res != null) {
+			while(res.next()) {
+				JSONObject unit = new JSONObject();
+				unit.element("unit_id", res.getLong("unit_id"));
+				unit.element("unit_description", res.getString("description"));
+				unit.element("dates", res.getString("json_agg"));
+				units.add(unit);
+			}
+		}
+		return units.toString();
+	}
+	
+	/**
+	 * Function selects days of stored positions for units in given group
+	 * @param groupName - name of unit group
+	 * @return JSON Array as String containing arrays of active days for each unit in group
+	 * @throws SQLException
+	 */
+	public static String getDatesByUnitsByGroup(String groupName) throws SQLException {
+		String query = "SELECT t.unit_id, t.description, json_agg(t.date_trunc) FROM"
+				+ " (SELECT u.unit_id, u.description, date_trunc('day', up.time_stamp)::date"
+				+ " FROM public.units_positions up, units u"
+				+ " WHERE u.unit_id IN ("
+				+ "SELECT unit_id FROM units_to_groups utg, groups g WHERE utg.group_id = g.id AND g.group_name='"+groupName+"')"
+				+ " GROUP BY u.unit_id, date_trunc ORDER BY u.unit_id, date_trunc) t"
+				+ " GROUP BY t.unit_id, t.description;";
+		ResultSet res = SQLExecutor.getInstance().executeQuery(query);
+		JSONArray units = new JSONArray();
+		if(res != null) {
+			while(res.next()) {
+				JSONObject unit = new JSONObject();
+				unit.element("unit_id", res.getLong("unit_id"));
+				unit.element("unit_description", res.getString("description"));
+				unit.element("dates", res.getString("json_agg"));
+				units.add(unit);
+			}
+		}
+		return units.toString();
+	}
+
+	/**
+	 * 
+	 * @param unitId
+	 * @param sensorIds
+	 * @param fromDate
+	 * @param toDate
+	 * @return
+	 * @throws SQLException
+	 */
+	public static String getTrackPoints(long unitId, String sensorIds, String fromDate, String toDate) throws SQLException {
+		StringBuilder query = new StringBuilder();
+		query.append("SELECT t.gid, t.geom, t.time_stamp, json_agg(json_build_object(t.sensor_name::text, t.observed_value))"
+					+ " FROM ("
+						+ "SELECT up.gid, st_asgeojson(up.the_geom) AS geom, up.time_stamp, o.observed_value, s.sensor_name"
+						+ " FROM units_positions up, observations o, sensors s");
+		query.append(" WHERE up.unit_id = "+unitId);
+		if(sensorIds != null) {
+			query.append(" AND o.sensor_id IN ("+sensorIds+")");
+		}
+		query.append(" AND up.gid = o.gid AND o.sensor_id = s.sensor_id");
+		if(fromDate != null && toDate == null) { 
+			query.append(" AND up.time_stamp >= '"+fromDate+"' AND up.time_stamp < ('"+fromDate+"'::date + interval '1 day')");
+		}
+		if(fromDate != null && toDate != null) {
+			query.append(" AND up.time_stamp >= '"+fromDate+"' AND up.time_stamp < '"+toDate+"'");
+		}
+		query.append(" ORDER BY up.time_stamp) t GROUP BY t.gid, t.geom, t.time_stamp;");
+		
+		String queryFull = query.toString();
+	
+		ResultSet res = SQLExecutor.getInstance().executeQuery(queryFull);
+		
+    	JSONObject geojson = new JSONObject();
+    	if(res != null) {
+    		geojson.element("type", "FeatureCollection");
+        	JSONArray features = new JSONArray();
+        	
+        	while (res.next()) {
+        		JSONObject feature = new JSONObject();
+            	feature.element("type", "Feature");
+            	
+            	JSONObject properties = new JSONObject();
+            	properties.element("time_stamp", res.getString("time_stamp")+"00");
+            	JSONObject obs = JSONObject.fromObject(res.getObject("json_agg"));
+            	JSONArray arr = JSONArray.fromObject(obs.get("value"));
+            	for(int i = 0; i < arr.size(); i++) {
+            		properties.accumulateAll(arr.getJSONObject(i));
+            	}
+            	feature.element("properties", properties);
+            	feature.element("geometry", res.getString("geom"));
+            	
+            	features.add(feature);
+        	}        	
+        	geojson.element("features", features);
+    	}
+    	return geojson.toString(); 
+	}
+}