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

📄 shapefile.cpp

📁 一个英国人写的GIS查看/编辑工具。支持标准的shapefile地图文件格式和coverage地图文件格式。同时可以编辑相应的dbf文件。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
         for (i = 0 ; i < pMapLayer->GetSize() && bOK; i++)
         {            
             CMapLayerObj* pMapLayerObj = pMapLayer->GetAt(i);
             CString s = GetLineText(pMapLayer, pMapLayerObj);             

             if (pMapLayerObj->GetDataType() == BDCOORD)
             {
                CLongCoord* pCoord = (CLongCoord*)pMapLayerObj->GetMapObject();
                             
                memset(&record,0x20,sizeof(CDBFRecordPoint));
                sprintf(record.m_sID,"%8i", nLabel++);                   
                memcpy(record.m_sName,s,min(sizeof(record.m_sName), s.GetLength()));

                if (fwrite(&nRecord,sizeof(BYTE),1,pFile) != 1 ||
                    fwrite(&record,sizeof(CDBFRecordPoint),1,pFile) != 1)
                {
                   bOK = FALSE;
                }             
                
             } 
             else if (pMapLayerObj->GetDataType() == BDMAPLINES)
             {                                
                CLongLines* pMapLines = (CLongLines*)pMapLayerObj->GetMapObject();                                

     // For NRDBPro only one record per multipart polyline

                {                     
                   memset(&record,0x20,sizeof(CDBFRecordPoint));
                   sprintf(record.m_sID,"%8i", nLabel++);                   
                   memcpy(record.m_sName,s,min(sizeof(record.m_sName), s.GetLength()));

                   if (fwrite(&nRecord,sizeof(BYTE),1,pFile) != 1 ||
                       fwrite(&record,sizeof(CDBFRecordPoint),1,pFile) != 1)
                   {
                      bOK = FALSE;
                   }                 
                };              
             }
         };

         // Write the end of record

         if (bOK && fwrite(&nEnd, sizeof(nEnd), 1, pFile) != 1)            
         {
            bOK = FALSE;
         }
      } else
      {
         bOK = FALSE;
      }
      fclose(pFile);
   } else
   {
      bOK = FALSE;
   }
   
   return bOK;
}

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

BOOL CShapeFile::IsValidMapObject(CAttrArray& aAttr, CArrayAttrSel& aAttrSel)
{
   BOOL bFound = FALSE;

// Determine the map objects to display

   for (int i = 0; i < aAttrSel.GetSize() && !bFound; i++)
   {
      for (int j = 0; j < aAttr.GetSize() && !bFound; j++)
      {
         if (aAttrSel[i].m_lAttr == aAttr.GetAt(j)->GetAttrId())      
         {
            CAttribute* pAttr = aAttr[j];
            if (pAttr->GetFTypeId() == aAttrSel[i].m_lFType)
            {               
               if (pAttr->GetDataType() == BDMAPLINES)
               {                        
                  CLongLines* pMapLines = new CLongLines(*pAttr->GetLongBinary());
                                
                  if (pMapLines != NULL)
                  {                     
                     bFound = TRUE;
                     break;
                  }                  
               }

               // Add coordinates to the map

               else if (pAttr->GetDataType() == BDCOORD)
               {	              
                  CCoord* pCoord = pAttr->GetCoord();
                  if (pCoord != NULL && !pCoord->IsNull())
                  {                     
                     bFound = TRUE;                   
                     break;
                  }                  
               }               
            };

         };
      };     
   };   
   return bFound;
}

///////////////////////////////////////////////////////////////////////////////
//
// Converts big endian to little endian
//

int CShapeFile::ReverseBytes(int n)
{
   union
   {
      BYTE a[4];
      int n;
   } u,v;

   u.n = n;
      
   v.a[0] = u.a[3];
   v.a[1] = u.a[2];
   v.a[2] = u.a[1];
   v.a[3] = u.a[0];   

   return v.n;
}

///////////////////////////////////////////////////////////////////////////////
//
// Converts a shapefile from one coordinate system to another
//


void CShapeFile::Convert()
{
   BOOL bOK = TRUE;
   m_bLatLon = FALSE;

   if (!BDProjection()->IsDefaultProjection())
   {
      if (!BDProjection()->InitialiseProjection()) return;
   }

   // First select and open the shapefile to determine its coordinate system

   CFileDialog dlg(TRUE, "shp", NULL, OFN_FILEMUSTEXIST, BDString(IDS_SHAPEFILE) + "|*.shp||");

   if (dlg.DoModal() == IDOK)
   {
      m_sFileIn = dlg.GetPathName();
      m_pFileIn = fopen(m_sFileIn, "rb");

      // Read the header

      if (fread(&m_mainheader, sizeof(CMainHeader),1,m_pFileIn) == 1)
      {        
         if (ReverseBytes(m_mainheader.m_nFileCode) != 9994)
         {
            bOK = FALSE;
            AfxMessageBox(BDString(IDS_INVALIDSHAPEFILE));
         }
         if (m_mainheader.m_nShapeType != SHPPoint && 
             m_mainheader.m_nShapeType != SHPPolyLine && 
             m_mainheader.m_nShapeType != SHPPolygon)
         { 
            AfxMessageBox(BDString(IDS_INVALIDSHAPEFILE));
            bOK = FALSE;
         };

         // Determine if lat/long or coordinates

         if (bOK)
         {
            if (m_mainheader.m_dXMin >= -180 && m_mainheader.m_dXMax <= 180 &&
                m_mainheader.m_dYMax <= 90 && m_mainheader.m_dYMin >= -90)
            {
               m_bLatLon = TRUE;
            }

            // Request user if conversion is correct

            CString sMsg;
            if (m_bLatLon)
            {
               sMsg = BDString(IDS_CONVERTLATLON) + " " + BDProjection()->GetProjectionName() + "?";
            } else
            {
               sMsg = BDString(IDS_CONVERTTOLATLON) + " " + BDProjection()->GetProjectionName() + "?";
            }
            if (AfxMessageBox(sMsg, MB_YESNO) != IDYES)
            {
               bOK = FALSE;
            }
         };

         // Determine export file

         CFileDialog dlg(FALSE, "shp", NULL, 0, BDString(IDS_SHAPEFILE) + "|*.shp||");
         if (dlg.DoModal() == IDOK)
         {
            m_sFileOut = dlg.GetPathName();
            if (m_sFileIn != m_sFileOut)
            {
               AfxGetApp()->BeginWaitCursor();
               if (ConvertShapeFile())
               {                
               } else
               {
                  bOK = FALSE;
                  AfxMessageBox(BDString(IDS_ERRORCONVERT));
               }
               AfxGetApp()->EndWaitCursor();
            }             
            else
            {
               AfxMessageBox(BDString(IDS_SAMEFILE));
               bOK = FALSE;
            } 
         } else
         {
            bOK = FALSE;
         }
      };   

      if (m_pFileIn != NULL) fclose (m_pFileIn);

      // Convert index and dbase files

      if (bOK)
      {
         AfxGetApp()->BeginWaitCursor();
         if (ConvertIndex())
         {
            if (!ConvertDBaseFile())
            {
               AfxMessageBox(BDString(IDS_ERRORDBASE));
               bOK = FALSE;
            }
         } else
         {
            AfxMessageBox(BDString(IDS_ERRORINDEX));
            bOK = FALSE;
         }
         AfxGetApp()->EndWaitCursor();
      }    

      if (bOK)
      {
         AfxMessageBox(BDString(IDS_SHAPEFILECONVERTED));
      }
   };   
}

///////////////////////////////////////////////////////////////////////////////
//
// Exports the shapefile
//

BOOL CShapeFile::ConvertShapeFile()
{
   BOOL bOK = TRUE;

    m_pFileOut = fopen(m_sFileOut, "wb");

    if (m_pFileOut != NULL)
    {    
       // Convert the bounding box

       if (m_bLatLon)
       {
          BDProjection()->LatLonToTransMercator(m_mainheader.m_dYMin, m_mainheader.m_dXMin, 
                                &m_mainheader.m_dXMin, &m_mainheader.m_dYMin);
          BDProjection()->LatLonToTransMercator(m_mainheader.m_dYMax, m_mainheader.m_dXMax, 
                                &m_mainheader.m_dXMax, &m_mainheader.m_dYMax);              
       } else
       {

          BDProjection()->TransMercatorToLatLon(m_mainheader.m_dXMin, m_mainheader.m_dYMin, 
                                &m_mainheader.m_dYMin, &m_mainheader.m_dXMin);
          BDProjection()->TransMercatorToLatLon(m_mainheader.m_dXMax, m_mainheader.m_dYMax, 
                                &m_mainheader.m_dYMax, &m_mainheader.m_dXMax);              
       }
       if (m_mainheader.m_dXMin > m_mainheader.m_dXMax) 
       {
          Swap(m_mainheader.m_dXMin, m_mainheader.m_dXMax);
       };
       if (m_mainheader.m_dYMin > m_mainheader.m_dYMax) 
       {
          Swap(m_mainheader.m_dYMin, m_mainheader.m_dYMax);
       };

       // Save the header

       if (fwrite(&m_mainheader, sizeof(CMainHeader),1,m_pFileOut) == 1)
       {
          while (bOK && fread(&m_recordheader, sizeof(CRecordHeader),1,m_pFileIn) == 1)
          {
            bOK &= fwrite(&m_recordheader, sizeof(CRecordHeader), 1, m_pFileOut) == 1;

         // Read the shape type
            if (fread(&m_nShape,sizeof(m_nShape),1,m_pFileIn) == 1)
            {
               bOK &= fwrite(&m_nShape, sizeof(m_nShape), 1, m_pFileOut) == 1;

               // Import only polylines

               if (m_nShape == SHPPolyLine || m_nShape == SHPPolygon)
               {               
                  bOK = ConvertPolyLine();
               } 

               else if (m_nShape == SHPPoint)
               {
                  bOK = ConvertPoints();
               }
               // Skip the record

               else
               {                  
                  AfxMessageBox(BDString(IDS_INVALIDSHAPEFILE));
                  bOK = FALSE;                  
               }
            } else
            {
               bOK = FALSE;
            }
         }
       } else
       {
          bOK = FALSE;
       }
   } else
   {
      bOK = FALSE;
   }    

   if (m_pFileOut != NULL) fclose(m_pFileOut);

   return bOK;
}

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

BOOL CShapeFile::ConvertPolyLine()
{
   BOOL bOK = TRUE;
   DWORD dwParts;
   double adPoints[2];

   CPolyLine polyline;

   if (fread(&polyline, sizeof(CPolyLine), 1, m_pFileIn))
   {
      // Convert extremese

       if (m_bLatLon)
       {
          BDProjection()->LatLonToTransMercator(polyline.m_dBox[1], polyline.m_dBox[0], 
                                &polyline.m_dBox[0], &polyline.m_dBox[1]);
          BDProjection()->LatLonToTransMercator(polyline.m_dBox[3], polyline.m_dBox[2], 
                                &polyline.m_dBox[2], &polyline.m_dBox[3]);

       } else
       {
          BDProjection()->TransMercatorToLatLon(polyline.m_dBox[0], polyline.m_dBox[1], 
                                &polyline.m_dBox[1], &polyline.m_dBox[0]);
          BDProjection()->TransMercatorToLatLon(polyline.m_dBox[2], polyline.m_dBox[3], 
                                &polyline.m_dBox[3], &polyline.m_dBox[2]);
       }
       if (polyline.m_dBox[0] > polyline.m_dBox[2]) 
       {
          Swap(polyline.m_dBox[0], polyline.m_dBox[2]);
       };
       if (polyline.m_dBox[1] > polyline.m_dBox[3]) 
       {
          Swap(polyline.m_dBox[1], polyline.m_dBox[3]);
       };

       // Save
 
       bOK = fwrite(&polyline, sizeof(CPolyLine), 1, m_pFileOut) == 1;
             
      // Read and write parts data

      for (DWORD i = 0; bOK && i < polyline.m_nParts; i++)
      {
         +bOK &= fread(&dwParts, sizeof(DWORD), 1, m_pFileIn) == 1;
         bOK &= fwrite(&dwParts, sizeof(DWORD), 1, m_pFileOut) == 1;
      }
      for (i = 0; bOK && i < polyline.m_nPoints; i++)
      {
         bOK &= fread(adPoints, sizeof(adPoints), 1, m_pFileIn) == 1;

         // Convert

         if (m_bLatLon)
         {
            BDProjection()->LatLonToTransMercator(adPoints[1], adPoints[0], &adPoints[0], &adPoints[1]);

         } else
         {
            BDProjection()->TransMercatorToLatLon(adPoints[0], adPoints[1], &adPoints[1], &adPoints[0]);
         }
         
         bOK &= fwrite(adPoints, sizeof(adPoints), 1, m_pFileOut) == 1;
      }
      
   } else
   {
      bOK = FALSE;
   }

   return bOK;
}

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

