报告模块重构
This commit is contained in:
parent
c0b9515088
commit
2d072b01ff
@ -1,15 +1,9 @@
|
|||||||
package com.cdzy.operations.utils;
|
package com.cdzy.operations.utils;
|
||||||
|
|
||||||
import org.locationtech.jts.geom.Coordinate;
|
|
||||||
import org.locationtech.jts.geom.GeometryFactory;
|
|
||||||
import org.locationtech.jts.geom.Polygon;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.geo.*;
|
|
||||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -24,131 +18,12 @@ public class RedisUtil {
|
|||||||
|
|
||||||
private final RedisTemplate<String, Object> redisTemplate;
|
private final RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
private final String geoKey="ebike_geo";
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
|
public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
|
||||||
this.redisTemplate = redisTemplate;
|
this.redisTemplate = redisTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------- key 相关操作 ------------------ */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加地理位置
|
|
||||||
*
|
|
||||||
* @param point 经纬度
|
|
||||||
* @param member 成员名称
|
|
||||||
*/
|
|
||||||
public void addLocation(Point point, String member) {
|
|
||||||
redisTemplate.opsForGeo().add(geoKey, point, member);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询指定范围内的成员
|
|
||||||
*
|
|
||||||
* @param center 中心点
|
|
||||||
* @param radius 半径(单位:公里)
|
|
||||||
* @return 范围内的成员列表
|
|
||||||
*/
|
|
||||||
public List<String> findNearbyMembers(Point center, double radius) {
|
|
||||||
Distance distance = new Distance(radius, RedisGeoCommands.DistanceUnit.KILOMETERS);
|
|
||||||
Circle circle = new Circle(center, distance);
|
|
||||||
GeoResults<RedisGeoCommands.GeoLocation<Object>> results = redisTemplate.opsForGeo()
|
|
||||||
.radius(geoKey, circle);
|
|
||||||
return results.getContent().stream()
|
|
||||||
.map(geoLocation -> geoLocation.getContent().getName().toString())
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多边形查询
|
|
||||||
* @param polygonPoints 边界点
|
|
||||||
* @return 成员列表
|
|
||||||
*/
|
|
||||||
public List<String> searchByPolygon( List<Point> polygonPoints ) {
|
|
||||||
|
|
||||||
// 1. 构造多边形
|
|
||||||
GeometryFactory factory = new GeometryFactory();
|
|
||||||
Coordinate[] coordinates = polygonPoints.stream()
|
|
||||||
.map(p -> new Coordinate(p.getX(), p.getY()))
|
|
||||||
.toArray(Coordinate[]::new);
|
|
||||||
Polygon polygon = factory.createPolygon(coordinates);
|
|
||||||
|
|
||||||
// 2. 计算最小外接圆
|
|
||||||
Point center = calculateBoundingCircleCenter(polygonPoints);
|
|
||||||
double radius = calculateMaxRadius(polygonPoints, center);
|
|
||||||
|
|
||||||
// 3. 查询圆内所有点
|
|
||||||
GeoResults<RedisGeoCommands.GeoLocation<Object>> results =
|
|
||||||
redisTemplate.opsForGeo()
|
|
||||||
.radius(geoKey,
|
|
||||||
new Circle(center, new Distance(radius, Metrics.KILOMETERS)),
|
|
||||||
RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
|
|
||||||
.includeCoordinates());
|
|
||||||
|
|
||||||
// 4. 过滤多边形内的点
|
|
||||||
List<String> matches = new ArrayList<>();
|
|
||||||
for (GeoResult<RedisGeoCommands.GeoLocation<Object>> result : results) {
|
|
||||||
Point point = result.getContent().getPoint();
|
|
||||||
if (polygon.contains(factory.createPoint(
|
|
||||||
new Coordinate(point.getX(), point.getY())))) {
|
|
||||||
matches.add(result.getContent().getName().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算外接圆中心(多边形顶点平均值)
|
|
||||||
private Point calculateBoundingCircleCenter(List<Point> points) {
|
|
||||||
double sumX = 0, sumY = 0;
|
|
||||||
for (Point p : points) {
|
|
||||||
sumX += p.getX();
|
|
||||||
sumY += p.getY();
|
|
||||||
}
|
|
||||||
return new Point(sumX / points.size(), sumY / points.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算最大半径
|
|
||||||
private double calculateMaxRadius(List<Point> points, Point center) {
|
|
||||||
return points.stream()
|
|
||||||
.mapToDouble(p -> Math.sqrt(
|
|
||||||
Math.pow(p.getX() - center.getX(), 2) +
|
|
||||||
Math.pow(p.getY() - center.getY(), 2)))
|
|
||||||
.max().orElse(0)*100;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断点是否在多边形内
|
|
||||||
* @param point 待判断点
|
|
||||||
* @param polygon 多边形顶点
|
|
||||||
* @return 是否在多边形内
|
|
||||||
*/
|
|
||||||
public static boolean isPointInPolygon(Point point, List<Point> polygon) {
|
|
||||||
double x = point.getX();
|
|
||||||
double y = point.getY();
|
|
||||||
|
|
||||||
boolean inside = false;
|
|
||||||
for (int i = 0, j = polygon.size() - 1; i < polygon.size(); j = i++) {
|
|
||||||
double xi = polygon.get(i).getX();
|
|
||||||
double yi = polygon.get(i).getY();
|
|
||||||
double xj = polygon.get(j).getX();
|
|
||||||
double yj = polygon.get(j).getY();
|
|
||||||
|
|
||||||
boolean intersect = ((yi > y) != (yj > y))
|
|
||||||
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
|
|
||||||
if (intersect) inside = !inside;
|
|
||||||
}
|
|
||||||
return inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除 Redis 键
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void deleteGeoKey() {
|
|
||||||
redisTemplate.delete(geoKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置过期时间
|
* 设置过期时间
|
||||||
* @param key 键
|
* @param key 键
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package com.cdzy.ebikereport;
|
package com.cdzy.report;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.cdzy.ebikereport.component;
|
package com.cdzy.report.component;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.health.Health;
|
import org.springframework.boot.actuate.health.Health;
|
||||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.cdzy.ebikereport.component;
|
package com.cdzy.report.component;
|
||||||
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
@ -1,12 +1,12 @@
|
|||||||
package com.cdzy.ebikereport.component;
|
package com.cdzy.report.component;
|
||||||
|
|
||||||
|
|
||||||
import com.cdzy.common.model.dto.EbikeTracking;
|
import com.cdzy.common.model.dto.EbikeTracking;
|
||||||
import com.cdzy.common.model.dto.ResGPSDto;
|
import com.cdzy.common.model.dto.ResGPSDto;
|
||||||
import com.cdzy.common.utils.CoordinateUtil;
|
import com.cdzy.common.utils.CoordinateUtil;
|
||||||
import com.cdzy.ebikereport.enums.BitSwitch;
|
import com.cdzy.report.enums.BitSwitch;
|
||||||
import com.cdzy.ebikereport.utils.BinaryUtil;
|
import com.cdzy.report.utils.BinaryUtil;
|
||||||
import com.cdzy.ebikereport.utils.RedisUtil;
|
import com.cdzy.report.utils.RedisUtil;
|
||||||
import com.ebike.feign.clients.OperationsFeignClient;
|
import com.ebike.feign.clients.OperationsFeignClient;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.cdzy.ebikereport.config;
|
package com.cdzy.report.config;
|
||||||
|
|
||||||
import cn.hutool.core.date.DatePattern;
|
import cn.hutool.core.date.DatePattern;
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.cdzy.ebikereport.config;
|
package com.cdzy.report.config;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.cdzy.ebikereport.enums;
|
package com.cdzy.report.enums;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author attiya
|
* @author attiya
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.cdzy.ebikereport.utils;
|
package com.cdzy.report.utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author attiya
|
* @author attiya
|
||||||
@ -1,15 +1,9 @@
|
|||||||
package com.cdzy.ebikereport.utils;
|
package com.cdzy.report.utils;
|
||||||
|
|
||||||
import org.locationtech.jts.geom.Coordinate;
|
|
||||||
import org.locationtech.jts.geom.GeometryFactory;
|
|
||||||
import org.locationtech.jts.geom.Polygon;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.geo.*;
|
|
||||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -24,131 +18,12 @@ public class RedisUtil {
|
|||||||
|
|
||||||
private final RedisTemplate<String, Object> redisTemplate;
|
private final RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
private final String geoKey="ebike_geo";
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
|
public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
|
||||||
this.redisTemplate = redisTemplate;
|
this.redisTemplate = redisTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------- key 相关操作 ------------------ */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加地理位置
|
|
||||||
*
|
|
||||||
* @param point 经纬度
|
|
||||||
* @param member 成员名称
|
|
||||||
*/
|
|
||||||
public void addLocation(Point point, String member) {
|
|
||||||
redisTemplate.opsForGeo().add(geoKey, point, member);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询指定范围内的成员
|
|
||||||
*
|
|
||||||
* @param center 中心点
|
|
||||||
* @param radius 半径(单位:公里)
|
|
||||||
* @return 范围内的成员列表
|
|
||||||
*/
|
|
||||||
public List<String> findNearbyMembers(Point center, double radius) {
|
|
||||||
Distance distance = new Distance(radius, RedisGeoCommands.DistanceUnit.KILOMETERS);
|
|
||||||
Circle circle = new Circle(center, distance);
|
|
||||||
GeoResults<RedisGeoCommands.GeoLocation<Object>> results = redisTemplate.opsForGeo()
|
|
||||||
.radius(geoKey, circle);
|
|
||||||
return results.getContent().stream()
|
|
||||||
.map(geoLocation -> geoLocation.getContent().getName().toString())
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多边形查询
|
|
||||||
* @param polygonPoints 边界点
|
|
||||||
* @return 成员列表
|
|
||||||
*/
|
|
||||||
public List<String> searchByPolygon( List<Point> polygonPoints ) {
|
|
||||||
|
|
||||||
// 1. 构造多边形
|
|
||||||
GeometryFactory factory = new GeometryFactory();
|
|
||||||
Coordinate[] coordinates = polygonPoints.stream()
|
|
||||||
.map(p -> new Coordinate(p.getX(), p.getY()))
|
|
||||||
.toArray(Coordinate[]::new);
|
|
||||||
Polygon polygon = factory.createPolygon(coordinates);
|
|
||||||
|
|
||||||
// 2. 计算最小外接圆
|
|
||||||
Point center = calculateBoundingCircleCenter(polygonPoints);
|
|
||||||
double radius = calculateMaxRadius(polygonPoints, center);
|
|
||||||
|
|
||||||
// 3. 查询圆内所有点
|
|
||||||
GeoResults<RedisGeoCommands.GeoLocation<Object>> results =
|
|
||||||
redisTemplate.opsForGeo()
|
|
||||||
.radius(geoKey,
|
|
||||||
new Circle(center, new Distance(radius, Metrics.KILOMETERS)),
|
|
||||||
RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
|
|
||||||
.includeCoordinates());
|
|
||||||
|
|
||||||
// 4. 过滤多边形内的点
|
|
||||||
List<String> matches = new ArrayList<>();
|
|
||||||
for (GeoResult<RedisGeoCommands.GeoLocation<Object>> result : results) {
|
|
||||||
Point point = result.getContent().getPoint();
|
|
||||||
if (polygon.contains(factory.createPoint(
|
|
||||||
new Coordinate(point.getX(), point.getY())))) {
|
|
||||||
matches.add(result.getContent().getName().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算外接圆中心(多边形顶点平均值)
|
|
||||||
private Point calculateBoundingCircleCenter(List<Point> points) {
|
|
||||||
double sumX = 0, sumY = 0;
|
|
||||||
for (Point p : points) {
|
|
||||||
sumX += p.getX();
|
|
||||||
sumY += p.getY();
|
|
||||||
}
|
|
||||||
return new Point(sumX / points.size(), sumY / points.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算最大半径
|
|
||||||
private double calculateMaxRadius(List<Point> points, Point center) {
|
|
||||||
return points.stream()
|
|
||||||
.mapToDouble(p -> Math.sqrt(
|
|
||||||
Math.pow(p.getX() - center.getX(), 2) +
|
|
||||||
Math.pow(p.getY() - center.getY(), 2)))
|
|
||||||
.max().orElse(0)*100;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断点是否在多边形内
|
|
||||||
* @param point 待判断点
|
|
||||||
* @param polygon 多边形顶点
|
|
||||||
* @return 是否在多边形内
|
|
||||||
*/
|
|
||||||
public static boolean isPointInPolygon(Point point, List<Point> polygon) {
|
|
||||||
double x = point.getX();
|
|
||||||
double y = point.getY();
|
|
||||||
|
|
||||||
boolean inside = false;
|
|
||||||
for (int i = 0, j = polygon.size() - 1; i < polygon.size(); j = i++) {
|
|
||||||
double xi = polygon.get(i).getX();
|
|
||||||
double yi = polygon.get(i).getY();
|
|
||||||
double xj = polygon.get(j).getX();
|
|
||||||
double yj = polygon.get(j).getY();
|
|
||||||
|
|
||||||
boolean intersect = ((yi > y) != (yj > y))
|
|
||||||
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
|
|
||||||
if (intersect) inside = !inside;
|
|
||||||
}
|
|
||||||
return inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除 Redis 键
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void deleteGeoKey() {
|
|
||||||
redisTemplate.delete(geoKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置过期时间
|
* 设置过期时间
|
||||||
* @param key 键
|
* @param key 键
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package com.cdzy.ebikereport;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.cdzy.common.model.EbikeTracking;
|
|
||||||
import com.cdzy.common.model.ResGPSDto;
|
|
||||||
import com.cdzy.common.utils.CoordinateUtil;
|
|
||||||
import com.cdzy.ebikereport.enums.BitSwitch;
|
|
||||||
import com.cdzy.ebikereport.utils.BinaryUtil;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.data.geo.Point;
|
|
||||||
|
|
||||||
@SpringBootTest
|
|
||||||
class EbikeReportApplicationTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void contextLoads() {
|
|
||||||
|
|
||||||
Integer number = 131082;
|
|
||||||
String binary = BinaryUtil.to32BitBinary(number);
|
|
||||||
binary = new StringBuilder(binary).reverse().toString();
|
|
||||||
System.out.println(binary);
|
|
||||||
char helmet = binary.charAt(BitSwitch.IS_HELMET_EXIT);
|
|
||||||
char acc = binary.charAt(BitSwitch.ACC_ON);
|
|
||||||
System.out.println(acc);
|
|
||||||
char wheelLocked = binary.charAt(BitSwitch.IS_WHEEL_LOCKED);
|
|
||||||
char setLocked = binary.charAt(BitSwitch.IS_SEAT_LOCKED);
|
|
||||||
char isHelmetLocked = binary.charAt(BitSwitch.IS_HELMET_LOCKED);
|
|
||||||
char isWheelSpin = binary.charAt(BitSwitch.IS_WHEEL_SPIN);
|
|
||||||
char isMoving = binary.charAt(BitSwitch.IS_MOVING);
|
|
||||||
ResGPSDto resGpsDto = new ResGPSDto();
|
|
||||||
resGpsDto.setHelmetExit(helmet);
|
|
||||||
resGpsDto.setAccOn(acc);
|
|
||||||
resGpsDto.setWheelLocked(wheelLocked);
|
|
||||||
resGpsDto.setSeatLocked(setLocked);
|
|
||||||
resGpsDto.setIsHelmetLocked(isHelmetLocked);
|
|
||||||
resGpsDto.setIsWheelSpin(isWheelSpin);
|
|
||||||
resGpsDto.setIsMoving(isMoving);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.cdzy.report;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class EbikeReportApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user