www.gusucode.com > VC++开源的SHP格式GIS地图查看软件源程序源码程序 > VC++开源的SHP格式GIS地图查看软件源程序源码程序\code\MapLine.cpp
//Download by http://www.NewXing.com #include "stdafx.h" #include "Global.h" #include "MapLine.h" IMPLEMENT_DYNAMIC(CMapLine,CObject) CMapLine::CMapLine() { } CMapLine::CMapLine(CMapLine& mapline ) { int i,iCount; CMapParts *pParts; iCount = m_Line.GetSize() - 1; for ( i = 0 ; i <= iCount ; i++ ) { pParts = new CMapParts(*(mapline.GetParts(i))); m_Line.Add(pParts); } } CMapLine::~CMapLine() { Clear(); } long CMapLine::GetCount() { return m_Line.GetSize(); } CMapRectangle CMapLine::GetExtent() { return m_Extent; } void CMapLine::SetExtent(CMapRectangle& extent) { m_Extent.SetLeft( extent.GetLeft()); m_Extent.SetRight( extent.GetRight()); m_Extent.SetTop(extent.GetTop()); m_Extent.SetBottom(extent.GetBottom()); } CMapParts* CMapLine::GetParts(long lIndex) { int iCount; CMapParts *pParts = NULL; iCount = m_Line.GetSize()-1; if ( lIndex < 0 || lIndex > iCount ) return pParts; pParts = m_Line.GetAt(lIndex); return pParts; } double CMapLine::GetLength() { return 0; } /***************************************************************************** 描述: 点到线距离 参数: 点 返回值 距离 ******************************************************************************/ double CMapLine::Distance(CMapPoint& pt ) { int i,j,k; double dblMinDist,dblDist; CMapParts *pParts; CMapPoints *pPoints; CMapPoint *pPoint1,*pPoint2; dblMinDist = infinity; dblDist = infinity; for ( i = 0 ; i < m_Line.GetSize() ; i++ ) { pParts = (CMapParts*)m_Line.GetAt(i); for ( j = 0 ; j < pParts->GetCount() ; j++) { pPoints = (CMapPoints*)pParts; for( k = 0 ; k < pPoints->GetCount() - 1 ; k++) { pPoint1 = (CMapPoint*)pPoints->Get(k); pPoint2 = (CMapPoint*)pPoints->Get(k+1); //计算点到线段最小距离 dblDist = ptToSegment(pt,*pPoint1,*pPoint2); if ( dblDist <= EP ) return 0.0; else if ( dblDist < dblMinDist ) dblMinDist = dblDist; } } } return dblMinDist; } /***************************************************************************** 描述: 计算点到线段最小距离 参数: p1 --- 线段起点 p2 --- 线段终点 返回值: 在点到线段最小距离 ******************************************************************************/ double CMapLine::ptToSegment(CMapPoint& pt,CMapPoint& ptStart,CMapPoint& ptEnd) { double dblDist,dblX,dblY,k; CMapPoint pPlumb; if ( pt.IsPointInLine(ptStart, ptEnd) ) return 0.0; //点在直线上 if ( fabs(ptEnd.GetX() - ptStart.GetX()) <= EP ) { dblX = ptStart.GetX(); dblY = pt.GetY(); pPlumb.SetX(dblX); pPlumb.SetY(dblY); if ( pPlumb.GetY() > min(ptStart.GetY(), ptEnd.GetY()) && pPlumb.GetY() < max(ptStart.GetY(), ptEnd.GetY())) { //垂足在线段范围内 return fabs(pPlumb.GetX() -pt.GetX()); } else { //判断线段的哪个端点离垂足比较近,然后计算两点间距离 if ( fabs(pPlumb.GetY() - ptStart.GetY()) < fabs(pPlumb.GetY() - ptEnd.GetY())) dblDist = pt.Distance(ptStart); else dblDist = pt.Distance(ptEnd); } //线段为垂直情况 } else if ( fabs(ptEnd.GetY() - ptStart.GetY()) <= EP ) { //线段为水平情况 dblX = pt.GetX(); dblY = ptStart.GetY(); pPlumb.SetX(dblX); pPlumb.SetY(dblY); if ( pPlumb.GetX() > min(ptStart.GetX(), ptEnd.GetX()) && pPlumb.GetX() < max(ptStart.GetX(), ptEnd.GetX())) { //垂足在线段范围内 return fabs(pPlumb.GetY() -pt.GetY()); } else { //判断线段的哪个端点离垂足比较近,然后计算两点间距离 if ( fabs(pPlumb.GetX() - ptStart.GetX()) < fabs(pPlumb.GetX() - ptEnd.GetX())) dblDist = pt.Distance(ptStart); else dblDist = pt.Distance(ptEnd); } } else { //线段倾斜状态 k = (double)((ptEnd.GetY() - ptStart.GetY() ) /(ptEnd.GetX() - ptStart.GetX())); // 计算垂足坐标 dblX = (k*k*ptStart.GetX() + k*(pt.GetY()-ptStart.GetY())+pt.GetX())/(k*k+1); dblY = k*(dblX-ptStart.GetX()) + ptStart.GetY(); pPlumb.SetX(dblX); pPlumb.SetY(dblY); if ( pPlumb.IsPointInLine(ptStart,ptEnd) ) { //垂足在线段上 dblDist = pt.Distance(pPlumb); } else { //判断线段的哪个端点离垂足比较近,然后计算两点间距离 if ( pPlumb.Distance(ptStart) < pPlumb.Distance(ptEnd)) dblDist = pt.Distance(ptStart); else dblDist = pt.Distance(ptEnd); } } return dblDist; } void CMapLine::Add(CMapParts* pParts) { if ( pParts == NULL ) return; m_Line.Add( pParts ); } void CMapLine::Set(long lIndex , CMapParts* pParts) { int iCount; CMapParts *pOldParts; if ( pParts == NULL ) return; iCount = m_Line.GetSize()-1; if ( lIndex < 0 || lIndex > iCount ) return ; pOldParts = m_Line.GetAt( lIndex ); m_Line.SetAt(lIndex,pParts); delete pOldParts; } void CMapLine::Remove(long lIndex) { int iCount; CMapParts *pParts; iCount = m_Line.GetSize()-1; if ( lIndex < 0 || lIndex > iCount ) return ; pParts = m_Line.GetAt( lIndex ); m_Line.RemoveAt(lIndex,1); delete pParts; } void CMapLine::Insert(long lIndex , CMapParts* pParts) { int iCount; iCount = m_Line.GetSize()-1; if ( lIndex < 0 || lIndex > iCount ) return ; m_Line.InsertAt(lIndex,pParts); } void CMapLine::Clear() { int i,iCount; CMapParts *pParts; iCount = m_Line.GetSize() - 1; for ( i = iCount ; i >= 0 ; i-- ) { pParts = m_Line.GetAt(i); delete pParts; } m_Line.RemoveAll(); }