⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 viewmap.cpp

📁 一个英国人写的GIS查看/编辑工具。支持标准的shapefile地图文件格式和coverage地图文件格式。同时可以编辑相应的dbf文件。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            break;
         case CMapLayer::Center: 
            rect.left = nX - sz.cx/2;
            rect.top = nY - sz.cy/2;      
            break;
      }
      rect.right = rect.left + sz.cx;                  
      rect.bottom = rect.top + sz.cy;      

   // Check for overlap, do not display if string overlaps others
      
      for (int i = 0; i < m_aRectText.GetSize(); i++)
      {
         if (rectI.IntersectRect(rect, m_aRectText[i]))
         {
            bDrawText = FALSE;
            break;
         }
      }

    // Check for overlap with existing text in this layer

      for (i = 0; i < m_aRectTextL.GetSize(); i++)
      {
         if (rectI.IntersectRect(rect, m_aRectTextL[i].m_rect))
         {
            bDrawText = FALSE;
            iOverlap = i;
            break;
         }
      }

    // Check for overlap with the edge of the page

      if (rect.left < m_rect.left || rect.right > m_rect.right ||
          rect.top < m_rect.top || rect.bottom > m_rect.bottom)
      {
         bDrawText = FALSE;
      }      
   };

   // If unable to fit the text then fry moving existing text

   if (iOverlap != -1 && !bDrawText)
   {
      // Move overlapping text

      CRectText rectT = m_aRectTextL[iOverlap];
      m_aRectTextL.RemoveAt(iOverlap);

      iPos =  rectT.m_iPos+1;      

      if (CheckOverlap(pDC, pMapLayer, rectT.m_sText, rectT.m_nX, rectT.m_nY, rect, 
                       iPos))
      {         
         // Re-add
         
         rectT.m_iPos = iPos;
         rectT.m_rect = rect;
         m_aRectTextL.Add(rectT);

         // If successful, try to re-fit the text
         iPos = 0;
         bDrawText = CheckOverlap(pDC, pMapLayer, sText, nX, nY, rect, iPos);
      }
      // If not-restore the overlapping text
      else
      {
         m_aRectTextL.Add(rectT);
      }

   }

   return bDrawText;
}


///////////////////////////////////////////////////////////////////////////////
//
// If symbols have the option - 'best fit' then the symbol will be moved to 
// different locations until a position where it does not overlap is found
//

void CViewMap::CheckOverlapSym(CDC* pDC, double dSize, double& dX, double& dY)
{      
   BOOL bOverlap = TRUE;
   CRect rectI, rect;   
   CPoint pt;
   CPoint ptCoord((int) dX, (int) dY);       
   
   // Determine the rectangle
   
   CSize sz = CComboBoxSymbol::GetSymSize(pDC, dSize*1.5);
     
   for (int iPos = 1; iPos <= 9 && bOverlap; iPos++)
   {
      bOverlap = FALSE;
      switch (iPos)
      {      
      case 1: 
            pt.x = ptCoord.x - sz.cx; pt.y = ptCoord.y - sz.cy;          
            break;
      case 2: 
            pt.x = ptCoord.x - sz.cx; pt.y = ptCoord.y + sz.cy;          
            break;
      case 3:
            pt.x = ptCoord.x + sz.cx; pt.y = ptCoord.y + sz.cy;          
            break;
      case 4:
            pt.x = ptCoord.x + sz.cx; pt.y = ptCoord.y - sz.cy;          
            break;            
      case 5: 
            pt.x = ptCoord.x; pt.y = ptCoord.y - sz.cy;          
            break;
      case 6: 
            pt.x = ptCoord.x + sz.cx; pt.y = ptCoord.y;          
            break;
      case 7: 
            pt.x = ptCoord.x; pt.y = ptCoord.y + sz.cy;          
            break;
      case 8:
            pt.x = ptCoord.x - sz.cx; pt.y = ptCoord.y;          
            break;           
      case 9:
            pt.x = ptCoord.x; pt.y = ptCoord.y;                                  
            break;
      }
      rect.left = pt.x - sz.cx/2;
      rect.right = pt.x + sz.cx/2;
      rect.top = pt.y - sz.cx/2;                  
      rect.bottom = pt.y + sz.cy/2;      

   // Check for overlap, do not display if string overlaps others
      
      for (int i = 0; i < m_aRectSym.GetSize(); i++)
      {
         if (rectI.IntersectRect(rect, m_aRectSym[i]))
         {
            bOverlap = TRUE;
            break;
         }
      }      
   };  
   m_aRectSym.Add(rect);

   dX = (rect.right + rect.left)/2;
   dY = (rect.top + rect.bottom)/2;
}

///////////////////////////////////////////////////////////////////////////////
//
// OLD retained for backwards compatibility
//

