Bläddra i källkod

移动距离 算法更新

suntianwu 3 år sedan
förälder
incheckning
bed5d14add

+ 5 - 1
src/main/java/com/care/common/cache/RedisKeyConstant.java

@@ -83,7 +83,11 @@ public class RedisKeyConstant {
 
     //活动信息 1天
     public static final String PEOPLEEVENT_ACTIVE_INFO = "PEOPLEEVENT:ACTIVE";
-    public static final int PEOPLEEVENT_ACTIVE_INFO_TIME = 60*2;
+    public static final int PEOPLEEVENT_ACTIVE_INFO_TIME = 3600 * 24;
+
+    //活动信息最近index 1天
+    public static final String PEOPLEEVENT_ACTIVE_INFO_LAST_INDEX = "PEOPLEEVENT:ACTIVE_LAST_INDEX";
+    public static final int PEOPLEEVENT_ACTIVE_INFO_ACTIVE_LAST_INDEX_TIME = 3600 * 24;
 
     // 与安服务平台 -> 小程序, QRCODE
     public static final String YUANSERVICE_QRCODE = "YUANSERVICE:QRCODE";

+ 77 - 36
src/main/java/com/care/mqtt/service/MqttMsgService.java

@@ -15,6 +15,7 @@ import com.care.common.entity.*;
 import com.care.common.enums.*;
 import com.care.common.service.*;
 import com.care.common.vo.device.MqttMsgVO;
+import io.swagger.models.auth.In;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -171,44 +172,45 @@ public class MqttMsgService {
             for(Map target : targets) {
                 Integer tid = (Integer) target.get("tid");
                 Integer cls = (Integer) target.get("cls");
-                BigDecimal x = new BigDecimal(String.valueOf(target.get("x"))) ;
-                BigDecimal y = new BigDecimal(String.valueOf(target.get("y"))) ;
+                double x = Double.parseDouble(String.valueOf(target.get("x"))) ;
+                double y = Double.parseDouble(String.valueOf(target.get("y"))) ;
                 if (cls == 1) { //是人
                     //先查是否存在
-                    String content = (String)redisUtil.hget(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO,careDevice.getDevCode()+ "_" + tid);
-                    if (content != null) {//之前有存储redis
-                        //计算当前的和存储的之间距离和时长
-                        double distance = getDistance(new BigDecimal(content.split("_")[1]),x,new BigDecimal(content.split("_")[2]),y);
-                        long duration = (date.getTime() - Long.parseLong(content.split("_")[0]));
-
-                        //存储行走距离明细表
-                        CareWalkingDistanceDetail careWalkingDistanceDetail = new CareWalkingDistanceDetail();
-                        careWalkingDistanceDetail.setDevId(careDevice.getId());
-                        careWalkingDistanceDetail.setTid(tid);
-                        careWalkingDistanceDetail.setDevScene(careDevice.getDevScene());
-                        careWalkingDistanceDetail.setWalkingDistance(distance);
-                        careWalkingDistanceDetail.setWalkingDuration(duration);
-                        careWalkingDistanceDetail.setCreateTime(date);
-                        careWalkingDistanceDetail.setModifyTime(date);
-                        careWalkingDistanceDetailService.save(careWalkingDistanceDetail);
-
-                        //加上之前累积的距离和时长
-                        double distanceTotal = distance + Double.parseDouble(content.split("_")[3]);
-                        long timeTotal = duration +  Long.parseLong(content.split("_")[4]);
-
-                        if ( timeTotal < 1000) { //累计时间不够一秒
-                            //更新redis
-                            redisUtil.hset(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO, careDevice.getDevCode() + "_" + tid, System.currentTimeMillis() +  "_" + x + "_" + y + "_" + distanceTotal +"_" + timeTotal, RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_TIME);
-
-                        } else { //够一秒
-                            if ( distanceTotal > 0.3) {
-                                moveState = DeviceMoveStateEnum.MOVE.getValue();
+                    Integer lastIndex = (Integer)redisUtil.hget(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_LAST_INDEX,careDevice.getDevCode() + "_" + tid);
+                    if(lastIndex == null) {//之前没有存储redis,则存储第一个
+                        redisUtil.hset(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO, 1 + "@" + careDevice.getDevCode() + "_" + tid , System.currentTimeMillis() +  "_" + x + "_" + y , RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_TIME);
+                        redisUtil.hset(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_LAST_INDEX, careDevice.getDevCode() + "_" + tid , 1 , RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_ACTIVE_LAST_INDEX_TIME);
+                    } else{
+                        //计算当前和最近之间时间,若超过1秒,删除之前的存储的,重新计数存储当前的
+                        String lastContent = (String)redisUtil.hget(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO,lastIndex + "@" + careDevice.getDevCode() + "_" + tid );
+                        long duration = (date.getTime() - Long.parseLong(lastContent.split("_")[0]));
+                        if (duration > 1000) { //超过1秒,删除之前的存储的,从头开始
+                            delBeforeContent(lastIndex,careDevice.getDevCode(),tid);
+                            redisUtil.hset(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO, 1 + "@" + careDevice.getDevCode() + "_" + tid , System.currentTimeMillis() +  "_" + x + "_" + y, RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_TIME);
+                            redisUtil.hset(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_LAST_INDEX, careDevice.getDevCode() + "_" + tid , 1 , RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_ACTIVE_LAST_INDEX_TIME);
+                        } else {
+                            //存储以供后面计算
+                            redisUtil.hset(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO, (lastIndex + 1) + "@" + careDevice.getDevCode() + "_" + tid , System.currentTimeMillis() +  "_" + x + "_" + y, RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_TIME);
+                            redisUtil.hset(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_LAST_INDEX, careDevice.getDevCode() + "_" + tid , lastIndex + 1 , RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_ACTIVE_LAST_INDEX_TIME);
+                            if(lastIndex >= 9) {
+                                int currIndex = lastIndex + 1;//当前是第10个或以上 开始计算
+                                //求前5个点平均坐标和后5个点的平均坐标,二者之间的距离即结果
+                                double distance = getDistance(currIndex,careDevice.getDevCode(),tid);
+                                if(distance > 0.3){
+                                    moveState = DeviceMoveStateEnum.MOVE.getValue();
+                                    //存储行走距离明细表
+                                    CareWalkingDistanceDetail careWalkingDistanceDetail = new CareWalkingDistanceDetail();
+                                    careWalkingDistanceDetail.setDevId(careDevice.getId());
+                                    careWalkingDistanceDetail.setTid(tid);
+                                    careWalkingDistanceDetail.setDevScene(careDevice.getDevScene());
+                                    careWalkingDistanceDetail.setWalkingDistance(distance);
+                                    careWalkingDistanceDetail.setWalkingDuration(duration);
+                                    careWalkingDistanceDetail.setCreateTime(date);
+                                    careWalkingDistanceDetail.setModifyTime(date);
+                                    careWalkingDistanceDetailService.save(careWalkingDistanceDetail);
+                                }
                             }
-                            //清除redis
-                            redisUtil.hset(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO, careDevice.getDevCode() + "_" + tid, null, RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_TIME);
                         }
-                    } else { //之前没有存储redis,则存储redis
-                        redisUtil.hset(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO, careDevice.getDevCode() + "_" + tid, System.currentTimeMillis() +  "_" + x + "_" + y + "_" + 0 + "_" + 0, RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_TIME);
                     }
                 }
             }
@@ -222,10 +224,49 @@ public class MqttMsgService {
 
     }
 
-    private double getDistance(BigDecimal x1, BigDecimal y1,BigDecimal x2, BigDecimal y2) {
-        double distance =  Math.sqrt(Math.abs((x1.doubleValue() - x2.doubleValue())*(x1.doubleValue() - x2.doubleValue()))+Math.abs((y1.doubleValue() - y2.doubleValue())*(y1.doubleValue() - y2.doubleValue())));
+    private void delBeforeContent(int lastIndex,String devCode,Integer tid) {
+        for(int i = lastIndex; i >= 1; i--) {
+            redisUtil.hset(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO, i + "@" + devCode + "_" + tid, null, RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO_TIME);
+        }
+      }
+
+    private double getDistance(int currIndex, String devCode,Integer tid) {
+        double totalX1 = 0;
+        double totalY1 = 0;
+        for(int i = currIndex - 9; i <= currIndex - 5; i++) {
+            String content = (String)redisUtil.hget(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO,i + "@" + devCode + "_" + tid );
+            double x = Double.parseDouble(String.valueOf(content.split("_")[1]));
+            totalX1 += x;
+            double y = Double.parseDouble(String.valueOf(content.split("_")[2]));
+            totalY1 += y;
+        }
+        double avgX1 = totalX1 / 5;
+        double avgY1 = totalY1 / 5;
+
+        double totalX2 = 0;
+        double totalY2 = 0;
+        for(int i = currIndex - 4; i <= currIndex; i++) {
+            String content = (String)redisUtil.hget(RedisKeyConstant.PEOPLEEVENT_ACTIVE_INFO,i + "@" + devCode + "_" + tid );
+            double x = Double.parseDouble(String.valueOf(content.split("_")[1]));
+            totalX2 += x;
+            double y = Double.parseDouble(String.valueOf(content.split("_")[2]));
+            totalY2 += y;
+        }
+
+        double avgX2 = totalX2 / 5;
+        double avgY2 = totalY2 / 5;
+
+
+        double distance = getDistance(avgX1,avgY1,avgX2,avgY2);
+        return distance;
+    }
+
+    private double getDistance(double x1, double y1,double x2, double y2) {
+        double distance =  Math.sqrt(Math.abs((x1 - x2)*(x1 - x2))+Math.abs((y1 - y2)*(y1 - y2)));
         return distance;
     }
+
+
     private void handleOptInOut(Map msg,CareDevice careDevice,Date date){
         Integer event = (Integer) msg.get("event"); //1 进事件,2 出事件
         Integer type = (Integer) msg.get("type");