Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Implements OGRMemLayer class.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2003, Frank Warmerdam <warmerdam@pobox.com>
9 : * Copyright (c) 2009-2013, Even Rouault <even dot rouault at spatialys.com>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #include "cpl_port.h"
15 : #include "ogr_mem.h"
16 :
17 : #include <cstddef>
18 : #include <cstring>
19 : #include <algorithm>
20 : #include <map>
21 : #include <new>
22 : #include <utility>
23 :
24 : #include "cpl_conv.h"
25 : #include "cpl_error.h"
26 : #include "cpl_vsi.h"
27 : #include "ogr_api.h"
28 : #include "ogr_core.h"
29 : #include "ogr_feature.h"
30 : #include "ogr_geometry.h"
31 : #include "ogr_p.h"
32 : #include "ogr_spatialref.h"
33 : #include "ogrsf_frmts.h"
34 :
35 : /************************************************************************/
36 : /* IOGRMemLayerFeatureIterator */
37 : /************************************************************************/
38 :
39 : class IOGRMemLayerFeatureIterator
40 : {
41 : public:
42 428 : virtual ~IOGRMemLayerFeatureIterator()
43 428 : {
44 428 : }
45 :
46 : virtual OGRFeature *Next() = 0;
47 : };
48 :
49 : /************************************************************************/
50 : /* OGRMemLayer() */
51 : /************************************************************************/
52 :
53 3370 : OGRMemLayer::OGRMemLayer(const char *pszName,
54 : const OGRSpatialReference *poSRSIn,
55 3370 : OGRwkbGeometryType eReqType)
56 3370 : : m_poFeatureDefn(new OGRFeatureDefn(pszName))
57 : {
58 3370 : m_poFeatureDefn->Reference();
59 :
60 3370 : SetDescription(m_poFeatureDefn->GetName());
61 3370 : m_poFeatureDefn->SetGeomType(eReqType);
62 :
63 3370 : if (eReqType != wkbNone && poSRSIn != nullptr)
64 : {
65 426 : OGRSpatialReference *poSRS = poSRSIn->Clone();
66 426 : m_poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS);
67 426 : poSRS->Release();
68 : }
69 :
70 3370 : m_oMapFeaturesIter = m_oMapFeatures.begin();
71 3370 : m_poFeatureDefn->Seal(/* bSealFields = */ true);
72 3370 : }
73 :
74 : /************************************************************************/
75 : /* ~OGRMemLayer() */
76 : /************************************************************************/
77 :
78 5575 : OGRMemLayer::~OGRMemLayer()
79 :
80 : {
81 3369 : if (m_nFeaturesRead > 0 && m_poFeatureDefn != nullptr)
82 : {
83 1350 : CPLDebug("Mem", CPL_FRMT_GIB " features read on layer '%s'.",
84 1350 : m_nFeaturesRead, m_poFeatureDefn->GetName());
85 : }
86 :
87 3369 : if (m_papoFeatures != nullptr)
88 : {
89 702163 : for (GIntBig i = 0; i < m_nMaxFeatureCount; i++)
90 : {
91 699990 : if (m_papoFeatures[i] != nullptr)
92 576738 : delete m_papoFeatures[i];
93 : }
94 2173 : CPLFree(m_papoFeatures);
95 : }
96 :
97 3369 : if (m_poFeatureDefn)
98 3369 : m_poFeatureDefn->Release();
99 5575 : }
100 :
101 : /************************************************************************/
102 : /* ResetReading() */
103 : /************************************************************************/
104 :
105 6180 : void OGRMemLayer::ResetReading()
106 :
107 : {
108 6180 : m_iNextReadFID = 0;
109 6180 : m_oMapFeaturesIter = m_oMapFeatures.begin();
110 6180 : }
111 :
112 : /************************************************************************/
113 : /* GetNextFeature() */
114 : /************************************************************************/
115 :
116 50509 : OGRFeature *OGRMemLayer::GetNextFeature()
117 :
118 : {
119 : while (true)
120 : {
121 50509 : OGRFeature *poFeature = nullptr;
122 50509 : if (m_papoFeatures)
123 : {
124 50339 : if (m_iNextReadFID >= m_nMaxFeatureCount)
125 1972 : return nullptr;
126 48367 : poFeature = m_papoFeatures[m_iNextReadFID++];
127 48367 : if (poFeature == nullptr)
128 29633 : continue;
129 : }
130 170 : else if (m_oMapFeaturesIter != m_oMapFeatures.end())
131 : {
132 21 : poFeature = m_oMapFeaturesIter->second.get();
133 21 : ++m_oMapFeaturesIter;
134 : }
135 : else
136 : {
137 149 : break;
138 : }
139 :
140 40640 : if ((m_poFilterGeom == nullptr ||
141 35238 : FilterGeometry(poFeature->GetGeomFieldRef(m_iGeomFieldFilter))) &&
142 16483 : (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
143 : {
144 15517 : m_nFeaturesRead++;
145 15517 : return poFeature->Clone();
146 : }
147 32871 : }
148 :
149 149 : return nullptr;
150 : }
151 :
152 : /************************************************************************/
153 : /* SetNextByIndex() */
154 : /************************************************************************/
155 :
156 358 : OGRErr OGRMemLayer::SetNextByIndex(GIntBig nIndex)
157 :
158 : {
159 358 : if (m_poFilterGeom != nullptr || m_poAttrQuery != nullptr ||
160 357 : m_papoFeatures == nullptr || m_bHasHoles)
161 32 : return OGRLayer::SetNextByIndex(nIndex);
162 :
163 326 : if (nIndex < 0 || nIndex >= m_nMaxFeatureCount)
164 34 : return OGRERR_FAILURE;
165 :
166 292 : m_iNextReadFID = nIndex;
167 :
168 292 : return OGRERR_NONE;
169 : }
170 :
171 : /************************************************************************/
172 : /* GetFeatureRef() */
173 : /************************************************************************/
174 :
175 3877 : OGRFeature *OGRMemLayer::GetFeatureRef(GIntBig nFeatureId)
176 :
177 : {
178 3877 : if (nFeatureId < 0)
179 26 : return nullptr;
180 :
181 3851 : OGRFeature *poFeature = nullptr;
182 3851 : if (m_papoFeatures != nullptr)
183 : {
184 3623 : if (nFeatureId >= m_nMaxFeatureCount)
185 53 : return nullptr;
186 3570 : poFeature = m_papoFeatures[nFeatureId];
187 : }
188 : else
189 : {
190 228 : FeatureIterator oIter = m_oMapFeatures.find(nFeatureId);
191 228 : if (oIter != m_oMapFeatures.end())
192 3 : poFeature = oIter->second.get();
193 : }
194 :
195 3798 : return poFeature;
196 : }
197 :
198 : /************************************************************************/
199 : /* GetFeature() */
200 : /************************************************************************/
201 :
202 3849 : OGRFeature *OGRMemLayer::GetFeature(GIntBig nFeatureId)
203 :
204 : {
205 3849 : const OGRFeature *poFeature = GetFeatureRef(nFeatureId);
206 3849 : return poFeature ? poFeature->Clone() : nullptr;
207 : }
208 :
209 : /************************************************************************/
210 : /* ISetFeature() */
211 : /************************************************************************/
212 :
213 577112 : OGRErr OGRMemLayer::ISetFeature(OGRFeature *poFeature)
214 :
215 : {
216 577112 : if (!m_bUpdatable)
217 0 : return OGRERR_FAILURE;
218 :
219 577112 : if (poFeature == nullptr)
220 0 : return OGRERR_FAILURE;
221 :
222 : // If we don't have a FID, find one available
223 577112 : GIntBig nFID = poFeature->GetFID();
224 577112 : if (nFID == OGRNullFID)
225 : {
226 576219 : if (m_papoFeatures != nullptr)
227 : {
228 574404 : while (m_iNextCreateFID < m_nMaxFeatureCount &&
229 571947 : m_papoFeatures[m_iNextCreateFID] != nullptr)
230 : {
231 1 : m_iNextCreateFID++;
232 : }
233 : }
234 : else
235 : {
236 1816 : FeatureIterator oIter;
237 1816 : while ((oIter = m_oMapFeatures.find(m_iNextCreateFID)) !=
238 3632 : m_oMapFeatures.end())
239 0 : ++m_iNextCreateFID;
240 : }
241 576219 : nFID = m_iNextCreateFID++;
242 576219 : poFeature->SetFID(nFID);
243 : }
244 893 : else if (nFID < OGRNullFID)
245 : {
246 11 : CPLError(CE_Failure, CPLE_NotSupported,
247 : "negative FID are not supported");
248 11 : return OGRERR_FAILURE;
249 : }
250 : else
251 : {
252 882 : if (!m_bHasHoles)
253 : {
254 : // If the feature does not exist, set m_bHasHoles
255 507 : if (m_papoFeatures != nullptr)
256 : {
257 265 : if (nFID >= m_nMaxFeatureCount ||
258 265 : m_papoFeatures[nFID] == nullptr)
259 : {
260 3 : m_bHasHoles = true;
261 : }
262 : }
263 : else
264 : {
265 242 : FeatureIterator oIter = m_oMapFeatures.find(nFID);
266 242 : if (oIter == m_oMapFeatures.end())
267 242 : m_bHasHoles = true;
268 : }
269 : }
270 : }
271 :
272 1154200 : auto poFeatureCloned = std::unique_ptr<OGRFeature>(poFeature->Clone());
273 577101 : if (poFeatureCloned == nullptr)
274 0 : return OGRERR_FAILURE;
275 :
276 577101 : if (m_papoFeatures != nullptr && nFID > 100000 &&
277 106751 : nFID > m_nMaxFeatureCount + 1000)
278 : {
279 : // Convert to map if gap from current max size is too big.
280 : auto poIter =
281 2 : std::unique_ptr<IOGRMemLayerFeatureIterator>(GetIterator());
282 : try
283 : {
284 2 : OGRFeature *poFeatureIter = nullptr;
285 5 : while ((poFeatureIter = poIter->Next()) != nullptr)
286 : {
287 3 : m_oMapFeatures[poFeatureIter->GetFID()] =
288 6 : std::unique_ptr<OGRFeature>(poFeatureIter);
289 : }
290 2 : CPLFree(m_papoFeatures);
291 2 : m_papoFeatures = nullptr;
292 2 : m_nMaxFeatureCount = 0;
293 : }
294 0 : catch (const std::bad_alloc &)
295 : {
296 0 : m_oMapFeatures.clear();
297 0 : m_oMapFeaturesIter = m_oMapFeatures.end();
298 0 : CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate memory");
299 0 : return OGRERR_FAILURE;
300 : }
301 : }
302 :
303 901407 : for (int i = 0; i < m_poFeatureDefn->GetGeomFieldCount(); ++i)
304 : {
305 324306 : OGRGeometry *poGeom = poFeatureCloned->GetGeomFieldRef(i);
306 324306 : if (poGeom != nullptr && poGeom->getSpatialReference() == nullptr)
307 : {
308 2986 : poGeom->assignSpatialReference(
309 2986 : m_poFeatureDefn->GetGeomFieldDefn(i)->GetSpatialRef());
310 : }
311 : }
312 :
313 577101 : if (m_papoFeatures != nullptr || (m_oMapFeatures.empty() && nFID <= 100000))
314 : {
315 577092 : if (nFID >= m_nMaxFeatureCount)
316 : {
317 : const GIntBig nNewCount = std::max(
318 4645 : m_nMaxFeatureCount + m_nMaxFeatureCount / 3 + 10, nFID + 1);
319 4645 : if (static_cast<GIntBig>(static_cast<size_t>(sizeof(OGRFeature *)) *
320 4645 : nNewCount) !=
321 4645 : static_cast<GIntBig>(sizeof(OGRFeature *)) * nNewCount)
322 : {
323 0 : CPLError(CE_Failure, CPLE_OutOfMemory,
324 : "Cannot allocate array of " CPL_FRMT_GIB " elements",
325 : nNewCount);
326 0 : return OGRERR_FAILURE;
327 : }
328 :
329 : OGRFeature **papoNewFeatures =
330 4645 : static_cast<OGRFeature **>(VSI_REALLOC_VERBOSE(
331 : m_papoFeatures,
332 : static_cast<size_t>(sizeof(OGRFeature *) * nNewCount)));
333 4645 : if (papoNewFeatures == nullptr)
334 : {
335 0 : return OGRERR_FAILURE;
336 : }
337 4645 : m_papoFeatures = papoNewFeatures;
338 4645 : memset(m_papoFeatures + m_nMaxFeatureCount, 0,
339 : sizeof(OGRFeature *) *
340 4645 : static_cast<size_t>(nNewCount - m_nMaxFeatureCount));
341 4645 : m_nMaxFeatureCount = nNewCount;
342 : }
343 : #ifdef DEBUG
344 : // Just to please Coverity. Cannot happen.
345 577092 : if (m_papoFeatures == nullptr)
346 : {
347 0 : return OGRERR_FAILURE;
348 : }
349 : #endif
350 :
351 577092 : if (m_papoFeatures[nFID] != nullptr)
352 : {
353 317 : delete m_papoFeatures[nFID];
354 317 : m_papoFeatures[nFID] = nullptr;
355 : }
356 : else
357 : {
358 576775 : ++m_nFeatureCount;
359 : }
360 :
361 577092 : m_papoFeatures[nFID] = poFeatureCloned.release();
362 : }
363 : else
364 : {
365 9 : FeatureIterator oIter = m_oMapFeatures.find(nFID);
366 9 : if (oIter != m_oMapFeatures.end())
367 : {
368 1 : oIter->second = std::move(poFeatureCloned);
369 : }
370 : else
371 : {
372 : try
373 : {
374 8 : m_oMapFeatures[nFID] = std::move(poFeatureCloned);
375 8 : m_oMapFeaturesIter = m_oMapFeatures.end();
376 8 : m_nFeatureCount++;
377 : }
378 0 : catch (const std::bad_alloc &)
379 : {
380 0 : CPLError(CE_Failure, CPLE_OutOfMemory,
381 : "Cannot allocate memory");
382 0 : return OGRERR_FAILURE;
383 : }
384 : }
385 : }
386 :
387 577101 : m_bUpdated = true;
388 :
389 577101 : return OGRERR_NONE;
390 : }
391 :
392 : /************************************************************************/
393 : /* ICreateFeature() */
394 : /************************************************************************/
395 :
396 576404 : OGRErr OGRMemLayer::ICreateFeature(OGRFeature *poFeature)
397 :
398 : {
399 576404 : if (!m_bUpdatable)
400 0 : return OGRERR_FAILURE;
401 :
402 576596 : if (poFeature->GetFID() != OGRNullFID &&
403 192 : poFeature->GetFID() != m_iNextCreateFID)
404 179 : m_bHasHoles = true;
405 :
406 : // If the feature has already a FID and that a feature with the same
407 : // FID is already registered in the layer, then unset our FID.
408 576404 : if (poFeature->GetFID() >= 0)
409 : {
410 191 : if (m_papoFeatures != nullptr)
411 : {
412 100 : if (poFeature->GetFID() < m_nMaxFeatureCount &&
413 46 : m_papoFeatures[poFeature->GetFID()] != nullptr)
414 : {
415 6 : poFeature->SetFID(OGRNullFID);
416 : }
417 : }
418 : else
419 : {
420 137 : FeatureIterator oIter = m_oMapFeatures.find(poFeature->GetFID());
421 137 : if (oIter != m_oMapFeatures.end())
422 1 : poFeature->SetFID(OGRNullFID);
423 : }
424 : }
425 :
426 : // Prevent calling ISetFeature() from derived classes
427 576404 : return OGRMemLayer::ISetFeature(poFeature);
428 : }
429 :
430 : /************************************************************************/
431 : /* UpsertFeature() */
432 : /************************************************************************/
433 :
434 2 : OGRErr OGRMemLayer::IUpsertFeature(OGRFeature *poFeature)
435 :
436 : {
437 2 : if (!TestCapability(OLCUpsertFeature))
438 0 : return OGRERR_FAILURE;
439 :
440 2 : if (GetFeatureRef(poFeature->GetFID()))
441 : {
442 1 : return ISetFeature(poFeature);
443 : }
444 : else
445 : {
446 1 : return ICreateFeature(poFeature);
447 : }
448 : }
449 :
450 : /************************************************************************/
451 : /* UpdateFeature() */
452 : /************************************************************************/
453 :
454 14 : OGRErr OGRMemLayer::IUpdateFeature(OGRFeature *poFeature,
455 : int nUpdatedFieldsCount,
456 : const int *panUpdatedFieldsIdx,
457 : int nUpdatedGeomFieldsCount,
458 : const int *panUpdatedGeomFieldsIdx,
459 : bool bUpdateStyleString)
460 :
461 : {
462 14 : if (!TestCapability(OLCUpdateFeature))
463 0 : return OGRERR_FAILURE;
464 :
465 14 : auto poFeatureRef = GetFeatureRef(poFeature->GetFID());
466 14 : if (!poFeatureRef)
467 2 : return OGRERR_NON_EXISTING_FEATURE;
468 :
469 24 : for (int i = 0; i < nUpdatedFieldsCount; ++i)
470 : {
471 12 : poFeatureRef->SetField(
472 12 : panUpdatedFieldsIdx[i],
473 12 : poFeature->GetRawFieldRef(panUpdatedFieldsIdx[i]));
474 : }
475 12 : for (int i = 0; i < nUpdatedGeomFieldsCount; ++i)
476 : {
477 0 : poFeatureRef->SetGeomFieldDirectly(
478 0 : panUpdatedGeomFieldsIdx[i],
479 0 : poFeature->StealGeometry(panUpdatedGeomFieldsIdx[i]));
480 : }
481 12 : if (bUpdateStyleString)
482 : {
483 0 : poFeatureRef->SetStyleString(poFeature->GetStyleString());
484 : }
485 :
486 12 : m_bUpdated = true;
487 :
488 12 : return OGRERR_NONE;
489 : }
490 :
491 : /************************************************************************/
492 : /* DeleteFeature() */
493 : /************************************************************************/
494 :
495 82 : OGRErr OGRMemLayer::DeleteFeature(GIntBig nFID)
496 :
497 : {
498 82 : if (!m_bUpdatable)
499 32 : return OGRERR_FAILURE;
500 :
501 50 : if (nFID < 0)
502 : {
503 7 : return OGRERR_FAILURE;
504 : }
505 :
506 43 : if (m_papoFeatures != nullptr)
507 : {
508 41 : if (nFID >= m_nMaxFeatureCount || m_papoFeatures[nFID] == nullptr)
509 : {
510 8 : return OGRERR_FAILURE;
511 : }
512 33 : delete m_papoFeatures[nFID];
513 33 : m_papoFeatures[nFID] = nullptr;
514 : }
515 : else
516 : {
517 2 : FeatureIterator oIter = m_oMapFeatures.find(nFID);
518 2 : if (oIter == m_oMapFeatures.end())
519 : {
520 1 : return OGRERR_FAILURE;
521 : }
522 1 : m_oMapFeatures.erase(oIter);
523 : }
524 :
525 34 : m_bHasHoles = true;
526 34 : --m_nFeatureCount;
527 :
528 34 : m_bUpdated = true;
529 :
530 34 : return OGRERR_NONE;
531 : }
532 :
533 : /************************************************************************/
534 : /* GetFeatureCount() */
535 : /* */
536 : /* If a spatial filter is in effect, we turn control over to */
537 : /* the generic counter. Otherwise we return the total count. */
538 : /* Eventually we should consider implementing a more efficient */
539 : /* way of counting features matching a spatial query. */
540 : /************************************************************************/
541 :
542 1542 : GIntBig OGRMemLayer::GetFeatureCount(int bForce)
543 :
544 : {
545 1542 : if (m_poFilterGeom != nullptr || m_poAttrQuery != nullptr)
546 190 : return OGRLayer::GetFeatureCount(bForce);
547 :
548 1352 : return m_nFeatureCount;
549 : }
550 :
551 : /************************************************************************/
552 : /* TestCapability() */
553 : /************************************************************************/
554 :
555 6575 : int OGRMemLayer::TestCapability(const char *pszCap)
556 :
557 : {
558 6575 : if (EQUAL(pszCap, OLCRandomRead))
559 13 : return TRUE;
560 :
561 6562 : else if (EQUAL(pszCap, OLCSequentialWrite) || EQUAL(pszCap, OLCRandomWrite))
562 121 : return m_bUpdatable;
563 :
564 6441 : else if (EQUAL(pszCap, OLCFastFeatureCount))
565 323 : return m_poFilterGeom == nullptr && m_poAttrQuery == nullptr;
566 :
567 6118 : else if (EQUAL(pszCap, OLCFastSpatialFilter))
568 1 : return FALSE;
569 :
570 6117 : else if (EQUAL(pszCap, OLCDeleteFeature) ||
571 6092 : EQUAL(pszCap, OLCUpsertFeature) || EQUAL(pszCap, OLCUpdateFeature))
572 43 : return m_bUpdatable;
573 :
574 6074 : else if (EQUAL(pszCap, OLCCreateField) ||
575 5993 : EQUAL(pszCap, OLCCreateGeomField) ||
576 5992 : EQUAL(pszCap, OLCDeleteField) || EQUAL(pszCap, OLCReorderFields) ||
577 5936 : EQUAL(pszCap, OLCAlterFieldDefn) ||
578 5908 : EQUAL(pszCap, OLCAlterGeomFieldDefn))
579 167 : return m_bUpdatable;
580 :
581 5907 : else if (EQUAL(pszCap, OLCFastSetNextByIndex))
582 3 : return m_poFilterGeom == nullptr && m_poAttrQuery == nullptr &&
583 1 : ((m_papoFeatures != nullptr && !m_bHasHoles) ||
584 2 : m_oMapFeatures.empty());
585 :
586 5905 : else if (EQUAL(pszCap, OLCStringsAsUTF8))
587 994 : return m_bAdvertizeUTF8;
588 :
589 4911 : else if (EQUAL(pszCap, OLCCurveGeometries))
590 2194 : return TRUE;
591 :
592 2717 : else if (EQUAL(pszCap, OLCMeasuredGeometries))
593 2207 : return TRUE;
594 :
595 510 : else if (EQUAL(pszCap, OLCZGeometries))
596 66 : return TRUE;
597 :
598 444 : return FALSE;
599 : }
600 :
601 : /************************************************************************/
602 : /* CreateField() */
603 : /************************************************************************/
604 :
605 11335 : OGRErr OGRMemLayer::CreateField(const OGRFieldDefn *poField,
606 : int /* bApproxOK */)
607 : {
608 11335 : if (!m_bUpdatable)
609 0 : return OGRERR_FAILURE;
610 :
611 : // Simple case, no features exist yet.
612 11335 : if (m_nFeatureCount == 0)
613 : {
614 10974 : whileUnsealing(m_poFeatureDefn)->AddFieldDefn(poField);
615 10974 : return OGRERR_NONE;
616 : }
617 :
618 : // Add field definition and setup remap definition.
619 : {
620 361 : whileUnsealing(m_poFeatureDefn)->AddFieldDefn(poField);
621 : }
622 :
623 : // Remap all the internal features. Hopefully there aren't any
624 : // external features referring to our OGRFeatureDefn!
625 361 : auto poIter = std::unique_ptr<IOGRMemLayerFeatureIterator>(GetIterator());
626 361 : OGRFeature *poFeature = nullptr;
627 936 : while ((poFeature = poIter->Next()) != nullptr)
628 : {
629 575 : poFeature->AppendField();
630 : }
631 :
632 361 : m_bUpdated = true;
633 :
634 361 : return OGRERR_NONE;
635 : }
636 :
637 : /************************************************************************/
638 : /* DeleteField() */
639 : /************************************************************************/
640 :
641 13 : OGRErr OGRMemLayer::DeleteField(int iField)
642 : {
643 13 : if (!m_bUpdatable)
644 0 : return OGRERR_FAILURE;
645 :
646 13 : if (iField < 0 || iField >= m_poFeatureDefn->GetFieldCount())
647 : {
648 3 : CPLError(CE_Failure, CPLE_NotSupported, "Invalid field index");
649 3 : return OGRERR_FAILURE;
650 : }
651 :
652 : // Update all the internal features. Hopefully there aren't any
653 : // external features referring to our OGRFeatureDefn!
654 10 : auto poIter = std::unique_ptr<IOGRMemLayerFeatureIterator>(GetIterator());
655 26 : while (OGRFeature *poFeature = poIter->Next())
656 : {
657 16 : OGRField *poFieldRaw = poFeature->GetRawFieldRef(iField);
658 23 : if (poFeature->IsFieldSetAndNotNull(iField) &&
659 7 : !poFeature->IsFieldNull(iField))
660 : {
661 : // Little trick to unallocate the field.
662 : OGRField sField;
663 7 : OGR_RawField_SetUnset(&sField);
664 7 : poFeature->SetField(iField, &sField);
665 : }
666 :
667 16 : if (iField < m_poFeatureDefn->GetFieldCount() - 1)
668 : {
669 6 : memmove(poFieldRaw, poFieldRaw + 1,
670 : sizeof(OGRField) *
671 6 : (m_poFeatureDefn->GetFieldCount() - 1 - iField));
672 : }
673 16 : }
674 :
675 10 : m_bUpdated = true;
676 :
677 10 : return whileUnsealing(m_poFeatureDefn)->DeleteFieldDefn(iField);
678 : }
679 :
680 : /************************************************************************/
681 : /* ReorderFields() */
682 : /************************************************************************/
683 :
684 17 : OGRErr OGRMemLayer::ReorderFields(int *panMap)
685 : {
686 17 : if (!m_bUpdatable)
687 0 : return OGRERR_FAILURE;
688 :
689 17 : if (m_poFeatureDefn->GetFieldCount() == 0)
690 4 : return OGRERR_NONE;
691 :
692 : const OGRErr eErr =
693 13 : OGRCheckPermutation(panMap, m_poFeatureDefn->GetFieldCount());
694 13 : if (eErr != OGRERR_NONE)
695 2 : return eErr;
696 :
697 : // Remap all the internal features. Hopefully there aren't any
698 : // external features referring to our OGRFeatureDefn!
699 11 : auto poIter = std::unique_ptr<IOGRMemLayerFeatureIterator>(GetIterator());
700 49 : while (OGRFeature *poFeature = poIter->Next())
701 : {
702 38 : poFeature->RemapFields(nullptr, panMap);
703 38 : }
704 :
705 11 : m_bUpdated = true;
706 :
707 11 : return whileUnsealing(m_poFeatureDefn)->ReorderFieldDefns(panMap);
708 : }
709 :
710 : /************************************************************************/
711 : /* AlterFieldDefn() */
712 : /************************************************************************/
713 :
714 64 : OGRErr OGRMemLayer::AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
715 : int nFlagsIn)
716 : {
717 64 : if (!m_bUpdatable)
718 0 : return OGRERR_FAILURE;
719 :
720 64 : if (iField < 0 || iField >= m_poFeatureDefn->GetFieldCount())
721 : {
722 3 : CPLError(CE_Failure, CPLE_NotSupported, "Invalid field index");
723 3 : return OGRERR_FAILURE;
724 : }
725 :
726 61 : OGRFieldDefn *poFieldDefn = m_poFeatureDefn->GetFieldDefn(iField);
727 122 : auto oTemporaryUnsealer(poFieldDefn->GetTemporaryUnsealer());
728 :
729 117 : if ((nFlagsIn & ALTER_TYPE_FLAG) &&
730 56 : (poFieldDefn->GetType() != poNewFieldDefn->GetType() ||
731 3 : poFieldDefn->GetSubType() != poNewFieldDefn->GetSubType()))
732 : {
733 106 : if ((poNewFieldDefn->GetType() == OFTDate ||
734 106 : poNewFieldDefn->GetType() == OFTTime ||
735 159 : poNewFieldDefn->GetType() == OFTDateTime) &&
736 12 : (poFieldDefn->GetType() == OFTDate ||
737 0 : poFieldDefn->GetType() == OFTTime ||
738 0 : poFieldDefn->GetType() == OFTDateTime))
739 : {
740 : // Do nothing on features.
741 : }
742 43 : else if (poNewFieldDefn->GetType() == OFTInteger64 &&
743 2 : poFieldDefn->GetType() == OFTInteger)
744 : {
745 : // Update all the internal features. Hopefully there aren't any
746 : // external features referring to our OGRFeatureDefn!
747 2 : IOGRMemLayerFeatureIterator *poIter = GetIterator();
748 2 : OGRFeature *poFeature = nullptr;
749 4 : while ((poFeature = poIter->Next()) != nullptr)
750 : {
751 2 : OGRField *poFieldRaw = poFeature->GetRawFieldRef(iField);
752 4 : if (poFeature->IsFieldSetAndNotNull(iField) &&
753 2 : !poFeature->IsFieldNull(iField))
754 : {
755 2 : const GIntBig nVal = poFieldRaw->Integer;
756 2 : poFieldRaw->Integer64 = nVal;
757 : }
758 : }
759 2 : delete poIter;
760 : }
761 54 : else if (poNewFieldDefn->GetType() == OFTReal &&
762 15 : poFieldDefn->GetType() == OFTInteger)
763 : {
764 : // Update all the internal features. Hopefully there aren't any
765 : // external features referring to our OGRFeatureDefn!
766 15 : IOGRMemLayerFeatureIterator *poIter = GetIterator();
767 15 : OGRFeature *poFeature = nullptr;
768 30 : while ((poFeature = poIter->Next()) != nullptr)
769 : {
770 15 : OGRField *poFieldRaw = poFeature->GetRawFieldRef(iField);
771 30 : if (poFeature->IsFieldSetAndNotNull(iField) &&
772 15 : !poFeature->IsFieldNull(iField))
773 : {
774 15 : const double dfVal = poFieldRaw->Integer;
775 15 : poFieldRaw->Real = dfVal;
776 : }
777 : }
778 15 : delete poIter;
779 : }
780 24 : else if (poNewFieldDefn->GetType() == OFTReal &&
781 0 : poFieldDefn->GetType() == OFTInteger64)
782 : {
783 : // Update all the internal features. Hopefully there aren't any
784 : // external features referring to our OGRFeatureDefn!
785 0 : IOGRMemLayerFeatureIterator *poIter = GetIterator();
786 0 : OGRFeature *poFeature = nullptr;
787 0 : while ((poFeature = poIter->Next()) != nullptr)
788 : {
789 0 : OGRField *poFieldRaw = poFeature->GetRawFieldRef(iField);
790 0 : if (poFeature->IsFieldSetAndNotNull(iField) &&
791 0 : !poFeature->IsFieldNull(iField))
792 : {
793 0 : const double dfVal =
794 0 : static_cast<double>(poFieldRaw->Integer64);
795 0 : poFieldRaw->Real = dfVal;
796 : }
797 : }
798 0 : delete poIter;
799 : }
800 : else
801 : {
802 24 : if (poFieldDefn->GetType() != OGRUnknownType)
803 : {
804 24 : if (poNewFieldDefn->GetType() != OFTString)
805 : {
806 0 : CPLError(CE_Failure, CPLE_NotSupported,
807 : "Can only convert from OFTInteger to OFTReal, "
808 : "or from anything to OFTString");
809 0 : return OGRERR_FAILURE;
810 : }
811 : }
812 :
813 : // Update all the internal features. Hopefully there aren't any
814 : // external features referring to our OGRFeatureDefn!
815 24 : IOGRMemLayerFeatureIterator *poIter = GetIterator();
816 24 : OGRFeature *poFeature = nullptr;
817 251 : while ((poFeature = poIter->Next()) != nullptr)
818 : {
819 227 : OGRField *poFieldRaw = poFeature->GetRawFieldRef(iField);
820 249 : if (poFeature->IsFieldSetAndNotNull(iField) &&
821 22 : !poFeature->IsFieldNull(iField))
822 : {
823 : char *pszVal =
824 22 : CPLStrdup(poFeature->GetFieldAsString(iField));
825 :
826 : // Little trick to unallocate the field.
827 : OGRField sField;
828 22 : OGR_RawField_SetUnset(&sField);
829 22 : poFeature->SetField(iField, &sField);
830 :
831 22 : poFieldRaw->String = pszVal;
832 : }
833 : }
834 24 : delete poIter;
835 : }
836 :
837 53 : poFieldDefn->SetSubType(OFSTNone);
838 53 : poFieldDefn->SetType(poNewFieldDefn->GetType());
839 53 : poFieldDefn->SetSubType(poNewFieldDefn->GetSubType());
840 : }
841 :
842 61 : if (nFlagsIn & ALTER_NAME_FLAG)
843 7 : poFieldDefn->SetName(poNewFieldDefn->GetNameRef());
844 61 : if (nFlagsIn & ALTER_WIDTH_PRECISION_FLAG)
845 : {
846 9 : poFieldDefn->SetWidth(poNewFieldDefn->GetWidth());
847 9 : poFieldDefn->SetPrecision(poNewFieldDefn->GetPrecision());
848 : }
849 :
850 61 : m_bUpdated = true;
851 :
852 61 : return OGRERR_NONE;
853 : }
854 :
855 : /************************************************************************/
856 : /* AlterGeomFieldDefn() */
857 : /************************************************************************/
858 :
859 7 : OGRErr OGRMemLayer::AlterGeomFieldDefn(
860 : int iGeomField, const OGRGeomFieldDefn *poNewGeomFieldDefn, int nFlagsIn)
861 : {
862 7 : if (!m_bUpdatable)
863 0 : return OGRERR_FAILURE;
864 :
865 7 : if (iGeomField < 0 || iGeomField >= m_poFeatureDefn->GetGeomFieldCount())
866 : {
867 0 : CPLError(CE_Failure, CPLE_NotSupported, "Invalid field index");
868 0 : return OGRERR_FAILURE;
869 : }
870 :
871 7 : auto poFieldDefn = m_poFeatureDefn->GetGeomFieldDefn(iGeomField);
872 14 : auto oTemporaryUnsealer(poFieldDefn->GetTemporaryUnsealer());
873 :
874 7 : if (nFlagsIn & ALTER_GEOM_FIELD_DEFN_NAME_FLAG)
875 5 : poFieldDefn->SetName(poNewGeomFieldDefn->GetNameRef());
876 7 : if (nFlagsIn & ALTER_GEOM_FIELD_DEFN_TYPE_FLAG)
877 : {
878 4 : if (poNewGeomFieldDefn->GetType() == wkbNone)
879 0 : return OGRERR_FAILURE;
880 4 : poFieldDefn->SetType(poNewGeomFieldDefn->GetType());
881 : }
882 7 : if (nFlagsIn & ALTER_GEOM_FIELD_DEFN_NULLABLE_FLAG)
883 4 : poFieldDefn->SetNullable(poNewGeomFieldDefn->IsNullable());
884 :
885 7 : if (nFlagsIn & ALTER_GEOM_FIELD_DEFN_SRS_FLAG)
886 : {
887 4 : OGRSpatialReference *poSRSNew = nullptr;
888 4 : const auto poSRSNewRef = poNewGeomFieldDefn->GetSpatialRef();
889 4 : if (poSRSNewRef)
890 : {
891 3 : poSRSNew = poSRSNewRef->Clone();
892 3 : if ((nFlagsIn & ALTER_GEOM_FIELD_DEFN_SRS_COORD_EPOCH_FLAG) == 0)
893 : {
894 0 : const auto poSRSOld = poFieldDefn->GetSpatialRef();
895 0 : if (poSRSOld)
896 0 : poSRSNew->SetCoordinateEpoch(
897 : poSRSOld->GetCoordinateEpoch());
898 : else
899 0 : poSRSNew->SetCoordinateEpoch(0);
900 : }
901 : }
902 4 : poFieldDefn->SetSpatialRef(poSRSNew);
903 4 : if (poSRSNew)
904 3 : poSRSNew->Release();
905 : }
906 3 : else if (nFlagsIn & ALTER_GEOM_FIELD_DEFN_SRS_COORD_EPOCH_FLAG)
907 : {
908 2 : const auto poSRSOld = poFieldDefn->GetSpatialRef();
909 2 : const auto poSRSNewRef = poNewGeomFieldDefn->GetSpatialRef();
910 2 : if (poSRSOld && poSRSNewRef)
911 : {
912 1 : auto poSRSNew = poSRSOld->Clone();
913 1 : poSRSNew->SetCoordinateEpoch(poSRSNewRef->GetCoordinateEpoch());
914 1 : poFieldDefn->SetSpatialRef(poSRSNew);
915 1 : poSRSNew->Release();
916 : }
917 : }
918 :
919 7 : m_bUpdated = true;
920 :
921 7 : return OGRERR_NONE;
922 : }
923 :
924 : /************************************************************************/
925 : /* CreateGeomField() */
926 : /************************************************************************/
927 :
928 352 : OGRErr OGRMemLayer::CreateGeomField(const OGRGeomFieldDefn *poGeomField,
929 : int /* bApproxOK */)
930 : {
931 352 : if (!m_bUpdatable)
932 0 : return OGRERR_FAILURE;
933 :
934 : // Simple case, no features exist yet.
935 352 : if (m_nFeatureCount == 0)
936 : {
937 349 : whileUnsealing(m_poFeatureDefn)->AddGeomFieldDefn(poGeomField);
938 349 : return OGRERR_NONE;
939 : }
940 :
941 : // Add field definition and setup remap definition.
942 3 : whileUnsealing(m_poFeatureDefn)->AddGeomFieldDefn(poGeomField);
943 :
944 3 : const int nGeomFieldCount = m_poFeatureDefn->GetGeomFieldCount();
945 6 : std::vector<int> anRemap(nGeomFieldCount);
946 9 : for (int i = 0; i < nGeomFieldCount; ++i)
947 : {
948 6 : if (i < nGeomFieldCount - 1)
949 3 : anRemap[i] = i;
950 : else
951 3 : anRemap[i] = -1;
952 : }
953 :
954 : // Remap all the internal features. Hopefully there aren't any
955 : // external features referring to our OGRFeatureDefn!
956 3 : auto poIter = std::unique_ptr<IOGRMemLayerFeatureIterator>(GetIterator());
957 6 : while (OGRFeature *poFeature = poIter->Next())
958 : {
959 3 : poFeature->RemapGeomFields(nullptr, anRemap.data());
960 3 : }
961 :
962 3 : m_bUpdated = true;
963 :
964 3 : return OGRERR_NONE;
965 : }
966 :
967 : /************************************************************************/
968 : /* OGRMemLayerIteratorArray */
969 : /************************************************************************/
970 :
971 : class OGRMemLayerIteratorArray final : public IOGRMemLayerFeatureIterator
972 : {
973 : GIntBig m_iCurIdx = 0;
974 : const GIntBig m_nMaxFeatureCount;
975 : OGRFeature **const m_papoFeatures;
976 :
977 : public:
978 427 : OGRMemLayerIteratorArray(GIntBig nMaxFeatureCount,
979 : OGRFeature **papoFeatures)
980 427 : : m_nMaxFeatureCount(nMaxFeatureCount), m_papoFeatures(papoFeatures)
981 : {
982 427 : }
983 :
984 4871 : virtual OGRFeature *Next() override
985 : {
986 4871 : while (m_iCurIdx < m_nMaxFeatureCount)
987 : {
988 4444 : OGRFeature *poFeature = m_papoFeatures[m_iCurIdx];
989 4444 : ++m_iCurIdx;
990 4444 : if (poFeature != nullptr)
991 878 : return poFeature;
992 : }
993 427 : return nullptr;
994 : }
995 : };
996 :
997 : /************************************************************************/
998 : /* OGRMemLayerIteratorMap */
999 : /************************************************************************/
1000 :
1001 : class OGRMemLayerIteratorMap final : public IOGRMemLayerFeatureIterator
1002 : {
1003 : typedef std::map<GIntBig, std::unique_ptr<OGRFeature>> FeatureMap;
1004 : typedef FeatureMap::iterator FeatureIterator;
1005 :
1006 : const FeatureMap &m_oMapFeatures;
1007 : FeatureIterator m_oIter;
1008 :
1009 : public:
1010 1 : explicit OGRMemLayerIteratorMap(FeatureMap &oMapFeatures)
1011 1 : : m_oMapFeatures(oMapFeatures), m_oIter(oMapFeatures.begin())
1012 : {
1013 1 : }
1014 :
1015 2 : virtual OGRFeature *Next() override
1016 : {
1017 2 : if (m_oIter != m_oMapFeatures.end())
1018 : {
1019 1 : OGRFeature *poFeature = m_oIter->second.get();
1020 1 : ++m_oIter;
1021 1 : return poFeature;
1022 : }
1023 1 : return nullptr;
1024 : }
1025 :
1026 : private:
1027 : CPL_DISALLOW_COPY_ASSIGN(OGRMemLayerIteratorMap)
1028 : };
1029 :
1030 : /************************************************************************/
1031 : /* GetIterator() */
1032 : /************************************************************************/
1033 :
1034 428 : IOGRMemLayerFeatureIterator *OGRMemLayer::GetIterator()
1035 : {
1036 428 : if (m_oMapFeatures.empty())
1037 427 : return new OGRMemLayerIteratorArray(m_nMaxFeatureCount, m_papoFeatures);
1038 :
1039 1 : return new OGRMemLayerIteratorMap(m_oMapFeatures);
1040 : }
|