int CViewMap::GetLineWidth(CDC* pDC, CMapLayer* pMapLayer)
{   
   if (pMapLayer->GetLineStyle() == PS_SOLID)
   {
      return (int)(pMapLayer->GetLineWidth() * pDC->GetDeviceCaps(LOGPIXELSX) / MMPERINCH /3);
   } else
   {
      return 1;
   }
}

/////////////////////////////////////////////////////////////////////////////

int CViewMap::GetLineWidth(CDC* pDC, int nLineStyle, int nLineWidth)
{   
   if (nLineStyle == PS_SOLID)
   {
      return (int)(nLineWidth * pDC->GetDeviceCaps(LOGPIXELSX) / MMPERINCH /3);
   } else
   {
      return 1;
   }
}

/////////////////////////////////////////////////////////////////////////////
//
// World to screen
//

int CViewMap::GetfXPos(long a) 
{
   return (int)(((a - m_dOffX) * m_dZoom / (m_dMaxX - m_dMinX) + 0.5) * (m_rectA.right - m_rectA.left)+ m_rectA.left);   
           
}
int CViewMap::GetfYPos(long a) 
{ 
   return (int)(m_rectA.Height() - (((a - m_dOffY) * m_dZoom / (m_dMaxY - m_dMinY) + 0.5) * 
           (m_rectA.bottom - m_rectA.top)) + m_rectA.top);      
}

///////////////////////////////////////////////////////////////////////////////
//
// Screen to world

long CViewMap::GetfXInv(int a)
{
   return (long)(((((double)a - m_rectA.left) / (m_rectA.right - m_rectA.left)) - 0.5) * (m_dMaxX - m_dMinX) / m_dZoom + m_dOffX);
}

long CViewMap::GetfYInv(int a)
{
   return (long)((((m_rectA.Height() - ((double)a - m_rectA.top)) / (m_rectA.bottom - m_rectA.top)) - 0.5) * (m_dMaxY - m_dMinY) / m_dZoom + m_dOffY);
}

///////////////////////////////////////////////////////////////////////////////

void CViewMap::OnSize(UINT nType, int cx, int cy) 
{
	CBDView::OnSize(nType, cx, cy);
	
   GetClientRect(&m_rect);   	

   DetermineAspect();   
}

///////////////////////////////////////////////////////////////////////////////   
//
// Determine the aspect ratio for printing or for drawing
//

void CViewMap::DetermineAspect(CDC* pDC)
{
   // Allow for different shaped pixels

   if (pDC == NULL) pDC = GetDC();
   
   // Correct for aspect ratio

   m_rectA = m_rect;
   
   double dAspect = (m_dMaxX - m_dMinX) / (m_dMaxY - m_dMinY);
   dAspect *= (double)pDC->GetDeviceCaps(LOGPIXELSX) / pDC->GetDeviceCaps(LOGPIXELSY);

   if ((m_rect.right - m_rect.left) / (m_dMaxX - m_dMinX) >
       (m_rect.bottom - m_rect.top) / (m_dMaxY - m_dMinY))
   {
      double dWidth = m_rect.Height() * dAspect;
      m_rectA.left = m_rect.left + (m_rect.Width() - (int)dWidth)/2;
      m_rectA.right = m_rectA.left + (int)dWidth;      
   }
   else
   {
      double dHeight = m_rect.Width() / dAspect;
      m_rectA.top = m_rect.top + (m_rect.Height() - (int)dHeight)/2;
      m_rectA.bottom = m_rectA.top + (int)dHeight; 
   }  
}

///////////////////////////////////////////////////////////////////////////////   
//
// Returns the current scale, e.g. 1:50,000

int CViewMap::GetScale(CDC* pDC)
{
   CRect rect = m_rect;    
   
   if (pDC->IsPrinting())
   {
      rect = m_rectP;
   }

   if (m_bCopy)
   {
      SetCopyRect(pDC);
      rect = m_rect;
   }     

   // Determine the scale range in meters

   int nMin = (int)GetfXInv(rect.left);   
   int nMax = (int)GetfXInv(rect.right);   
   double dWidthW = nMax - nMin;   

   // Determine width of rectangle in metres on the screen or printer

   double dPixelsPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
   double dWidthS = (rect.Width() / dPixelsPerInch) * MMPERINCH / 1000;

   // Tidy up

   if (m_bCopy)
   {
      GetClientRect(&m_rect);   
   };

   if (dWidthS == 0) return 0;
   else return (int)(dWidthW / dWidthS);
}

///////////////////////////////////////////////////////////////////////////////   

void CViewMap::OnLButtonDown(UINT nFlags, CPoint point) 
{  
   if (m_pDoc->GetLayers()->GetSize() == 0) return;

   // Add new point to polygon or polyline

   if (m_nMapMode == pan)
   {
	   m_ptPan = point;
	   return;
   }

   // Add points to array of lines

   if (m_nMapMode == measure)
   {
      CLongCoord coord;
      coord.x = GetfXInv(point.x);
      coord.y = GetfYInv(point.y);
      m_aMeasure.Add(coord);   
      
      // Remove last point

      if (m_ptMeasure1.x != -1)
      {
         CDC* pDC = GetDC(); // DC changes each time retrieved
         int nOldROP = pDC->SetROP2(R2_NOTXORPEN );
         pDC->MoveTo(m_ptMeasure2);      
         pDC->LineTo(m_ptMeasure1);
         pDC->SetROP2(nOldROP);

         m_ptMeasure1 = CPoint(-1,-1);
         m_ptMeasure2 = CPoint(-1,-1);
      }      

      // Update tape without redrawing entire map

      DrawTapeMeasure(GetDC());      

      return;
   }

   if (m_pMapLinesEdit != NULL)
   {           
      CLongCoord coord;
      coord.x = GetfXInv(point.x);
	   coord.y = GetfYInv(point.y);

      // Snap

      if (nFlags & MK_CONTROL)
      {
         SnapPoint(point, coord);
      }

      EditPolylines(coord, TRUE);      
      return;
   }

   // Add new point

   if (m_pMapCoordEdit != NULL)
   {                
      m_pMapCoordEdit->x = GetfXInv(point.x);
	   m_pMapCoordEdit->y = GetfYInv(point.y);

      EditMode(FALSE);
      return;
   }



   // If drag mode is selected then allow controls to be dragged

   if (m_bDragMode)
   {
      CMapLayerObj* pMapLayerObj = HitTest(point, m_pEditMapLayer);
      if (pMapLayerObj != NULL && pMapLayerObj->GetDataType() == BDCOORD)
      {
         m_pMapLayer = m_pDoc->GetLayers()->GetAt(m_pDoc->GetLayers()->GetDefault());
         m_pEditMapObj = pMapLayerObj;                  
      }
   } 

   // Otherwise create the tracker

   else
   {
      CreateTracker(point);	
   };
	CBDView::OnLButtonDown(nFlags, point);
}

///////////////////////////////////////////////////////////////////////////////
//
// Snaps the point to the nearest node in the current layer, excluding edited
// object
//

void CViewMap::SnapPoint(CPoint point, CLongCoord& rCoord)
{   
   double dDistMin = DBL_MAX;
   CPoint point1;
   CLongCoord coordMin;

   ASSERT(m_pMapLayer != NULL);
   for (int i = 0; i < m_pMapLayer->GetSize(); i++)
   {
      CMapLayerObj* pMapLayerObj = m_pMapLayer->GetAt(i); 
      
      ASSERT(pMapLayerObj->GetDataType() == BDMAPLINES);

      // Don't snap to lines being edited

      if (pMapLayerObj != m_pEditMapObj)
      {
         CLongLines* pMapLines = (CLongLines*)pMapLayerObj->GetMapObject();   

         for (int j = 0; j < pMapLines->GetSize(); j++)
         {
             CLongCoord coordE = pMapLines->GetAt(j);

             if (!coordE.IsNull())
             {
                point1.x = GetfXPos(coordE.x);
                point1.y = GetfYPos(coordE.y);

                double dDist = square(point1.x - point.x)+square(point1.y-point.y);
                if (dDist < dDistMin)
                {
                    dDistMin = dDist;                    
                    coordMin = coordE;
                }
             }             
         }
      }      
   }

   if (dDistMin < square(4*NODESIZE))
   {
      rCoord = coordMin;
   }
}

///////////////////////////////////////////////////////////////////////////////

void CViewMap::EditPolylines(CLongCoord coord, BOOL bAdd)
{
   CRect rect = CRect(0,0,0,0); // Refresh rect
   CPoint point, point1;

   CArray <CLongCoord, CLongCoord> aUpdate;   

   if (bAdd)
   {
      // If clicking on a node then select it

      int iClosest = -1;
      double dDistMin = DBL_MAX;

      if (m_pMapLinesEdit->GetSize() > 0)
      {
         aUpdate.Add(m_pMapLinesEdit->GetAt(m_iEditPoint1));      
         aUpdate.Add(m_pMapLinesEdit->GetAt(m_iEditPoint2));      

         point.x = GetfXPos(coord.x);
         point.y = GetfYPos(coord.y);
         
         for (int i = 0; i < m_pMapLinesEdit->GetSize(); i++)
         {         
            CLongCoord coordE = m_pMapLinesEdit->GetAt(i);
            if (!coordE.IsNull())
            {
               point1.x =

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -