rel_affected_space.md 4.1 KB

计算当新模型上传之后, 因元空间的变化, 受影响的业务空间

前置条件

1. 数据中心楼层绑定了模型服务中的楼层id
2. 划分了业务空间
3. 该模型上传时, 该楼层上必须已有模型
4. 原模型有元空间信息

依赖函数

处理逻辑

1. 查询出所有绑定该revit模型楼层的数据中心楼层
    SELECT id FROM public.floor where model_id = 'revit模型楼层'
2. 查询出1中楼层下的所有业务空间
3. 获取当前模型和前一个版本的模型id
4. 获取3中当前模型和上一个版本模型的所有元空间信息
5. 执行get_affected_spaced(space_data, new_ispace_data, prev_ispace_data) 函数

get_affected_spaced函数逻辑:
1. 根据业务空间的外轮廓和prev_ispace_data的外轮廓是否有重叠来获取 业务空间的原元空间的关系
2. 根据元空间的sourceId 来判断删除了哪些元空间
3. 根据sourceId匹配出当前模型和上一个模型中都存在的元空间, 根据元空间的外轮廓判断是否发生过改变
4. 根据2, 3中改变的元空间来判断 1中获取的关系中哪些业务空间因元空间的改变而发生了改变
5. 返回4中得到的业务空间

函数

源码
CREATE OR REPLACE FUNCTION rel_affected_space(floor_id character varying) RETURNS boolean AS
$$
from relations.src.affected_space.affected_space import get_affected_spaced
from shapely.geometry import Polygon
import json

try:
    # 获取当前楼层绑定的数据中心楼层的id
    floor_plan = plpy.prepare("SELECT id FROM public.floor where model_id = $1", ["text"])
    floor_data = floor_plan.execute([floor_id])
    floor_arr = []
    for fl_row in floor_data:
        floor_arr.append(fl_row['id'])
    
    if len(floor_arr) == 0:
        plpy.info("no binding floor")
        return True
    floor_str = ""
    for fl in floor_arr:
        floor_str = (floor_str + "'" + fl + "',")
    floor_str = floor_str.strip(',')
    plpy.info(floor_str)
    # 获取当前模型和前一个版本的模型id
    model_plan = plpy.prepare("select id from revit.model_file where model_floor_id = $1 and removed = false and status = 4 and version is not null order by version desc", ["text"])
    model_data = model_plan.execute([floor_id], 2)
    if len(model_data) != 2:
        plpy.info("no previous model")
        return True
    sql_str = "select rel.floor_id, rel.space_id, sp.outline from r_sp_in_fl rel left join zone_space_base sp on rel.space_id = sp.id where rel.floor_id in (" + floor_str + ")"
    # 查询出来的跟模型可能相关的所有业务空间
    space_data = plpy.execute(sql_str)
    if len(space_data) == 0:
        plpy.info("no space relation under binding floor")
        return True
    plpy.info('space data count : {0}'.format(len(space_data)))
    # 获取新模型的元空间
    new_ispace_plan = plpy.prepare("select source_id, outline from revit.space where model_id = $1", ["text"])
    new_ispace_data = new_ispace_plan.execute([model_data[0]['id']])
    plpy.info('new_ispace_data count : {0}'.format(len(new_ispace_data)))
    # 获取旧模型的所有元空间
    prev_ispace_plan = plpy.prepare("select source_id, outline from revit.space where model_id = $1", ["text"])
    prev_ispace_data = prev_ispace_plan.execute([model_data[1]['id']])
    plpy.info('prev_ispace_data count : {0}'.format(len(prev_ispace_data)))
    if len(prev_ispace_data) == 0:
        plpy.info("no prev ispace data")
        return True
    
    affected_space_ids = get_affected_spaced(space_data, new_ispace_data, prev_ispace_data)
    
    
    
    plpy.info('affected_space_ids count : {0}'.format(len(affected_space_ids)))
    for space_id in affected_space_ids:
        space_plan = plpy.prepare("update zone_space_base set state = 1 where id = $1", ["text"])
        space_plan.execute([space_id])
    
    return True
except Exception as e:
    plpy.info(e)
    return False
$$
LANGUAGE 'plpython3u' VOLATILE;

入参

1. web模型服务中的floor_id, 格式是uuid

返回结果

true    成功
false   失败