|
@@ -0,0 +1,491 @@
|
|
|
+package com.persagy.dmp.rwd.digital.service.calstrategy;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.map.MapUtil;
|
|
|
+import cn.hutool.core.math.MathUtil;
|
|
|
+import cn.hutool.core.util.NumberUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
|
+import com.persagy.dmp.basic.dto.RelationCalRuleDTO;
|
|
|
+import com.persagy.dmp.basic.dto.SpaceConnectionCalDTO;
|
|
|
+import com.persagy.dmp.common.helper.SpringHelper;
|
|
|
+import com.persagy.dmp.digital.entity.ObjectRelation;
|
|
|
+import com.persagy.dmp.rwd.basic.utils.DigitalCommonUtils;
|
|
|
+import com.persagy.dmp.rwd.basic.utils.GeoToolsUtil;
|
|
|
+import com.persagy.dmp.rwd.digital.dao.ObjectDigitalMapper;
|
|
|
+import com.persagy.dmp.rwd.digital.dao.ObjectRelationMapper;
|
|
|
+import com.persagy.dmp.rwd.digital.domain.CalculatingDTO;
|
|
|
+import com.persagy.dmp.rwd.digital.domain.OpenPointDTO;
|
|
|
+import com.persagy.dmp.rwd.digital.domain.SpaceCalDTO;
|
|
|
+import com.persagy.dmp.rwd.digital.service.CalculateService;
|
|
|
+import com.persagy.dmp.rwd.digital.service.IObjectRelationService;
|
|
|
+import com.persagy.dmp.rwd.digital.utils.ObjectDigitalCriteriaHelper;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/***
|
|
|
+ * Description: 空间连通关系计算
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/9 16:26
|
|
|
+ * Update By lijie 2021/10/9 16:26
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class SpaceConnectionRelCalculateServiceImpl implements CalculateService {
|
|
|
+
|
|
|
+ private final IObjectRelationService objectRelationService;
|
|
|
+ private final ObjectRelationMapper objectRelationMapper;
|
|
|
+ private final ObjectDigitalMapper objectDigitalMapper;
|
|
|
+
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 空间连通关系计算
|
|
|
+ * @param calRule : 计算规则
|
|
|
+ * @param calculatingDTO : 请求参数
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/9 16:26
|
|
|
+ * Update By lijie 2021/10/9 16:26
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void calculateRelation(RelationCalRuleDTO calRule, CalculatingDTO calculatingDTO) {
|
|
|
+ // 1.获取有所在楼层的所有业务空间, 并按照所在楼层和业务空间类型排序
|
|
|
+ List<SpaceCalDTO> spaceCalDTOS = objectRelationMapper.querySpacesByProjectId(calculatingDTO);
|
|
|
+ if (CollUtil.isEmpty(spaceCalDTOS)){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 1.1 获得[[space,space]]的二维数组
|
|
|
+ Map<String,List<SpaceCalDTO>> spaceMap = spaceCalDTOS.stream()
|
|
|
+ .collect(Collectors.groupingBy(spaceCalDTO -> spaceCalDTO.getFloorId()+StrUtil.UNDERLINE+spaceCalDTO.getClassCode()));
|
|
|
+
|
|
|
+ // 存储的关系列表
|
|
|
+ List<ObjectRelation> resultList = new ArrayList<>();
|
|
|
+ // 2.门的计算
|
|
|
+ calculateRelationInternal(resultList,spaceCalDTOS,calculatingDTO,spaceMap,"CFBEDR",
|
|
|
+ calRule.getSpaceConnectionCal().getDoorCalFlag());
|
|
|
+ // 3.窗的计算
|
|
|
+ calculateRelationInternal(resultList,spaceCalDTOS,calculatingDTO,spaceMap,"CFBEWN",
|
|
|
+ calRule.getSpaceConnectionCal().getWindowCalFlag());
|
|
|
+ // 4.虚拟墙的计算(暂时没有虚拟墙的概念,先置为false)
|
|
|
+ calculateRelationInternal(resultList,spaceCalDTOS,calculatingDTO,spaceMap,"CFBEXX",
|
|
|
+ calRule.getSpaceConnectionCal().getVirtualWindowCalFlag());
|
|
|
+ // 5.元空间的计算
|
|
|
+ ispaceCalculateRelationInternal(resultList,spaceCalDTOS,calculatingDTO,spaceMap,
|
|
|
+ calRule.getSpaceConnectionCal().getIspaceCalFlag());
|
|
|
+ if (CollUtil.isNotEmpty(resultList)){
|
|
|
+ // 3.根据图类型编码,边类型编码,relValue,项目id,集团编码删除关系
|
|
|
+ deleteRelDataByCondition(calculatingDTO);
|
|
|
+ // 4.新增关系
|
|
|
+ objectRelationService.saveBatch(resultList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /***
|
|
|
+ * Description: 元空间的计算
|
|
|
+ * @param resultList : 结果集
|
|
|
+ * @param spaceCalDTOS : 空间数据
|
|
|
+ * @param calculatingDTO : 请求参数
|
|
|
+ * @param spaceMap:{floorId_classCode:空间对象}
|
|
|
+ * @param calFlag : 是否计算的标记
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 22:06
|
|
|
+ * Update By lijie 2021/10/11 22:06
|
|
|
+ */
|
|
|
+ private void ispaceCalculateRelationInternal(List<ObjectRelation> resultList, List<SpaceCalDTO> spaceCalDTOS,
|
|
|
+ CalculatingDTO calculatingDTO,
|
|
|
+ Map<String, List<SpaceCalDTO>> spaceMap,
|
|
|
+ Boolean calFlag) {
|
|
|
+ if (!calFlag){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 1.根据modelId批量查询门
|
|
|
+ List<SpaceCalDTO> ispaces = objectDigitalMapper.queryIspacesByModelIds(spaceCalDTOS.stream()
|
|
|
+ .map(SpaceCalDTO::getFloorModelId).collect(Collectors.toSet()),calculatingDTO);
|
|
|
+ if (CollUtil.isEmpty(ispaces)){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 1.1 获得modelId和[door,door]的映射
|
|
|
+ Map<String, List<SpaceCalDTO>> ispaceMap = ispaces
|
|
|
+ .stream().collect(Collectors.groupingBy(SpaceCalDTO::getModelId));
|
|
|
+ // 2.根据空间分组及门的数据计算关系
|
|
|
+ Set<Map.Entry<String, List<SpaceCalDTO>>> entries = spaceMap.entrySet();
|
|
|
+ for (Map.Entry<String, List<SpaceCalDTO>> entry : entries) {
|
|
|
+ List<SpaceCalDTO> spaces = entry.getValue();
|
|
|
+ if (CollUtil.isEmpty(spaces) || spaces.size()<2){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ SpaceCalDTO spaceCal = spaces.get(0);
|
|
|
+ if (!ispaceMap.containsKey(spaceCal.getFloorModelId())
|
|
|
+ || CollUtil.isEmpty(ispaceMap.get(spaceCal.getFloorModelId()))){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<SpaceCalDTO> subIspaces = ispaceMap.get(spaceCal.getFloorModelId());
|
|
|
+ List<String> relIds = new ArrayList<>();
|
|
|
+ for (SpaceCalDTO subIspace : subIspaces) {
|
|
|
+ List<LinkedHashMap<String, Object>> outLines = subIspace.getOutLines();
|
|
|
+ for (SpaceCalDTO space : spaces) {
|
|
|
+ if (GeoToolsUtil.isPolyInPoly(space.getOutLines(),outLines)){
|
|
|
+ relIds.add(space.getSpaceId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (CollUtil.isNotEmpty(relIds)){
|
|
|
+ for (int i = 0; i < relIds.size(); i++) {
|
|
|
+ for (int j = 1; j < relIds.size(); j++) {
|
|
|
+ if (relIds.get(i).equals(relIds.get(j))){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ resultList.add(createObjectRelation(calculatingDTO,spaceCal.getGroupCode(),
|
|
|
+ spaceCal.getProjectId(),relIds.get(i),relIds.get(j),spaceCal.getClassCode()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 通过门计算空间连通性
|
|
|
+ * @param resultList : 结果集
|
|
|
+ * @param spaceCalDTOS : 空间数据
|
|
|
+ * @param calculatingDTO : 请求参数
|
|
|
+ * @param spaceMap:{floorId_classCode:空间对象}
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 17:44
|
|
|
+ * Update By lijie 2021/10/11 17:44
|
|
|
+ */
|
|
|
+ private void calculateRelationInternal(List<ObjectRelation> resultList,
|
|
|
+ List<SpaceCalDTO> spaceCalDTOS,
|
|
|
+ CalculatingDTO calculatingDTO,
|
|
|
+ Map<String, List<SpaceCalDTO>> spaceMap,
|
|
|
+ String classCode,Boolean calFlag) {
|
|
|
+ if (!calFlag){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 1.根据modelId批量查询门
|
|
|
+ List<SpaceCalDTO> doors = objectDigitalMapper.queryEquipmentsByModelIds(spaceCalDTOS.stream()
|
|
|
+ .map(SpaceCalDTO::getFloorModelId).collect(Collectors.toSet()),calculatingDTO,classCode);
|
|
|
+ if (CollUtil.isEmpty(doors)){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ commonCalculateRelationInternal(doors,resultList,calculatingDTO,spaceMap);
|
|
|
+ }
|
|
|
+ /***
|
|
|
+ * Description: 通用计算空间连通性
|
|
|
+ * @param spaceCals : 空间数据
|
|
|
+ * @param resultList : 结果集
|
|
|
+ * @param calculatingDTO : 请求参数
|
|
|
+ * @param spaceMap:{floorId_classCode:空间对象}
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 21:51
|
|
|
+ * Update By lijie 2021/10/11 21:51
|
|
|
+ */
|
|
|
+ private void commonCalculateRelationInternal(List<SpaceCalDTO> spaceCals,
|
|
|
+ List<ObjectRelation> resultList,
|
|
|
+ CalculatingDTO calculatingDTO,
|
|
|
+ Map<String, List<SpaceCalDTO>> spaceMap) {
|
|
|
+ // 1.1 获得modelId和[door,door]的映射
|
|
|
+ Map<String, List<SpaceCalDTO>> doorMap = spaceCals
|
|
|
+ .stream().collect(Collectors.groupingBy(SpaceCalDTO::getModelId));
|
|
|
+ ObjectMapper objectMapper = SpringHelper.getBean(ObjectMapper.class);
|
|
|
+ // 2.根据空间分组及门的数据计算关系
|
|
|
+ Set<Map.Entry<String, List<SpaceCalDTO>>> entries = spaceMap.entrySet();
|
|
|
+ for (Map.Entry<String, List<SpaceCalDTO>> entry : entries) {
|
|
|
+ List<SpaceCalDTO> spaces = entry.getValue();
|
|
|
+ if (CollUtil.isEmpty(spaces) || spaces.size()<2){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ SpaceCalDTO spaceCal = spaces.get(0);
|
|
|
+ if (!doorMap.containsKey(spaceCal.getFloorModelId())
|
|
|
+ || CollUtil.isEmpty(doorMap.get(spaceCal.getFloorModelId()))){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 2.1 遍历相同下的门
|
|
|
+ List<SpaceCalDTO> subDoors = doorMap.get(spaceCal.getFloorModelId());
|
|
|
+ for (SpaceCalDTO subDoor : subDoors) {
|
|
|
+ ObjectNode firstPoint = subDoor.getFirstPoint();
|
|
|
+ ObjectNode secondPoint = subDoor.getSecondPoint();
|
|
|
+ // 2.1.1 校验坐标点的值是否合法
|
|
|
+ if (!checkPointIsValid(firstPoint,secondPoint)){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 2.1.2 获得门打开后覆盖的坐标点
|
|
|
+ List<OpenPointDTO> openPoints = getOpenPoint(firstPoint,secondPoint);
|
|
|
+ if (CollUtil.isEmpty(openPoints)){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ List<String> relIds = new ArrayList<>();
|
|
|
+ // 2.1.3 通过门打开后的坐标点与空间关联性获得连通的空间数组
|
|
|
+ for (SpaceCalDTO space : spaces) {
|
|
|
+ List<LinkedHashMap<String, Object>> outLines = space.getOutLines();
|
|
|
+ for (OpenPointDTO openPoint : openPoints) {
|
|
|
+ ObjectNode pointNode = objectMapper
|
|
|
+ .createObjectNode()
|
|
|
+ .put("X", openPoint.getDestX()).put("Y", openPoint.getDestY());
|
|
|
+ if (GeoToolsUtil.isPointInPoly(pointNode,outLines)){
|
|
|
+ relIds.add(space.getSpaceId());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (relIds.size()==2){
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 2.1.4 生成关系
|
|
|
+ if (relIds.size()==2){
|
|
|
+ resultList.add(createObjectRelation(calculatingDTO,spaceCal.getGroupCode(),
|
|
|
+ spaceCal.getProjectId(),relIds.get(0),relIds.get(1),spaceCal.getClassCode()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 创建关系对象
|
|
|
+ * @return : com.persagy.dmp.digital.entity.ObjectRelation
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 21:39
|
|
|
+ * Update By lijie 2021/10/11 21:39
|
|
|
+ * @param calculatingDTO :请求参数
|
|
|
+ * @param groupCode :集团编码
|
|
|
+ * @param projectId :项目id
|
|
|
+ * @param objFrom : objFrom
|
|
|
+ * @param objTo : objTo
|
|
|
+ * @param classCode: classCode
|
|
|
+ */
|
|
|
+ private ObjectRelation createObjectRelation(CalculatingDTO calculatingDTO, String groupCode,
|
|
|
+ String projectId, String objFrom, String objTo, String classCode) {
|
|
|
+ // 空间有相交的空间,说明两者竖井是连通的
|
|
|
+ ObjectRelation objectRelation = new ObjectRelation();
|
|
|
+ objectRelation.setGroupCode(groupCode);
|
|
|
+ objectRelation.setProjectId(projectId);
|
|
|
+ objectRelation.setGraphId(DigitalCommonUtils.getDefaultGraphIdByGraphCode(calculatingDTO.getGraphCode()));
|
|
|
+ objectRelation.setGraphCode(calculatingDTO.getGraphCode());
|
|
|
+ objectRelation.setRelCode(calculatingDTO.getRelCode());
|
|
|
+ objectRelation.setObjFrom(objFrom);
|
|
|
+ objectRelation.setObjTo(objTo);
|
|
|
+ objectRelation.setRelValue(classCode);
|
|
|
+ objectRelation.setCreateApp(calculatingDTO.getAppId());
|
|
|
+ objectRelation.setUpdateApp(calculatingDTO.getAppId());
|
|
|
+ objectRelation.setCreator(calculatingDTO.getAccountId());
|
|
|
+ objectRelation.setModifier(calculatingDTO.getAccountId());
|
|
|
+ objectRelation.setValid(1);
|
|
|
+ return objectRelation;
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 获得门,窗,虚拟墙,元空间打开后两点的坐标信息
|
|
|
+ * @param firstPoint : 第一个坐标点
|
|
|
+ * @param secondPoint : 第二个坐标点
|
|
|
+ * @return : com.persagy.dmp.rwd.digital.domain.OpenPointDTO
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 20:19
|
|
|
+ * Update By lijie 2021/10/11 20:19
|
|
|
+ */
|
|
|
+ private List<OpenPointDTO> getOpenPoint(ObjectNode firstPoint, ObjectNode secondPoint) {
|
|
|
+ double deltaDistance = 200.0;
|
|
|
+ double doorLength = 1500.0;
|
|
|
+ double closedFirstX = NumberUtil.parseDouble(firstPoint.get("X").asText());
|
|
|
+ double closedFirstY = NumberUtil.parseDouble(firstPoint.get("Y").asText());
|
|
|
+ double closedSecondX = NumberUtil.parseDouble(secondPoint.get("X").asText());
|
|
|
+ double closedSecondY = NumberUtil.parseDouble(secondPoint.get("Y").asText());
|
|
|
+ // 1.计算两个坐标点的直线距离
|
|
|
+ double distance = getSegmentDistance(closedFirstX, closedFirstY, closedSecondX, closedSecondY);
|
|
|
+ // 2.计算该直线的斜率
|
|
|
+ Double k=null;
|
|
|
+ if(closedFirstX!=closedSecondX){
|
|
|
+ k=(closedFirstY-closedSecondY)/(closedFirstX-closedSecondX);
|
|
|
+ }
|
|
|
+ // 2.1 获得垂直线的斜率
|
|
|
+ Double verticalK = getVerticalK(k);
|
|
|
+ // 2.2 获得当前直线的a
|
|
|
+ Double closedA = getAByPointAndK(closedFirstX,closedFirstY,k);
|
|
|
+ List<OpenPointDTO> result = new ArrayList<>();
|
|
|
+ if (distance>deltaDistance){
|
|
|
+ // 距离大于delta_distance, 则足够开两个门
|
|
|
+ OpenPointDTO firstSegOpenPoint = getPointByDistanceOnSegment(closedFirstX,closedFirstY,
|
|
|
+ k,closedA,deltaDistance,closedSecondX,closedSecondY);
|
|
|
+ OpenPointDTO secondSegOpenPoint = getPointByDistanceOnSegment(closedSecondX,closedSecondY,
|
|
|
+ k,closedA,deltaDistance,closedFirstX,closedFirstY);
|
|
|
+ Double firstA = getAByPointAndK(firstSegOpenPoint.getDestX(), firstSegOpenPoint.getDestY(), verticalK);
|
|
|
+ Double secondA = getAByPointAndK(secondSegOpenPoint.getDestX(), secondSegOpenPoint.getDestY(), verticalK);
|
|
|
+ OpenPointDTO firstDistance = getPointByDistance(firstSegOpenPoint.getDestX(), firstSegOpenPoint.getDestY(), verticalK, firstA, doorLength);
|
|
|
+ OpenPointDTO secondDistance = getPointByDistance(secondSegOpenPoint.getDestX(), secondSegOpenPoint.getDestY(), verticalK, secondA, doorLength);
|
|
|
+ result.add(OpenPointDTO.builder().destX(firstDistance.getFirstX()).destY(firstDistance.getFirstY()).build());
|
|
|
+ result.add(OpenPointDTO.builder().destX(firstDistance.getSecondX()).destY(firstDistance.getSecondY()).build());
|
|
|
+ result.add(OpenPointDTO.builder().destX(secondDistance.getFirstX()).destY(secondDistance.getFirstY()).build());
|
|
|
+ result.add(OpenPointDTO.builder().destX(secondDistance.getSecondX()).destY(secondDistance.getSecondY()).build());
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ // 中间开门
|
|
|
+ OpenPointDTO openPoint = getPointByDistanceOnSegment(closedFirstX, closedFirstY,
|
|
|
+ k, closedA, distance / 2, closedSecondX, closedSecondY);
|
|
|
+ Double verticalA = getAByPointAndK(openPoint.getDestX(), openPoint.getDestY(), verticalK);
|
|
|
+ OpenPointDTO firstDistance = getPointByDistance(openPoint.getDestX(), openPoint.getDestY(), verticalK, verticalA, doorLength);
|
|
|
+ result.add(OpenPointDTO.builder().destX(firstDistance.getFirstX()).destY(firstDistance.getFirstY()).build());
|
|
|
+ result.add(OpenPointDTO.builder().destX(firstDistance.getSecondX()).destY(firstDistance.getSecondY()).build());
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ /***
|
|
|
+ * Description: 根据距离和坐标点计算打开后的坐标点
|
|
|
+ * @param baseX : 第一个坐标点的Y值
|
|
|
+ * @param baseY : 第一个坐标点的Y值
|
|
|
+ * @param k : 斜率
|
|
|
+ * @param a : a值
|
|
|
+ * @param distance : 距离
|
|
|
+ * @param vecX : 第二个坐标点的X值
|
|
|
+ * @param vecY : 第二个坐标点的Y值
|
|
|
+ * @return : com.persagy.dmp.rwd.digital.domain.OpenPointDTO
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 20:54
|
|
|
+ * Update By lijie 2021/10/11 20:54
|
|
|
+ */
|
|
|
+ private OpenPointDTO getPointByDistanceOnSegment(double baseX, double baseY,
|
|
|
+ Double k, Double a,
|
|
|
+ double distance,
|
|
|
+ double vecX,
|
|
|
+ double vecY) {
|
|
|
+ OpenPointDTO openPoint = getPointByDistance(baseX,baseY,k,a,distance);
|
|
|
+ Double distanceOne = getSegmentDistance(openPoint.getFirstX(), openPoint.getFirstY(), vecX, vecY);
|
|
|
+ Double distanceTwo = getSegmentDistance(openPoint.getSecondX(), openPoint.getSecondY(), vecX, vecY);
|
|
|
+ if (distanceOne>distanceTwo){
|
|
|
+ return OpenPointDTO.builder().destX(openPoint.getSecondX()).destY(openPoint.getSecondY()).build();
|
|
|
+ }
|
|
|
+ return OpenPointDTO.builder().destX(openPoint.getFirstX()).destY(openPoint.getFirstY()).build();
|
|
|
+ }
|
|
|
+ /***
|
|
|
+ * Description: 根据坐标和线段长度计算坐标点
|
|
|
+ * @param baseX : x值
|
|
|
+ * @param baseY : y值
|
|
|
+ * @param k : 斜率
|
|
|
+ * @param a : a值
|
|
|
+ * @param distance : 距离
|
|
|
+ * @return : com.persagy.dmp.rwd.digital.domain.OpenPointDTO
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 20:58
|
|
|
+ * Update By lijie 2021/10/11 20:58
|
|
|
+ */
|
|
|
+ private OpenPointDTO getPointByDistance(double baseX, double baseY, Double k, Double a, double distance) {
|
|
|
+ if (null==k){
|
|
|
+ return OpenPointDTO.builder()
|
|
|
+ .firstX(baseX)
|
|
|
+ .firstY(baseY+distance)
|
|
|
+ .secondX(baseX)
|
|
|
+ .secondY(baseY-distance).build();
|
|
|
+ }
|
|
|
+ double vectorX1 = Math.sqrt(distance*distance/(1+k*k));
|
|
|
+ double vectorX2 = -vectorX1;
|
|
|
+ double vectorY1 = k*vectorX1+a;
|
|
|
+ double vectorY2 = k*vectorX2+a;
|
|
|
+ return OpenPointDTO.builder()
|
|
|
+ .firstX(baseX+vectorX1)
|
|
|
+ .firstY(baseY+vectorY1)
|
|
|
+ .secondX(baseX+vectorX2)
|
|
|
+ .secondY(baseY+vectorY2).build();
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 获得直线方程式中的a值(y=kx+a)
|
|
|
+ * @param x : x坐标值
|
|
|
+ * @param y : y坐标值
|
|
|
+ * @param k : 斜率
|
|
|
+ * @return : java.lang.Double
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 20:34
|
|
|
+ * Update By lijie 2021/10/11 20:34
|
|
|
+ */
|
|
|
+ private Double getAByPointAndK(double x, double y, Double k) {
|
|
|
+ if (null==k){
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ return y-k*x;
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 获得垂直线的斜率
|
|
|
+ * @param k : 斜率
|
|
|
+ * @return : java.lang.Double
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 20:31
|
|
|
+ * Update By lijie 2021/10/11 20:31
|
|
|
+ */
|
|
|
+ private Double getVerticalK(Double k) {
|
|
|
+ if (null==k){
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ if (0.0==k){
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return 1/k;
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 计算两个坐标点之间的距离
|
|
|
+ * @param firstX : 第一个坐标点的x值
|
|
|
+ * @param firstY : 第一个坐标点的Y值
|
|
|
+ * @param secondX : 第二个坐标点的x值
|
|
|
+ * @param secondY : 第二个坐标点的y值
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 20:24
|
|
|
+ * Update By lijie 2021/10/11 20:24
|
|
|
+ */
|
|
|
+ private Double getSegmentDistance(Double firstX, Double firstY, Double secondX, Double secondY) {
|
|
|
+ double xDistance = firstX - secondX;
|
|
|
+ double yDistance = firstY - secondY;
|
|
|
+ return Math.sqrt(xDistance*xDistance+yDistance*yDistance);
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 校验两个坐标点是否合理
|
|
|
+ * @param firstPoint : 第一个坐标点
|
|
|
+ * @param secondPoint : 第二个坐标点
|
|
|
+ * @return : boolean
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/11 20:06
|
|
|
+ * Update By lijie 2021/10/11 20:06
|
|
|
+ */
|
|
|
+ private Boolean checkPointIsValid(ObjectNode firstPoint, ObjectNode secondPoint) {
|
|
|
+ // 1.校验是否为空
|
|
|
+ if (null==firstPoint
|
|
|
+ || null==secondPoint
|
|
|
+ || !firstPoint.has("X")
|
|
|
+ || !firstPoint.has("Y")
|
|
|
+ || !secondPoint.has("X")
|
|
|
+ || !secondPoint.has("Y")){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 2.校验是否为数字
|
|
|
+ if (!NumberUtil.isNumber(firstPoint.get("X").asText())
|
|
|
+ || !NumberUtil.isNumber(firstPoint.get("Y").asText())
|
|
|
+ || !NumberUtil.isNumber(secondPoint.get("X").asText())
|
|
|
+ || !NumberUtil.isNumber(secondPoint.get("Y").asText())){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 3.校验坐标点是否相等
|
|
|
+ return firstPoint.get("X").equals(secondPoint.get("X")) && firstPoint.get("Y").equals(secondPoint.get("Y"));
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 根据请求参数和id集合删除关系
|
|
|
+ * @param calculatingDTO : 请求参数
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/9/11 16:13
|
|
|
+ * Update By lijie 2021/9/11 16:13
|
|
|
+ */
|
|
|
+ private void deleteRelDataByCondition(CalculatingDTO calculatingDTO) {
|
|
|
+ QueryWrapper<ObjectRelation> queryWrapper = ObjectDigitalCriteriaHelper.createCommonQueryWrapper(null,calculatingDTO);
|
|
|
+ queryWrapper.eq(StrUtil.toUnderlineCase(ObjectRelation.GRAPH_CODE_HUM),calculatingDTO.getGraphCode());
|
|
|
+ queryWrapper.eq(StrUtil.toUnderlineCase(ObjectRelation.REL_CODE_HUM),calculatingDTO.getRelCode());
|
|
|
+ objectRelationService.remove(queryWrapper);
|
|
|
+ }
|
|
|
+}
|