LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/miramon - mm_rdlayr.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 255 315 81.0 %
Date: 2024-11-21 22:18:42 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  C API to read a MiraMon layer
       5             :  * Author:   Abel Pau, a.pau@creaf.uab.cat, based on the MiraMon codes,
       6             :  *           mainly written by Xavier Pons, Joan Maso (correctly written
       7             :  *           "Mas0xF3"), Abel Pau, Nuria Julia (N0xFAria Juli0xE0),
       8             :  *           Xavier Calaf, Lluis (Llu0xEDs) Pesquer and Alaitz Zabala, from
       9             :  *           CREAF and Universitat Autonoma (Aut0xF2noma) de Barcelona.
      10             :  *           For a complete list of contributors:
      11             :  *           https://www.miramon.cat/eng/QuiSom.htm
      12             :  ******************************************************************************
      13             :  * Copyright (c) 2024, Xavier Pons
      14             :  *
      15             :  * SPDX-License-Identifier: MIT
      16             :  ****************************************************************************/
      17             : 
      18             : #ifdef GDAL_COMPILATION
      19             : #include "ogr_api.h"  // For CPL_C_START
      20             : #include "mm_wrlayr.h"
      21             : #include "mm_wrlayr.h"  // For MMReadHeader()
      22             : #include "mm_gdal_functions.h"
      23             : #include "mm_gdal_constants.h"
      24             : #else
      25             : #include "CmptCmp.h"                    // Compatibility between compilers
      26             : #include "mm_gdal\mm_wrlayr.h"          // For MMReadHeader()
      27             : #include "mm_gdal\mm_gdal_functions.h"  // For int MM_GetArcHeights()
      28             : #include "mm_constants.h"
      29             : #endif
      30             : 
      31             : #include "mm_rdlayr.h"
      32             : 
      33             : #ifdef GDAL_COMPILATION
      34             : CPL_C_START  // Necessary for compiling in GDAL project
      35             : #endif
      36             : 
      37             :     /* -------------------------------------------------------------------- */
      38             :     /*      Reading MiraMon format file functions                           */
      39             :     /* -------------------------------------------------------------------- */
      40             : 
      41             :     // Initializes a MiraMon vector layer for reading
      42             :     int
      43         119 :     MMInitLayerToRead(struct MiraMonVectLayerInfo *hMiraMonLayer,
      44             :                       FILE_TYPE *m_fp, const char *pszFilename)
      45             : {
      46             :     char szResult[MM_MAX_ID_SNY + 10];
      47             :     char *pszSRS;
      48             : 
      49         119 :     memset(hMiraMonLayer, 0, sizeof(*hMiraMonLayer));
      50         119 :     if (MMReadHeader(m_fp, &hMiraMonLayer->TopHeader))
      51             :     {
      52           0 :         MMCPLError(CE_Failure, CPLE_NoWriteAccess,
      53             :                    "Error reading header of file %s", pszFilename);
      54           0 :         return 1;
      55             :     }
      56         119 :     hMiraMonLayer->ReadOrWrite = MM_READING_MODE;
      57         119 :     strcpy(hMiraMonLayer->pszFlags, "rb");
      58             : 
      59         119 :     hMiraMonLayer->pszSrcLayerName = strdup_function(pszFilename);
      60             : 
      61         119 :     hMiraMonLayer->LayerVersion =
      62         119 :         (char)MMGetVectorVersion(&hMiraMonLayer->TopHeader);
      63         119 :     if (hMiraMonLayer->LayerVersion == MM_UNKNOWN_VERSION)
      64             :     {
      65           0 :         MMCPLError(CE_Failure, CPLE_NotSupported,
      66             :                    "MiraMon version file unknown.");
      67           0 :         return 1;
      68             :     }
      69         119 :     if (hMiraMonLayer->LayerVersion == MM_LAST_VERSION)
      70           0 :         hMiraMonLayer->nHeaderDiskSize = MM_HEADER_SIZE_64_BITS;
      71         119 :     else if (hMiraMonLayer->LayerVersion == MM_32BITS_VERSION)
      72         113 :         hMiraMonLayer->nHeaderDiskSize = MM_HEADER_SIZE_32_BITS;
      73             :     else
      74           6 :         hMiraMonLayer->nHeaderDiskSize = MM_HEADER_SIZE_64_BITS;
      75             : 
      76         119 :     if (hMiraMonLayer->TopHeader.aFileType[0] == 'P' &&
      77          89 :         hMiraMonLayer->TopHeader.aFileType[1] == 'N' &&
      78          41 :         hMiraMonLayer->TopHeader.aFileType[2] == 'T')
      79             :     {
      80          41 :         if (hMiraMonLayer->TopHeader.Flag & MM_LAYER_3D_INFO)
      81             :         {
      82          12 :             hMiraMonLayer->TopHeader.bIs3d = 1;
      83          12 :             hMiraMonLayer->eLT = MM_LayerType_Point3d;
      84             :         }
      85             :         else
      86          29 :             hMiraMonLayer->eLT = MM_LayerType_Point;
      87             : 
      88          41 :         hMiraMonLayer->bIsPoint = TRUE;
      89             :     }
      90          78 :     else if (hMiraMonLayer->TopHeader.aFileType[0] == 'A' &&
      91          30 :              hMiraMonLayer->TopHeader.aFileType[1] == 'R' &&
      92          30 :              hMiraMonLayer->TopHeader.aFileType[2] == 'C')
      93             :     {
      94          30 :         if (hMiraMonLayer->TopHeader.Flag & MM_LAYER_3D_INFO)
      95             :         {
      96           7 :             hMiraMonLayer->TopHeader.bIs3d = 1;
      97           7 :             hMiraMonLayer->eLT = MM_LayerType_Arc3d;
      98             :         }
      99             :         else
     100          23 :             hMiraMonLayer->eLT = MM_LayerType_Arc;
     101             : 
     102          30 :         hMiraMonLayer->bIsArc = TRUE;
     103             :     }
     104          48 :     else if (hMiraMonLayer->TopHeader.aFileType[0] == 'P' &&
     105          48 :              hMiraMonLayer->TopHeader.aFileType[1] == 'O' &&
     106          48 :              hMiraMonLayer->TopHeader.aFileType[2] == 'L')
     107             :     {
     108             :         // 3D
     109          48 :         if (hMiraMonLayer->TopHeader.Flag & MM_LAYER_3D_INFO)
     110             :         {
     111           2 :             hMiraMonLayer->TopHeader.bIs3d = 1;
     112           2 :             hMiraMonLayer->eLT = MM_LayerType_Pol3d;
     113             :         }
     114             :         else
     115          46 :             hMiraMonLayer->eLT = MM_LayerType_Pol;
     116             : 
     117          48 :         hMiraMonLayer->bIsPolygon = TRUE;
     118             : 
     119          48 :         if (hMiraMonLayer->TopHeader.Flag & MM_LAYER_MULTIPOLYGON)
     120          21 :             hMiraMonLayer->TopHeader.bIsMultipolygon = 1;
     121             :     }
     122             : 
     123             :     //hMiraMonLayer->Version = MM_VECTOR_LAYER_LAST_VERSION;
     124             : 
     125         119 :     if (MMInitLayerByType(hMiraMonLayer))
     126           8 :         return 1;
     127         111 :     hMiraMonLayer->bIsBeenInit = 1;
     128             : 
     129             :     // Get the basic metadata
     130         111 :     pszSRS = MMReturnValueFromSectionINIFile(
     131         111 :         hMiraMonLayer->pszMainREL_LayerName,
     132             :         "SPATIAL_REFERENCE_SYSTEM:HORIZONTAL", "HorizontalSystemIdentifier");
     133         111 :     if (pszSRS)
     134          67 :         hMiraMonLayer->pSRS = pszSRS;
     135             :     else
     136          44 :         hMiraMonLayer->pSRS = nullptr;
     137             : 
     138         111 :     if (!hMiraMonLayer->pSRS && hMiraMonLayer->bIsPolygon)
     139             :     {
     140          44 :         pszSRS = MMReturnValueFromSectionINIFile(
     141          44 :             hMiraMonLayer->MMPolygon.MMArc.pszREL_LayerName,
     142             :             "SPATIAL_REFERENCE_SYSTEM:HORIZONTAL",
     143             :             "HorizontalSystemIdentifier");
     144             : 
     145          44 :         hMiraMonLayer->pSRS = pszSRS;
     146             :     }
     147             : 
     148         111 :     if (!ReturnEPSGCodeSRSFromMMIDSRS(hMiraMonLayer->pSRS, szResult))
     149             :     {
     150          60 :         if (MMIsEmptyString(szResult))
     151           0 :             hMiraMonLayer->nSRS_EPSG = 0;
     152             :         else
     153          60 :             hMiraMonLayer->nSRS_EPSG = atoi(szResult);
     154             :     }
     155             :     else
     156          51 :         hMiraMonLayer->nSRS_EPSG = 0;
     157             : 
     158         111 :     if (hMiraMonLayer->nSRS_EPSG == 0)
     159             :     {
     160          51 :         if (hMiraMonLayer->pSRS && strcmp(hMiraMonLayer->pSRS, "plane"))
     161             :         {
     162           0 :             MMCPLWarning(CE_Warning, CPLE_NotSupported,
     163             :                          "The MiraMon layer SRS has no equivalent "
     164             :                          "in EPSG code");
     165             :         }
     166             :     }
     167             : 
     168             :     // If more nNumStringToOperate is needed, it'll be increased.
     169         111 :     hMiraMonLayer->nNumStringToOperate = 0;
     170         111 :     if (MMResizeStringToOperateIfNeeded(hMiraMonLayer, 5000))
     171           0 :         return 1;
     172             : 
     173         111 :     return 0;
     174             : }
     175             : 
     176             : // Reads stringline coordinates and puts them in a buffer
     177             : static int
     178        1128 : MMAddStringLineCoordinates(struct MiraMonVectLayerInfo *hMiraMonLayer,
     179             :                            MM_INTERNAL_FID i_elem, uint32_t flag_z,
     180             :                            MM_N_VERTICES_TYPE nStartVertice,
     181             :                            MM_BOOLEAN bAvoidFirst, unsigned char VFG)
     182             : {
     183             :     FILE_TYPE *pF;
     184             :     struct MM_AH *pArcHeader;
     185             :     struct MiraMonArcLayer *pMMArc;
     186        1128 :     struct MM_ZD *pZDescription = nullptr;
     187             : 
     188        1128 :     if (hMiraMonLayer->bIsPolygon)
     189         774 :         pMMArc = &hMiraMonLayer->MMPolygon.MMArc;
     190             :     else
     191         354 :         pMMArc = &hMiraMonLayer->MMArc;
     192             : 
     193        1128 :     pF = pMMArc->pF;
     194        1128 :     pArcHeader = pMMArc->pArcHeader;
     195        1128 :     if (hMiraMonLayer->TopHeader.bIs3d)
     196         671 :         pZDescription = pMMArc->pZSection.pZDescription;
     197             : 
     198        1128 :     fseek_function(pF, pArcHeader[i_elem].nOffset, SEEK_SET);
     199             : 
     200        1128 :     if (hMiraMonLayer->bIsPolygon && (VFG & MM_POL_REVERSE_ARC))  // &&
     201             :         //nStartVertice > 0)
     202         240 :     {
     203             :         MM_N_VERTICES_TYPE nIVertice;
     204             : 
     205             :         // Reading arcs vertices in an inverse order
     206         240 :         if (MMResizeMM_POINT2DPointer(
     207             :                 &hMiraMonLayer->ReadFeature.pCoord,
     208             :                 &hMiraMonLayer->ReadFeature.nMaxpCoord,
     209         240 :                 nStartVertice + pArcHeader[i_elem].nElemCount *
     210             :                                     2,  // ask for twice memory to reverse
     211             :                 0, 0))
     212           0 :             return 1;
     213             : 
     214             :         // Get the vertices far away from their place to be inverted later
     215         240 :         if (pArcHeader[i_elem].nElemCount !=
     216         240 :             fread_function(hMiraMonLayer->ReadFeature.pCoord + nStartVertice +
     217             :                                pArcHeader[i_elem].nElemCount,
     218             :                            sizeof(*hMiraMonLayer->ReadFeature.pCoord),
     219             :                            (size_t)pArcHeader[i_elem].nElemCount, pF))
     220             :         {
     221           0 :             return 1;
     222             :         }
     223             : 
     224         240 :         if (hMiraMonLayer->TopHeader.bIs3d)
     225             :         {
     226         165 :             if (MMResizeDoublePointer(
     227             :                     &hMiraMonLayer->ReadFeature.pZCoord,
     228             :                     &hMiraMonLayer->ReadFeature.nMaxpZCoord,
     229         165 :                     nStartVertice + pArcHeader[i_elem].nElemCount * 2, 0, 0))
     230           0 :                 return 1;
     231             : 
     232             :             // +nStartVertice
     233         165 :             MM_GetArcHeights(hMiraMonLayer->ReadFeature.pZCoord +
     234         165 :                                  nStartVertice + pArcHeader[i_elem].nElemCount,
     235         165 :                              pF, pArcHeader[i_elem].nElemCount,
     236         165 :                              pZDescription + i_elem, flag_z);
     237             : 
     238             :             // If there is a value for Z-nodata in GDAL this lines can be uncommented
     239             :             // and MM_GDAL_NODATA_COORD_Z can be defined
     240             :             /*if(!DOUBLES_DIFERENTS_DJ(punts_z[k], MM_NODATA_COORD_Z))
     241             :             {
     242             :                 MM_N_VERTICES_TYPE nIVertice;
     243             :                 for(nIVertice=0; nIVertice<pArcHeader[i_elem].nElemCount; nIVertice++)
     244             :                     hMiraMonLayer->ReadFeature.pZCoord[nIVertice]=MM_GDAL_NODATA_COORD_Z;
     245             :             }
     246             :             */
     247             :         }
     248             : 
     249             :         // Reverse the vertices while putting on their place
     250        1339 :         for (nIVertice = 0; nIVertice < pArcHeader[i_elem].nElemCount;
     251        1099 :              nIVertice++)
     252             :         {
     253        1099 :             memcpy(hMiraMonLayer->ReadFeature.pCoord + nStartVertice -
     254         726 :                        ((nStartVertice > 0 && bAvoidFirst) ? 1 : 0) + nIVertice,
     255        1099 :                    hMiraMonLayer->ReadFeature.pCoord + nStartVertice +
     256        1099 :                        2 * pArcHeader[i_elem].nElemCount - nIVertice - 1,
     257             :                    sizeof(*hMiraMonLayer->ReadFeature.pCoord));
     258             : 
     259        1099 :             if (hMiraMonLayer->TopHeader.bIs3d)
     260             :             {
     261         330 :                 memcpy(hMiraMonLayer->ReadFeature.pZCoord + nStartVertice -
     262         540 :                            ((nStartVertice > 0 && bAvoidFirst) ? 1 : 0) +
     263             :                            nIVertice,
     264         330 :                        hMiraMonLayer->ReadFeature.pZCoord + nStartVertice +
     265         330 :                            2 * pArcHeader[i_elem].nElemCount - nIVertice - 1,
     266             :                        sizeof(*hMiraMonLayer->ReadFeature.pZCoord));
     267             :             }
     268             :         }
     269             :     }
     270             :     else
     271             :     {
     272             :         // Reading arcs vertices
     273         888 :         if (MMResizeMM_POINT2DPointer(
     274             :                 &hMiraMonLayer->ReadFeature.pCoord,
     275             :                 &hMiraMonLayer->ReadFeature.nMaxpCoord,
     276         888 :                 nStartVertice + pArcHeader[i_elem].nElemCount, 0, 0))
     277           0 :             return 1;
     278             : 
     279         888 :         if (pArcHeader[i_elem].nElemCount !=
     280         888 :             fread_function(hMiraMonLayer->ReadFeature.pCoord + nStartVertice -
     281             :                                (bAvoidFirst ? 1 : 0),
     282             :                            sizeof(*hMiraMonLayer->ReadFeature.pCoord),
     283             :                            (size_t)pArcHeader[i_elem].nElemCount, pF))
     284             :         {
     285           8 :             return 1;
     286             :         }
     287             : 
     288         880 :         if (hMiraMonLayer->TopHeader.bIs3d)
     289             :         {
     290         500 :             if (MMResizeDoublePointer(
     291             :                     &hMiraMonLayer->ReadFeature.pZCoord,
     292             :                     &hMiraMonLayer->ReadFeature.nMaxpZCoord,
     293         500 :                     nStartVertice + pArcHeader[i_elem].nElemCount, 0, 0))
     294           0 :                 return 1;
     295             : 
     296             :             // +nStartVertice
     297        1000 :             MM_GetArcHeights(hMiraMonLayer->ReadFeature.pZCoord +
     298         500 :                                  nStartVertice - (bAvoidFirst ? 1 : 0),
     299         500 :                              pF, pArcHeader[i_elem].nElemCount,
     300         500 :                              pZDescription + i_elem, flag_z);
     301             : 
     302             :             // If there is a value for Z-nodata in GDAL this lines can be uncommented
     303             :             // and MM_GDAL_NODATA_COORD_Z can be defined
     304             :             /*if(!DOUBLES_DIFERENTS_DJ(punts_z[k], MM_NODATA_COORD_Z))
     305             :             {
     306             :                 MM_N_VERTICES_TYPE nIVertice;
     307             :                 for(nIVertice=0; nIVertice<pArcHeader[i_elem].nElemCount; nIVertice++)
     308             :                     hMiraMonLayer->ReadFeature.pZCoord[nIVertice]=MM_GDAL_NODATA_COORD_Z;
     309             :             }
     310             :             */
     311             :         }
     312             :     }
     313        1120 :     hMiraMonLayer->ReadFeature.nNumpCoord =
     314        1120 :         pArcHeader[i_elem].nElemCount == 0
     315             :             ? 0
     316        1120 :             : pArcHeader[i_elem].nElemCount - (bAvoidFirst ? 1 : 0);
     317             : 
     318        1120 :     return 0;
     319             : }
     320             : 
     321             : // Reads Polygon coordinates and puts them in a buffer
     322             : static int
     323         340 : MMGetMultiPolygonCoordinates(struct MiraMonVectLayerInfo *hMiraMonLayer,
     324             :                              MM_INTERNAL_FID i_pol, uint32_t flag_z)
     325             : {
     326             :     struct MM_PH *pPolHeader;
     327             :     struct MM_AH *pArcHeader;
     328             :     char *pBuffer;
     329             :     MM_POLYGON_ARCS_COUNT nIndex;
     330             :     MM_BOOLEAN bAvoidFirst;
     331         340 :     MM_N_VERTICES_TYPE nNAcumulVertices = 0;
     332             : 
     333             :     // Checking if the index of the polygon is in the correct range.
     334         340 :     if (i_pol >= hMiraMonLayer->TopHeader.nElemCount)
     335           0 :         return 1;
     336             : 
     337         340 :     MMResetFeatureGeometry(&hMiraMonLayer->ReadFeature);
     338         340 :     MMResetFeatureRecord(&hMiraMonLayer->ReadFeature);
     339         340 :     pPolHeader = hMiraMonLayer->MMPolygon.pPolHeader + i_pol;
     340             : 
     341             :     // It's accepted not having arcs in the universal polygon
     342         340 :     if (!pPolHeader->nArcsCount)
     343             :     {
     344           0 :         if (i_pol == 0)
     345           0 :             return 0;
     346             :         else
     347           0 :             return 1;
     348             :     }
     349             : 
     350         340 :     if (MMResizeMiraMonPolygonArcs(&hMiraMonLayer->pArcs,
     351             :                                    &hMiraMonLayer->nMaxArcs,
     352             :                                    pPolHeader->nArcsCount, 0, 0))
     353           0 :         return 1;
     354             : 
     355         340 :     if (MMInitFlush(&hMiraMonLayer->FlushPAL, hMiraMonLayer->MMPolygon.pF,
     356         340 :                     hMiraMonLayer->MMPolygon.nPALElementSize *
     357         340 :                         pPolHeader->nArcsCount,
     358             :                     &pBuffer, pPolHeader->nOffset, 0))
     359             :     {
     360           0 :         if (pBuffer)
     361           0 :             free_function(pBuffer);
     362           0 :         return 1;
     363             :     }
     364             : 
     365         340 :     hMiraMonLayer->FlushPAL.pBlockWhereToSaveOrRead = (void *)pBuffer;
     366         340 :     if (MMReadFlush(&hMiraMonLayer->FlushPAL))
     367             :     {
     368           6 :         if (pBuffer)
     369           6 :             free_function(pBuffer);
     370           6 :         return 1;
     371             :     }
     372             : 
     373         334 :     hMiraMonLayer->ReadFeature.nNRings = 0;
     374         334 :     hMiraMonLayer->ReadFeature.nNumpCoord = 0;
     375         334 :     if (MMResize_MM_N_VERTICES_TYPE_Pointer(
     376             :             &hMiraMonLayer->ReadFeature.pNCoordRing,
     377             :             &hMiraMonLayer->ReadFeature.nMaxpNCoordRing,
     378         334 :             (MM_N_VERTICES_TYPE)hMiraMonLayer->ReadFeature.nNRings + 1, 10, 10))
     379             :     {
     380           0 :         free_function(pBuffer);
     381           0 :         return 1;
     382             :     }
     383             : 
     384         334 :     if (MMResizeVFGPointer(&hMiraMonLayer->ReadFeature.flag_VFG,
     385             :                            &hMiraMonLayer->ReadFeature.nMaxVFG,
     386         334 :                            (MM_INTERNAL_FID)pPolHeader->nArcsCount, 0,
     387             :                            0))  // Perhaps more memory than needed
     388             :     {
     389           0 :         free_function(pBuffer);
     390           0 :         return 1;
     391             :     }
     392             : 
     393             :     // Preparing memory for all coordinates
     394         334 :     hMiraMonLayer->ReadFeature.pNCoordRing[hMiraMonLayer->ReadFeature.nNRings] =
     395             :         0;
     396        1108 :     for (nIndex = 0; nIndex < pPolHeader->nArcsCount; nIndex++)
     397             :     {
     398         774 :         hMiraMonLayer->FlushPAL.SizeOfBlockToBeSaved =
     399             :             sizeof((hMiraMonLayer->pArcs + nIndex)->VFG);
     400         774 :         hMiraMonLayer->FlushPAL.pBlockToBeSaved =
     401         774 :             (void *)&(hMiraMonLayer->pArcs + nIndex)->VFG;
     402         774 :         if (MMReadBlockFromBuffer(&hMiraMonLayer->FlushPAL))
     403             :         {
     404           0 :             if (pBuffer)
     405           0 :                 free_function(pBuffer);
     406           0 :             return 1;
     407             :         }
     408             : 
     409             :         // Arc index
     410         774 :         if (MMReadGUInt64DependingOnVersion(
     411             :                 hMiraMonLayer, &hMiraMonLayer->FlushPAL,
     412         774 :                 &((hMiraMonLayer->pArcs + nIndex)->nIArc)))
     413             :         {
     414           0 :             if (pBuffer)
     415           0 :                 free_function(pBuffer);
     416           0 :             return 1;
     417             :         }
     418             : 
     419         774 :         if (hMiraMonLayer->MMPolygon.MMArc.pArcHeader == nullptr)
     420             :         {
     421           0 :             if (pBuffer)
     422           0 :                 free_function(pBuffer);
     423           0 :             return 1;
     424             :         }
     425             : 
     426             :         // Checking if the index of the arc is in the correct range.
     427         774 :         if ((hMiraMonLayer->pArcs + nIndex)->nIArc >=
     428         774 :             hMiraMonLayer->MMPolygon.TopArcHeader.nElemCount)
     429             :         {
     430           0 :             free_function(pBuffer);
     431           0 :             return 1;
     432             :         }
     433             : 
     434         774 :         pArcHeader = hMiraMonLayer->MMPolygon.MMArc.pArcHeader +
     435         774 :                      (hMiraMonLayer->pArcs + nIndex)->nIArc;
     436             : 
     437         774 :         if (hMiraMonLayer->ReadFeature
     438         774 :                 .pNCoordRing[hMiraMonLayer->ReadFeature.nNRings] >
     439         774 :             UINT64_MAX - pArcHeader->nElemCount)
     440             :         {
     441           0 :             free_function(pBuffer);
     442           0 :             return 1;
     443             :         }
     444             : 
     445         774 :         if (hMiraMonLayer->ReadFeature
     446         774 :                 .pNCoordRing[hMiraMonLayer->ReadFeature.nNRings] >
     447         774 :             UINT64_MAX - pArcHeader->nElemCount)
     448             :         {
     449           0 :             free_function(pBuffer);
     450           0 :             return 1;
     451             :         }
     452             : 
     453             :         hMiraMonLayer->ReadFeature
     454         774 :             .pNCoordRing[hMiraMonLayer->ReadFeature.nNRings] +=
     455         774 :             pArcHeader->nElemCount;
     456             :     }
     457         334 :     if (MMResizeMM_POINT2DPointer(
     458             :             &hMiraMonLayer->ReadFeature.pCoord,
     459             :             &hMiraMonLayer->ReadFeature.nMaxpCoord,
     460             :             hMiraMonLayer->ReadFeature
     461         334 :                 .pNCoordRing[hMiraMonLayer->ReadFeature.nNRings],
     462             :             0, 0))
     463             :     {
     464           0 :         free_function(pBuffer);
     465           0 :         return 1;
     466             :     }
     467             : 
     468         334 :     hMiraMonLayer->FlushPAL.CurrentOffset = 0;
     469             : 
     470             :     // Real work
     471         334 :     hMiraMonLayer->ReadFeature.pNCoordRing[hMiraMonLayer->ReadFeature.nNRings] =
     472             :         0;
     473        1107 :     for (nIndex = 0; nIndex < pPolHeader->nArcsCount; nIndex++)
     474             :     {
     475         774 :         hMiraMonLayer->FlushPAL.SizeOfBlockToBeSaved =
     476             :             sizeof((hMiraMonLayer->pArcs + nIndex)->VFG);
     477         774 :         hMiraMonLayer->FlushPAL.pBlockToBeSaved =
     478         774 :             (void *)&(hMiraMonLayer->pArcs + nIndex)->VFG;
     479         774 :         if (MMReadBlockFromBuffer(&hMiraMonLayer->FlushPAL))
     480             :         {
     481           0 :             if (pBuffer)
     482           0 :                 free_function(pBuffer);
     483           0 :             return 1;
     484             :         }
     485             : 
     486             :         // Arc index
     487         774 :         if (MMReadGUInt64DependingOnVersion(
     488             :                 hMiraMonLayer, &hMiraMonLayer->FlushPAL,
     489         774 :                 &((hMiraMonLayer->pArcs + nIndex)->nIArc)))
     490             :         {
     491           0 :             if (pBuffer)
     492           0 :                 free_function(pBuffer);
     493           0 :             return 1;
     494             :         }
     495             : 
     496         774 :         bAvoidFirst = FALSE;
     497         774 :         if (hMiraMonLayer->ReadFeature
     498         774 :                 .pNCoordRing[hMiraMonLayer->ReadFeature.nNRings] != 0)
     499         299 :             bAvoidFirst = TRUE;
     500             : 
     501             :         // Add coordinates to hMiraMonLayer->ReadFeature.pCoord
     502         774 :         if (MMAddStringLineCoordinates(hMiraMonLayer,
     503         774 :                                        (hMiraMonLayer->pArcs + nIndex)->nIArc,
     504             :                                        flag_z, nNAcumulVertices, bAvoidFirst,
     505         774 :                                        (hMiraMonLayer->pArcs + nIndex)->VFG))
     506             :         {
     507           1 :             free_function(pBuffer);
     508           1 :             return 1;
     509             :         }
     510             : 
     511         773 :         if (MMResize_MM_N_VERTICES_TYPE_Pointer(
     512             :                 &hMiraMonLayer->ReadFeature.pNCoordRing,
     513             :                 &hMiraMonLayer->ReadFeature.nMaxpNCoordRing,
     514         773 :                 (MM_N_VERTICES_TYPE)hMiraMonLayer->ReadFeature.nNRings + 1, 10,
     515             :                 10))
     516             :         {
     517           0 :             free_function(pBuffer);
     518           0 :             return 1;
     519             :         }
     520             : 
     521         773 :         if (hMiraMonLayer->ReadFeature
     522         773 :                 .pNCoordRing[hMiraMonLayer->ReadFeature.nNRings] >
     523         773 :             UINT64_MAX - hMiraMonLayer->ReadFeature.nNumpCoord)
     524             :         {
     525           0 :             free_function(pBuffer);
     526           0 :             return 1;
     527             :         }
     528             : 
     529             :         hMiraMonLayer->ReadFeature
     530         773 :             .pNCoordRing[hMiraMonLayer->ReadFeature.nNRings] +=
     531         773 :             hMiraMonLayer->ReadFeature.nNumpCoord;
     532         773 :         nNAcumulVertices += hMiraMonLayer->ReadFeature.nNumpCoord;
     533             : 
     534         773 :         if ((hMiraMonLayer->pArcs + nIndex)->VFG & MM_POL_END_RING)
     535             :         {
     536             :             hMiraMonLayer->ReadFeature
     537         474 :                 .flag_VFG[hMiraMonLayer->ReadFeature.nNRings] =
     538         474 :                 (hMiraMonLayer->pArcs + nIndex)->VFG;
     539         474 :             hMiraMonLayer->ReadFeature.nNRings++;
     540             :             hMiraMonLayer->ReadFeature
     541         474 :                 .pNCoordRing[hMiraMonLayer->ReadFeature.nNRings] = 0;
     542             :         }
     543             :     }
     544         333 :     hMiraMonLayer->nNumArcs = pPolHeader->nArcsCount;
     545         333 :     if (pBuffer)
     546         333 :         free_function(pBuffer);
     547             : 
     548         333 :     return 0;
     549             : }
     550             : 
     551             : // Reads the geographical part of a MiraMon layer feature
     552        1709 : int MMGetGeoFeatureFromVector(struct MiraMonVectLayerInfo *hMiraMonLayer,
     553             :                               MM_INTERNAL_FID i_elem)
     554             : {
     555             :     FILE_TYPE *pF;
     556             :     struct MM_ZD *pZDescription;
     557             :     uint32_t flag_z;
     558             :     int num;
     559             :     double cz;
     560             : 
     561        1709 :     if (hMiraMonLayer->nSelectCoordz == MM_SELECT_HIGHEST_COORDZ)
     562           1 :         flag_z = MM_STRING_HIGHEST_ALTITUDE;
     563        1708 :     else if (hMiraMonLayer->nSelectCoordz == MM_SELECT_LOWEST_COORDZ)
     564           1 :         flag_z = MM_STRING_LOWEST_ALTITUDE;
     565             :     else
     566        1707 :         flag_z = 0L;
     567             : 
     568        1709 :     if (hMiraMonLayer->bIsPoint)
     569             :     {
     570        1015 :         pF = hMiraMonLayer->MMPoint.pF;
     571             : 
     572             :         // Getting to the i-th element offset
     573        1015 :         fseek_function(pF,
     574             :                        hMiraMonLayer->nHeaderDiskSize +
     575             :                            sizeof(MM_COORD_TYPE) * 2 * i_elem,
     576             :                        SEEK_SET);
     577             : 
     578             :         // Reading the point
     579        1015 :         if (MMResizeMM_POINT2DPointer(&hMiraMonLayer->ReadFeature.pCoord,
     580             :                                       &hMiraMonLayer->ReadFeature.nMaxpCoord,
     581             :                                       hMiraMonLayer->ReadFeature.nNumpCoord, 1,
     582             :                                       1))
     583           0 :             return 1;
     584             : 
     585        1015 :         if (1 != fread_function(hMiraMonLayer->ReadFeature.pCoord,
     586             :                                 sizeof(MM_COORD_TYPE) * 2, 1, pF))
     587             :         {
     588           5 :             return 1;
     589             :         }
     590             : 
     591        1010 :         hMiraMonLayer->ReadFeature.nNRings = 1;
     592             : 
     593        1010 :         if (MMResize_MM_N_VERTICES_TYPE_Pointer(
     594             :                 &hMiraMonLayer->ReadFeature.pNCoordRing,
     595             :                 &hMiraMonLayer->ReadFeature.nMaxpNCoordRing, 1, 0, 1))
     596           0 :             return 1;
     597             : 
     598        1010 :         hMiraMonLayer->ReadFeature.pNCoordRing[0] = 1;
     599             : 
     600        1010 :         if (hMiraMonLayer->TopHeader.bIs3d)
     601             :         {
     602         874 :             pZDescription =
     603         874 :                 hMiraMonLayer->MMPoint.pZSection.pZDescription + i_elem;
     604         874 :             if (pZDescription->nZCount == INT_MIN)
     605           0 :                 return 1;
     606         874 :             num = MM_ARC_TOTAL_N_HEIGHTS_DISK(pZDescription->nZCount, 1);
     607             : 
     608         874 :             if (MMResizeDoublePointer(&hMiraMonLayer->ReadFeature.pZCoord,
     609             :                                       &hMiraMonLayer->ReadFeature.nMaxpZCoord,
     610             :                                       1, 1, 1))
     611           0 :                 return 1;
     612             : 
     613         874 :             if (num == 0)
     614           0 :                 hMiraMonLayer->ReadFeature.pZCoord[0] = MM_NODATA_COORD_Z;
     615             :             else
     616             :             {
     617         874 :                 if (flag_z == MM_STRING_HIGHEST_ALTITUDE)  // Max z
     618           1 :                     cz = pZDescription->dfBBmaxz;
     619         873 :                 else if (flag_z == MM_STRING_LOWEST_ALTITUDE)  // Min z
     620           1 :                     cz = pZDescription->dfBBminz;
     621             :                 else
     622             :                 {
     623             :                     // Reading the first z coordinate
     624         872 :                     fseek_function(pF, pZDescription->nOffsetZ, SEEK_SET);
     625         872 :                     if ((size_t)1 !=
     626         872 :                         fread_function(
     627             :                             &cz, sizeof(*hMiraMonLayer->ReadFeature.pZCoord), 1,
     628             :                             pF))
     629             :                     {
     630           0 :                         return 1;
     631             :                     }
     632             :                 }
     633             :                 // If there is a value for Z-nodata in GDAL this lines can be uncommented
     634             :                 // and MM_GDAL_NODATA_COORD_Z can be defined
     635             :                 /*if(!DOUBLES_DIFERENTS_DJ(cz, MM_NODATA_COORD_Z))
     636             :                     hMiraMonLayer->ReadFeature.pZCoord[0]=MM_GDAL_NODATA_COORD_Z;
     637             :                 else */
     638         874 :                 hMiraMonLayer->ReadFeature.pZCoord[0] = cz;
     639             :             }
     640             :         }
     641             : 
     642        1010 :         return 0;
     643             :     }
     644             : 
     645             :     // Stringlines
     646         694 :     if (hMiraMonLayer->bIsArc && !hMiraMonLayer->bIsPolygon)
     647             :     {
     648         354 :         if (MMAddStringLineCoordinates(hMiraMonLayer, i_elem, flag_z, 0, FALSE,
     649             :                                        0))
     650           7 :             return 1;
     651             : 
     652         347 :         if (MMResize_MM_N_VERTICES_TYPE_Pointer(
     653             :                 &hMiraMonLayer->ReadFeature.pNCoordRing,
     654             :                 &hMiraMonLayer->ReadFeature.nMaxpNCoordRing, 1, 0, 1))
     655           0 :             return 1;
     656             : 
     657         347 :         hMiraMonLayer->ReadFeature.pNCoordRing[0] =
     658         347 :             hMiraMonLayer->ReadFeature.nNumpCoord;
     659             : 
     660         347 :         return 0;
     661             :     }
     662             : 
     663             :     // Polygons or multipolygons
     664         340 :     if (MMGetMultiPolygonCoordinates(hMiraMonLayer, i_elem, flag_z))
     665           7 :         return 1;
     666             : 
     667         333 :     return 0;
     668             : }
     669             : 
     670             : // Reads the header of a MiraMon DBF
     671             : // Please read the format at this link:
     672             : // https://www.miramon.cat/new_note/usa/notes/DBF_estesa.pdf
     673         160 : int MM_ReadExtendedDBFHeader(struct MiraMonVectLayerInfo *hMiraMonLayer)
     674             : {
     675         160 :     const char *pszRelFile = nullptr;
     676             :     struct MM_DATA_BASE_XP *pMMBDXP;
     677         160 :     const char *szDBFFileName = nullptr;
     678             : 
     679             :     // If read don't read again. It happens when Polygon reads
     680             :     // the database and then in initArc() it's read again.
     681         160 :     if (hMiraMonLayer->pMMBDXP)
     682          44 :         return 0;
     683             : 
     684         116 :     pMMBDXP = hMiraMonLayer->pMMBDXP = calloc_function(sizeof(*pMMBDXP));
     685         116 :     if (!pMMBDXP)
     686           0 :         return 1;
     687             : 
     688         116 :     if (hMiraMonLayer->bIsPoint)
     689             :     {
     690          40 :         hMiraMonLayer->MMPoint.MMAdmDB.pMMBDXP = pMMBDXP;
     691          40 :         szDBFFileName = hMiraMonLayer->MMPoint.MMAdmDB.pszExtDBFLayerName;
     692          40 :         pszRelFile = hMiraMonLayer->MMPoint.pszREL_LayerName;
     693             :     }
     694          76 :     else if (hMiraMonLayer->bIsArc && !hMiraMonLayer->bIsPolygon)
     695             :     {
     696          29 :         hMiraMonLayer->MMArc.MMAdmDB.pMMBDXP = pMMBDXP;
     697          29 :         szDBFFileName = hMiraMonLayer->MMArc.MMAdmDB.pszExtDBFLayerName;
     698          29 :         pszRelFile = hMiraMonLayer->MMArc.pszREL_LayerName;
     699             :     }
     700          47 :     else if (hMiraMonLayer->bIsPolygon)
     701             :     {
     702          47 :         hMiraMonLayer->MMPolygon.MMAdmDB.pMMBDXP = pMMBDXP;
     703          47 :         szDBFFileName = hMiraMonLayer->MMPolygon.MMAdmDB.pszExtDBFLayerName;
     704          47 :         pszRelFile = hMiraMonLayer->MMPolygon.pszREL_LayerName;
     705             :     }
     706             : 
     707         116 :     if (MM_ReadExtendedDBFHeaderFromFile(szDBFFileName, pMMBDXP, pszRelFile))
     708             :     {
     709           1 :         MMCPLError(CE_Failure, CPLE_NotSupported,
     710             :                    "Error reading the format in the DBF file %s.",
     711             :                    szDBFFileName);
     712           1 :         return 1;
     713             :     }
     714             : 
     715         115 :     fclose_and_nullify(&pMMBDXP->pfDataBase);
     716         115 :     return 0;
     717             : }
     718             : 
     719             : #ifdef GDAL_COMPILATION
     720             : CPL_C_END  // Necessary for compiling in GDAL project
     721             : #endif

Generated by: LCOV version 1.14