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