提交 3c00542a 作者: 方治民

feat: 简化信标、围栏存储表字段、新增真源实时消息日志存储、README 新增 JTS 引用

上级 f360f80d
...@@ -33,3 +33,9 @@ ...@@ -33,3 +33,9 @@
- [ ] XXL-JOB 定时任务模块 - [ ] XXL-JOB 定时任务模块
- [x] @Convert 处理 Raw JSON 数据格式转换 - [x] @Convert 处理 Raw JSON 数据格式转换
- [ ] 扩展 PostgresDialect 实现时序查询函数 - [ ] 扩展 PostgresDialect 实现时序查询函数
---
> 引用
1. [JTS](https://github.com/locationtech/jts)
2. [GeoTools](http://docs.geotools.org/)
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.domain.alarm;
/**
* 标签报警
*
* @author Jim
* @version 0.1
* 2022/4/25 15:38
*/
public class TagAlarm {}
...@@ -2,20 +2,21 @@ ...@@ -2,20 +2,21 @@
package com.yiring.app.domain.location; package com.yiring.app.domain.location;
import com.yiring.common.annotation.FieldMapping; import com.yiring.common.annotation.FieldMapping;
import com.yiring.common.domain.BasicEntity;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import javax.persistence.*; import javax.persistence.*;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
import org.hibernate.snowflake.SnowflakeId;
import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Point;
/** /**
...@@ -32,7 +33,7 @@ import org.locationtech.jts.geom.Point; ...@@ -32,7 +33,7 @@ import org.locationtech.jts.geom.Point;
@Getter @Getter
@Setter @Setter
@ToString @ToString
@Builder @SuperBuilder(toBuilder = true)
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@FieldNameConstants @FieldNameConstants
...@@ -43,17 +44,11 @@ import org.locationtech.jts.geom.Point; ...@@ -43,17 +44,11 @@ import org.locationtech.jts.geom.Point;
indexes = { @Index(columnList = "linkId"), @Index(columnList = "code", unique = true) } indexes = { @Index(columnList = "linkId"), @Index(columnList = "code", unique = true) }
) )
@Comment("定位信标") @Comment("定位信标")
public class LocationBeacon implements Serializable { public class LocationBeacon extends BasicEntity implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 5419734189897829250L; private static final long serialVersionUID = 5419734189897829250L;
@Comment("主键")
@Id
@GeneratedValue(generator = SnowflakeId.GENERATOR)
@GenericGenerator(name = SnowflakeId.GENERATOR, strategy = SnowflakeId.Strategy.LONG)
Long id;
/** /**
* 数据来源于【真源人员定位系统 - 定位信标】 * 数据来源于【真源人员定位系统 - 定位信标】
* 作用: 用于双向联动进行数据同步 * 作用: 用于双向联动进行数据同步
...@@ -99,19 +94,18 @@ public class LocationBeacon implements Serializable { ...@@ -99,19 +94,18 @@ public class LocationBeacon implements Serializable {
@Comment("电量单位") @Comment("电量单位")
String voltUnit; String voltUnit;
@FieldMapping(value = "time", desc = "更新时间戳", type = Long.class) @Comment("围栏集合")
@Comment("更新时间") @Builder.Default
LocalDateTime updateTime; @ManyToMany(mappedBy = "beacons")
@ToString.Exclude
@Comment("创建时间") Set<LocationFence> fences = new HashSet<>(0);
LocalDateTime createTime;
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
LocationBeacon that = (LocationBeacon) o; LocationBeacon that = (LocationBeacon) o;
return id != null && Objects.equals(id, that.id); return getId() != null && Objects.equals(getId(), that.getId());
} }
@Override @Override
......
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.domain.location;
import java.io.Serializable;
import java.util.Set;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**
* @author Jim
* @version 0.1
* 2022/4/24 14:19
*/
@Repository
public interface LocationBeaconRepository
extends JpaRepository<LocationBeacon, Serializable>, JpaSpecificationExecutor<LocationBeacon> {
/**
* 根据编号集合查询
* @param codes 编号集合
* @return 查询结果
*/
Set<LocationBeacon> findByCodeIn(Set<String> codes);
}
...@@ -2,19 +2,18 @@ ...@@ -2,19 +2,18 @@
package com.yiring.app.domain.location; package com.yiring.app.domain.location;
import com.yiring.common.annotation.FieldMapping; import com.yiring.common.annotation.FieldMapping;
import com.yiring.common.domain.BasicEntity;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.persistence.*; import javax.persistence.*;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
import org.hibernate.snowflake.SnowflakeId;
import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Geometry;
/** /**
...@@ -29,7 +28,7 @@ import org.locationtech.jts.geom.Geometry; ...@@ -29,7 +28,7 @@ import org.locationtech.jts.geom.Geometry;
@Getter @Getter
@Setter @Setter
@ToString @ToString
@Builder @SuperBuilder(toBuilder = true)
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@FieldNameConstants @FieldNameConstants
...@@ -37,25 +36,11 @@ import org.locationtech.jts.geom.Geometry; ...@@ -37,25 +36,11 @@ import org.locationtech.jts.geom.Geometry;
@Entity @Entity
@Table(name = "BS_LOCATION_FENCE", indexes = { @Index(columnList = "linkId"), @Index(columnList = "mode") }) @Table(name = "BS_LOCATION_FENCE", indexes = { @Index(columnList = "linkId"), @Index(columnList = "mode") })
@Comment("围栏") @Comment("围栏")
public class LocationFence implements Serializable { public class LocationFence extends BasicEntity implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 4155868702188991300L; private static final long serialVersionUID = 4155868702188991300L;
@Comment("主键")
@Id
@GeneratedValue(generator = SnowflakeId.GENERATOR)
@GenericGenerator(name = SnowflakeId.GENERATOR, strategy = SnowflakeId.Strategy.LONG)
Long id;
/**
* 数据来源于【真源人员定位系统 - 电子围栏】
* 作用: 用于双向联动进行数据同步
*/
@FieldMapping("id")
@Comment("外链主键")
Long linkId;
@Comment("地图 ID") @Comment("地图 ID")
Long areaId; Long areaId;
...@@ -64,21 +49,11 @@ public class LocationFence implements Serializable { ...@@ -64,21 +49,11 @@ public class LocationFence implements Serializable {
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
Mode mode; Mode mode;
@Comment("坐标信息(x,y,r)")
@Column(columnDefinition = "JSON")
String shape;
@Comment("形状信息(circle: 圆形, polygon: 多边形)")
String shapeType;
@Comment("空间信息") @Comment("空间信息")
@Type(type = "jts_geometry") @Type(type = "jts_geometry")
@Column(columnDefinition = "geometry") @Column(columnDefinition = "geometry")
Geometry geometry; Geometry geometry;
@Comment("半径,米/单位(圆形围栏)")
Double radius;
@Comment("超时时间(秒)") @Comment("超时时间(秒)")
Integer overtime; Integer overtime;
...@@ -87,17 +62,20 @@ public class LocationFence implements Serializable { ...@@ -87,17 +62,20 @@ public class LocationFence implements Serializable {
@Comment("信标集合") @Comment("信标集合")
@Builder.Default @Builder.Default
@ManyToMany @ManyToMany(mappedBy = "fences")
@ToString.Exclude @ToString.Exclude
Set<LocationBeacon> beacons = new HashSet<>(0); Set<LocationBeacon> beacons = new HashSet<>(0);
@Comment("创建时间") @Comment("围栏规则集合")
LocalDateTime createTime; @Builder.Default
@OneToMany(mappedBy = "fence")
@ToString.Exclude
Set<LocationFenceRule> rules = new HashSet<>(0);
@SuppressWarnings({ "unused" }) @SuppressWarnings({ "unused" })
public enum Mode { public enum Mode {
NORMAL("标准"), NORMAL("常规区域"),
DANGER("危险区域"); DANGER("危险区域");
@Getter @Getter
final String text; final String text;
......
/* (C) 2022 YiRing, Inc. */ /* (C) 2022 YiRing, Inc. */
package com.yiring.app.domain.location; package com.yiring.app.domain.location;
import com.yiring.auth.domain.user.User; import com.yiring.common.domain.BasicEntity;
import com.yiring.common.annotation.FieldMapping;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalTime; import javax.persistence.Entity;
import java.util.HashSet; import javax.persistence.JoinColumn;
import java.util.Set; import javax.persistence.ManyToOne;
import javax.persistence.*; import javax.persistence.Table;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.snowflake.SnowflakeId;
/** /**
* 围栏规则 * 围栏规则
...@@ -36,67 +33,18 @@ import org.hibernate.snowflake.SnowflakeId; ...@@ -36,67 +33,18 @@ import org.hibernate.snowflake.SnowflakeId;
@Entity @Entity
@Table(name = "BS_LOCATION_FENCE_RULE") @Table(name = "BS_LOCATION_FENCE_RULE")
@Comment("围栏规则") @Comment("围栏规则")
public class LocationFenceRule implements Serializable { public class LocationFenceRule extends BasicEntity implements Serializable {
@Serial @Serial
private static final long serialVersionUID = -6683465582430417205L; private static final long serialVersionUID = -6683465582430417205L;
@Comment("主键")
@Id
@GeneratedValue(generator = SnowflakeId.GENERATOR)
@GenericGenerator(name = SnowflakeId.GENERATOR, strategy = SnowflakeId.Strategy.LONG)
Long id;
@Comment("围栏") @Comment("围栏")
@ManyToOne @ManyToOne
@JoinColumn(name = "fence_id") @JoinColumn(name = "fence_id")
LocationFence fence; LocationFence fence;
// TODO
// 字段补充
// 关联表补充(报警规则)
// 关联表配置值补充
@FieldMapping("entityTypes")
@Comment("规则模型")
@Enumerated(EnumType.STRING)
Mode mode;
@Comment("规则名称")
String name;
@Comment("规则描述")
String describe;
@Comment("最小值(人数)")
Integer minValue;
@Comment("最大值(人数)")
Integer maxValue;
@Comment("规则生效开始时间")
LocalTime minTime;
@Comment("规则生效结束时间")
LocalTime maxTime;
@Comment("允许的用户(人员)")
@OneToMany
@Builder.Default
@ToString.Exclude
Set<User> includes = new HashSet<>(0);
@Comment("不允许的用户(人员)")
@OneToMany
@Builder.Default
@ToString.Exclude
Set<User> excludes = new HashSet<>(0);
@SuppressWarnings({ "unused" })
public enum Mode {
STAFF("人员"),
NUMBER("数量");
@Getter
final String text;
Mode(String text) {
this.text = text;
}
}
} }
...@@ -6,26 +6,25 @@ import com.vladmihalcea.hibernate.type.json.JsonType; ...@@ -6,26 +6,25 @@ import com.vladmihalcea.hibernate.type.json.JsonType;
import com.yiring.auth.domain.user.User; import com.yiring.auth.domain.user.User;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.HashSet; import java.util.HashSet;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import javax.persistence.*; import javax.persistence.*;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import org.hibernate.Hibernate;
import org.hibernate.annotations.Comment; import org.hibernate.annotations.Comment;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDef;
import org.hibernate.snowflake.SnowflakeId;
import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Point;
/** /**
* 定位数据 * 定位数据
* 引用: 定位平台接口规范V3.0.1 #6 * 引用: 定位平台接口规范V3.0.1 #6
* TODO:
* 1. 实时数据日志的存储结构 TimeScale: 时间粒度,每天一个分区
* eg: SELECT create_hypertable('BS_LOCATION_LOG', 'time', chunk_time_interval => INTERVAL '1 day')
* *
* @author Jim * @author Jim
* @version 0.1 * @version 0.1
...@@ -42,18 +41,24 @@ import org.locationtech.jts.geom.Point; ...@@ -42,18 +41,24 @@ import org.locationtech.jts.geom.Point;
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
@Entity @Entity
@TypeDef(name = "json", typeClass = JsonType.class) @TypeDef(name = "json", typeClass = JsonType.class)
@Table(name = "BS_LOCATION_LOG", indexes = { @Index(columnList = "time"), @Index(columnList = "silent") }) @Table(name = "BS_LOCATION_LOG")
@Comment("定位数据") @Comment("定位数据")
public class LocationLog implements Serializable { public class LocationLog implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 3467455881020691989L; private static final long serialVersionUID = 3467455881020691989L;
@Comment("主键")
@Id @Id
@GeneratedValue(generator = SnowflakeId.GENERATOR) @Comment("时间")
@GenericGenerator(name = SnowflakeId.GENERATOR, strategy = SnowflakeId.Strategy.LONG) @Column(nullable = false)
Long id; @CreationTimestamp
LocalDateTime time;
@Comment("地图 ID")
Long areaId;
@Comment("楼层")
String floor;
/** /**
* 来源于定位数据产生时刻标签所属的人员 * 来源于定位数据产生时刻标签所属的人员
...@@ -74,19 +79,6 @@ public class LocationLog implements Serializable { ...@@ -74,19 +79,6 @@ public class LocationLog implements Serializable {
@JoinColumn(name = "tag_id") @JoinColumn(name = "tag_id")
LocationTag tag; LocationTag tag;
@Comment("时间")
@Column(nullable = false)
LocalDateTime time;
@Comment("经度")
BigDecimal lon;
@Comment("纬度")
BigDecimal lat;
@Comment("海拔高度(m)")
BigDecimal altitude;
@Comment("坐标点信息") @Comment("坐标点信息")
@Type(type = "jts_geometry") @Type(type = "jts_geometry")
@Column(columnDefinition = "point") @Column(columnDefinition = "point")
...@@ -94,13 +86,13 @@ public class LocationLog implements Serializable { ...@@ -94,13 +86,13 @@ public class LocationLog implements Serializable {
@Comment("信标集合") @Comment("信标集合")
@Builder.Default @Builder.Default
@ManyToMany @OneToMany
@ToString.Exclude @ToString.Exclude
Set<LocationBeacon> beacons = new HashSet<>(0); Set<LocationBeacon> beacons = new HashSet<>(0);
@Comment("围栏集合") @Comment("围栏集合")
@Builder.Default @Builder.Default
@ManyToMany @OneToMany
@ToString.Exclude @ToString.Exclude
Set<LocationFence> fences = new HashSet<>(0); Set<LocationFence> fences = new HashSet<>(0);
...@@ -118,19 +110,6 @@ public class LocationLog implements Serializable { ...@@ -118,19 +110,6 @@ public class LocationLog implements Serializable {
@Column(columnDefinition = "json") @Column(columnDefinition = "json")
JSONObject raw; JSONObject raw;
@Comment("创建时间") @Comment("定位时间")
LocalDateTime createTime; LocalDateTime locationTime;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
LocationLog locationLog = (LocationLog) o;
return id != null && Objects.equals(id, locationLog.id);
}
@Override
public int hashCode() {
return getClass().hashCode();
}
} }
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.domain.location;
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**
* @author Jim
* @version 0.1
* 2022/4/24 18:03
*/
@Repository
public interface LocationLogRepository
extends JpaRepository<LocationLog, Serializable>, JpaSpecificationExecutor<LocationLog> {}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.domain.log;
import com.alibaba.fastjson.JSONObject;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import javax.persistence.*;
import lombok.*;
import lombok.experimental.FieldDefaults;
import lombok.experimental.FieldNameConstants;
import org.hibernate.annotations.Comment;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.TypeDef;
/**
* 真源定位系统实时数据日志
* TODO:
* 1. 实时数据日志的存储结构 TimeScale: 时间粒度,每小时一个分区
* eg: SELECT create_hypertable('zy_realtime_log', 'time', chunk_time_interval => INTERVAL '1 hour')
* 2. 数据分区压缩
* 3. 定时删除过期分区数据
* 参考:<a href="https://blog.csdn.net/yang_z_1/article/details/111560747">文档</a>
*
* @author Jim
* @version 0.1
* 2022/4/25 15:52
*/
@Getter
@Setter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldNameConstants
@FieldDefaults(level = AccessLevel.PRIVATE)
@Entity
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Table(name = "ZY_REALTIME_LOG", indexes = { @Index(columnList = "method") })
@Comment("真源定位系统实时数据日志")
public class ZyRealtimeLog implements Serializable {
@Serial
private static final long serialVersionUID = 5545864821082386L;
@Id
@Comment("时间")
@Column(nullable = false)
@CreationTimestamp
LocalDateTime time;
@Comment("类型")
@Column(nullable = false)
String method;
@Comment("内容")
@org.hibernate.annotations.Type(type = "jsonb")
@Column(nullable = false, columnDefinition = "jsonb")
JSONObject raw;
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.domain.log;
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author Jim
* @version 0.1
* 2022/4/25 16:02
*/
public interface ZyRealtimeLogRepository extends JpaRepository<ZyRealtimeLog, Serializable> {}
...@@ -4,16 +4,26 @@ package com.yiring.app.rabbit.receiver; ...@@ -4,16 +4,26 @@ package com.yiring.app.rabbit.receiver;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel; import com.rabbitmq.client.Channel;
import com.yiring.app.push.service.PushService; import com.yiring.app.domain.location.*;
import com.yiring.app.domain.log.ZyRealtimeLog;
import com.yiring.app.domain.log.ZyRealtimeLogRepository;
import com.yiring.app.rabbit.config.ZyRabbitConfig; import com.yiring.app.rabbit.config.ZyRabbitConfig;
import com.yiring.app.util.GeoUtils;
import java.io.IOException; import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource; import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.Point;
import org.springframework.amqp.core.Message; import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.Example;
import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -38,11 +48,20 @@ public class ZyRabbitReceiver { ...@@ -38,11 +48,20 @@ public class ZyRabbitReceiver {
// 3. 订阅 position(定位数据)、lowPower(低电量报警)、deviceStatus(设备状态)、keyWarning(按键报警) // 3. 订阅 position(定位数据)、lowPower(低电量报警)、deviceStatus(设备状态)、keyWarning(按键报警)
@Resource @Resource
PushService pushService; LocationTagRepository locationTagRepository;
@Resource
LocationBeaconRepository locationBeaconRepository;
@Resource
LocationLogRepository locationLogRepository;
@Resource @Resource
SimpMessagingTemplate simpMessagingTemplate; SimpMessagingTemplate simpMessagingTemplate;
@Resource
ZyRealtimeLogRepository zyRealtimeLogRepository;
/** /**
* 订阅真源定位系统 RabbitMQ 推送过来的消息(主动订阅的一些消息类别) * 订阅真源定位系统 RabbitMQ 推送过来的消息(主动订阅的一些消息类别)
* 参见: 定位平台接口规范V3.0.1 - 通用版.pdf #6 * 参见: 定位平台接口规范V3.0.1 - 通用版.pdf #6
...@@ -68,6 +87,12 @@ public class ZyRabbitReceiver { ...@@ -68,6 +87,12 @@ public class ZyRabbitReceiver {
// 解构消息内容 // 解构消息内容
JSONObject data = info.getJSONObject("params"); JSONObject data = info.getJSONObject("params");
String method = info.getString("method"); String method = info.getString("method");
// 记录日志
ZyRealtimeLog realtimeLog = ZyRealtimeLog.builder().method(method).raw(info).build();
zyRealtimeLogRepository.save(realtimeLog);
// 业务处理
switch (method) { switch (method) {
// 实时定位 // 实时定位
case "position" -> processPositionMessage(data); case "position" -> processPositionMessage(data);
...@@ -100,10 +125,74 @@ public class ZyRabbitReceiver { ...@@ -100,10 +125,74 @@ public class ZyRabbitReceiver {
// 1. 解析消息内容,进行围栏、出入标识判断等处理,将定位记录录入数据库 // 1. 解析消息内容,进行围栏、出入标识判断等处理,将定位记录录入数据库
// 2. 创建一条需要进行消息推送的记录 // 2. 创建一条需要进行消息推送的记录
// 3. 将记录推送的消息推送模块 // 3. 将记录推送的消息推送模块
// 4. 坚持是否触发围栏告警,记录告警数据,并推送消息 // 4. 检查是否触发围栏告警,记录告警数据,并推送消息
// 定位时间
Instant instant = Instant.ofEpochMilli(data.getLongValue("locationTime"));
LocalDateTime time = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
// 定位的基本信息
LocationLog locationLog = LocationLog
.builder()
.raw(data)
.locationTime(time)
.silent(data.getBoolean("silent"))
.volt(data.getInteger("volt"))
.voltUnit(data.getString("voltUnit"))
.build();
// 设置空间点位信息
Point point = GeoUtils.createPoint(
data.getDoubleValue("longitude"),
data.getDoubleValue("latitude"),
data.getDoubleValue("altitude")
);
locationLog.setPoint(point);
// WebSocket 消息推送 // 查询定位标签
simpMessagingTemplate.convertAndSend("/topic/position", data); Example<LocationTag> example = Example.of(LocationTag.builder().code(data.getString("tagId")).build());
Optional<LocationTag> optional = locationTagRepository.findOne(example);
if (optional.isPresent()) {
LocationTag tag = optional.get();
// 设置定位标签
locationLog.setTag(tag);
// 定位标签当时所属的用户
locationLog.setUser(tag.getUser());
// 查询当前用户的状态
// TODO
}
// 查询定位信标
Set<String> codes = Arrays
.stream(data.getString("beacons").split(","))
.map(beacon -> beacon.replaceAll("\\(.*\\)", ""))
.collect(Collectors.toSet());
Set<LocationBeacon> beacons = locationBeaconRepository.findByCodeIn(codes);
locationLog.setBeacons(beacons);
// 查询定位所在围栏信息
Set<LocationFence> fences = locationLog
.getBeacons()
.stream()
.map(LocationBeacon::getFences)
.flatMap(Set::stream)
.collect(Collectors.toSet());
locationLog.setFences(fences);
// TODO
// 并计算出入标记(围栏、区域)
// 写入数据
locationLogRepository.saveAndFlush(locationLog);
// 更新定位标签卡电量信息
// TODO
// WebSocket 推送定位消息
// 消息内容需要确定 TODO
simpMessagingTemplate.convertAndSend("/topic/position", "{}");
// TODO
// 判断围栏告警是否触发,触发写入告警记录,并推送消息
} }
/** /**
......
...@@ -18,7 +18,7 @@ import org.locationtech.jts.geom.Point; ...@@ -18,7 +18,7 @@ import org.locationtech.jts.geom.Point;
@UtilityClass @UtilityClass
public class GeoUtils { public class GeoUtils {
private final GeometryFactory factory = new GeometryFactory(); public final GeometryFactory factory = new GeometryFactory();
/** /**
* 创建点 * 创建点
...@@ -30,4 +30,29 @@ public class GeoUtils { ...@@ -30,4 +30,29 @@ public class GeoUtils {
public Point createPoint(double lon, double lat) { public Point createPoint(double lon, double lat) {
return factory.createPoint(new Coordinate(lon, lat)); return factory.createPoint(new Coordinate(lon, lat));
} }
/**
* 创建一个三维点
* @param lon 经度
* @param lat 纬度
* @param alt 高度
* @return 点
*/
public Point createPoint(double lon, double lat, double alt) {
return factory.createPoint(new Coordinate(lon, lat, alt));
}
/**
* 相对坐标转换为经纬度
* @param x x 坐标值
* @param y y 坐标值
* @param z z 坐标值
* @return 经纬度点
*/
public Point xyzToPoint(double x, double y, double z) {
// TODO
// 根据真源定位系统设置的坐标系,转换为经纬度
// 根据北向的地图左下角坐标点,矩形长宽距离,结合二维图片的像素比,计算经纬度
return factory.createPoint(new Coordinate(x, y, z));
}
} }
...@@ -2,29 +2,15 @@ ...@@ -2,29 +2,15 @@
package com.yiring.app.web; package com.yiring.app.web;
import com.yiring.app.constant.Code; import com.yiring.app.constant.Code;
import com.yiring.app.domain.location.LocationTag;
import com.yiring.app.exception.CodeException; import com.yiring.app.exception.CodeException;
import com.yiring.app.util.GeoUtils;
import com.yiring.auth.domain.user.User;
import com.yiring.common.core.Result; import com.yiring.common.core.Result;
import com.yiring.common.domain.BasicEntity;
import com.yiring.common.param.PageParam; import com.yiring.common.param.PageParam;
import com.yiring.common.vo.PageVo; import com.yiring.common.vo.PageVo;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.criteria.*;
import javax.validation.Valid; import javax.validation.Valid;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.Point;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
...@@ -60,56 +46,4 @@ public class HelloController { ...@@ -60,56 +46,4 @@ public class HelloController {
PageVo<String> vo = PageVo.build(data, data.size()); PageVo<String> vo = PageVo.build(data, data.size());
return Result.ok(vo); return Result.ok(vo);
} }
@Resource
SimpMessagingTemplate simpMessagingTemplate;
@GetMapping("test")
public Result<Point> test() {
Point point = GeoUtils.createPoint(112.1, 23.56);
simpMessagingTemplate.convertAndSend("/topic/position", point);
return Result.ok(point);
}
@Resource
EntityManager em;
@Data
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public static class UserVo {
Long id;
String avatar;
String code;
}
@GetMapping("test2")
public Result<ArrayList<UserVo>> query() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<UserVo> cq = cb.createQuery(UserVo.class);
Root<User> root = cq.from(User.class);
Expression<Long> id = root.get(BasicEntity.Fields.id);
Expression<String> avatar = root.get(User.Fields.avatar);
// 子查询
Subquery<String> query = cq.subquery(String.class);
Root<LocationTag> tagRoot = query.from(LocationTag.class);
query.select(tagRoot.get(LocationTag.Fields.code));
query.where(cb.equal(tagRoot.get(LocationTag.Fields.user), root));
// 构建查询字段
cq.multiselect(id, avatar, query);
// 查询条件
List<Predicate> predicates = new ArrayList<>();
// 可根据入参判断是否需要查询指定字段
predicates.add(cb.isNotNull(root.get(User.Fields.avatar)));
predicates.add(cb.equal(query, "BTT22222222"));
cq.where(predicates.toArray(new Predicate[0]));
List<UserVo> users = em.createQuery(cq).getResultList();
return Result.ok(new ArrayList<>(users));
}
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论