Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/main/java/club/joylink/xiannccda/ats/cache/LineGraphicDataRepository.java
#	xian-ncc-da-message
This commit is contained in:
joylink_zhangsai 2023-07-24 16:24:51 +08:00
commit 14454be2dc
8 changed files with 1755 additions and 1544 deletions

View File

@ -5,20 +5,18 @@ import club.joylink.xiannccda.dto.PublishedGIQueryDTO;
import club.joylink.xiannccda.entity.PublishedGi; import club.joylink.xiannccda.entity.PublishedGi;
import club.joylink.xiannccda.repository.IPublishedGiRepository; import club.joylink.xiannccda.repository.IPublishedGiRepository;
import java.util.List; import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner; import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** 线路发布数据内存管理 */ /** 线路发布数据内存管理 */
@Component @Component
@RequiredArgsConstructor
public class LineGraphicDataManage implements ApplicationRunner { public class LineGraphicDataManage implements ApplicationRunner {
final IPublishedGiRepository iPublishedGiRepository; final IPublishedGiRepository iPublishedGiRepository;
public LineGraphicDataManage(IPublishedGiRepository iPublishedGiRepository) {
this.iPublishedGiRepository = iPublishedGiRepository;
}
@Override @Override
public void run(ApplicationArguments args) throws Exception { public void run(ApplicationArguments args) throws Exception {
PublishedGIQueryDTO query = new PublishedGIQueryDTO(); PublishedGIQueryDTO query = new PublishedGIQueryDTO();

View File

@ -1,6 +1,8 @@
package club.joylink.xiannccda.ats.cache; package club.joylink.xiannccda.ats.cache;
import club.joylink.xiannccda.dto.protos.DeviceInfoProto; import club.joylink.xiannccda.dto.protos.DeviceInfoProto;
import club.joylink.xiannccda.dto.protos.DeviceInfoProto.DeviceKilometer;
import club.joylink.xiannccda.dto.protos.DeviceInfoProto.Turnout;
import club.joylink.xiannccda.dto.protos.LayoutGraphicsProto; import club.joylink.xiannccda.dto.protos.LayoutGraphicsProto;
import club.joylink.xiannccda.dto.protos.LayoutGraphicsProto.CommonInfo; import club.joylink.xiannccda.dto.protos.LayoutGraphicsProto.CommonInfo;
import club.joylink.xiannccda.dto.protos.LayoutGraphicsProto.KilometerSystem; import club.joylink.xiannccda.dto.protos.LayoutGraphicsProto.KilometerSystem;
@ -26,34 +28,25 @@ import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
/** /** 发布时缓存在内存中的线路数据 */
* 发布时缓存在内存中的线路数据
*/
@Slf4j @Slf4j
public class LineGraphicDataRepository { public class LineGraphicDataRepository {
/** /** 线路数据信息 */
* 线路数据信息
*/
private static final Map<Integer, Map<String, Map<String, Builder>>> lineGraphMap = private static final Map<Integer, Map<String, Map<String, Builder>>> lineGraphMap =
new ConcurrentHashMap<>(); new ConcurrentHashMap<>();
/** /** 线路各坐标系转换关系 */
* 线路各坐标系转换关系
*/
private static final Map<Integer, Map<String, CoordinateConvertor>> lineCoordinateMain = private static final Map<Integer, Map<String, CoordinateConvertor>> lineCoordinateMain =
new HashMap<>(); new HashMap<>();
/** /** 线路-设备code-设备 */
* 线路-设备code-设备 private static final HashBasedTable<Short, String, MessageOrBuilder> line_code_table =
*/
private static final HashBasedTable<Integer, String, MessageOrBuilder> line_code_table =
HashBasedTable.create(); HashBasedTable.create();
/** /** 线路-设备id-设备 */
* 线路-设备id-设备 private static final HashBasedTable<Short, String, MessageOrBuilder> line_id_table =
*/ HashBasedTable.create();
private static final HashBasedTable<Integer, String, MessageOrBuilder> line_id_table = HashBasedTable.create();
/** /**
* 缓存线路数据信息 * 缓存线路数据信息
@ -68,13 +61,17 @@ public class LineGraphicDataRepository {
// DeviceNameChanger.init(storage); // DeviceNameChanger.init(storage);
Map<String, Map<String, Builder>> lineDataMap = new HashMap<>(); Map<String, Map<String, Builder>> lineDataMap = new HashMap<>();
// 构建区段 // 构建区段
sectionInitLineGraph(lineDataMap, storage); physicalSectionInitLineGraph(lineDataMap, storage);
// 构建道岔 // 构建道岔
turnoutInitLineGraph(publishGi.getLineId(), lineDataMap, storage); turnoutInitLineGraph(publishGi.getLineId(), lineDataMap, storage);
// 设置公里标 // 设置公里标
setUpKilometerCode(publishGi.getLineId(), lineDataMap, storage); setUpKilometerCode(publishGi.getLineId(), lineDataMap, storage);
// --------------------这里需要依赖区段道岔初始化信息 start-----------------
// 设置公里标后开始构建逻辑区段的编码公里标信息 // 设置公里标后开始构建逻辑区段的编码公里标信息
setUpLogicSectionInfo(lineDataMap, storage); setUpLogicSectionInfo(lineDataMap, storage);
// 设置道岔区段信息
setUpTurnoutPhysicalSectionInfo(lineDataMap, storage);
// --------------------这里需要依赖区段道岔初始化信息 end ------------------
lineGraphMap.put(publishGi.getLineId(), lineDataMap); lineGraphMap.put(publishGi.getLineId(), lineDataMap);
// 填充line_code_table // 填充line_code_table
@ -88,18 +85,18 @@ public class LineGraphicDataRepository {
/** /**
* 获取线路上区段名为sectionName的公里标 * 获取线路上区段名为sectionName的公里标
* *
* @param lineId 线路ID * @param lineId 线路ID
* @param sectionName 区段名称 * @param sectionName 区段名称
* @return 公里标 * @return 公里标
*/ */
public static List<Long> getKilometerCodeList(int lineId, String sectionName) { public static DeviceKilometer.Builder getKilometerCodeList(int lineId, String sectionName) {
Map<String, Map<String, Builder>> lineDataMap = lineGraphMap.get(lineId); Map<String, Map<String, Builder>> lineDataMap = lineGraphMap.get(lineId);
if (CollectionUtils.isNotEmpty(lineDataMap)) { if (CollectionUtils.isNotEmpty(lineDataMap)) {
Map<String, Builder> sectionMap = lineDataMap.get(DeviceType.Section.name()); Map<String, Builder> sectionMap = lineDataMap.get(DeviceType.Section.name());
for (Builder v : sectionMap.values()) { for (Builder v : sectionMap.values()) {
DeviceInfoProto.Section.Builder builder = (DeviceInfoProto.Section.Builder) v; DeviceInfoProto.Section.Builder builder = (DeviceInfoProto.Section.Builder) v;
if (Objects.equals(builder.getCode(), sectionName)) { if (Objects.equals(builder.getCode(), sectionName)) {
return builder.getConvertKilometerList(); return builder.getKilometerBuilder();
} }
} }
@ -107,16 +104,14 @@ public class LineGraphicDataRepository {
for (Builder v : turnoutMap.values()) { for (Builder v : turnoutMap.values()) {
DeviceInfoProto.Turnout.Builder builder = (DeviceInfoProto.Turnout.Builder) v; DeviceInfoProto.Turnout.Builder builder = (DeviceInfoProto.Turnout.Builder) v;
if (Objects.equals(builder.getCode(), sectionName)) { if (Objects.equals(builder.getCode(), sectionName)) {
return builder.getConvertKilometerList(); return builder.getKilometerBuilder();
} }
} }
} }
return List.of(); return null;
} }
/** /** 删除线路绘图数据 */
* 删除线路绘图数据
*/
public static void removeLineGraph(Integer id) { public static void removeLineGraph(Integer id) {
lineGraphMap.remove(id); lineGraphMap.remove(id);
} }
@ -165,55 +160,59 @@ public class LineGraphicDataRepository {
}); });
} }
/**
* 获取线路的区段集合
*
* @param lineId 线路ID
* @return 区段集合
*/
public static Map<String, Builder> getLineSectionBuild(int lineId) {
Map<String, Map<String, Builder>> lineDataMap = lineGraphMap.get(lineId);
if (CollectionUtils.isNotEmpty(lineDataMap)) {
return lineDataMap.get(DeviceType.Section.name());
}
return Map.of();
}
/** /**
* 构建程序中的区段信息 * 构建程序中的区段信息
* *
* @param dataMap 缓存数据 * @param dataMap 缓存数据
* @param storage 地图构建数据 * @param storage 地图构建数据
*/ */
private static void sectionInitLineGraph( private static void physicalSectionInitLineGraph(
Map<String, Map<String, Builder>> dataMap, LayoutGraphicsProto.RtssGraphicStorage storage) { Map<String, Map<String, Builder>> dataMap, LayoutGraphicsProto.RtssGraphicStorage storage) {
// 地图 // 先初始化物理区段信息
List<Section> sectionList = storage.getSectionList(); List<Section> sectionList =
// 物理区段数据 storage.getSectionList().stream()
Map<String, Builder> cacheSectionMap = new HashMap<>(sectionList.size()); .filter(s -> Objects.equals(s.getSectionType(), SectionType.Physical))
// 要保存的逻辑区段信息,预设值[section数量 * ABCD] .toList();
Map<String, Builder> cacheLogicSectionMap = new HashMap<>(sectionList.size() * 4); // 物理区段数据 + 逻辑区段数据预设值[物理section数量 * ABCD]
Map<String, Builder> sectionMap = new HashMap<>(sectionList.size() * 5);
sectionList.stream() sectionList.stream()
// 目前数据中还存在 区段类型为 逻辑区段类型暂时先过滤掉错误 // 目前数据中还存在 区段类型为 逻辑区段类型暂时先过滤掉错误
.filter(section -> !SectionType.UNRECOGNIZED.equals(section.getSectionType())) .filter(section -> !SectionType.UNRECOGNIZED.equals(section.getSectionType()))
.forEach( .forEach(
section -> { section -> {
String sid = section.getCommon().getId(); String sid = section.getCommon().getId();
DeviceInfoProto.Section.Builder sectionBuilder = DeviceInfoProto.Section.Builder sectionBuilder = initSection(sectionMap, sid);
cacheSectionMap.containsKey(sid)
? (DeviceInfoProto.Section.Builder) cacheSectionMap.get(sid)
: DeviceInfoProto.Section.newBuilder().setId(sid);
sectionBuilder.setCode(section.getCode()); sectionBuilder.setCode(section.getCode());
sectionBuilder.setDestinationCode(section.getDestinationCode());
if (section.getChildrenCount() > 0) { if (section.getChildrenCount() > 0) {
sectionBuilder.addAllChildrenId(section.getChildrenList()); sectionBuilder.addAllChildrenId(section.getChildrenList());
// 初始化逻辑区段信息,建立逻辑区段与物理区段之间的关系 // 初始化逻辑区段信息,建立逻辑区段与物理区段之间的关系
section section
.getChildrenList() .getChildrenList()
.forEach( .forEach(id -> initSection(sectionMap, id).setPhysicalSectionId(sid));
id ->
cacheLogicSectionMap.put(
id,
DeviceInfoProto.Section.newBuilder()
.setId(id)
.setPhysicalSectionId(sid)));
} }
cacheSectionMap.put(sid, sectionBuilder);
}); });
// 将逻辑区段信息放入区段集合中 dataMap.put(DeviceType.Section.name(), sectionMap);
cacheSectionMap.putAll(cacheLogicSectionMap);
dataMap.put(DeviceType.Section.name(), cacheSectionMap);
} }
/** /**
* 构建道岔信息 * 构建道岔信息
* *
* @param lineId 线路ID * @param lineId 线路ID
* @param dataMap 缓存数据 * @param dataMap 缓存数据
* @param storage 地图构建数据 * @param storage 地图构建数据
*/ */
@ -234,37 +233,56 @@ public class LineGraphicDataRepository {
DeviceInfoProto.Turnout.Builder turnoutBuilder = DeviceInfoProto.Turnout.newBuilder(); DeviceInfoProto.Turnout.Builder turnoutBuilder = DeviceInfoProto.Turnout.newBuilder();
turnoutBuilder.setId(t.getCommon().getId()); turnoutBuilder.setId(t.getCommon().getId());
turnoutBuilder.setCode(t.getCode()); turnoutBuilder.setCode(t.getCode());
turnoutBuilder.addAllKilometerSystem(systemList); turnoutBuilder.setKilometer(initKilometer(systemList));
cacheSwitchMap.put(t.getCommon().getId(), turnoutBuilder); cacheSwitchMap.put(t.getCommon().getId(), turnoutBuilder);
// 从道岔中生成坐标转换对象 convertorCoordinateByTurnoutKM(convertorMap, systemList);
if (systemList.size() > 1) {
for (int i = 0, len = systemList.size(); i < len; i++) {
KilometerSystem si = systemList.get(i);
for (int j = i + 1; j < len; j++) {
KilometerSystem sj = systemList.get(j);
// 坐标系不一致时生成转换对象
if (!Objects.equals(sj.getCoordinateSystem(), si.getCoordinateSystem())) {
String convertorKey =
CoordinateConvertor.generateConvertorKey(
sj.getCoordinateSystem(), si.getCoordinateSystem());
if (!convertorMap.containsKey(convertorKey)) {
convertorMap.put(
convertorKey,
CoordinateConvertor.generate(
si, sj.getCoordinateSystem(), sj.getKilometer()));
}
}
}
}
}
}); });
dataMap.put(DeviceType.Turnout.name(), cacheSwitchMap); dataMap.put(DeviceType.Turnout.name(), cacheSwitchMap);
} }
/**
* 设置道岔区段信息
*
* @param dataMap 设备信息
* @param storage
*/
private static void setUpTurnoutPhysicalSectionInfo(
Map<String, Map<String, Builder>> dataMap, LayoutGraphicsProto.RtssGraphicStorage storage) {
Map<String, Builder> curSectionMap = dataMap.getOrDefault(DeviceType.Section.name(), Map.of());
Map<String, Builder> turnoutMap = dataMap.getOrDefault(DeviceType.Turnout.name(), Map.of());
// 先初始化物理区段信息
List<Section> sectionList =
storage.getSectionList().stream()
.filter(s -> Objects.equals(s.getSectionType(), SectionType.TurnoutPhysical))
.toList();
// 道岔区段数据
Map<String, Builder> sectionMap = new HashMap<>(sectionList.size());
sectionList.forEach(
section -> {
String sid = section.getCommon().getId();
DeviceInfoProto.Section.Builder s = initSection(sectionMap, sid);
s.setCode(section.getCode());
s.setDestinationCode(section.getDestinationCode());
if (section.getChildrenCount() > 0) {
section
.getChildrenList()
.forEach(
tid -> {
Turnout.Builder t = findTurnout(turnoutMap, tid);
if (t != null) {
updateMinAndMaxKilometer(s.getKilometerBuilder(), t.getKilometerBuilder());
}
});
}
});
curSectionMap.putAll(sectionMap);
dataMap.put(DeviceType.Section.name(), curSectionMap);
}
/** /**
* 设置公里标 * 设置公里标
* *
* @param lineId 线路ID * @param lineId 线路ID
* @param dataMap 缓存数据 * @param dataMap 缓存数据
* @param storage 地图构建数据 * @param storage 地图构建数据
*/ */
@ -285,27 +303,23 @@ public class LineGraphicDataRepository {
.forEach( .forEach(
ref -> { ref -> {
if (Objects.equals(DeviceType.Section, ref.getDeviceType())) { if (Objects.equals(DeviceType.Section, ref.getDeviceType())) {
if (sectionMap.containsKey(ref.getId())) { DeviceInfoProto.Section.Builder b = findSection(sectionMap, ref.getId());
DeviceInfoProto.Section.Builder sectionBuilder = if (b != null) {
(DeviceInfoProto.Section.Builder) sectionMap.get(ref.getId()); DeviceInfoProto.DeviceKilometer.Builder k = b.getKilometerBuilder();
sectionBuilder.addKilometerSystem(ac.getKilometerSystem()); updateKilometer(k, ac.getKilometerSystem(), mainLineCoordinate);
sectionBuilder.addConvertKilometer(mainLineCoordinate);
} }
} else if (Objects.equals(DeviceType.Turnout, ref.getDeviceType())) { } else if (Objects.equals(DeviceType.Turnout, ref.getDeviceType())) {
if (turnoutMap.containsKey(ref.getId())) { DeviceInfoProto.Turnout.Builder b = findTurnout(turnoutMap, ref.getId());
DeviceInfoProto.Turnout.Builder turnoutBuilder = if (b != null) {
(DeviceInfoProto.Turnout.Builder) turnoutMap.get(ref.getId()); DeviceInfoProto.DeviceKilometer.Builder k = b.getKilometerBuilder();
// 如果已经转换过则不再做转换 // 更新道岔自身的公里标数据
if (turnoutBuilder.getConvertKilometerCount() == 0) { k.getKilometerSystemList()
turnoutBuilder.getKilometerSystemList().stream() .forEach(
.filter(s -> StringUtils.isNotEmpty(s.getCoordinateSystem())) s ->
.forEach( updateMinAndMaxKilometer(
s -> k, doConvertorCoordinate(lineId, s)));
turnoutBuilder.addConvertKilometer( // 放入当前计轴信息
doConvertorCoordinate(lineId, s))); updateKilometer(k, ac.getKilometerSystem(), mainLineCoordinate);
}
// 放入当前计轴转换信息
turnoutBuilder.addConvertKilometer(mainLineCoordinate);
} }
} }
}); });
@ -315,7 +329,7 @@ public class LineGraphicDataRepository {
/** /**
* 初始化坐标转换对象 * 初始化坐标转换对象
* *
* @param lineId 线路ID * @param lineId 线路ID
* @param dataMap 设备集合 * @param dataMap 设备集合
* @param storage 地图信息 * @param storage 地图信息
*/ */
@ -343,8 +357,8 @@ public class LineGraphicDataRepository {
DeviceType.Turnout.equals(ref.getDeviceType()) DeviceType.Turnout.equals(ref.getDeviceType())
&& turnoutMap.containsKey(ref.getId())) && turnoutMap.containsKey(ref.getId()))
.map(ref -> (DeviceInfoProto.Turnout.Builder) turnoutMap.get(ref.getId())) .map(ref -> (DeviceInfoProto.Turnout.Builder) turnoutMap.get(ref.getId()))
.filter(t -> t.getKilometerSystemCount() > 0) .filter(t -> t.getKilometer().getKilometerSystemCount() > 0)
.map(t -> t.getKilometerSystemList().get(0)) .map(t -> t.getKilometer().getKilometerSystemList().get(0))
.toList(); .toList();
// 如果关联多个道岔 // 如果关联多个道岔
if (kilometerSystemList.size() > 1) { if (kilometerSystemList.size() > 1) {
@ -387,6 +401,49 @@ public class LineGraphicDataRepository {
}); });
} }
/**
* 根据道岔的公里标获取转换信息
*
* @param convertorMap 转换保存集合
* @param systemList 公里标集合
*/
private static void convertorCoordinateByTurnoutKM(
Map<String, CoordinateConvertor> convertorMap, List<KilometerSystem> systemList) {
if (CollectionUtils.isEmpty(systemList)) {
return;
}
// 有效坐标系
List<KilometerSystem> effectiveList =
systemList.stream().filter(s -> StringUtils.isNotEmpty(s.getCoordinateSystem())).toList();
if (CollectionUtils.isEmpty(effectiveList)) {
return;
}
// 坐标系的种类
long typeCount =
effectiveList.stream().map(KilometerSystem::getCoordinateSystem).distinct().count();
if (typeCount < 2) { // 种类小于2则不需要转换
return;
}
// 从道岔中生成坐标转换对象
for (int i = 0, len = effectiveList.size(); i < len; i++) {
KilometerSystem si = effectiveList.get(i);
for (int j = i + 1; j < len; j++) {
KilometerSystem sj = effectiveList.get(j);
// 坐标系不一致时生成转换对象
if (!Objects.equals(sj.getCoordinateSystem(), si.getCoordinateSystem())) {
String convertorKey =
CoordinateConvertor.generateConvertorKey(
sj.getCoordinateSystem(), si.getCoordinateSystem());
if (!convertorMap.containsKey(convertorKey)) {
convertorMap.put(
convertorKey,
CoordinateConvertor.generate(si, sj.getCoordinateSystem(), sj.getKilometer()));
}
}
}
}
}
/** /**
* 公里标转换 * 公里标转换
* *
@ -426,32 +483,134 @@ public class LineGraphicDataRepository {
section -> { section -> {
String sid = section.getCommon().getId(); String sid = section.getCommon().getId();
if (sectionMap.containsKey(sid)) { if (sectionMap.containsKey(sid)) {
DeviceInfoProto.Section.Builder sectionBuilder = DeviceInfoProto.Section.Builder sectionBuilder = findSection(sectionMap, sid);
(DeviceInfoProto.Section.Builder) sectionMap.get(sid);
sectionBuilder.setCode(section.getCode()); sectionBuilder.setCode(section.getCode());
// 获取到物理区段信息 // 获取到物理区段信息
DeviceInfoProto.Section.Builder physicalSection = DeviceInfoProto.Section.Builder physicalSection =
(DeviceInfoProto.Section.Builder) findSection(sectionMap, sectionBuilder.getPhysicalSectionId());
sectionMap.get(sectionBuilder.getPhysicalSectionId()); DeviceKilometer.Builder deviceKilometer = sectionBuilder.getKilometerBuilder();
if (physicalSection.getKilometerSystemCount() > 0) { DeviceKilometer.Builder parentKilometer = physicalSection.getKilometerBuilder();
long min = if (parentKilometer.getKilometerSystemCount() > 0) {
physicalSection.getConvertKilometerList().stream().min(Long::compareTo).get(); long min = parentKilometer.getMinKilometer();
long max = long max = parentKilometer.getMaxKilometer();
physicalSection.getConvertKilometerList().stream().max(Long::compareTo).get();
long avgDistance = (max - min) / physicalSection.getChildrenIdCount(); long avgDistance = (max - min) / physicalSection.getChildrenIdCount();
int index = physicalSection.getChildrenIdList().indexOf(sid); int index = physicalSection.getChildrenIdList().indexOf(sid);
// 最小公里标 deviceKilometer.setMinKilometer(min + index * avgDistance); // 最小公里标
sectionBuilder.addConvertKilometer(min + index * avgDistance); deviceKilometer.setMaxKilometer(min + (index + 1) * avgDistance); // 最大公里标
// 最大公里标
sectionBuilder.addConvertKilometer(min + (index + 1) * avgDistance);
} }
} }
}); });
} }
/** /**
* 坐标系枚举 * <<<<<<< HEAD 生成默认的公里标对象
*
* @param list 公里标列表
* @return 对象信息
*/ */
private static DeviceInfoProto.DeviceKilometer.Builder initKilometer(List<KilometerSystem> list) {
DeviceInfoProto.DeviceKilometer.Builder builder = initKilometer();
if (CollectionUtils.isNotEmpty(list)) {
builder.addAllKilometerSystem(list);
}
return builder;
}
/**
* 生成默认的公里标对象
*
* @return 对象信息
*/
private static DeviceInfoProto.DeviceKilometer.Builder initKilometer() {
DeviceInfoProto.DeviceKilometer.Builder builder = DeviceInfoProto.DeviceKilometer.newBuilder();
builder.setMinKilometer(Long.MAX_VALUE);
builder.setMaxKilometer(Long.MIN_VALUE);
return builder;
}
/**
* 更新实体内的公里标信息
*
* @param kilometer 公里标对象
* @param km 传入的公里标
* @param mainLineCoordinate 转换成的正线公里标信息
*/
private static void updateKilometer(
DeviceInfoProto.DeviceKilometer.Builder kilometer,
KilometerSystem km,
long mainLineCoordinate) {
kilometer.addKilometerSystem(km);
kilometer.setMinKilometer(Math.min(kilometer.getMinKilometer(), mainLineCoordinate));
kilometer.setMaxKilometer(Math.max(kilometer.getMaxKilometer(), mainLineCoordinate));
}
/**
* 更新实体最大最小公里标
*
* @param kilometer 公里标对象
* @param mainLineCoordinate 转换的正线数据
*/
private static void updateMinAndMaxKilometer(
DeviceInfoProto.DeviceKilometer.Builder kilometer, long mainLineCoordinate) {
kilometer.setMinKilometer(Math.min(kilometer.getMinKilometer(), mainLineCoordinate));
kilometer.setMaxKilometer(Math.max(kilometer.getMaxKilometer(), mainLineCoordinate));
}
private static void updateMinAndMaxKilometer(
DeviceInfoProto.DeviceKilometer.Builder kilometer,
DeviceInfoProto.DeviceKilometer.Builder km) {
kilometer.setMinKilometer(Math.min(kilometer.getMinKilometer(), km.getMinKilometer()));
kilometer.setMaxKilometer(Math.max(kilometer.getMaxKilometer(), km.getMaxKilometer()));
}
/**
* 获取区段信息没有时创建并放入map中
*
* @param map 区段的集合
* @param id 区段ID
* @return 区段实体信息
*/
private static DeviceInfoProto.Section.Builder initSection(Map<String, Builder> map, String id) {
if (map.containsKey(id)) {
return (DeviceInfoProto.Section.Builder) map.get(id);
} else {
DeviceInfoProto.Section.Builder builder = DeviceInfoProto.Section.newBuilder();
builder.setId(id);
builder.setKilometer(initKilometer());
map.put(id, builder);
return builder;
}
}
/**
* 获取区段信息
*
* @param map 区段集合
* @param id 区段ID
* @return 区段信息
*/
private static DeviceInfoProto.Section.Builder findSection(Map<String, Builder> map, String id) {
if (map.containsKey(id)) {
return (DeviceInfoProto.Section.Builder) map.get(id);
}
return null;
}
/**
* 获取道岔信息
*
* @param map 道岔集合
* @param id 道岔ID
* @return 道岔信息
*/
private static DeviceInfoProto.Turnout.Builder findTurnout(Map<String, Builder> map, String id) {
if (map.containsKey(id)) {
return (DeviceInfoProto.Turnout.Builder) map.get(id);
}
return null;
}
/** 坐标系枚举 */
@Getter @Getter
private enum CoordinateEnum { private enum CoordinateEnum {
MAIN_LINE("MAIN_LINE", List.of("YDK", "ZDK", "XDK", "SDK")), MAIN_LINE("MAIN_LINE", List.of("YDK", "ZDK", "XDK", "SDK")),
@ -496,9 +655,7 @@ public class LineGraphicDataRepository {
} }
} }
/** /** 坐标转换对象 */
* 坐标转换对象
*/
@Getter @Getter
private static class CoordinateConvertor { private static class CoordinateConvertor {
@ -513,8 +670,8 @@ public class LineGraphicDataRepository {
/** /**
* 生成坐标转换对象 * 生成坐标转换对象
* *
* @param configSystem 原配置坐标系信息 * @param configSystem 原配置坐标系信息
* @param convertorSystem 转换坐标系类型 * @param convertorSystem 转换坐标系类型
* @param convertorCoordinate 转换坐标 * @param convertorCoordinate 转换坐标
* @return 转换对象 * @return 转换对象
*/ */
@ -566,7 +723,7 @@ public class LineGraphicDataRepository {
* 将出入库公里标转换为正线标 * 将出入库公里标转换为正线标
* *
* @param basisKilometer 出入库基准公里标 * @param basisKilometer 出入库基准公里标
* @param targetType 目标坐标系 * @param targetType 目标坐标系
* @return 正线公里标数字 * @return 正线公里标数字
*/ */
public long convertorKilometer(KilometerSystem basisKilometer, CoordinateEnum targetType) { public long convertorKilometer(KilometerSystem basisKilometer, CoordinateEnum targetType) {

View File

@ -6,11 +6,14 @@ import club.joylink.xiannccda.ats.message.collect.DeviceStatusDataRepository;
import club.joylink.xiannccda.ats.message.collect.datasource.DeviceStatusData; import club.joylink.xiannccda.ats.message.collect.datasource.DeviceStatusData;
import club.joylink.xiannccda.ats.message.line3.changer.DeviceNameChangerManage; import club.joylink.xiannccda.ats.message.line3.changer.DeviceNameChangerManage;
import club.joylink.xiannccda.ats.message.line3.device.DeviceType; import club.joylink.xiannccda.ats.message.line3.device.DeviceType;
import club.joylink.xiannccda.dto.protos.DeviceInfoProto;
import club.joylink.xiannccda.dto.protos.DeviceInfoProto.DeviceKilometer;
import club.joylink.xiannccda.dto.protos.WsMessageProto; import club.joylink.xiannccda.dto.protos.WsMessageProto;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.protobuf.GeneratedMessageV3.Builder; import com.google.protobuf.GeneratedMessageV3.Builder;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
/** 线网的列车数据,一些公共方法 */ /** 线网的列车数据,一些公共方法 */
@ -51,27 +54,116 @@ public abstract class LineNetTrainComMethod {
*/ */
public static void setUpKilometerCode( public static void setUpKilometerCode(
WsMessageProto.WsLineNetTrainOffsetMessage.Builder obj, DeviceType type, String deviceName) { WsMessageProto.WsLineNetTrainOffsetMessage.Builder obj, DeviceType type, String deviceName) {
// 非区段道岔直接返回 // 获取到当前区段公里标
if (!DeviceType.DEVICE_TYPE_TRACK.equals(type) && !DeviceType.DEVICE_TYPE_SWITCH.equals(type)) { DeviceKilometer.Builder km = getDeviceKM(obj.getLineId(), type, deviceName);
if (km != null) {
obj.setKilometerCode(selectDeviceKilometerCode(obj.getDir(), km));
} else {
log.warn(String.format("设备%s没有公里标信息", deviceName));
}
}
/**
* 根据目的码确定方向并确定公里标
*
* @param obj 要设置的对象
* @param destinationCode 目的码
* @param type 设备类型
* @param name 设备名称
*/
public static void setTrainDirectionAndKilometerCode(
WsMessageProto.WsLineNetTrainOffsetMessage.Builder obj,
String destinationCode,
DeviceType type,
String name) {
DeviceKilometer.Builder deviceKm = getDeviceKM(obj.getLineId(), type, name);
if (deviceKm == null) {
return; return;
} }
// 转换成程序中的名称 DeviceKilometer.Builder destinationKm = getDirectionCodeKM(obj.getLineId(), destinationCode);
String convertName = DeviceNameChangerManage.findMatch(type, deviceName); if (destinationKm == null) {
// 获取到当前区段公里标 return;
List<Long> kmList = }
LineGraphicDataRepository.getKilometerCodeList(obj.getLineId(), convertName); // 确定方向
if (CollectionUtils.isNotEmpty(kmList)) { if (destinationKm.getMaxKilometer() > deviceKm.getMaxKilometer()) { // 目的地最大公里标大于设备最大公里标上行
long kilometer; obj.setDir(TrainRunDirection.UP.getDir());
if (obj.getDir() == 1) { // 下行取大值
kilometer = kmList.stream().min(Long::compareTo).get();
} else if (obj.getDir() == 2) { // 上行取小值
kilometer = kmList.stream().max(Long::compareTo).get();
} else { // 无方向获取第一个
kilometer = kmList.get(0);
}
obj.setKilometerCode(kilometer);
} else { } else {
log.warn(String.format("设备%s没有公里标信息", convertName)); obj.setDir(TrainRunDirection.DOWN.getDir());
}
// 赋值公里标
obj.setKilometerCode(selectDeviceKilometerCode(obj.getDir(), deviceKm));
}
/**
* 获取设备的公里标
*
* @param lineId 线路ID
* @param type 设备类型
* @param name 设备名称
* @return 公里标列表
*/
private static DeviceKilometer.Builder getDeviceKM(int lineId, DeviceType type, String name) {
// 非区段道岔直接返回
if (!DeviceType.DEVICE_TYPE_TRACK.equals(type) && !DeviceType.DEVICE_TYPE_SWITCH.equals(type)) {
return null;
}
// 转换成程序中的名称
String convertName = DeviceNameChangerManage.findMatch(type, name);
// 获取到当前区段公里标
return LineGraphicDataRepository.getKilometerCodeList(lineId, convertName);
}
/**
* 获取目的地码的公里标信息
*
* @param lineId 线路ID
* @param code 目的地码
* @return 公里标列表
*/
private static DeviceKilometer.Builder getDirectionCodeKM(int lineId, String code) {
Map<String, Builder> map = LineGraphicDataRepository.getLineSectionBuild(lineId);
Optional<Builder> destination =
map.values().stream()
.filter(
s -> {
DeviceInfoProto.Section.Builder b = (DeviceInfoProto.Section.Builder) s;
return Objects.equals(b.getDestinationCode(), code);
})
.findFirst();
if (destination.isPresent()) {
DeviceInfoProto.Section.Builder b = (DeviceInfoProto.Section.Builder) destination.get();
return b.getKilometerBuilder();
} else {
return null;
}
}
/**
* 选择对应的公里标信息
*
* @param dir 运行方向
* @param km 公里标信息
* @return 公里标
*/
private static long selectDeviceKilometerCode(int dir, DeviceKilometer.Builder km) {
// 下行(1)取小值 \ 上行(2)取大值
return TrainRunDirection.UP.isMatch(dir) ? km.getMaxKilometer() : km.getMinKilometer();
}
@Getter
public static enum TrainRunDirection {
UP(2),
DOWN(1),
NO(0);
private int dir;
TrainRunDirection(int dir) {
this.dir = dir;
}
public boolean isMatch(int dir) {
return this.dir == dir;
} }
} }
} }

View File

@ -35,9 +35,8 @@ public class LineNetTrainInitConvertor extends DeviceStatusConvertor {
offset.setLineId(response.getLineId()); // 线路id offset.setLineId(response.getLineId()); // 线路id
offset.setTrainIndex(trainCell.getTrainIndex()); // 列车标示号全线唯一 offset.setTrainIndex(trainCell.getTrainIndex()); // 列车标示号全线唯一
offset.setGroupId(trainCell.getGroupId()); // 车组号 offset.setGroupId(trainCell.getGroupId()); // 车组号
offset.setDir(0); // 初始设置无运行方向 LineNetTrainComMethod.setTrainDirectionAndKilometerCode(
LineNetTrainComMethod.setUpKilometerCode( offset, trainCell.getDestinationId(), trainCell.getDevType(), trainCell.getDevName());
offset, trainCell.getDevType(), trainCell.getDevName());
offset.setShow(offset.getKilometerCode() != 0); offset.setShow(offset.getKilometerCode() != 0);
buildList.add(offset); buildList.add(offset);
} }

View File

@ -35,8 +35,8 @@ public class LineNetTrainUpdateConvertor extends DeviceStatusConvertor {
offset.setTrainIndex(response.getTrainIndex()); // 列车标示号全线唯一 offset.setTrainIndex(response.getTrainIndex()); // 列车标示号全线唯一
offset.setGroupId(response.getGroupId()); // 车组号 offset.setGroupId(response.getGroupId()); // 车组号
LineNetTrainComMethod.getDeviceStatusById(offset); // 合并老旧数据 LineNetTrainComMethod.getDeviceStatusById(offset); // 合并老旧数据
LineNetTrainComMethod.setUpKilometerCode( LineNetTrainComMethod.setTrainDirectionAndKilometerCode(
offset, response.getDevType(), response.getDevName()); offset, response.getDestinationId(), response.getDevType(), response.getDevName());
offset.setShow(offset.getKilometerCode() != 0); offset.setShow(offset.getKilometerCode() != 0);
buildList.add(offset); buildList.add(offset);
} }

View File

@ -20,28 +20,25 @@ import club.joylink.xiannccda.ws.LineNetMessageServer;
import club.joylink.xiannccda.ws.LineTrainMessageServer; import club.joylink.xiannccda.ws.LineTrainMessageServer;
import club.joylink.xiannccda.ws.WsMessageServerManager; import club.joylink.xiannccda.ws.WsMessageServerManager;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import java.util.List; import java.util.List;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** 线路设备信息更新 */ /** 线路设备信息更新 */
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor
public class LineDeviceStatusService { public class LineDeviceStatusService {
private final WsMessageServerManager wsMessageServerManager; private final WsMessageServerManager wsMessageServerManager;
private final NccMockDataService nccMockDataService; private final NccMockDataService nccMockDataService;
public LineDeviceStatusService(
WsMessageServerManager wsMessageServerManager, NccMockDataService nccMockDataService) {
this.wsMessageServerManager = wsMessageServerManager;
this.nccMockDataService = nccMockDataService;
}
@PostConstruct @PostConstruct
public void deviceStatusRefresh() { public void deviceStatusRefresh() {
this.createDataConvertor(); this.createDataConvertor();

@ -1 +1 @@
Subproject commit e9ebd34921652f48c2d84ac531e392ce32d17bb5 Subproject commit b3b9885e2784cdad86901303e0bb9abf28c35e10