123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- package com.persagy.bdtp.adm.service.impl;
- import cn.hutool.core.date.DatePattern;
- import cn.hutool.core.date.DateUtil;
- import cn.hutool.core.util.IdUtil;
- import cn.hutool.core.util.StrUtil;
- import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import com.fasterxml.jackson.databind.JsonNode;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fasterxml.jackson.databind.node.ArrayNode;
- import com.fasterxml.jackson.databind.node.ObjectNode;
- import com.fasterxml.jackson.databind.node.TextNode;
- import com.persagy.bdtp.adm.common.AdmConst;
- import com.persagy.bdtp.adm.dao.AdmJobSpaceMapper;
- import com.persagy.bdtp.adm.entity.Pagination;
- import com.persagy.bdtp.adm.entity.db.AdmJobSpace;
- import com.persagy.bdtp.adm.entity.db.AdmObject;
- import com.persagy.bdtp.adm.service.ISyncSpace;
- import com.persagy.bdtp.adm.service.ServiceUtil;
- import com.persagy.bdtp.adm.util.GeomUtil;
- import com.persagy.dmp.basic.model.QueryCriteria;
- import com.persagy.dmp.common.constant.ValidEnum;
- import com.persagy.dmp.digital.client.DigitalObjectClient;
- import org.locationtech.jts.geom.Polygon;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import java.io.IOException;
- import java.util.*;
- @Service
- public class SyncSpaceImpl implements ISyncSpace {
- @Autowired
- private ObjectMapper objectMapper;
- @Autowired
- private DigitalObjectClient objectClient;
- @Autowired
- private AdmJobSpaceMapper jobSpaceMapper;
- @Override
- @Transactional(rollbackFor = Exception.class)
- public Map<String, Object> sync(String groupCode, String projectId, String userId, String floorId, String zone) {
- if(StrUtil.isBlank(floorId))
- floorId = null;
- //查询bdtp的空间数据
- QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper, AdmConst.OBJ_TYPE_SPACE);
- criteria.getCriteria().put("classCode", zone); //默认工作空间为物业分区
- //按楼层查询
- if (floorId != null) {
- ObjectNode rt = criteria.getCriteria().putObject("relationTo");
- rt.put("graphCode", "ArchSubset");
- rt.put("relCode", "Fl2Sp");
- rt.put("objFrom", floorId);
- }
- List<ObjectNode> spList = ServiceUtil.queryAllPage(() -> objectClient.query(groupCode, projectId, AdmConst.APP_ID, userId, criteria), criteria, new Pagination(500));
- List<AdmJobSpace> toCreate = new ArrayList<>();
- List<AdmJobSpace> toModify = new ArrayList<>();
- if(floorId == null){
- HashMap<String, List<ObjectNode>> floorMap = new HashMap<>();
- for(ObjectNode sp : spList) {
- JsonNode fId = sp.get("floorId");
- if(fId != null) {
- String flId = fId.asText();
- List<ObjectNode> flSps = floorMap.get(flId);
- if(flSps == null)
- floorMap.put(flId, flSps = new ArrayList<>());
- flSps.add(sp);
- }
- }
- for (Map.Entry<String, List<ObjectNode>> entry : floorMap.entrySet()) {
- syncByFloor(projectId, entry.getKey(), entry.getValue(), toCreate, toModify);
- }
- } else {
- syncByFloor(projectId, floorId, spList, toCreate, toModify);
- }
- String time = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN);
- for(AdmJobSpace job : toCreate) {
- job.setCreationTime(time);
- job.setCreator(AdmConst.CREATOR_SYNC);
- jobSpaceMapper.insert(job);
- }
- for(AdmJobSpace job : toModify) {
- job.setModifiedTime(time);
- job.setModifier(AdmConst.CREATOR_SYNC);
- jobSpaceMapper.updateById(job);
- }
- HashMap<String, Object> rtn = new HashMap<>();
- rtn.put("syncSpaces", toCreate.size() + toModify.size());
- return rtn;
- }
- private void syncByFloor(String projectId, String floorId, List<ObjectNode> spList, List<AdmJobSpace> toCreate, List<AdmJobSpace> toModify){
- //查询任务空间数据
- QueryWrapper<AdmJobSpace> wrapper = new QueryWrapper<>();
- wrapper.eq("project_id", projectId).eq("floor_id", floorId).eq("valid", ValidEnum.TRUE.getType());
- List<AdmJobSpace> jobSpaceList = jobSpaceMapper.selectList(wrapper);
- HashMap<String, AdmJobSpace> jobMap = new HashMap<>(jobSpaceList.size());
- jobSpaceList.forEach(job -> jobMap.put(job.getBimId() != null ? job.getBimId() : job.getSpaceId(), job));
- //同步操作
- for(ObjectNode sp : spList){
- String spId = sp.get("id").asText();
- String bimId = sp.get("bimId") != null ? sp.get("bimId").asText() : null;
- ArrayNode spOutline = null;
- Object o1 = sp.get("outline");
- if(o1 instanceof TextNode) {
- try {
- spOutline = objectMapper.readValue(((TextNode) o1).asText().toLowerCase(), ArrayNode.class); //暂时toLowerCase()处理
- } catch (IOException e) {
- }
- }
- if(!GeomUtil.checkPolygon(spOutline))
- continue;
- AdmJobSpace job = jobMap.remove(bimId != null ? bimId : spId);
- if(job != null) { //id匹配
- boolean change = false;
- //轮廓变化的空间,重置任务状态
- if(!outlineMatch(job.getOutline(), spOutline)){
- job.setArchState(AdmConst.JOB_STATE_PROCESSING);
- job.setEquipState(AdmConst.JOB_STATE_PROCESSING);
- job.setOutline(spOutline);
- change = true;
- }
- //重置空间id
- if(!Objects.equals(spId, job.getSpaceId()) || !Objects.equals(bimId, job.getBimId())) {
- job.setBimId(bimId);
- job.setSpaceId(spId);
- change = true;
- }
- //轮廓和空间id都一致的,不需要做处理
- if(change)
- toModify.add(job);
- } else { //bimId未匹配
- job = matchByOutline(jobMap, sp);
- if(job != null) { //轮廓完全一致的任务空间,重新设置bimId和spaceId
- job.setBimId(bimId);
- job.setSpaceId(spId);
- toModify.add(job);
- }
- }
- if (job == null) {
- job = new AdmJobSpace();
- job.setId(IdUtil.fastSimpleUUID());
- job.setSpaceId(spId);
- job.setBimId(bimId);
- job.setOutline(spOutline);
- job.setArchState(AdmConst.JOB_STATE_PROCESSING);
- job.setEquipState(AdmConst.JOB_STATE_PROCESSING);
- job.setProjectId(projectId);
- job.setBuildingId(sp.get("buildingId").asText());
- job.setFloorId(floorId != null ? floorId : sp.get("floorId").asText());
- job.setValid(ValidEnum.TRUE.getType());
- toCreate.add(job);
- }
- }
- //未找到匹配关系的任务空间,删除
- for(AdmJobSpace job : jobMap.values()){
- job.setValid(ValidEnum.FALSE.getType());
- toModify.add(job);
- }
- }
- @Override
- public Map<String, Object> sync(String groupCode, String projectId, String userId, String zone) {
- return sync(groupCode, projectId, userId, null, zone);
- }
- private AdmJobSpace matchByOutline(HashMap<String, AdmJobSpace> jobMap, ObjectNode space){
- if(jobMap.size() == 0)
- return null;
- ArrayNode o1 = (ArrayNode) space.get("outline");
- if(!isValidOutline(o1))
- return null;
- Polygon[] ps = GeomUtil.getPolygon(o1);
- Map.Entry<String, AdmJobSpace> target = null;
- for(Map.Entry<String, AdmJobSpace> entry : jobMap.entrySet()){
- ArrayNode o2 = entry.getValue().getOutline();
- if(isValidOutline(o2) && polygonsMatch(ps, GeomUtil.getPolygon(o2))){
- target = entry;
- break;
- }
- }
- if(target != null){
- jobMap.remove(target.getKey());
- return target.getValue();
- }
- return null;
- }
- /**
- * 判断空间轮廓是否变化
- * TODO 区分覆盖等情况
- */
- private boolean outlineMatch(ArrayNode o1, ArrayNode o2){
- return polygonsMatch(GeomUtil.getPolygon(o1), GeomUtil.getPolygon(o2));
- }
- /**
- * 轮廓匹配判断
- * TODO 暂不考虑顺序
- */
- private boolean polygonsMatch(Polygon[] ps1, Polygon[] ps2){
- if (ps1.length == ps2.length) {
- for (int i = 0; i < ps2.length; i++) {
- if (!ps1[i].equalsExact(ps2[i]))
- return false;
- }
- return true;
- }
- return false;
- }
- private boolean isValidOutline(ArrayNode outline) {
- if(outline != null && outline.size() > 0 && outline.get(0).isArray()) {
- ArrayNode o1 = (ArrayNode) outline.get(0);
- if (o1.size() > 0 && o1.get(0).isArray()) {
- ArrayNode o2 = (ArrayNode) o1.get(0);
- return o2.size() >= 3;
- }
- }
- return false;
- }
- }
|