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