修复坐标转换问题并新增车辆列表接口
- 修正经纬度坐标转换错误(longitude/latitude互换) - 新增车辆列表查询接口 GET /api/vehicle-manager/vehicles - 支持分页、状态筛选和离线判定 - 更新生产环境配置(Redis主机和无人车服务地址) - 优化任务路径点坐标映射
This commit is contained in:
parent
5309b98bcf
commit
8347eae959
@ -21,7 +21,7 @@ spring:
|
||||
# Redis配置(支持环境变量)
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:localhost}
|
||||
host: ${REDIS_HOST:10.0.0.58}
|
||||
port: ${REDIS_PORT:6379}
|
||||
database: ${REDIS_DATABASE:0}
|
||||
password: ${REDIS_PASSWORD:}
|
||||
@ -77,8 +77,8 @@ data:
|
||||
retry-attempts: ${VEHICLE_API_RETRY:3}
|
||||
|
||||
vehicle-manager:
|
||||
host: ${VEHICLE_MANAGER_HOST:}
|
||||
port: ${VEHICLE_MANAGER_PORT:0}
|
||||
host: ${VEHICLE_MANAGER_HOST:localhost}
|
||||
port: ${VEHICLE_MANAGER_PORT:8020}
|
||||
reconnect-delay-millis: ${VEHICLE_MANAGER_RECONNECT_DELAY:3000}
|
||||
ws:
|
||||
at-manager: /ws/at_manager
|
||||
|
||||
@ -40,7 +40,7 @@ spring:
|
||||
|
||||
# 默认激活的profile(开发环境)
|
||||
profiles:
|
||||
# active: dev,druid
|
||||
#active: dev,druid
|
||||
active: prod,druid
|
||||
|
||||
# 文件上传
|
||||
|
||||
@ -38,6 +38,16 @@ public class VehicleManagerApiController {
|
||||
return AjaxResult.success(summary).put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@GetMapping("/vehicles")
|
||||
public AjaxResult getVehicleList(
|
||||
@RequestParam(defaultValue = "1") int pageNum,
|
||||
@RequestParam(defaultValue = "10") int pageSize,
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(defaultValue = "30000") long staleMillis) {
|
||||
VehicleManagerQueryService.VehicleListResponse response = queryService.getVehicleList(pageNum, pageSize, status, staleMillis);
|
||||
return AjaxResult.success(response).put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@GetMapping("/vehicles/{vehicleId}")
|
||||
public AjaxResult getVehicleSnapshot(@PathVariable String vehicleId) {
|
||||
Map<String, Object> snapshot = queryService.getVehicleSnapshot(vehicleId);
|
||||
@ -122,8 +132,8 @@ public class VehicleManagerApiController {
|
||||
Double y = getDouble(node, "y");
|
||||
waypoints.add(MissionContextDTO.WaypointDTO.builder()
|
||||
.waypointId(String.valueOf(index++))
|
||||
.longitude(x)
|
||||
.latitude(y)
|
||||
.longitude(y)
|
||||
.latitude(x)
|
||||
.status("PENDING")
|
||||
.build());
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ public class DataCollectorService {
|
||||
Double x = getDouble(dataNode, "x");
|
||||
Double y = getDouble(dataNode, "y");
|
||||
if (x != null && y != null) {
|
||||
Point currentPosition = geometryFactory.createPoint(new org.locationtech.jts.geom.Coordinate(x, y));
|
||||
Point currentPosition = geometryFactory.createPoint(new org.locationtech.jts.geom.Coordinate(y, x));
|
||||
|
||||
MovingObject existing = activeMovingObjectsCache.get(vehicleId);
|
||||
UnmannedVehicle vehicle = existing instanceof UnmannedVehicle
|
||||
|
||||
@ -6,9 +6,7 @@ import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@ -187,4 +185,166 @@ public class VehicleManagerQueryService {
|
||||
}
|
||||
return value.asText();
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public static class VehicleListItemDTO {
|
||||
private String vehicleId;
|
||||
private String vehicleType;
|
||||
private String status;
|
||||
private Map<String, Object> position;
|
||||
private Double speed;
|
||||
private Double batteryLevel;
|
||||
private Long lastSeenAt;
|
||||
private Boolean isEmergency;
|
||||
private Boolean isFault;
|
||||
private String currentTask;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public static class VehicleListResponse {
|
||||
private int total;
|
||||
private int pageNum;
|
||||
private int pageSize;
|
||||
private List<VehicleListItemDTO> rows;
|
||||
private VehicleSummary summary;
|
||||
}
|
||||
|
||||
public VehicleListResponse getVehicleList(int pageNum, int pageSize, String statusFilter, long staleMillis) {
|
||||
long now = System.currentTimeMillis();
|
||||
Set<String> vehicleIds = cacheService.getKnownVehicleIds();
|
||||
List<VehicleListItemDTO> allVehicles = new ArrayList<>();
|
||||
|
||||
for (String vehicleId : vehicleIds) {
|
||||
VehicleManagerCacheService.CacheEntry detailsEntry = cacheService.getVehicleDetails(vehicleId);
|
||||
VehicleManagerCacheService.CacheEntry loginEntry = cacheService.getVehicleLoginStatus(vehicleId);
|
||||
VehicleManagerCacheService.CacheEntry positionEntry = cacheService.getVehiclePosition(vehicleId);
|
||||
VehicleManagerCacheService.CacheEntry chassisEntry = cacheService.getVehicleChassis(vehicleId);
|
||||
VehicleManagerCacheService.CacheEntry suspendEntry = cacheService.getVehicleSuspend(vehicleId);
|
||||
VehicleManagerCacheService.CacheEntry fmsEntry = cacheService.getVehicleFmsMessage(vehicleId);
|
||||
VehicleManagerCacheService.CacheEntry orderEntry = cacheService.getVehicleOrder(vehicleId);
|
||||
|
||||
String vehicleType = getText(detailsEntry != null ? detailsEntry.getData() : null, "vehicleType");
|
||||
String loginStatus = getText(loginEntry != null ? loginEntry.getData() : null, "loginStatus");
|
||||
boolean loginStale = isStale(loginEntry, now, staleMillis);
|
||||
|
||||
String status;
|
||||
if (loginEntry == null || loginStale) {
|
||||
status = "offline";
|
||||
} else {
|
||||
status = "login".equalsIgnoreCase(loginStatus) ? "online" : "offline";
|
||||
}
|
||||
|
||||
boolean isEmergency = false;
|
||||
if (!isStale(suspendEntry, now, staleMillis)) {
|
||||
Integer suspendStatus = getInt(suspendEntry != null ? suspendEntry.getData() : null, "suspendStatus");
|
||||
if (suspendStatus != null && suspendStatus != 0) {
|
||||
isEmergency = true;
|
||||
status = "emergency";
|
||||
}
|
||||
}
|
||||
|
||||
boolean isFault = false;
|
||||
if (!isStale(fmsEntry, now, staleMillis)) {
|
||||
if (isFault(fmsEntry != null ? fmsEntry.getData() : null)) {
|
||||
isFault = true;
|
||||
status = "fault";
|
||||
}
|
||||
}
|
||||
|
||||
if (statusFilter != null && !statusFilter.isEmpty() && !status.equalsIgnoreCase(statusFilter)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<String, Object> position = null;
|
||||
if (positionEntry != null && positionEntry.getData() != null) {
|
||||
JsonNode posData = positionEntry.getData();
|
||||
position = new HashMap<>();
|
||||
position.put("x", getDouble(posData, "x"));
|
||||
position.put("y", getDouble(posData, "y"));
|
||||
position.put("theta", getDouble(posData, "theta"));
|
||||
}
|
||||
|
||||
Double speed = null;
|
||||
if (chassisEntry != null && chassisEntry.getData() != null) {
|
||||
JsonNode chassisData = chassisEntry.getData();
|
||||
JsonNode stateInfo = chassisData.path("sys_info").path("state_info");
|
||||
speed = getDouble(stateInfo, "d_speed_kmph");
|
||||
}
|
||||
|
||||
Double batteryLevel = null;
|
||||
if (chassisEntry != null && chassisEntry.getData() != null) {
|
||||
JsonNode chassisData = chassisEntry.getData();
|
||||
JsonNode stateInfo = chassisData.path("sys_info").path("state_info");
|
||||
String batteryStr = getText(stateInfo, "d_battery_available");
|
||||
if (batteryStr != null) {
|
||||
try {
|
||||
batteryLevel = Double.parseDouble(batteryStr);
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String currentTask = null;
|
||||
if (orderEntry != null && orderEntry.getData() != null) {
|
||||
currentTask = getText(orderEntry.getData(), "businessKey");
|
||||
}
|
||||
|
||||
VehicleListItemDTO item = VehicleListItemDTO.builder()
|
||||
.vehicleId(vehicleId)
|
||||
.vehicleType(vehicleType)
|
||||
.status(status)
|
||||
.position(position)
|
||||
.speed(speed)
|
||||
.batteryLevel(batteryLevel)
|
||||
.lastSeenAt(getLastSeenAt(vehicleId))
|
||||
.isEmergency(isEmergency)
|
||||
.isFault(isFault)
|
||||
.currentTask(currentTask)
|
||||
.build();
|
||||
|
||||
allVehicles.add(item);
|
||||
}
|
||||
|
||||
int total = allVehicles.size();
|
||||
int fromIndex = (pageNum - 1) * pageSize;
|
||||
int toIndex = Math.min(fromIndex + pageSize, total);
|
||||
List<VehicleListItemDTO> pagedVehicles = fromIndex < total ?
|
||||
allVehicles.subList(fromIndex, toIndex) : new ArrayList<>();
|
||||
|
||||
VehicleSummary summary = getVehicleSummary(staleMillis);
|
||||
|
||||
return VehicleListResponse.builder()
|
||||
.total(total)
|
||||
.pageNum(pageNum)
|
||||
.pageSize(pageSize)
|
||||
.rows(pagedVehicles)
|
||||
.summary(summary)
|
||||
.build();
|
||||
}
|
||||
|
||||
private Double getDouble(JsonNode node, String field) {
|
||||
if (node == null || node.isMissingNode()) {
|
||||
return null;
|
||||
}
|
||||
JsonNode value = node.get(field);
|
||||
if (value == null || value.isNull()) {
|
||||
return null;
|
||||
}
|
||||
if (value.isDouble() || value.isFloat()) {
|
||||
return value.asDouble();
|
||||
}
|
||||
if (value.isInt() || value.isLong()) {
|
||||
return (double) value.asLong();
|
||||
}
|
||||
if (value.isTextual()) {
|
||||
try {
|
||||
return Double.parseDouble(value.asText());
|
||||
} catch (NumberFormatException ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,8 +61,8 @@ public class VehicleStatusAggregationService {
|
||||
Double y = getDouble(data, "y");
|
||||
if (x != null && y != null) {
|
||||
position = MotionStatusDTO.PositionDTO.builder()
|
||||
.longitude(x)
|
||||
.latitude(y)
|
||||
.longitude(y)
|
||||
.latitude(x)
|
||||
.build();
|
||||
}
|
||||
Double theta = getDouble(data, "theta");
|
||||
@ -166,8 +166,8 @@ public class VehicleStatusAggregationService {
|
||||
Double y = getDouble(node, "y");
|
||||
MissionContextDTO.WaypointDTO waypoint = MissionContextDTO.WaypointDTO.builder()
|
||||
.waypointId(String.valueOf(index++))
|
||||
.longitude(x)
|
||||
.latitude(y)
|
||||
.longitude(y)
|
||||
.latitude(x)
|
||||
.status("PENDING")
|
||||
.build();
|
||||
waypoints.add(waypoint);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user