LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/miramon - ogrmiramondatasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 76 84 90.5 %
Date: 2024-11-21 22:18:42 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements OGRMiraMonDataSource class.
       5             :  * Author:   Abel Pau
       6             :  ******************************************************************************
       7             :  * Copyright (c) 2024, Xavier Pons
       8             :  *
       9             :  * SPDX-License-Identifier: MIT
      10             :  ****************************************************************************/
      11             : 
      12             : #include "ogrmiramon.h"
      13             : 
      14             : /****************************************************************************/
      15             : /*                          OGRMiraMonDataSource()                          */
      16             : /****************************************************************************/
      17         186 : OGRMiraMonDataSource::OGRMiraMonDataSource()
      18             : {
      19         186 :     memset(&m_MMMap, 0, sizeof(m_MMMap));
      20         186 : }
      21             : 
      22             : /****************************************************************************/
      23             : /*                         ~OGRMiraMonDataSource()                          */
      24             : /****************************************************************************/
      25             : 
      26         372 : OGRMiraMonDataSource::~OGRMiraMonDataSource()
      27             : 
      28             : {
      29         186 :     m_apoLayers.clear();
      30             : 
      31         186 :     if (m_MMMap.fMMMap)
      32          45 :         VSIFCloseL(m_MMMap.fMMMap);
      33         372 : }
      34             : 
      35             : /****************************************************************************/
      36             : /*                                Open()                                    */
      37             : /****************************************************************************/
      38             : 
      39         201 : bool OGRMiraMonDataSource::Open(const char *pszFilename, VSILFILE *fp,
      40             :                                 const OGRSpatialReference *poSRS,
      41             :                                 CSLConstList papszOpenOptionsUsr)
      42             : 
      43             : {
      44             :     auto poLayer = std::make_unique<OGRMiraMonLayer>(
      45         402 :         this, pszFilename, fp, poSRS, m_bUpdate, papszOpenOptionsUsr, &m_MMMap);
      46         201 :     if (!poLayer->bValidFile)
      47             :     {
      48           8 :         return false;
      49             :     }
      50             : 
      51         193 :     if (!m_osRootName.empty())
      52             :     {
      53          82 :         const char *pszExtension = CPLGetExtension(m_osRootName.c_str());
      54          82 :         if (!EQUAL(pszExtension, "pol") && !EQUAL(pszExtension, "arc") &&
      55          70 :             !EQUAL(pszExtension, "pnt"))
      56             :         {
      57          61 :             CPLStrlcpy(m_MMMap.pszMapName,
      58             :                        CPLFormFilename(m_osRootName.c_str(),
      59             :                                        CPLGetBasename(m_osRootName.c_str()),
      60             :                                        "mmm"),
      61             :                        sizeof(m_MMMap.pszMapName));
      62          61 :             if (!m_MMMap.nNumberOfLayers)
      63             :             {
      64          45 :                 m_MMMap.fMMMap = VSIFOpenL(m_MMMap.pszMapName, "w+");
      65          45 :                 if (!m_MMMap.fMMMap)
      66             :                 {
      67             :                     // It could be an error but it is not so important
      68             :                     // to stop the process. This map is an extra element
      69             :                     // to open all layers in one click, at least in MiraMon
      70             :                     // software.
      71           0 :                     *m_MMMap.pszMapName = '\0';
      72             :                 }
      73             :                 else
      74             :                 {
      75          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "[VERSIO]\n");
      76          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "Vers=2\n");
      77          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "SubVers=0\n");
      78          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "variant=b\n");
      79          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "\n");
      80          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "[DOCUMENT]\n");
      81          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "Titol= %s(map)\n",
      82          45 :                                 CPLGetBasename(poLayer->GetName()));
      83          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "\n");
      84             :                 }
      85             :             }
      86             :         }
      87             :         else
      88          21 :             *m_MMMap.pszMapName = '\0';
      89             :     }
      90             :     else
      91         111 :         *m_MMMap.pszMapName = '\0';
      92             : 
      93         193 :     m_apoLayers.emplace_back(std::move(poLayer));
      94             : 
      95         193 :     return true;
      96             : }
      97             : 
      98             : /****************************************************************************/
      99             : /*                               Create()                                   */
     100             : /*                                                                          */
     101             : /*      Create a new datasource.  This does not really do anything          */
     102             : /*      currently but save the name.                                        */
     103             : /****************************************************************************/
     104             : 
     105          67 : bool OGRMiraMonDataSource::Create(const char *pszDataSetName,
     106             :                                   CSLConstList /* papszOptions */)
     107             : 
     108             : {
     109          67 :     m_bUpdate = true;
     110          67 :     m_osRootName = pszDataSetName;
     111             : 
     112          67 :     return true;
     113             : }
     114             : 
     115             : /****************************************************************************/
     116             : /*                           ICreateLayer()                                 */
     117             : /****************************************************************************/
     118             : 
     119             : OGRLayer *
     120          83 : OGRMiraMonDataSource::ICreateLayer(const char *pszLayerName,
     121             :                                    const OGRGeomFieldDefn *poGeomFieldDefn,
     122             :                                    CSLConstList papszOptions)
     123             : {
     124          83 :     CPLAssert(nullptr != pszLayerName);
     125             : 
     126          83 :     const auto eType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone;
     127             :     const auto poSRS =
     128          83 :         poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr;
     129             : 
     130             :     // It's a seed to be able to generate a random identifier in
     131             :     // MMGenerateFileIdentifierFromMetadataFileName() function
     132          83 :     srand((unsigned int)time(nullptr));
     133             : 
     134          83 :     if (OGR_GT_HasM(eType))
     135             :     {
     136           0 :         CPLError(CE_Warning, CPLE_NotSupported,
     137             :                  "Measures in this layer will be ignored.");
     138             :     }
     139             : 
     140             :     /* -------------------------------------------------------------------- */
     141             :     /*    If the dataset has an extension, it is understood that the path   */
     142             :     /*       of the file is where to write, and the layer name is the       */
     143             :     /*       dataset name (without extension).                              */
     144             :     /* -------------------------------------------------------------------- */
     145          83 :     const char *pszExtension = CPLGetExtension(m_osRootName.c_str());
     146         166 :     std::string osFullMMLayerName;
     147          83 :     if (EQUAL(pszExtension, "pol") || EQUAL(pszExtension, "arc") ||
     148          71 :         EQUAL(pszExtension, "pnt"))
     149             :     {
     150          21 :         osFullMMLayerName = CPLResetExtension(m_osRootName.c_str(), "");
     151          21 :         if (!osFullMMLayerName.empty())
     152          21 :             osFullMMLayerName.pop_back();
     153             : 
     154             :         // Checking that the folder where to write exists
     155             :         const std::string osDestFolder =
     156          21 :             CPLGetDirname(osFullMMLayerName.c_str());
     157          21 :         if (!STARTS_WITH(osDestFolder.c_str(), "/vsimem"))
     158             :         {
     159             :             VSIStatBufL sStat;
     160           0 :             if (VSIStatL(osDestFolder.c_str(), &sStat) != 0 ||
     161           0 :                 !VSI_ISDIR(sStat.st_mode))
     162             :             {
     163           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     164             :                          "The folder %s does not exist.", osDestFolder.c_str());
     165           0 :                 return nullptr;
     166             :             }
     167          21 :         }
     168             :     }
     169             :     else
     170             :     {
     171             :         osFullMMLayerName =
     172          62 :             CPLFormFilename(m_osRootName.c_str(), pszLayerName, "");
     173             : 
     174             :         /* -------------------------------------------------------------------- */
     175             :         /*      Let's create the folder if it's not already created.            */
     176             :         /*      (only the las level of the folder)                              */
     177             :         /* -------------------------------------------------------------------- */
     178          62 :         if (!STARTS_WITH(m_osRootName.c_str(), "/vsimem"))
     179             :         {
     180             :             VSIStatBufL sStat;
     181          14 :             if (VSIStatL(m_osRootName.c_str(), &sStat) != 0 ||
     182           0 :                 !VSI_ISDIR(sStat.st_mode))
     183             :             {
     184          14 :                 if (VSIMkdir(m_osRootName.c_str(), 0755) != 0)
     185             :                 {
     186           1 :                     CPLError(CE_Failure, CPLE_AppDefined,
     187             :                              "Unable to create the folder %s.",
     188             :                              m_osRootName.c_str());
     189           1 :                     return nullptr;
     190             :                 }
     191             :             }
     192             :         }
     193             :     }
     194             : 
     195             :     /* -------------------------------------------------------------------- */
     196             :     /*      Return open layer handle.                                       */
     197             :     /* -------------------------------------------------------------------- */
     198          82 :     if (Open(osFullMMLayerName.c_str(), nullptr, poSRS, papszOptions))
     199             :     {
     200          82 :         return m_apoLayers.back().get();
     201             :     }
     202             : 
     203           0 :     return nullptr;
     204             : }
     205             : 
     206             : /****************************************************************************/
     207             : /*                           TestCapability()                               */
     208             : /****************************************************************************/
     209             : 
     210         201 : int OGRMiraMonDataSource::TestCapability(const char *pszCap)
     211             : 
     212             : {
     213         201 :     if (EQUAL(pszCap, ODsCCreateLayer))
     214          63 :         return m_bUpdate;
     215         138 :     else if (EQUAL(pszCap, ODsCZGeometries))
     216          20 :         return TRUE;
     217             : 
     218         118 :     return FALSE;
     219             : }
     220             : 
     221             : /****************************************************************************/
     222             : /*                              GetLayer()                                  */
     223             : /****************************************************************************/
     224             : 
     225         362 : OGRLayer *OGRMiraMonDataSource::GetLayer(int iLayer)
     226             : 
     227             : {
     228         362 :     if (iLayer < 0 || iLayer >= static_cast<int>(m_apoLayers.size()))
     229          20 :         return nullptr;
     230             : 
     231         342 :     return m_apoLayers[iLayer].get();
     232             : }
     233             : 
     234             : /************************************************************************/
     235             : /*                            GetFileList()                             */
     236             : /************************************************************************/
     237             : 
     238          10 : char **OGRMiraMonDataSource::GetFileList()
     239             : {
     240          20 :     CPLStringList oFileList;
     241          20 :     for (auto &poLayer : m_apoLayers)
     242             :     {
     243          10 :         poLayer->AddToFileList(oFileList);
     244             :     }
     245          20 :     return oFileList.StealList();
     246             : }

Generated by: LCOV version 1.14