BOOL CShapeFile::ConvertPoints()
{
   CShapePoint shapepoint;

   BOOL bOK = TRUE;
   if (fread(&shapepoint, sizeof(shapepoint), 1, m_pFileIn))
   {      
		if (m_bLatLon)
		{
		  BDProjection()->LatLonToTransMercator(shapepoint.m_dY, shapepoint.m_dX, 
                              &shapepoint.m_dX, &shapepoint.m_dY);

      } else
      {

        BDProjection()->TransMercatorToLatLon(shapepoint.m_dX, shapepoint.m_dY, 
                              &shapepoint.m_dY, &shapepoint.m_dX);        
      }
      bOK = fwrite(&shapepoint, sizeof(shapepoint), 1, m_pFileOut) == 1;
   } else
   {
      bOK = FALSE;
   }
   return bOK;
		
}

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

BOOL CShapeFile::ConvertIndex()
{
   BOOL bOK = TRUE;
   //char ch;

   CMainHeader mainheader;

   CString sIndexIn = m_sFileIn.Left(m_sFileIn.ReverseFind('.')) + ".shx";
   CString sIndexOut = m_sFileOut.Left(m_sFileOut.ReverseFind('.')) + ".shx";

   m_pFileIn = fopen(sIndexIn, "rb");
   m_pFileOut = fopen(sIndexOut, "wb");
   if (m_pFileIn != NULL && m_pFileOut != NULL)
   {
      // Read the header and write the converted one 

       bOK &= fread(&mainheader, sizeof(CMainHeader),1,m_pFileIn) == 1;

       m_mainheader.m_nFileLength = mainheader.m_nFileLength;
       bOK &= fwrite(&m_mainheader, sizeof(CMainHeader),1,m_pFileOut) == 1;

      // Now copy the rest of the file

       CIndexRecord indexrecord;   
       while (bOK && fread(&indexrecord, sizeof(CIndexRecord),1,m_pFileIn) == 1)
       {
          bOK &= fwrite(&indexrecord, sizeof(CIndexRecord),1,m_pFileOut) == 1;
       };       
   } else
   {
      bOK = FALSE;
   }

   if (m_pFileIn != NULL) fclose (m_pFileIn);
   if (m_pFileOut != NULL) fclose(m_pFileOut);    

   return bOK;
}

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

BOOL CShapeFile::ConvertDBaseFile()
{
   // Copy the dBase file

   BOOL bOK = TRUE;
   char ch;   

   CString sIndexIn = m_sFileIn.Left(m_sFileIn.ReverseFind('.')) + ".dbf";
   CString sIndexOut = m_sFileOut.Left(m_sFileOut.ReverseFind('.')) + ".dbf";

   m_pFileIn = fopen(sIndexIn, "rb");
   m_pFileOut = fopen(sIndexOut, "wb");
   if (m_pFileIn != NULL && m_pFileOut != NULL)
   {   
      // Now copy the rest of the file

       while (bOK && (ch = getc(m_pFileIn)) != EOF)
       {
          fputc(ch, m_pFileOut);
       }
   } else
   {
      bOK = FALSE;
   }

   if (m_pFileIn != NULL) fclose (m_pFileIn);
   if (m_pFileOut != NULL) fclose(m_pFileOut);    

   return bOK;
}

⌨️ 快捷键说明

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