package com.persagy.proxy.adm.service.impl; import cn.hutool.core.collection.CollUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.persagy.dmp.basic.model.QueryCriteria; 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.model.*; import com.persagy.proxy.adm.request.AdmQueryCriteria; import com.persagy.proxy.adm.request.AdmResponse; import com.persagy.proxy.adm.service.*; import com.persagy.proxy.adm.utils.GeoToolsUtil; import com.persagy.proxy.common.entity.InstanceUrlParam; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.management.Query; 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 iAdmObjectRelationCalService; /** * 模型修改设备元空间的建筑楼层信息 * @param context * @param clazz * @param vo * @return */ @Override public List doUpdateModelInfo(InstanceUrlParam context, Class clazz, AdmModelRel vo) throws Exception{ //1.查询模型文件是否有楼层在使用 AdmModelRel floorCriteria = new AdmModelRel(); floorCriteria.setModelId(vo.getModelId()); List floorList = queryFloorEntity(context,floorCriteria); if(CollUtil.isNotEmpty(floorList)){ Set floorQueryTypes = getFloorQueryTypes(floorList); List relationProjectCals = iAdmObjectRelationCalService.queryCalRelByRelationType(context, floorQueryTypes); if(CollUtil.isNotEmpty(relationProjectCals)){ //更新边类型计算状态:computationalState为2 relationProjectCals.forEach(item->{ item.setComputationalState(2); }); iAdmObjectRelationCalService.updateObjectCalRel(context,relationProjectCals); } } //2.修改设备和元空间的建筑楼层信息 String oldBimId = vo.getOldBimId(); String bimId = vo.getBimId(); if(StringUtils.isNotEmpty(oldBimId) && !oldBimId.equals(bimId)){ //根据模型id重置设备元空间的建筑楼层信息 resetEquipIspaceInfo(context,vo); } //查询楼层实体 floorCriteria = new AdmModelRel(); floorCriteria.setFloorId(vo.getFloorId()); List admFloors = queryFloorEntity(context, floorCriteria); if(CollUtil.isEmpty(admFloors)){ throw new Exception("楼层不存在"); } AdmFloor floorEntity = admFloors.get(0); //2.1 模型修改设备的建筑楼层信息 if(CollUtil.isEmpty(floorEntity.getOutline())){ //如果楼层的轮廓线为空的话,直接修改 updateEquipModelInfo(context, vo,floorEntity); }else{ //判断该设备的坐标是否在层楼的轮廓中,若在,修改;不在,不修改 List admEquipments = queryModelEquip(context, vo); Boolean pointInPolygon = isPointInPolygon(admEquipments, floorEntity); if(pointInPolygon){ updateEquipModelInfo(context, vo,floorEntity); } } //2.2 模型修改元空间的建筑楼层信息 updateIspaceModelInfo(context, vo,floorEntity); //3. 修改楼层平面图地址 if(StringUtils.isNotEmpty(vo.getFloorMap())){ floorEntity.setFloorMap(vo.getFloorMap()); } floorEntity.setModelId(vo.getModelId()); floorEntity.setBimIdPre(vo.getBimId()); //4.处理楼层自定义属性:楼层标高 ObjectNode attributeMap = vo.getAttributeMap(); if(attributeMap!=null){ updateFloorElevation(vo.getAttributeMap().toString(),floorEntity); } //5.修改楼层信息 ArrayList floors = new ArrayList<>(); floors.add(floorEntity); List floorUpresult = floorService.doUpdate(context, AdmFloor.class, floors); if(CollUtil.isEmpty(floorUpresult)) { //6.发送消息,BDTP已发送,不再重复发送修改对象消息 } return null; } /** * 模型修改设备的建筑楼层信息 */ private void updateEquipModelInfo(InstanceUrlParam context, AdmModelRel modelRel,AdmFloor floorEntity){ //查询模型下的设备信息 AdmQueryCriteria criteria = new AdmQueryCriteria(); criteria.setFilters("bimId = '"+modelRel.getBimId()+"'"); criteria.setFilters("floorId = '"+modelRel.getFloorId()+"'"); AdmResponse admResponse = equipmentService.doQuery(context, criteria, AdmEquipment.class); List content = (List) admResponse.getContent(); if(CollUtil.isEmpty(content)){ return; } for (AdmEquipment admEquipment : content) { //修改设备的建筑楼层信息 admEquipment.setBuildingId(floorEntity.getBuildingId()); admEquipment.setFloorId(floorEntity.getId()); } List admEquipments = equipmentService.doUpdate(context, AdmEquipment.class, content); log.info("模型修改设备建筑楼层信息结果"+admEquipments); } /** * 模型修改元空间的建筑楼层信息 */ private void updateIspaceModelInfo(InstanceUrlParam context, AdmModelRel modelRel,AdmFloor floorEntity){ //查询模型下的元空间信息 AdmQueryCriteria criteria = new AdmQueryCriteria(); criteria.setFilters("bimId = '"+modelRel.getBimId()+"'"); criteria.setFilters("floorId = '"+modelRel.getFloorId()+"'"); AdmResponse admResponse = iSpaceService.doQuery(context, criteria, AdmISpace.class); List content = (List) admResponse.getContent(); if(CollUtil.isEmpty(content)){ return; } for (AdmISpace admIspace : content) { //修改设备的建筑楼层信息 admIspace.setBuildingId(floorEntity.getBuildingId()); admIspace.setFloorId(floorEntity.getId()); } List admEquipments = iSpaceService.doUpdate(context, AdmISpace.class, content); log.info("模型修改元空间的建筑楼层信息结果"+admEquipments); } /** * 判断点是否在面中 * @return */ private Boolean isPointInPolygon(List equipments,AdmFloor floor){ if(CollUtil.isEmpty(equipments)){ return false; } Boolean flag = true; //楼层轮廓线 List outline = floor.getOutline(); for (AdmEquipment equipment : equipments) { //设备BIM坐标 String bimLocation = equipment.getBimLocation(); //判断点是否在面中:即设备位置是否在该楼层轮廓线中 if(StringUtils.isEmpty(bimLocation)){ continue; } 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])); flag = GeoToolsUtil.isPointInPoly(node,outline); if(!flag){ return flag; } } return flag; } /** * 楼层属性修改 * @param floorMapStr * @param floorEntity */ private void updateFloorMap(String floorMapStr,AdmFloor floorEntity){ if(StringUtils.isEmpty(floorMapStr)){ return; } Map floorMap = JSONObject.toJavaObject(JSON.parseObject(floorMapStr), Map.class); Map infos = floorEntity.getInfos(); for(Map.Entry map : floorMap.entrySet()){ infos.put(map.getKey(),map.getValue()); } floorEntity.setInfos(infos); } /** * 处理楼层标高 * @param floorMapStr * @param floorEntity */ private void updateFloorElevation(String floorMapStr,AdmFloor floorEntity){ if(StringUtils.isEmpty(floorMapStr)){ return; } Map floorMap = JSONObject.toJavaObject(JSON.parseObject(floorMapStr), Map.class); Map infos = floorEntity.getInfos(); if(floorMap.containsKey(AdmCommonConstant.FLOOR_ELEVATION)){ Object object = floorMap.get(AdmCommonConstant.FLOOR_ELEVATION); if(object != null){ double floorElevation = Double.valueOf(object.toString()) / 1000; infos.put(AdmCommonConstant.FLOOR_ELEVATION,floorElevation); } } } /** * 根据模型id重置设备元空间的建筑楼层信息 * @param context * @param vo */ private void resetEquipIspaceInfo(InstanceUrlParam context, AdmModelRel vo){ //重置历史设备的建筑楼层信息 List admEquipments = queryEquipmentByBimId(context, vo); if(CollUtil.isNotEmpty(admEquipments)){ admEquipments.forEach(item->{ item.setFloorId(null); item.setBuildingId(null); }); } equipmentService.doUpdate(context,AdmEquipment.class,admEquipments); //重置历史元空间的建筑楼层信息 List admISpaces = queryIspaceByBimId(context, vo); if(CollUtil.isNotEmpty(admISpaces)){ admISpaces.forEach(item->{ item.setFloorId(null); item.setBuildingId(null); }); } iSpaceService.doUpdate(context,AdmISpace.class,admISpaces); } /** * 查询设备信息 * @param context * @param modelRel */ private List queryModelEquip(InstanceUrlParam context, AdmModelRel modelRel){ //查询模型下的设备信息 AdmQueryCriteria criteria = new AdmQueryCriteria(); criteria.setFilters("bimId = '"+modelRel.getBimId()+"' and floorId = '"+modelRel.getFloorId()+"'"); // criteria.setFilters("floorId = '"+modelRel.getFloorId()+"'"); AdmResponse admResponse = equipmentService.doQuery(context, criteria, AdmEquipment.class); if(CollUtil.isEmpty(admResponse.getContent())){ return new ArrayList<>(); } return (List) admResponse.getContent(); } /** * 根据BIMID查询历史设备信息 */ private List queryEquipmentByBimId(InstanceUrlParam context, AdmModelRel vo){ AdmQueryCriteria criteria = new AdmQueryCriteria(); criteria.setFilters("bimId = '"+vo.getOldBimId()+"'"); AdmResponse admResponse = equipmentService.doQuery(context, criteria, AdmEquipment.class); return (List)admResponse.getContent(); } /** * 根据BIMID查询历史元空间信息 */ private List queryIspaceByBimId(InstanceUrlParam context, AdmModelRel vo){ AdmQueryCriteria criteria = new AdmQueryCriteria(); criteria.setFilters("bimId = '"+vo.getOldBimId()+"'"); AdmResponse admResponse = iSpaceService.doQuery(context, criteria, AdmISpace.class); return (List)admResponse.getContent(); } /** * 查询模型文件是否有楼层在使用 */ private List queryFloorEntity(InstanceUrlParam context, AdmModelRel vo){ AdmQueryCriteria criteria = new AdmQueryCriteria(); if(StringUtils.isNotEmpty(vo.getModelId())){ criteria.setFilters("modelId = '"+vo.getModelId()+"'"); } if(StringUtils.isNotEmpty(vo.getFloorId())){ criteria.setFilters("id = '"+vo.getFloorId()+"'"); } criteria.setName("floor"); 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; } }