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