|
@@ -1,6 +1,7 @@
|
|
|
package com.persagy.proxy.adm.service.impl;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.math.MathUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
@@ -14,7 +15,9 @@ import com.persagy.dmp.common.helper.SpringHelper;
|
|
|
import com.persagy.dmp.common.model.response.CommonResult;
|
|
|
import com.persagy.dmp.digital.client.DigitalObjectFacade;
|
|
|
import com.persagy.dmp.digital.client.DigitalRelationCaclFacade;
|
|
|
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
|
|
|
import com.persagy.dmp.digital.entity.ObjectDigital;
|
|
|
+import com.persagy.dmp.digital.entity.ObjectRelation;
|
|
|
import com.persagy.proxy.adm.constant.AdmObjectInfoConstant;
|
|
|
import com.persagy.proxy.adm.constant.AdmObjectType;
|
|
|
import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
|
|
@@ -22,14 +25,14 @@ import com.persagy.proxy.adm.constant.ObjTypeMapping;
|
|
|
import com.persagy.proxy.adm.dto.TwicePointDTO;
|
|
|
import com.persagy.proxy.adm.request.AdmResponse;
|
|
|
import com.persagy.proxy.adm.service.AdmRelCalService;
|
|
|
+import com.persagy.proxy.adm.utils.GeoToolsUtil;
|
|
|
import com.persagy.proxy.common.entity.InstanceUrlParam;
|
|
|
import lombok.Data;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.List;
|
|
|
+import java.util.*;
|
|
|
|
|
|
@Service
|
|
|
@Slf4j
|
|
@@ -40,24 +43,27 @@ public class AdmRelCalServiceImpl implements AdmRelCalService {
|
|
|
* Description: 计算关系
|
|
|
* @param context : 请求参数
|
|
|
* @param admRelationTypeEnums : 关系类型集合
|
|
|
- * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型)
|
|
|
- * @param relationTypeStr : 关系类型
|
|
|
+ //* @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型)
|
|
|
+ //* @param relationTypeStr : 关系类型
|
|
|
* return : void
|
|
|
* @author : lijie
|
|
|
* date :2021/9/11 20:35
|
|
|
* Update By lijie 2021/9/11 20:35
|
|
|
*/
|
|
|
@Override
|
|
|
- public void calcRelation(InstanceUrlParam context, List<AdmRelationTypeEnum> admRelationTypeEnums, String objectTypeStr,
|
|
|
- String relationTypeStr) {
|
|
|
+ public void calcRelation(InstanceUrlParam context, List<AdmRelationTypeEnum> admRelationTypeEnums,String relValue) {
|
|
|
for (AdmRelationTypeEnum admRelationTypeEnum : admRelationTypeEnums) {
|
|
|
+ RequestData requestData = RequestData.builder()
|
|
|
+ .graphCode(admRelationTypeEnum.getGraphCode())
|
|
|
+ .relCode(admRelationTypeEnum.getRelCode())
|
|
|
+ .calBeforeRelFlag(true)
|
|
|
+ .build();
|
|
|
+ if (StrUtil.isNotBlank(relValue)){
|
|
|
+ requestData.setRelValue(relValue);
|
|
|
+ }
|
|
|
// 调用中台的计算逻辑
|
|
|
DigitalRelationCaclFacade.calculatingObjRelationPrototype(context.getGroupCode(),context.getProjectId(),
|
|
|
- context.getAppId(), CommonConstant.DEFAULT_ID, RequestData.builder()
|
|
|
- .graphCode(admRelationTypeEnum.getGraphCode())
|
|
|
- .relCode(admRelationTypeEnum.getRelCode())
|
|
|
- .calBeforeRelFlag(true)
|
|
|
- .build());
|
|
|
+ context.getAppId(), CommonConstant.DEFAULT_ID, requestData);
|
|
|
}
|
|
|
}
|
|
|
/***
|
|
@@ -75,50 +81,59 @@ public class AdmRelCalServiceImpl implements AdmRelCalService {
|
|
|
@Override
|
|
|
public AdmResponse calcRelationForArchForArchSpToSp(InstanceUrlParam context, String buildingId, String objectType,
|
|
|
String type, AdmRelationTypeEnum relationTypeEnum) {
|
|
|
- double distance = 100.00;
|
|
|
if (StrUtil.isBlank(buildingId)){
|
|
|
return AdmResponse.success(new ArrayList<>());
|
|
|
}
|
|
|
+ RequestData requestData = RequestData
|
|
|
+ .builder()
|
|
|
+ .buildingId(buildingId)
|
|
|
+ .objTypes(CollUtil.newHashSet(AdmObjectType.FLOOR.getIndex()))
|
|
|
+ .build();
|
|
|
// 1.根据建筑id查询建筑下的所有楼层
|
|
|
CommonResult<List<ObjectDigital>> commonResult = DigitalObjectFacade
|
|
|
.queryObjectListSuperiorIdPrototype(context.getGroupCode(), context.getProjectId(),
|
|
|
- context.getAppId(), context.getUserId(), RequestData
|
|
|
- .builder()
|
|
|
- .buildingId(buildingId)
|
|
|
- .objTypes(CollUtil.newHashSet(AdmObjectType.FLOOR.getIndex()))
|
|
|
- .build());
|
|
|
+ context.getAppId(), context.getUserId(), requestData);
|
|
|
if (!"success".equals(commonResult.getResult())){
|
|
|
return AdmResponse.failure(commonResult.getMessage());
|
|
|
}
|
|
|
Long count = commonResult.getCount();
|
|
|
List<ObjectDigital> data = commonResult.getData();
|
|
|
- handleFloorRelationCalc(data,context);
|
|
|
-
|
|
|
- long skip = data.size();
|
|
|
- while (skip<count){
|
|
|
- // 有未处理完的楼层
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ handleFloorRelationCalc(data,context,objectType,relationTypeEnum);
|
|
|
+ if (data.size() == count){
|
|
|
+ // 不需要分页查询
|
|
|
+ return AdmResponse.success();
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- return null;
|
|
|
-
|
|
|
+ // 有结果集未查完
|
|
|
+ long page = (count % CommonConstant.QUERY_DEFAULT_PAGE_SIZE) == 0
|
|
|
+ ? (count / CommonConstant.QUERY_DEFAULT_PAGE_SIZE) : (count / CommonConstant.QUERY_DEFAULT_PAGE_SIZE + 1);
|
|
|
+ for (long i = 1; i < page; i++) {
|
|
|
+ requestData.setPage(i);
|
|
|
+ requestData.setSize(CommonConstant.QUERY_DEFAULT_PAGE_SIZE);
|
|
|
+ List<ObjectDigital> pageFloors = DigitalObjectFacade
|
|
|
+ .queryObjectListSuperiorId(context.getGroupCode(),
|
|
|
+ context.getProjectId(), context.getAppId(), context.getUserId(), requestData);
|
|
|
+ handleFloorRelationCalc(pageFloors,context,objectType,relationTypeEnum);
|
|
|
+ }
|
|
|
+ return AdmResponse.success();
|
|
|
}
|
|
|
/***
|
|
|
* Description: 处理楼层下的关系计算(BDTP平台已经限制查询数据量)
|
|
|
* @param data : 楼层数据
|
|
|
- * @param context: 请求参数
|
|
|
+ * @param context : 请求参数
|
|
|
+ * @param classCode : 对象类型code
|
|
|
+ * @param relationTypeEnum: 图类型对象
|
|
|
* @return : void
|
|
|
* @author : lijie
|
|
|
* @date :2021/9/30 16:46
|
|
|
* Update By lijie 2021/9/30 16:46
|
|
|
*/
|
|
|
- private void handleFloorRelationCalc(List<ObjectDigital> data, InstanceUrlParam context) {
|
|
|
+ private void handleFloorRelationCalc(List<ObjectDigital> data, InstanceUrlParam context, String classCode,
|
|
|
+ AdmRelationTypeEnum relationTypeEnum) {
|
|
|
if (CollUtil.isEmpty(data)){
|
|
|
return;
|
|
|
}
|
|
|
+ ObjectMapper objectMapper = SpringHelper.getBean(ObjectMapper.class);
|
|
|
+ List<ObjectNode> relations = new ArrayList<>();
|
|
|
// 2.循环所有楼层
|
|
|
for (ObjectDigital floor : data) {
|
|
|
if (!floor.getInfos().has(AdmObjectInfoConstant.MODEL_ID)
|
|
@@ -131,21 +146,139 @@ public class AdmRelCalServiceImpl implements AdmRelCalService {
|
|
|
.getInfos()
|
|
|
.get(AdmObjectInfoConstant.MODEL_ID)
|
|
|
.asText(),context);
|
|
|
- // 2.1 根据楼层id和classCode查询所有的空间
|
|
|
-
|
|
|
-
|
|
|
+ if (CollUtil.isEmpty(pointDTOS)){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 2.2 根据楼层id和classCode查询所有的空间
|
|
|
+ List<ObjectDigital> spaces = queryAllSpacesByFloorIdAndClassCode(floor.getId(),
|
|
|
+ classCode,floor.getProjectId(),context);
|
|
|
+ if (CollUtil.isEmpty(spaces)){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
// 2.3 遍历所有的门,得到门拥有的两组x,y坐标
|
|
|
- // 2.4 遍历坐标组,与空间进行对比,得到所有符合的空间id数组
|
|
|
+ Map<Integer,List<String>> spaceIndexMap = new HashMap<>();
|
|
|
+ for (int i = 0; i < pointDTOS.size(); i++) {
|
|
|
+ TwicePointDTO pointDTO = pointDTOS.get(i);
|
|
|
+ ObjectNode point1 = objectMapper
|
|
|
+ .createObjectNode()
|
|
|
+ .put("x", pointDTO.getX1())
|
|
|
+ .put("y", pointDTO.getY1())
|
|
|
+ .put("z", 0.00);
|
|
|
+ ObjectNode point2 = objectMapper
|
|
|
+ .createObjectNode()
|
|
|
+ .put("x", pointDTO.getX2())
|
|
|
+ .put("y", pointDTO.getY2())
|
|
|
+ .put("z", 0.00);
|
|
|
+ // 2.4 遍历坐标组,与空间进行对比,得到所有符合的空间id数组
|
|
|
+ for (ObjectDigital space : spaces) {
|
|
|
+ if (null==space.getInfos()){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!space.getInfos().has("outline")
|
|
|
+ || !(space.getInfos().get("outline").size()>0)
|
|
|
+ || !(space.getInfos().get("outline").get(0).size()>0)){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 空间的第一个数组
|
|
|
+ JsonNode jsonNode = space.getInfos().get("outline").get(0).get(0);
|
|
|
+ if (jsonNode==null || !jsonNode.isArray()){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ ArrayNode jsonNodes = (ArrayNode) jsonNode;
|
|
|
+ List<ObjectNode> temp = new ArrayList<>();
|
|
|
+ jsonNodes.forEach(node->temp.add((ObjectNode) node));
|
|
|
+ if (GeoToolsUtil.isPointInPoly(point1,temp) || GeoToolsUtil.isPointInPoly(point2,temp)){
|
|
|
+ List<String> spaceIds = spaceIndexMap.getOrDefault(i, new ArrayList<>());
|
|
|
+ spaceIds.add(space.getId());
|
|
|
+ spaceIndexMap.put(i,spaceIds);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
// 2.5 创建空间服务关系的关系数据
|
|
|
-
|
|
|
-
|
|
|
+ Set<Map.Entry<Integer, List<String>>> entries = spaceIndexMap.entrySet();
|
|
|
+
|
|
|
+ for (Map.Entry<Integer, List<String>> entry : entries) {
|
|
|
+ List<String> list = entry.getValue();
|
|
|
+ if(CollUtil.isEmpty(list) || list.size()<2){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String oneSpaceId = list.get(0);
|
|
|
+ for (int i = 1; i < list.size(); i++) {
|
|
|
+ String otherSpaceId = list.get(i);
|
|
|
+ ObjectNode objectNode = objectMapper.createObjectNode()
|
|
|
+ .put("graphCode", relationTypeEnum.getGraphCode())
|
|
|
+ .put("relCode", relationTypeEnum.getRelCode())
|
|
|
+ .put("graphId", StrUtil.format(CommonConstant.DEFAULT_GRAPH_ID_FORMAT, relationTypeEnum.getGraphCode()))
|
|
|
+ .put("projectId", floor.getProjectId())
|
|
|
+ .put("objTo", otherSpaceId)
|
|
|
+ .put("objFrom", oneSpaceId)
|
|
|
+ .put("valid", 1)
|
|
|
+ .put("createApp", context.getAppId())
|
|
|
+ .put("updateApp", context.getAppId())
|
|
|
+ .put("groupCode", context.getGroupCode())
|
|
|
+ .put("creator", context.getUserId())
|
|
|
+ .put("modifier", context.getUserId());
|
|
|
+ if (StrUtil.isNotBlank(classCode)){
|
|
|
+ objectNode.put("relValue",classCode);
|
|
|
+ }
|
|
|
+ relations.add(objectNode);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ if (CollUtil.isNotEmpty(relations)){
|
|
|
+ DigitalRelationFacade.create(context.getGroupCode(),context.getProjectId(),context.getAppId(),context.getUserId(),relations);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /***
|
|
|
+ * Description: 查询楼层下的所有空间
|
|
|
+ * @param floorId : 楼层id
|
|
|
+ * @param classCode : 对象类型code
|
|
|
+ * @param projectId : 项目id
|
|
|
+ * @param context: 内容上下文
|
|
|
+ * @return : java.util.List<com.persagy.dmp.digital.entity.ObjectDigital>
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/8 14:47
|
|
|
+ * Update By lijie 2021/10/8 14:47
|
|
|
+ */
|
|
|
+ private List<ObjectDigital> queryAllSpacesByFloorIdAndClassCode(String floorId, String classCode,
|
|
|
+ String projectId, InstanceUrlParam context) {
|
|
|
+ RequestData requestData = RequestData
|
|
|
+ .builder()
|
|
|
+ .projectId(projectId)
|
|
|
+ .floorId(floorId)
|
|
|
+ .objTypes(CollUtil.newHashSet(AdmObjectType.SPACE.getIndex()))
|
|
|
+ .classCodes(CollUtil.newHashSet(classCode))
|
|
|
+ .build();
|
|
|
+ // 1.查询通用结果集
|
|
|
+ CommonResult<List<ObjectDigital>> commonResult = DigitalObjectFacade
|
|
|
+ .queryObjectListSuperiorIdPrototype(context.getGroupCode(),
|
|
|
+ context.getProjectId(), context.getAppId(), context.getUserId(), requestData);
|
|
|
+ List<ObjectDigital> spaces = commonResult.getData();
|
|
|
+ if (CollUtil.isEmpty(spaces)){
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+ Long count = commonResult.getCount();
|
|
|
+ if (spaces.size() == count){
|
|
|
+ // 不需要分页查询
|
|
|
+ return spaces;
|
|
|
+ }
|
|
|
+ // 有结果集未查完
|
|
|
+ long page = (count % CommonConstant.QUERY_DEFAULT_PAGE_SIZE) == 0
|
|
|
+ ? (count / CommonConstant.QUERY_DEFAULT_PAGE_SIZE) : (count / CommonConstant.QUERY_DEFAULT_PAGE_SIZE + 1);
|
|
|
+ for (long i = 1; i < page; i++) {
|
|
|
+ requestData.setPage(i);
|
|
|
+ requestData.setSize(CommonConstant.QUERY_DEFAULT_PAGE_SIZE);
|
|
|
+ List<ObjectDigital> pageSpaces = DigitalObjectFacade
|
|
|
+ .queryObjectListSuperiorId(context.getGroupCode(),
|
|
|
+ context.getProjectId(), context.getAppId(), context.getUserId(), requestData);
|
|
|
+ if (CollUtil.isEmpty(pageSpaces)){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ spaces.addAll(pageSpaces);
|
|
|
+ }
|
|
|
+ return spaces;
|
|
|
}
|
|
|
+
|
|
|
/***
|
|
|
* Description: 根据楼层模型id查询所有门数据(BDTP限制了查询条数,需要做分页查询)
|
|
|
* @param floorModelId : 楼层模型id
|
|
@@ -156,18 +289,50 @@ public class AdmRelCalServiceImpl implements AdmRelCalService {
|
|
|
* Update By lijie 2021/10/8 10:02
|
|
|
*/
|
|
|
private List<TwicePointDTO> queryAllDoorByFloorModelId(String floorModelId, InstanceUrlParam context) {
|
|
|
+
|
|
|
// 门的classCode:CFBEDR,obj_type为equipment
|
|
|
QueryCriteria queryCriteria = new QueryCriteria();
|
|
|
queryCriteria.getCriteria().put("classCode","CFBEDR")
|
|
|
.put("objType",AdmObjectType.EQUIPMENT.getIndex())
|
|
|
.put("modelId",floorModelId);
|
|
|
- List<ObjectNode> objectNodes = DigitalObjectFacade
|
|
|
- .query(context.getGroupCode(), context.getProjectId(), context.getAppId(),
|
|
|
+ CommonResult<List<ObjectNode>> commonResult = DigitalObjectFacade
|
|
|
+ .queryPrototype(context.getGroupCode(), context.getProjectId(), context.getAppId(),
|
|
|
context.getUserId(), queryCriteria);
|
|
|
+ List<TwicePointDTO> result = new ArrayList<>();
|
|
|
+ List<ObjectNode> objectNodes = commonResult.getData();
|
|
|
+ Long count = commonResult.getCount();
|
|
|
+ analysisDoorResultData(result,objectNodes);
|
|
|
+ if (objectNodes.size()==count){
|
|
|
+ // 查询结果集小于BDTP默认分页条数
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ // 有结果集未查完
|
|
|
+ long page = (count % CommonConstant.QUERY_DEFAULT_PAGE_SIZE) == 0
|
|
|
+ ? (count / CommonConstant.QUERY_DEFAULT_PAGE_SIZE) : (count / CommonConstant.QUERY_DEFAULT_PAGE_SIZE + 1);
|
|
|
+ for (long i = 1; i < page; i++) {
|
|
|
+ queryCriteria.setPage(i);
|
|
|
+ queryCriteria.setSize(CommonConstant.QUERY_DEFAULT_PAGE_SIZE);
|
|
|
+ analysisDoorResultData(result,DigitalObjectFacade
|
|
|
+ .query(context.getGroupCode(), context.getProjectId(), context.getAppId(),
|
|
|
+ context.getUserId(), queryCriteria));
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 解析门查询结果集
|
|
|
+ * @param result : 存储结果集
|
|
|
+ * @param objectNodes : 对象结果集
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/8 14:26
|
|
|
+ * Update By lijie 2021/10/8 14:26
|
|
|
+ */
|
|
|
+ private void analysisDoorResultData(List<TwicePointDTO> result, List<ObjectNode> objectNodes) {
|
|
|
+ double distance = 100.00;
|
|
|
if (CollUtil.isEmpty(objectNodes)){
|
|
|
- return new ArrayList<>();
|
|
|
+ return;
|
|
|
}
|
|
|
- List<TwicePointDTO> result = new ArrayList<>();
|
|
|
for (ObjectNode objectNode : objectNodes) {
|
|
|
// 1.获得outline
|
|
|
if (!objectNode.has("outline")
|
|
@@ -186,19 +351,44 @@ public class AdmRelCalServiceImpl implements AdmRelCalService {
|
|
|
ArrayNode points = (ArrayNode) objectNode.get("outline").get(0);
|
|
|
JsonNode firstPoint = points.get(0);
|
|
|
JsonNode secondPoint = points.get(1);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ Double k=getPoints(firstPoint.get("x").asDouble(),firstPoint.get("y").asDouble(),
|
|
|
+ secondPoint.get("x").asDouble(),secondPoint.get("y").asDouble());
|
|
|
+ if (null==k){
|
|
|
+ result.add(TwicePointDTO
|
|
|
+ .builder()
|
|
|
+ .x1(point.get("x").asDouble())
|
|
|
+ .y1(point.get("y").asDouble()+distance)
|
|
|
+ .x2(point.get("x").asDouble())
|
|
|
+ .y2(point.get("y").asDouble()-distance)
|
|
|
+ .build());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ result.add(getPointByDistance(point.get("x").asDouble(),point.get("y").asDouble(),k,distance*2));
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
- return null;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ /***
|
|
|
+ * Description: 计算两点之间的距离(我不太明白这个算法是怎么算的)
|
|
|
+ * @param baseX : 坐标点1的x值
|
|
|
+ * @param baseY : 坐标点1的y值
|
|
|
+ * @param k : 坐标点2的x值
|
|
|
+ * @param distance : 坐标点2的y值
|
|
|
+ * @return : java.lang.Double
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/10/8 11:31
|
|
|
+ * Update By lijie 2021/10/8 11:31
|
|
|
+ */
|
|
|
+ private TwicePointDTO getPointByDistance(Double baseX,Double baseY,Double k,Double distance){
|
|
|
+ if (null==k){
|
|
|
+ return TwicePointDTO.builder().x1(baseX).y1(baseY+distance).x2(baseX).y2(baseY-distance).build();
|
|
|
+ }
|
|
|
+ double vectorX1 = Math.sqrt(distance * distance / (1 + k * k));
|
|
|
+ double vectorX2 = -vectorX1;
|
|
|
+ double vectorY1 = k*vectorX1;
|
|
|
+ double vectorY2 = k*vectorX2;
|
|
|
+ return TwicePointDTO.builder().x1(baseX+vectorX1).y1(baseY+vectorY1).x2(baseX+vectorX2).y2(baseY+vectorY2).build();
|
|
|
}
|
|
|
+
|
|
|
/***
|
|
|
* Description: 计算两点之间的距离(我不太明白这个算法是怎么算的)
|
|
|
* @param x1 : 坐标点1的x值
|