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