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