LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/miramon - ogrmiramondatasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 78 86 90.7 %
Date: 2025-01-18 12:42:00 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             :         const std::string osExtension =
      54         164 :             CPLGetExtensionSafe(m_osRootName.c_str());
      55          82 :         if (!EQUAL(osExtension.c_str(), "pol") &&
      56         152 :             !EQUAL(osExtension.c_str(), "arc") &&
      57          70 :             !EQUAL(osExtension.c_str(), "pnt"))
      58             :         {
      59          61 :             CPLStrlcpy(m_MMMap.pszMapName,
      60         122 :                        CPLFormFilenameSafe(
      61             :                            m_osRootName.c_str(),
      62         122 :                            CPLGetBasenameSafe(m_osRootName.c_str()).c_str(),
      63             :                            "mmm")
      64             :                            .c_str(),
      65             :                        sizeof(m_MMMap.pszMapName));
      66          61 :             if (!m_MMMap.nNumberOfLayers)
      67             :             {
      68          45 :                 m_MMMap.fMMMap = VSIFOpenL(m_MMMap.pszMapName, "w+");
      69          45 :                 if (!m_MMMap.fMMMap)
      70             :                 {
      71             :                     // It could be an error but it is not so important
      72             :                     // to stop the process. This map is an extra element
      73             :                     // to open all layers in one click, at least in MiraMon
      74             :                     // software.
      75           0 :                     *m_MMMap.pszMapName = '\0';
      76             :                 }
      77             :                 else
      78             :                 {
      79          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "[VERSIO]\n");
      80          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "Vers=2\n");
      81          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "SubVers=0\n");
      82          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "variant=b\n");
      83          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "\n");
      84          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "[DOCUMENT]\n");
      85          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "Titol= %s(map)\n",
      86          90 :                                 CPLGetBasenameSafe(poLayer->GetName()).c_str());
      87          45 :                     VSIFPrintfL(m_MMMap.fMMMap, "\n");
      88             :                 }
      89             :             }
      90             :         }
      91             :         else
      92          21 :             *m_MMMap.pszMapName = '\0';
      93             :     }
      94             :     else
      95         111 :         *m_MMMap.pszMapName = '\0';
      96             : 
      97         193 :     m_apoLayers.emplace_back(std::move(poLayer));
      98             : 
      99         193 :     return true;
     100             : }
     101             : 
     102             : /****************************************************************************/
     103             : /*                               Create()                                   */
     104             : /*                                                                          */
     105             : /*      Create a new datasource.  This does not really do anything          */
     106             : /*      currently but save the name.                                        */
     107             : /****************************************************************************/
     108             : 
     109          67 : bool OGRMiraMonDataSource::Create(const char *pszDataSetName,
     110             :                                   CSLConstList /* papszOptions */)
     111             : 
     112             : {
     113          67 :     m_bUpdate = true;
     114          67 :     m_osRootName = pszDataSetName;
     115             : 
     116          67 :     return true;
     117             : }
     118             : 
     119             : /****************************************************************************/
     120             : /*                           ICreateLayer()                                 */
     121             : /****************************************************************************/
     122             : 
     123             : OGRLayer *
     124          83 : OGRMiraMonDataSource::ICreateLayer(const char *pszLayerName,
     125             :                                    const OGRGeomFieldDefn *poGeomFieldDefn,
     126             :                                    CSLConstList papszOptions)
     127             : {
     128          83 :     CPLAssert(nullptr != pszLayerName);
     129             : 
     130          83 :     const auto eType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone;
     131             :     const auto poSRS =
     132          83 :         poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr;
     133             : 
     134             :     // It's a seed to be able to generate a random identifier in
     135             :     // MMGenerateFileIdentifierFromMetadataFileName() function
     136          83 :     srand((unsigned int)time(nullptr));
     137             : 
     138          83 :     if (OGR_GT_HasM(eType))
     139             :     {
     140           0 :         CPLError(CE_Warning, CPLE_NotSupported,
     141             :                  "Measures in this layer will be ignored.");
     142             :     }
     143             : 
     144             :     /* -------------------------------------------------------------------- */
     145             :     /*    If the dataset has an extension, it is understood that the path   */
     146             :     /*       of the file is where to write, and the layer name is the       */
     147             :     /*       dataset name (without extension).                              */
     148             :     /* -------------------------------------------------------------------- */
     149         166 :     const std::string osExtension = CPLGetExtensionSafe(m_osRootName.c_str());
     150         166 :     std::string osFullMMLayerName;
     151          83 :     if (EQUAL(osExtension.c_str(), "pol") ||
     152          83 :         EQUAL(osExtension.c_str(), "arc") || EQUAL(osExtension.c_str(), "pnt"))
     153             :     {
     154          21 :         osFullMMLayerName = CPLResetExtensionSafe(m_osRootName.c_str(), "");
     155          21 :         if (!osFullMMLayerName.empty())
     156          21 :             osFullMMLayerName.pop_back();
     157             : 
     158             :         // Checking that the folder where to write exists
     159             :         const std::string osDestFolder =
     160          21 :             CPLGetDirnameSafe(osFullMMLayerName.c_str());
     161          21 :         if (!STARTS_WITH(osDestFolder.c_str(), "/vsimem"))
     162             :         {
     163             :             VSIStatBufL sStat;
     164           0 :             if (VSIStatL(osDestFolder.c_str(), &sStat) != 0 ||
     165           0 :                 !VSI_ISDIR(sStat.st_mode))
     166             :             {
     167           0 :                 CPLError(CE_Failure, CPLE_AppDefined,
     168             :                          "The folder %s does not exist.", osDestFolder.c_str());
     169           0 :                 return nullptr;
     170             :             }
     171             :         }
     172             :     }
     173             :     else
     174             :     {
     175             :         osFullMMLayerName =
     176          62 :             CPLFormFilenameSafe(m_osRootName.c_str(), pszLayerName, "");
     177             : 
     178             :         /* -------------------------------------------------------------------- */
     179             :         /*      Let's create the folder if it's not already created.            */
     180             :         /*      (only the las level of the folder)                              */
     181             :         /* -------------------------------------------------------------------- */
     182          62 :         if (!STARTS_WITH(m_osRootName.c_str(), "/vsimem"))
     183             :         {
     184             :             VSIStatBufL sStat;
     185          14 :             if (VSIStatL(m_osRootName.c_str(), &sStat) != 0 ||
     186           0 :                 !VSI_ISDIR(sStat.st_mode))
     187             :             {
     188          14 :                 if (VSIMkdir(m_osRootName.c_str(), 0755) != 0)
     189             :                 {
     190           1 :                     CPLError(CE_Failure, CPLE_AppDefined,
     191             :                              "Unable to create the folder %s.",
     192             :                              m_osRootName.c_str());
     193           1 :                     return nullptr;
     194             :                 }
     195             :             }
     196             :         }
     197             :     }
     198             : 
     199             :     /* -------------------------------------------------------------------- */
     200             :     /*      Return open layer handle.                                       */
     201             :     /* -------------------------------------------------------------------- */
     202          82 :     if (Open(osFullMMLayerName.c_str(), nullptr, poSRS, papszOptions))
     203             :     {
     204          82 :         return m_apoLayers.back().get();
     205             :     }
     206             : 
     207           0 :     return nullptr;
     208             : }
     209             : 
     210             : /****************************************************************************/
     211             : /*                           TestCapability()                               */
     212             : /****************************************************************************/
     213             : 
     214         201 : int OGRMiraMonDataSource::TestCapability(const char *pszCap)
     215             : 
     216             : {
     217         201 :     if (EQUAL(pszCap, ODsCCreateLayer))
     218          63 :         return m_bUpdate;
     219         138 :     else if (EQUAL(pszCap, ODsCZGeometries))
     220          20 :         return TRUE;
     221             : 
     222         118 :     return FALSE;
     223             : }
     224             : 
     225             : /****************************************************************************/
     226             : /*                              GetLayer()                                  */
     227             : /****************************************************************************/
     228             : 
     229         362 : OGRLayer *OGRMiraMonDataSource::GetLayer(int iLayer)
     230             : 
     231             : {
     232         362 :     if (iLayer < 0 || iLayer >= static_cast<int>(m_apoLayers.size()))
     233          20 :         return nullptr;
     234             : 
     235         342 :     return m_apoLayers[iLayer].get();
     236             : }
     237             : 
     238             : /************************************************************************/
     239             : /*                            GetFileList()                             */
     240             : /************************************************************************/
     241             : 
     242          10 : char **OGRMiraMonDataSource::GetFileList()
     243             : {
     244          20 :     CPLStringList oFileList;
     245          20 :     for (auto &poLayer : m_apoLayers)
     246             :     {
     247          10 :         poLayer->AddToFileList(oFileList);
     248             :     }
     249          20 :     return oFileList.StealList();
     250             : }

Generated by: LCOV version 1.14