package com.persagy.proxy.dictionary.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.persagy.dmp.common.exception.BusinessException; import com.persagy.dmp.digital.entity.ObjectRelationProjectCal; import com.persagy.proxy.adm.constant.AdmCommonConstant; import com.persagy.proxy.adm.constant.AdmRelationTypeEnum; import com.persagy.proxy.adm.request.AdmQueryCriteria; import com.persagy.proxy.adm.request.AdmResponse; import com.persagy.proxy.adm.service.impl.AbstractAdmBaseServiceImpl; import com.persagy.proxy.adm.utils.GeoToolsUtil; import com.persagy.proxy.calculation.service.IAdmObjectRelationCalService; import com.persagy.proxy.common.entity.InstanceUrlParam; import com.persagy.proxy.dictionary.model.AdmModelRel; import com.persagy.proxy.dictionary.service.IAdmModelRelService; import com.persagy.proxy.object.model.AdmEquipment; import com.persagy.proxy.object.model.AdmFloor; import com.persagy.proxy.object.model.AdmISpace; import com.persagy.proxy.object.service.IAdmEquipmentService; import com.persagy.proxy.object.service.IAdmFloorService; import com.persagy.proxy.object.service.IAdmISpaceService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; /** * @ClassName AdmModelRelServiceImpl * @Description: 模型修改设备元空间的建筑楼层信息 * @Author linhuili * @Date 2021/8/31 14:31 * @Version V1.0 **/ @Service @Slf4j public class AdmModelRelServiceImpl extends AbstractAdmBaseServiceImpl implements IAdmModelRelService { @Autowired private IAdmFloorService floorService; @Autowired private IAdmEquipmentService equipmentService; @Autowired private IAdmISpaceService iSpaceService; @Autowired private IAdmObjectRelationCalService relationCalService; /** * 模型修改设备元空间的建筑楼层信息 * @param context * @param clazz * @param vo * @return */ @Override public void doUpdateModelInfo(InstanceUrlParam context, Class clazz, AdmModelRel vo){ // 查询楼层实体 List admFloors = queryFloorEntity(context, null, vo.getFloorId()); if(CollUtil.isEmpty(admFloors)){ throw new BusinessException("楼层不存在"); } log.info("模型修改设备元空间参数{},{}"+context,vo); // 在用模型的楼层计算状态改为2 processFloorCalState(context, vo.getModelId()); AdmFloor floorEntity = admFloors.get(0); processRelObjects(context, vo.getOldBimId(), vo.getBimId(), floorEntity); // 补充楼层属性 Map infos = floorEntity.getInfos(); if(CollUtil.isEmpty(infos)){ infos = new HashMap<>(16); floorEntity.setInfos(infos); } infos.put("floorMap",vo.getFloorMap()); Double floorElevation = MapUtil.getDouble(vo.getAttributeMap(), AdmCommonConstant.FLOOR_ELEVATION); if(floorElevation != null){ infos.put(AdmCommonConstant.FLOOR_ELEVATION, floorElevation/1000); } floorEntity.setModelId(vo.getModelId()); floorEntity.setBimIdPre(vo.getBimId()); //5.修改楼层信息 floorService.doUpdate(context, AdmFloor.class, CollUtil.newArrayList(floorEntity)); } /** * 处理在用模型文件的楼层计算状态 * @param context * @param modelId */ private void processFloorCalState(InstanceUrlParam context, String modelId) { List floorList = queryFloorEntity(context, modelId, null); if(CollUtil.isEmpty(floorList)) { return; } Set floorQueryTypes = getFloorQueryTypes(floorList); List needCals = relationCalService.queryCalRelByRelationType(context, floorQueryTypes); if(CollUtil.isEmpty(needCals)) { return; } //更新边类型计算状态:computationalState为2 needCals.forEach(item->{ item.setComputationalState(2); }); relationCalService.updateObjectCalRel(context, needCals); } /** * 处理关联的元空间和设备 * @param context * @param oldBimId * @param bimId * @param floor */ private void processRelObjects(InstanceUrlParam context, String oldBimId, String bimId, AdmFloor floor) { // 如果bimId不一致,则清空原来的楼层信息 if(StrUtil.isNotBlank(oldBimId) && !StrUtil.equals(oldBimId, bimId)) { updateRelEquipments(context, oldBimId, floor, true); updateRelISpace(context, oldBimId, floor, true); } // 更新新关联的 updateRelEquipments(context, bimId, floor, false); updateRelISpace(context, bimId, floor, false); } /** * 更新设备 * @param context * @param bimId * @param floor */ private void updateRelEquipments(InstanceUrlParam context, String bimId, AdmFloor floor, boolean deleteFlag) { if(StrUtil.isBlank(bimId)) { return; } //查询模型下的设备信息 AdmQueryCriteria criteria = new AdmQueryCriteria(); criteria.addFilters("bimId startwith '" + bimId + ":'"); // 如果是删除,只删本楼层的 if(deleteFlag) { criteria.addFilters("floorId = '" + floor.getId() + "'"); } criteria.setName(AdmEquipment.OBJ_TYPE); AdmResponse admResponse = equipmentService.doQuery(context, criteria, AdmEquipment.class); List content = (List) admResponse.getContent(); if(CollUtil.isEmpty(content)) { return; } List rsList = new ArrayList<>(); for (AdmEquipment admEquipment : content) { if(deleteFlag) { admEquipment.setBuildingId(null); admEquipment.setFloorId(null); rsList.add(admEquipment); continue; } if(!isPointInPolygon(admEquipment, floor.getOutline())) { continue; } //修改设备的建筑楼层信息 admEquipment.setBuildingId(floor.getBuildingId()); admEquipment.setFloorId(floor.getId()); rsList.add(admEquipment); } if(CollUtil.isEmpty(rsList)) { return; } equipmentService.doUpdate(context, AdmEquipment.class, rsList); } /** * 更新元空间 * @param context * @param bimId * @param floor */ private void updateRelISpace(InstanceUrlParam context, String bimId, AdmFloor floor, boolean deleteFlag) { if(StrUtil.isBlank(bimId)) { return; } //查询模型下的设备信息 AdmQueryCriteria criteria = new AdmQueryCriteria(); criteria.addFilters("bimId startwith '" + bimId + ":'"); // 如果是删除,只删本楼层的 if(deleteFlag) { criteria.addFilters("floorId = '" + floor.getId() + "'"); } criteria.setName(AdmISpace.OBJ_TYPE); AdmResponse admResponse = iSpaceService.doQuery(context, criteria, AdmISpace.class); List content = (List) admResponse.getContent(); if(CollUtil.isEmpty(content)) { return; } Set nullList = CollUtil.newHashSet("buildingId", "floorId"); for (AdmISpace iSpace : content) { if(deleteFlag) { iSpace.setBuildingId(null); iSpace.setFloorId(null); iSpace.setNullList(nullList); continue; } //修改设备的建筑楼层信息 iSpace.setBuildingId(floor.getBuildingId()); iSpace.setFloorId(floor.getId()); } iSpaceService.doUpdate(context, AdmISpace.class, content); } /** * 判断点是否在面中 * @return */ private boolean isPointInPolygon(AdmEquipment equipment, List outline){ // 如果为空,表示无限边界 if(CollUtil.isEmpty(outline)) { return true; } Boolean flag = true; //设备BIM坐标 String bimLocation = equipment.getBimLocation(); //判断点是否在面中:即设备位置是否在该楼层轮廓线中 if(StrUtil.isBlank(bimLocation)){ return false; } String[] split = bimLocation.split(","); ObjectNode node = JsonNodeFactory.instance.objectNode(); node.put("x",Double.valueOf(split[0])); node.put("y",Double.valueOf(split[1])); node.put("z",Double.valueOf(split[2])); return GeoToolsUtil.isPointInPoly(node,outline); } /** * 查询模型文件是否有楼层在使用 */ private List queryFloorEntity(InstanceUrlParam context, String modelId, String floorId){ if(StrUtil.isBlank(modelId) && StrUtil.isBlank(floorId)){ return new ArrayList<>(); } AdmQueryCriteria criteria = new AdmQueryCriteria(); if(StrUtil.isNotBlank(modelId)) { criteria.addFilters(" modelId = '" + modelId + "' "); } if(StrUtil.isNotBlank(floorId)) { criteria.addFilters(" id = '"+floorId+"' "); } criteria.setName(AdmFloor.OBJ_TYPE); AdmResponse admResponse = floorService.doQuery(context, criteria, AdmFloor.class); return (List)admResponse.getContent(); } /** * 获取楼层查询类型 * @param floorList */ private Set getFloorQueryTypes(List floorList){ Set types = new HashSet<>(); for (AdmFloor admFloor : floorList) { if(CollUtil.isNotEmpty(admFloor.getOutline())){ types.add(AdmRelationTypeEnum.EQ2FL.getRelCode()); types.add(AdmRelationTypeEnum.FL2SP.getRelCode()); types.add(AdmRelationTypeEnum.BD2SP.getRelCode()); } } types.add(AdmRelationTypeEnum.EQ2SP_IN.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_2.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_CONDWATERNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_VENTNETWORK_2.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_3.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_HEATWATERLOOP_4.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_HEATWATERLOOP_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_DHWNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_RECYCLEWATERNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_FIREVENTNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_FIREWATERNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_VRFNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_CHILLWATERLOOP_2.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQFRESHAIRNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_CHILLWATERLOOP_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_DRINKINGWATERNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_COOLINGWATERLOOP_2.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_VENTNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_HEATWATERLOOP_2.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_COOLINGWATERLOOP_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_SUPPLYWATERNETWORK_1.getRelCode()); types.add(AdmRelationTypeEnum.EQ2EQ_DRAININGWATERNETWORK_1.getRelCode()); return types; } }