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
|