opencpn 显示时海图的拼接过程。
中国船舶工业系统工程研究院电子海图
OpenCPN海图显示分为拼接和非拼接两种模式:拼接指的是当前视口内所有符合要求的海图都会显示;非拼接指的是只有覆盖视口中心点的海图才会显示出来。拼接过程中有很多规则,《OpenCPN开发者手册-中文版》详细描述了拼接、全屏显示都显示规则。1.首先,根据用户设置的参数,读取是否需要拼接、全屏显示等。函数void MyFrame::SetupQuiltMode( void )主要用来设置拼接(Quilt模式)。在设置中主要是要找到当前的参考图, if( pCurrentStack ) { target_new_dbindex = pCurrentStack->GetCurrentEntrydbIndex();#ifdef QUILT_ONLY_MERC if(-1!= target_new_dbindex) { // Check to see if the targetnew chart is Merc intproj = ChartData->GetDBChartProj(target_new_dbindex); inttype = ChartData->GetDBChartType(target_new_dbindex); if(PROJECTION_MERCATOR != proj) { // If it is not Merc, cannot use it for quilting // walk the stack up looking for a satisfactory chart int stack_index = pCurrentStack->CurrentStackEntry; while((stack_index < pCurrentStack->nEntry-1) &&(stack_index >= 0)) { int proj_tent = ChartData->GetDBChartProj(pCurrentStack->GetDBIndex(stack_index)); int type_tent =ChartData->GetDBChartType( pCurrentStack->GetDBIndex(stack_index)); if((PROJECTION_MERCATOR ==proj_tent) && (type_tent == type)) { target_new_dbindex =pCurrentStack->GetDBIndex(stack_index); break; } stack_index++; } } }#endif } if(cc1->IsChartQuiltableRef( target_new_dbindex ) ) SelectQuiltRefdbChart( target_new_dbindex ); else SelectQuiltRefdbChart( -1 ); Current_Ch= NULL; 找到当前参考图后,重新设置视口参数,刷新显示内容。如果不是拼接模式(即单图模式,则只需要找到当前视口内最佳显示比例的图即可。)2.拼接模式下主要处理函数bool Quilt::Compose( const ViewPort&vp_in ),该函数主要是根据参考图,根据候选显示图列表,生成显示图列表,提供给显示时使用。获取参考图信息if( m_refchart_dbIndex >= 0 ) { constChartTableEntry &cte_ref = ChartData->GetChartTableEntry(m_refchart_dbIndex ); m_reference_scale = cte_ref.GetScale(); m_reference_type = cte_ref.GetChartType(); m_quilt_proj = ChartData->GetDBChartProj( m_refchart_dbIndex ); m_reference_family = cte_ref.GetChartFamily(); } bool bf =false; for( unsignedint i = 0; i < m_pcandidate_array->GetCount(); i++ ) { QuiltCandidate *qc = m_pcandidate_array->Item( i ); if(qc->dbIndex == m_refchart_dbIndex ) { bf =true; break; } }根据候选图列表,计算相交区域。if( !b_vis && m_pcandidate_array->GetCount() ){ intadd_scale = 0; for( int i= m_pcandidate_array->GetCount() - 1; i >= 0; i-- ) { QuiltCandidate *pqc = m_pcandidate_array->Item( i ); constChartTableEntry &cte = ChartData->GetChartTableEntry( pqc->dbIndex ); // Don't add cm93 yet, it is always coveringthe quilt... if(cte.GetChartType() == CHART_TYPE_CM93COMP ) continue; // Check intersection wxRegion vpck_region( vp_local.rv_rect ); wxRegion chart_region =pqc->quilt_region; //GetChartQuiltRegion( cte, vp_local ); if(!chart_region.Empty() ) vpck_region.Intersect( chart_region ); if(!vpck_region.IsEmpty() ) { if(add_scale ) { if( add_scale == cte.GetScale() )pqc->b_include = true; ; }else { pqc->b_include = true; add_scale = cte.GetScale(); } } } }根据候选图列表,生成用于显示的列表m_PatchList,并且根据比例尺由小到大排序。if( m_pcandidate_array->GetCount() ) { for( int i= m_pcandidate_array->GetCount() - 1; i >= 0; i-- ) { QuiltCandidate *pqc = m_pcandidate_array->Item( i ); // cm93 add has been deferred until here // so that it would not displace possibleraster or ENCs of larger scale constChartTableEntry &m = ChartData->GetChartTableEntry( pqc->dbIndex ); if(m.GetChartType() == CHART_TYPE_CM93COMP ) pqc->b_include = true; // forceacceptance of this chart in quilt //would not be in candidate array if not elected if(pqc->b_include ) { QuiltPatch *pqp = new QuiltPatch; pqp->dbIndex = pqc->dbIndex; pqp->ProjType = m.GetChartProjectionType(); pqp->quilt_region = pqc->quilt_region; pqp->b_Valid = true; m_PatchList.Append( pqp ); } } }根据生成的m_PatchList列表,根据视口,计算渲染区域,最近读取SENC文件的内容,用于渲染海图 for( ir = 0; ir <m_pcandidate_array->GetCount(); ir++ ) { QuiltCandidate *pqc = m_pcandidate_array->Item( ir ); if( (pqc->b_include ) && ( !pqc->b_eclipsed ) ) if(!ChartData->IsChartInCache( pqc->dbIndex ) ) { cc1->StopAutoPan(); b_stop_ap = true; } ChartData->OpenChartFromDB( pqc->dbIndex, FULL_INIT ); }至此,海图拼接的主要流程完成。
引自:http://www.opencpn.cn/OpenCPNDocs/OpenCPN%E6%8E%A2%E7%B4%A2--%E6%B5%B7%E5%9B%BE%E6%8B%BC%E6%8E%A5.pdf附件:
OpenCPN探索--海图拼接.pdf
已同步至 懒猴航海的微博
中国船舶工业系统工程研究院电子海图
OpenCPN海图显示分为拼接和非拼接两种模式:拼接指的是当前视口内所有符合要求的海图都会显示;非拼接指的是只有覆盖视口中心点的海图才会显示出来。拼接过程中有很多规则,《OpenCPN开发者手册-中文版》详细描述了拼接、全屏显示都显示规则。1.首先,根据用户设置的参数,读取是否需要拼接、全屏显示等。函数void MyFrame::SetupQuiltMode( void )主要用来设置拼接(Quilt模式)。在设置中主要是要找到当前的参考图, if( pCurrentStack ) { target_new_dbindex = pCurrentStack->GetCurrentEntrydbIndex();#ifdef QUILT_ONLY_MERC if(-1!= target_new_dbindex) { // Check to see if the targetnew chart is Merc intproj = ChartData->GetDBChartProj(target_new_dbindex); inttype = ChartData->GetDBChartType(target_new_dbindex); if(PROJECTION_MERCATOR != proj) { // If it is not Merc, cannot use it for quilting // walk the stack up looking for a satisfactory chart int stack_index = pCurrentStack->CurrentStackEntry; while((stack_index < pCurrentStack->nEntry-1) &&(stack_index >= 0)) { int proj_tent = ChartData->GetDBChartProj(pCurrentStack->GetDBIndex(stack_index)); int type_tent =ChartData->GetDBChartType( pCurrentStack->GetDBIndex(stack_index)); if((PROJECTION_MERCATOR ==proj_tent) && (type_tent == type)) { target_new_dbindex =pCurrentStack->GetDBIndex(stack_index); break; } stack_index++; } } }#endif } if(cc1->IsChartQuiltableRef( target_new_dbindex ) ) SelectQuiltRefdbChart( target_new_dbindex ); else SelectQuiltRefdbChart( -1 ); Current_Ch= NULL; 找到当前参考图后,重新设置视口参数,刷新显示内容。如果不是拼接模式(即单图模式,则只需要找到当前视口内最佳显示比例的图即可。)2.拼接模式下主要处理函数bool Quilt::Compose( const ViewPort&vp_in ),该函数主要是根据参考图,根据候选显示图列表,生成显示图列表,提供给显示时使用。获取参考图信息if( m_refchart_dbIndex >= 0 ) { constChartTableEntry &cte_ref = ChartData->GetChartTableEntry(m_refchart_dbIndex ); m_reference_scale = cte_ref.GetScale(); m_reference_type = cte_ref.GetChartType(); m_quilt_proj = ChartData->GetDBChartProj( m_refchart_dbIndex ); m_reference_family = cte_ref.GetChartFamily(); } bool bf =false; for( unsignedint i = 0; i < m_pcandidate_array->GetCount(); i++ ) { QuiltCandidate *qc = m_pcandidate_array->Item( i ); if(qc->dbIndex == m_refchart_dbIndex ) { bf =true; break; } }根据候选图列表,计算相交区域。if( !b_vis && m_pcandidate_array->GetCount() ){ intadd_scale = 0; for( int i= m_pcandidate_array->GetCount() - 1; i >= 0; i-- ) { QuiltCandidate *pqc = m_pcandidate_array->Item( i ); constChartTableEntry &cte = ChartData->GetChartTableEntry( pqc->dbIndex ); // Don't add cm93 yet, it is always coveringthe quilt... if(cte.GetChartType() == CHART_TYPE_CM93COMP ) continue; // Check intersection wxRegion vpck_region( vp_local.rv_rect ); wxRegion chart_region =pqc->quilt_region; //GetChartQuiltRegion( cte, vp_local ); if(!chart_region.Empty() ) vpck_region.Intersect( chart_region ); if(!vpck_region.IsEmpty() ) { if(add_scale ) { if( add_scale == cte.GetScale() )pqc->b_include = true; ; }else { pqc->b_include = true; add_scale = cte.GetScale(); } } } }根据候选图列表,生成用于显示的列表m_PatchList,并且根据比例尺由小到大排序。if( m_pcandidate_array->GetCount() ) { for( int i= m_pcandidate_array->GetCount() - 1; i >= 0; i-- ) { QuiltCandidate *pqc = m_pcandidate_array->Item( i ); // cm93 add has been deferred until here // so that it would not displace possibleraster or ENCs of larger scale constChartTableEntry &m = ChartData->GetChartTableEntry( pqc->dbIndex ); if(m.GetChartType() == CHART_TYPE_CM93COMP ) pqc->b_include = true; // forceacceptance of this chart in quilt //would not be in candidate array if not elected if(pqc->b_include ) { QuiltPatch *pqp = new QuiltPatch; pqp->dbIndex = pqc->dbIndex; pqp->ProjType = m.GetChartProjectionType(); pqp->quilt_region = pqc->quilt_region; pqp->b_Valid = true; m_PatchList.Append( pqp ); } } }根据生成的m_PatchList列表,根据视口,计算渲染区域,最近读取SENC文件的内容,用于渲染海图 for( ir = 0; ir <m_pcandidate_array->GetCount(); ir++ ) { QuiltCandidate *pqc = m_pcandidate_array->Item( ir ); if( (pqc->b_include ) && ( !pqc->b_eclipsed ) ) if(!ChartData->IsChartInCache( pqc->dbIndex ) ) { cc1->StopAutoPan(); b_stop_ap = true; } ChartData->OpenChartFromDB( pqc->dbIndex, FULL_INIT ); }至此,海图拼接的主要流程完成。
引自:http://www.opencpn.cn/OpenCPNDocs/OpenCPN%E6%8E%A2%E7%B4%A2--%E6%B5%B7%E5%9B%BE%E6%8B%BC%E6%8E%A5.pdf附件:

