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

📄 viewmap.cpp

📁 一个英国人写的GIS查看/编辑工具。支持标准的shapefile地图文件格式和coverage地图文件格式。同时可以编辑相应的dbf文件。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				FitText(pDC, pMapLayerObj, pMapLayer, x, y);
			 };                  
		 };
      }
      DrawText(pDC, pMapLayer);
   };
}

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

void CViewMap::GetExtent(CMapLayer* pMapLayer, CMapLayerObj* pMapLayerObj)
{  
   CRectEx rectE, rectPMax; 

   CRect& rRect = pMapLayerObj->GetExtent();

   // TODO need to optimise by determining centroid automatically as extent is loaded
   // from shapefiles for overlays and could be stored in CLongBinary

   if ((rRect.left == 0 && rRect.right == 0) ||
       (pMapLayerObj->GetCentreX() == 0 && pMapLayerObj->GetCentreY() == 0))
   {
      if (pMapLayerObj->GetDataType() == BDMAPLINES)
      {       
         CLongLines* pMapLines = (CLongLines*)pMapLayerObj->GetMapObject();

         // Determine extent of maplines

         // Determine extent of largest polygon/polyline so as to 
         // exclude islands etc.

         CRectEx rectP;

         for (int i = 0; i < pMapLines->GetSize(); i++)
         {      
            CLongCoord coord = pMapLines->GetAt(i);
            if (!coord.IsNull())      
            {  
               // Determine the extent of the polyline

               if (rectP.IsEmpty())
               {
                  rectP.left = rectP.right = coord.x;
                  rectP.top = rectP.bottom = coord.y;
               } else
               {
                  rectP.left = min(rectP.left, coord.x);
                  rectP.right = max(rectP.right, coord.x);
                  rectP.top = min(rectP.top, coord.y);
                  rectP.bottom = max(rectP.bottom, coord.y);
               }
            }
                       
            if (coord.IsNull() || i+1 == pMapLines->GetSize())
            {  
               // Determine the overall extent

               if (rectE.IsEmpty())
               {
                  rectE = rectP;
               } else if (!rectP.IsEmpty())
               {
                  rectE.left = min(rectE.left, rectP.left);
                  rectE.right = max(rectE.right,  rectP.right);
                  rectE.top = min(rectE.top, rectP.top);
                  rectE.bottom = max(rectE.bottom,  rectP.bottom);
               };

               // Determine the extent of the largest polgon

               if (fabs(rectPMax.Area()) < fabs(rectP.Area()))                      
               {                     
                  rectPMax = rectP;
               }                   
               rectP = CRectEx();
            }
         };         
      } 
      else if (pMapLayerObj->GetDataType() == BDCOORD)
      {
         CCoord* pCoord = (CCoord*)pMapLayerObj->GetMapObject();
                  
         double dX = GetfXInv((int)pMapLayer->GetSymSize()) - GetfXInv(0);

         rectE.left = (int)(pCoord->x - dX*2 + 0.5);
         rectE.right = (int)(pCoord->x + dX*2 + 0.5);
         rectE.top = (int)(pCoord->y - dX*2 + 0.5);
         rectE.bottom = (int)(pCoord->y + dX*2 + 0.5);

         rectPMax = rectE;
      }
      
      // Determine extent for images

      else if (pMapLayerObj->GetDataType() == BDIMAGE)
      {
         double dX, dY;
         CImageFile* pImageFile = (CImageFile*)pMapLayerObj->GetMapObject();

         pImageFile->m_georef.Convert(CPoint(0,0), dX, dY);
         rectE.left = (int)dX;
         rectE.bottom = (int)dY;

         pImageFile->m_georef.Convert(CPoint(pImageFile->m_buffer.width-1, pImageFile->m_buffer.height-1), dX, dY);
         rectE.right = (int)dX;
         rectE.top = (int)dY;         

         rectPMax = rectE;
      }

      // Store the result 

      if (!rectE.IsEmpty())
      {
         rRect = rectE; 

         // Store the centre of the largest polygon

         pMapLayerObj->GetCentreX() = (rectPMax.right + rectPMax.left)/2;
         pMapLayerObj->GetCentreY() = (rectPMax.bottom + rectPMax.top)/2;
      }   
   };

   
}

/////////////////////////////////////////////////////////////////////////////
//
// Determine if the map layer is visible within the current map extent.  If 
// not, offer to update the extent
//

void CViewMap::CheckExtent(CMapLayerArray* pMapLayerArray)
{
    CBDProjection projection;    

   // Determine the full extent of the view
   
    CRect rectNew = CRect(0,0,0,0);
    CRect rectAll = CRect(0,0,0,0);
       
    for (int j = 0; j < pMapLayerArray->GetSize(); j++)
    {
       CMapLayer* pMapLayer = pMapLayerArray->GetAt(j);
             
       for (int i = 0; i < pMapLayer->GetSize(); i++)
       {                       
          CMapLayerObj* pMapObj = pMapLayer->GetAt(i);

          // Determine extent of new layers

          if (!pMapLayer->IsExtentChecked())
          {
             if (rectNew.IsRectNull())
             {
                rectNew = pMapObj->GetExtent();
             } else
             {                    
                rectNew.top = min(rectNew.top, pMapObj->GetExtent().top);
                rectNew.bottom = max(rectNew.bottom, pMapObj->GetExtent().bottom); 
                rectNew.left = min(rectNew.left, pMapObj->GetExtent().left);
                rectNew.right = max(rectNew.right, pMapObj->GetExtent().right);
             }       
          } 

          // Determine total extent

           if (rectAll.IsRectNull())
           {
              rectAll = pMapObj->GetExtent();
           } else
           {                    
              rectAll.top = min(rectAll.top, pMapObj->GetExtent().top);
              rectAll.bottom = max(rectAll.bottom, pMapObj->GetExtent().bottom); 
              rectAll.left = min(rectAll.left, pMapObj->GetExtent().left);
              rectAll.right = max(rectAll.right, pMapObj->GetExtent().right);
           }       
       }
       pMapLayer->SetExtentChecked();
    };

   // If the view does not fit in the default view then offer to update it

    if (rectNew.left != rectNew.right)
    {
       if (m_bDefaultExtentNull || 
           ((rectNew.right < m_dMinX || rectNew.left > m_dMaxX) &&
           (rectNew.top < m_dMinY || rectNew.bottom > m_dMaxY)))
       {
          // Ask the user if the view should be updated

          if (AfxMessageBox(IDS_OUTSIDEEXTENT, MB_YESNO) == IDYES)
          {
             // Find the default projection

             BOOL bFound = BDProjection(BDHandle(), &projection, BDGETINIT);
             while (bFound)
             {   
                // Update it

               if (projection.m_bDefault) 
               {  
                  BDEnd(BDHandle());

                  projection.m_dMinEasting = rectAll.left;
                  projection.m_dMaxEasting = rectAll.right;
                  projection.m_dMinNorthing = rectAll.top;
                  projection.m_dMaxNorthing = rectAll.bottom;

                  BDProjection(BDHandle(), &projection, BDUPDATE);                                    

                  m_bDefaultExtentNull = FALSE;

               // Initialise and redraw the view

                  InitialiseMapView();                     
                  OnViewZoomnormal();

                  break;
               };
               bFound = BDGetNext(BDHandle());
            };
            BDEnd(BDHandle());                       

   // Initialise to latitude/longitude

           if (!bFound)
           {
               InitialiseMapView();                     
               OnViewZoomnormal();
           }
          };
       };
    };                   
}

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

void CViewMap::DrawCoords(CDC* pDC, CMapLayerObj* pMapLayerObj, CMapLayer* pMapLayer, BOOL bSearch)
{   
   CBrush brush;   
   CRect rectWindow;         
   char* pName = NULL; 
   CRect rectI;                 
   
   // Optimization: If the extent is outside the current view then no need to draw, should
   // speed up drawing of custom symbols as well as prevent Win 98 from crashing when zoomed in 

   // Determine the extent

   GetExtent(pMapLayer, pMapLayerObj);

   if (!IsVisible(pDC, pMapLayerObj)) return;   
   
   CMapStyle mapstyle;
   GetStyle(pMapLayer, pMapLayerObj, 0, mapstyle);

   if (bSearch)
   {
	   mapstyle.m_crFill = RGB(255,255,255);
	   mapstyle.m_crLine = RGB(255,0,0);
   }
      
  // Convert the coordinate to screen coordinates     
 
   CCoord* pCoord = (CCoord*)pMapLayerObj->GetMapObject();

   if (pCoord != NULL && !pCoord->IsNull())
   {
	   double dX = GetfXPos((long)(pCoord->x + 0.5));
	   double dY = GetfYPos((long)(pCoord->y + 0.5));      

   // Determine the auto symbol size

      if (pMapLayer->GetAutoSize())
      {                
         ASSERT(pMapLayer->GetAutoMax() - pMapLayer->GetAutoMin() != 0);
         if (pMapLayerObj->GetValue() != AFX_RFX_DOUBLE_PSEUDO_NULL)
         {            
            double d = (pMapLayerObj->GetValue() - pMapLayer->GetAutoMin()) / 
                       (pMapLayer->GetAutoMax() - pMapLayer->GetAutoMin());

            mapstyle.m_dSymSize *= AUTOSCALE*d;
         }       
      }

   // Scale the symbol

      if (pMapLayer->GetScaleFont())
      {
         mapstyle.m_dSymSize *= m_dZoom;
      }

   // Draw position of station      
      
      if (pMapLayer->GetBestFitSym())
      {
         CheckOverlapSym(pDC, mapstyle.m_dSymSize, dX, dY);
      }           
           
         CComboBoxSymbol::DrawSymbol(pDC, dX, dY, mapstyle);                 
   };
}

///////////////////////////////////////////////////////////////////////////////
//
// Display a georeferenced image associated with a map object
//

void CViewMap::DrawImage(CDC* pDC, CMapLayerObj* pMapLayerObj, CMapLayer* pMapLayer)
{
   CImageFile* pImage = (CImageFile*)pMapLayerObj->GetMapObject();

   // Determine if window is visible

   GetExtent(pMapLayer, pMapLayerObj);

   if (!IsVisible(pDC, pMapLayerObj)) return;   

   // Determine location of window

   CRect rect = m_rect;
   if (m_rectPaint.left != 0 && m_rectPaint.right != 0)
   {
      rect.IntersectRect(m_rect, m_rectPaint);
   };
   
   pImage->OnDraw(pDC, this, &rect);
}

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

void CViewMap::FitText(CDC* pDC, CMapLayerObj* pMapLayerObj, CMapLayer* pMapLayer, 
                       int x, int y)
{
   CRect rect;
   BOOL bDrawText = FALSE;
   CRectText rectT;
   int iPos = 0;
          
   // Search through all posible positions

   bDrawText = CheckOverlap(pDC, pMapLayer, pMapLayerObj->GetText(), x, y, rect, iPos);
   // If overlaps are allowed and the text cannot be fit
   // then draw it anyway

   if (pMapLayer->GetOverlap()) bDrawText = TRUE;

   // If the text label is outside the drawn rectangle then do not draw it

   if (rect.left < m_rect.left || rect.right > m_rect.right ||
       rect.top < m_rect.top || rect.bottom > m_rect.bottom)
   {
      bDrawText = FALSE;
   }
 
   if (bDrawText)
   {
      rectT.m_sText = pMapLayerObj->GetText();
      rectT.m_rect = rect;
      rectT.m_iPos = iPos;      
      rectT.m_nX = x;
      rectT.m_nY = y;      
      m_aRectTextL.Add(rectT);   
   };
   
}

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

void CViewMap::DrawText(CDC* pDC, CMapLayer* pMapLayer)
{
   pDC->SetBkMode(TRANSPARENT);      
   pDC->SetTextColor(pMapLayer->GetTextColour());

   // Output the text

   for (int i = 0; i < m_aRectTextL.GetSize(); i++)
   {
      pDC->TextOut(m_aRectTextL[i].m_rect.left, m_aRectTextL[i].m_rect.top, 
                   m_aRectTextL[i].m_sText);                      
   };   

   // Copy the text areas

   for (i = 0; i < m_aRectTextL.GetSize(); i++)
   {
      m_aRectText.Add(m_aRectTextL[i].m_rect);
   }
   m_aRectTextL.RemoveAll();

}

///////////////////////////////////////////////////////////////////////////////
//
// Returns true if the coordinate can be drawn and the rectangle into which
// it will be drawn
//


BOOL CViewMap::CheckOverlap(CDC* pDC, CMapLayer* pMapLayer, LPCSTR sText, 
                            int nX, int nY, CRect& rect, int& iPos)
{
   CSize sz(0,0);
   int nPosMin, nPosMax;
   BOOL bDrawText = FALSE;
   CRect rectI;
   int iOverlap = -1;

   if (pMapLayer->GetSize() == 0) return FALSE;
   BOOL bMapLines = pMapLayer->GetAt(0)->GetDataType() == BDMAPLINES;   
  
  // Determine the range of available positions

   if (pMapLayer->GetTextPos() == CMapLayer::BestFit)
   {
      if (!bMapLines)
      {
         nPosMin = CMapLayer::BottomRight;
         nPosMax = CMapLayer::BottomLeft;
      } else
      {
         nPosMin = CMapLayer::BottomRight;
         nPosMax = CMapLayer::Center;
      }
   } else
   {
      nPosMin = pMapLayer->GetTextPos();
      nPosMax = pMapLayer->GetTextPos();
   }

   // If refitting then start from last position

   if (iPos != 0)
   {
      nPosMin = iPos;      
   };

   // Determine the rectangle
   
   sz = pDC->GetTextExtent(sText);
   
   for (iPos = nPosMin; iPos <= nPosMax && !bDrawText; iPos++)
   {
      bDrawText = TRUE;

      // For maplines, make centre the default option

      int nPos = iPos;
      if (pMapLayer->GetTextPos() == CMapLayer::BestFit && bMapLines)
      {
          nPos = CMapLayer::Center - iPos;
      }

      switch (nPos)
      {
         case CMapLayer::TopLeft : 
            rect.left = nX - sz.cx - 2; 
            rect.top = nY - sz.cy -2;
            break;
         case CMapLayer::BottomRight : 
            rect.left = nX +2; 
            rect.top = nY+2;
            break;
         case CMapLayer::TopRight :
            rect.left = nX +2; 
            rect.top = nY - sz.cy -2;
            break;
         case CMapLayer::BottomLeft:
            rect.left = nX - sz.cx - 2; 
            rect.top = nY+2;

⌨️ 快捷键说明

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