# stack_number_automatic_matching **Repository Path**: Morgenrot/stack_number_automatic_matching ## Basic Information - **Project Name**: stack_number_automatic_matching - **Description**: No description available - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-03-11 - **Last Updated**: 2022-10-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 结构说明 | project | - xxx.py | - basic_functions.py 基础的几何操作(如合并、分割、捕捉等)和异常 | - settings.py 数据库连接、字段规范 | - postgis.py sql语句,增删查改等 # 预处理部分的封装 - function_table(table, **params) 输入为表名,在这一层用简单的sql提取出需要处理的路段的pk值 - function_workflow(pk_queue, **params) 输入需要处理的路段的pk值(以list或queue的形式),在这一层描述整个处理流程,如出队入队、增删改等。 #关于postgis.py - 使用了事务(with conn语句) 例如在去除伪结点的时候,需要删除原线段和插入合并后的线段, 如果前一步出错导致执行中断,就会影响数据的完整性。 因此将它们作为一个执行单元,如果产生错误则回滚。 相关文档:https://www.psycopg.org/docs/connection.html?highlight=context 自动提交的函数,如postgis_add_column。特征为: ```python with conn: with conn.cursor() as cursor: sql = "XXXXX" conn.execute(sql) ``` 需要手动提交的函数,如postgis_delete_by_attr(insert,update,delete等)。特征为: ```python with conn.cursor() as cursor: sql = "XXXXX" conn.execute(sql) ``` 提交方法:调用后执行conn.commit(),或在with conn语句中调用。 # 关于match_reverse 匹配条件: 1. 缓冲区重叠度>0.7 2. 缓冲区重叠度在(0.5, 0.7],且hausdorff距离<=60,且首尾方向角度差<=10° 3. 交点数>3 满足以上任意条件则认为匹配成功。 若某遥感路网成功匹配到多条上报路网,则取缓冲区重叠度最大的作为最终匹配结果。 # 关于match_postprocessing 匹配后处理,共分为3步: 1.直接尝试合并(try_merge); 2.补充两端都匹配到同一上报路段的遥感路段(match_by_topology),并尝试合并(try_merge); 3.沿上报路网方向重建遥感路网,去除分叉,并尝试合并(remove_multi_match) ## try_merge ```python input: ldbm:路段编码, rp_geom:该路段的geom, rp_table:路段所在表名 match_df = 匹配到ldbm的所有遥感路段 # step 1 尝试合并 方法1(快速):用linemerge合并。合并失败可能是由于容差或匹配的遥感路段无法构成简单线 方法2(较慢):如果方法1失败了,用方法2再做一遍,以解决由于容差导致失败的问题 # step 2 重新计算匹配路段的相似度 match_df = 重新读取匹配到ldbm的所有遥感路段 if match_df.shape[0] == 1: # 该上报路网对应的遥感路段唯一,合并成功 # step 3 调整匹配结果的方向,使与上报路网的方向一致 return True else: # 合并失败,匹配的遥感路段无法构成简单线,进行后续处理 return False ``` ## remove_multi_match ```python input: ldbm:路段编码, rp_geom:该路段的geom, rp_table:路段所在表名 QD = rp_geom的起点 next_coord = QD坐标 match_df = 匹配到ldbm的所有遥感路段 loop_count = 0(循环次数) while not match_df.empty: 计算match_df中所有遥感路段到next_coord的距离 nearest_dist = 最短距离 + 容差(为了检测到分叉的情况) if loop_count > 0 and nearest_dist > 1: # 前后不连续(第一段通常与上报路网相聚几米~几十米,不做要求) 保存前一段pk_list和coord_list,开始新的一段pk_list和coord_list continue loop_count += 1 next_df = match_df[match_df["dist"] <= nearest_dist] # 把与next_coord距离最近的道路作为后续道路 if next_df.shape[0] == 1: # 后续道路唯一 调整该遥感路段的方向,并加入当前pk_list和coord_list 从match_df中弹出该路段 else: # 后续出现分叉 next_df.score = next_df.buffer_similarity * next_df.length # 毛刺等错误匹配路段通常重叠度较小、长度较短 取score最大的路段,调整其方向,并加入当前pk_list和coord_list 将其他分叉的match_road置为空 从match_df中弹出所有分叉 next_coord = 当前coord_list里的最后一个点 # end while 保存当前的pk_list和coord_list 删除所有pk_list里的路段(原来的短路段),插入所有coord_list里的新路段(合并后的长路段) ```