Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: Implements OGREditableLayer class
5 : * Author: Even Rouault <even.rouault at spatialys.com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2015, Even Rouault <even.rouault at spatialys.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "ogreditablelayer.h"
14 : #include "../mem/ogr_mem.h"
15 :
16 : #include <map>
17 :
18 : //! @cond Doxygen_Suppress
19 :
20 : /************************************************************************/
21 : /* ~IOGREditableLayerSynchronizer() */
22 : /************************************************************************/
23 :
24 371 : IOGREditableLayerSynchronizer::~IOGREditableLayerSynchronizer()
25 : {
26 371 : }
27 :
28 : /************************************************************************/
29 : /* OGREditableLayer() */
30 : /************************************************************************/
31 :
32 371 : OGREditableLayer::OGREditableLayer(
33 : OGRLayer *poDecoratedLayer, bool bTakeOwnershipDecoratedLayer,
34 : IOGREditableLayerSynchronizer *poSynchronizer,
35 371 : bool bTakeOwnershipSynchronizer)
36 : : OGRLayerDecorator(poDecoratedLayer, bTakeOwnershipDecoratedLayer),
37 : m_poSynchronizer(poSynchronizer),
38 : m_bTakeOwnershipSynchronizer(bTakeOwnershipSynchronizer),
39 371 : m_poEditableFeatureDefn(poDecoratedLayer->GetLayerDefn()->Clone()),
40 371 : m_nNextFID(0), m_poMemLayer(new OGRMemLayer("", nullptr, wkbNone)),
41 : m_bStructureModified(false), m_bSupportsCreateGeomField(false),
42 1113 : m_bSupportsCurveGeometries(false)
43 : {
44 371 : m_poEditableFeatureDefn->Reference();
45 :
46 1348 : for (int i = 0; i < m_poEditableFeatureDefn->GetFieldCount(); i++)
47 977 : m_poMemLayer->CreateField(m_poEditableFeatureDefn->GetFieldDefn(i));
48 :
49 549 : for (int i = 0; i < m_poEditableFeatureDefn->GetGeomFieldCount(); i++)
50 356 : m_poMemLayer->CreateGeomField(
51 178 : m_poEditableFeatureDefn->GetGeomFieldDefn(i));
52 :
53 371 : m_oIter = m_oSetCreated.begin();
54 371 : }
55 :
56 : /************************************************************************/
57 : /* ~OGREditableLayer() */
58 : /************************************************************************/
59 :
60 371 : OGREditableLayer::~OGREditableLayer()
61 : {
62 371 : OGREditableLayer::SyncToDisk();
63 :
64 371 : m_poEditableFeatureDefn->Release();
65 371 : delete m_poMemLayer;
66 371 : if (m_bTakeOwnershipSynchronizer)
67 371 : delete m_poSynchronizer;
68 371 : }
69 :
70 : /************************************************************************/
71 : /* SetNextFID() */
72 : /************************************************************************/
73 :
74 3 : void OGREditableLayer::SetNextFID(GIntBig nNextFID)
75 : {
76 3 : m_nNextFID = nNextFID;
77 3 : }
78 :
79 : /************************************************************************/
80 : /* SetSupportsCurveGeometries() */
81 : /************************************************************************/
82 :
83 208 : void OGREditableLayer::SetSupportsCurveGeometries(bool bSupportsCurveGeometries)
84 : {
85 208 : m_bSupportsCurveGeometries = bSupportsCurveGeometries;
86 208 : }
87 :
88 : /************************************************************************/
89 : /* SetSupportsCreateGeomField() */
90 : /************************************************************************/
91 :
92 208 : void OGREditableLayer::SetSupportsCreateGeomField(bool bSupportsCreateGeomField)
93 : {
94 208 : m_bSupportsCreateGeomField = bSupportsCreateGeomField;
95 208 : }
96 :
97 : /************************************************************************/
98 : /* DetectNextFID() */
99 : /************************************************************************/
100 :
101 6 : void OGREditableLayer::DetectNextFID()
102 : {
103 6 : if (m_nNextFID > 0)
104 1 : return;
105 5 : m_nNextFID = 0;
106 5 : m_poDecoratedLayer->ResetReading();
107 5 : OGRFeature *poFeat = nullptr;
108 26 : while ((poFeat = m_poDecoratedLayer->GetNextFeature()) != nullptr)
109 : {
110 21 : if (poFeat->GetFID() > m_nNextFID)
111 20 : m_nNextFID = poFeat->GetFID();
112 21 : delete poFeat;
113 : }
114 5 : m_nNextFID++;
115 : }
116 :
117 : /************************************************************************/
118 : /* GetSrcGeomFieldIndex() */
119 : /************************************************************************/
120 :
121 176 : int OGREditableLayer::GetSrcGeomFieldIndex(int iGeomField)
122 : {
123 347 : if (m_poDecoratedLayer == nullptr || iGeomField < 0 ||
124 171 : iGeomField >= m_poEditableFeatureDefn->GetGeomFieldCount())
125 : {
126 21 : return -1;
127 : }
128 : OGRGeomFieldDefn *poGeomFieldDefn =
129 155 : m_poEditableFeatureDefn->GetGeomFieldDefn(iGeomField);
130 310 : return m_poDecoratedLayer->GetLayerDefn()->GetGeomFieldIndex(
131 155 : poGeomFieldDefn->GetNameRef());
132 : }
133 :
134 : /************************************************************************/
135 : /* ResetReading() */
136 : /************************************************************************/
137 :
138 550 : void OGREditableLayer::ResetReading()
139 : {
140 550 : if (!m_poDecoratedLayer)
141 0 : return;
142 550 : m_poDecoratedLayer->ResetReading();
143 550 : m_oIter = m_oSetCreated.begin();
144 : }
145 :
146 : /************************************************************************/
147 : /* Translate() */
148 : /************************************************************************/
149 :
150 1236 : OGRFeature *OGREditableLayer::Translate(OGRFeatureDefn *poTargetDefn,
151 : OGRFeature *poSrcFeature,
152 : bool bCanStealSrcFeature,
153 : bool bHideDeletedFields)
154 : {
155 1236 : if (poSrcFeature == nullptr)
156 20 : return nullptr;
157 1216 : OGRFeature *poRet = new OGRFeature(poTargetDefn);
158 :
159 1216 : std::map<CPLString, int> oMapTargetFieldNameToIdx;
160 1216 : std::map<CPLString, int> *poMap = &oMapTargetFieldNameToIdx;
161 2031 : if (poTargetDefn == m_poEditableFeatureDefn &&
162 815 : !m_oMapEditableFDefnFieldNameToIdx.empty())
163 : {
164 677 : poMap = &m_oMapEditableFDefnFieldNameToIdx;
165 : }
166 : else
167 : {
168 3448 : for (int iField = 0; iField < poTargetDefn->GetFieldCount(); iField++)
169 : {
170 2909 : oMapTargetFieldNameToIdx[poTargetDefn->GetFieldDefn(iField)
171 2909 : ->GetNameRef()] = iField;
172 : }
173 539 : if (poTargetDefn == m_poEditableFeatureDefn)
174 : {
175 : m_oMapEditableFDefnFieldNameToIdx =
176 138 : std::move(oMapTargetFieldNameToIdx);
177 138 : poMap = &m_oMapEditableFDefnFieldNameToIdx;
178 : }
179 : }
180 :
181 : int *panMap = static_cast<int *>(
182 1216 : CPLMalloc(sizeof(int) * poSrcFeature->GetFieldCount()));
183 10849 : for (int iField = 0; iField < poSrcFeature->GetFieldCount(); iField++)
184 : {
185 : const char *pszFieldName =
186 9633 : poSrcFeature->GetFieldDefnRef(iField)->GetNameRef();
187 16652 : if (bHideDeletedFields &&
188 16652 : m_oSetDeletedFields.find(pszFieldName) != m_oSetDeletedFields.end())
189 : {
190 7 : panMap[iField] = -1;
191 : }
192 : else
193 : {
194 9626 : auto oIter = poMap->find(pszFieldName);
195 9626 : panMap[iField] = (oIter == poMap->end()) ? -1 : oIter->second;
196 : }
197 : }
198 1216 : poRet->SetFieldsFrom(poSrcFeature, panMap, TRUE);
199 1216 : CPLFree(panMap);
200 :
201 2156 : for (int i = 0; i < poTargetDefn->GetGeomFieldCount(); i++)
202 : {
203 940 : OGRGeomFieldDefn *poGeomField = poTargetDefn->GetGeomFieldDefn(i);
204 : int iSrcGeomFieldIdx =
205 940 : poTargetDefn->GetGeomFieldIndex(poGeomField->GetNameRef());
206 940 : if (iSrcGeomFieldIdx >= 0)
207 : {
208 940 : if (bCanStealSrcFeature)
209 : {
210 730 : poRet->SetGeomFieldDirectly(
211 : i, poSrcFeature->StealGeometry(iSrcGeomFieldIdx));
212 : }
213 : else
214 : {
215 210 : poRet->SetGeomField(
216 210 : i, poSrcFeature->GetGeomFieldRef(iSrcGeomFieldIdx));
217 : }
218 940 : OGRGeometry *poGeom = poRet->GetGeomFieldRef(i);
219 940 : if (poGeom != nullptr)
220 870 : poGeom->assignSpatialReference(poGeomField->GetSpatialRef());
221 : }
222 : }
223 1216 : poRet->SetStyleString(poSrcFeature->GetStyleString());
224 1216 : poRet->SetNativeData(poSrcFeature->GetNativeData());
225 1216 : poRet->SetNativeMediaType(poSrcFeature->GetNativeMediaType());
226 1216 : poRet->SetFID(poSrcFeature->GetFID());
227 :
228 1216 : return poRet;
229 : }
230 :
231 : /************************************************************************/
232 : /* GetNextFeature() */
233 : /************************************************************************/
234 :
235 774 : OGRFeature *OGREditableLayer::GetNextFeature()
236 : {
237 774 : if (!m_poDecoratedLayer)
238 0 : return nullptr;
239 : while (true)
240 : {
241 927 : OGRFeature *poSrcFeature = m_poDecoratedLayer->GetNextFeature();
242 927 : bool bHideDeletedFields = true;
243 927 : if (poSrcFeature != nullptr)
244 : {
245 746 : const GIntBig nFID = poSrcFeature->GetFID();
246 746 : if (m_oSetDeleted.find(nFID) != m_oSetDeleted.end())
247 : {
248 6 : delete poSrcFeature;
249 6 : continue;
250 : }
251 1469 : else if (m_oSetCreated.find(nFID) != m_oSetCreated.end() ||
252 1469 : m_oSetEdited.find(nFID) != m_oSetEdited.end())
253 : {
254 48 : delete poSrcFeature;
255 48 : poSrcFeature = m_poMemLayer->GetFeature(nFID);
256 48 : bHideDeletedFields = false;
257 : }
258 : }
259 : else
260 : {
261 181 : if (m_oIter != m_oSetCreated.end())
262 : {
263 17 : poSrcFeature = m_poMemLayer->GetFeature(*m_oIter);
264 17 : bHideDeletedFields = false;
265 17 : ++m_oIter;
266 : }
267 : else
268 : {
269 164 : return nullptr;
270 : }
271 : }
272 757 : OGRFeature *poRet = Translate(m_poEditableFeatureDefn, poSrcFeature,
273 : true, bHideDeletedFields);
274 757 : delete poSrcFeature;
275 :
276 1650 : if ((m_poFilterGeom == nullptr ||
277 1512 : FilterGeometry(poRet->GetGeomFieldRef(m_iGeomFieldFilter))) &&
278 755 : (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poRet)))
279 : {
280 610 : return poRet;
281 : }
282 147 : delete poRet;
283 153 : }
284 : }
285 :
286 : /************************************************************************/
287 : /* SetNextByIndex() */
288 : /************************************************************************/
289 :
290 18 : OGRErr OGREditableLayer::SetNextByIndex(GIntBig nIndex)
291 : {
292 31 : if (m_poDecoratedLayer != nullptr && m_oSetCreated.empty() &&
293 49 : m_oSetDeleted.empty() && m_oSetEdited.empty())
294 : {
295 13 : return m_poDecoratedLayer->SetNextByIndex(nIndex);
296 : }
297 :
298 5 : return OGRLayer::SetNextByIndex(nIndex);
299 : }
300 :
301 : /************************************************************************/
302 : /* GetFeature() */
303 : /************************************************************************/
304 :
305 78 : OGRFeature *OGREditableLayer::GetFeature(GIntBig nFID)
306 : {
307 78 : if (!m_poDecoratedLayer)
308 0 : return nullptr;
309 :
310 78 : OGRFeature *poSrcFeature = nullptr;
311 78 : bool bHideDeletedFields = true;
312 151 : if (m_oSetCreated.find(nFID) != m_oSetCreated.end() ||
313 151 : m_oSetEdited.find(nFID) != m_oSetEdited.end())
314 : {
315 20 : poSrcFeature = m_poMemLayer->GetFeature(nFID);
316 20 : bHideDeletedFields = false;
317 : }
318 58 : else if (m_oSetDeleted.find(nFID) != m_oSetDeleted.end())
319 : {
320 4 : poSrcFeature = nullptr;
321 : }
322 : else
323 : {
324 54 : poSrcFeature = m_poDecoratedLayer->GetFeature(nFID);
325 : }
326 78 : OGRFeature *poRet = Translate(m_poEditableFeatureDefn, poSrcFeature, true,
327 : bHideDeletedFields);
328 78 : delete poSrcFeature;
329 78 : return poRet;
330 : }
331 :
332 : /************************************************************************/
333 : /* ISetFeature() */
334 : /************************************************************************/
335 :
336 27 : OGRErr OGREditableLayer::ISetFeature(OGRFeature *poFeature)
337 : {
338 27 : if (!m_poDecoratedLayer)
339 0 : return OGRERR_FAILURE;
340 :
341 40 : if (!m_bStructureModified && m_oSetDeleted.empty() &&
342 74 : m_oSetEdited.empty() && m_oSetCreated.empty() &&
343 7 : m_poDecoratedLayer->TestCapability(OLCRandomWrite))
344 : {
345 0 : OGRFeature *poTargetFeature = Translate(
346 0 : m_poDecoratedLayer->GetLayerDefn(), poFeature, false, false);
347 0 : OGRErr eErr = m_poDecoratedLayer->SetFeature(poTargetFeature);
348 0 : delete poTargetFeature;
349 0 : return eErr;
350 : }
351 :
352 : OGRFeature *poMemFeature =
353 27 : Translate(m_poMemLayer->GetLayerDefn(), poFeature, false, false);
354 27 : OGRErr eErr = m_poMemLayer->SetFeature(poMemFeature);
355 27 : if (eErr == OGRERR_NONE)
356 : {
357 23 : const GIntBig nFID = poMemFeature->GetFID();
358 23 : m_oSetDeleted.erase(nFID);
359 : // If the feature isn't in the created list, insert it in the edited
360 : // list
361 23 : if (m_oSetCreated.find(nFID) == m_oSetCreated.end())
362 : {
363 21 : m_oSetEdited.insert(nFID);
364 : }
365 23 : poFeature->SetFID(nFID);
366 : }
367 27 : delete poMemFeature;
368 :
369 27 : return eErr;
370 : }
371 :
372 : /************************************************************************/
373 : /* ICreateFeature() */
374 : /************************************************************************/
375 :
376 374 : OGRErr OGREditableLayer::ICreateFeature(OGRFeature *poFeature)
377 : {
378 374 : if (!m_poDecoratedLayer)
379 0 : return OGRERR_FAILURE;
380 :
381 740 : if (!m_bStructureModified && m_oSetDeleted.empty() &&
382 1114 : m_oSetCreated.empty() &&
383 369 : m_poDecoratedLayer->TestCapability(OLCSequentialWrite))
384 : {
385 368 : OGRFeature *poTargetFeature = Translate(
386 368 : m_poDecoratedLayer->GetLayerDefn(), poFeature, false, false);
387 368 : OGRErr eErr = m_poDecoratedLayer->CreateFeature(poTargetFeature);
388 368 : if (poFeature->GetFID() < 0)
389 358 : poFeature->SetFID(poTargetFeature->GetFID());
390 368 : delete poTargetFeature;
391 368 : return eErr;
392 : }
393 :
394 : OGRFeature *poMemFeature =
395 6 : Translate(m_poMemLayer->GetLayerDefn(), poFeature, false, false);
396 6 : DetectNextFID();
397 6 : if (poMemFeature->GetFID() < 0)
398 4 : poMemFeature->SetFID(m_nNextFID++);
399 6 : OGRErr eErr = m_poMemLayer->CreateFeature(poMemFeature);
400 6 : if (eErr == OGRERR_NONE)
401 : {
402 6 : const GIntBig nFID = poMemFeature->GetFID();
403 6 : m_oSetDeleted.erase(nFID);
404 6 : m_oSetEdited.erase(nFID);
405 6 : m_oSetCreated.insert(nFID);
406 6 : poFeature->SetFID(nFID);
407 : }
408 6 : delete poMemFeature;
409 :
410 6 : ResetReading();
411 :
412 6 : return eErr;
413 : }
414 :
415 : /************************************************************************/
416 : /* IUpsertFeature() */
417 : /************************************************************************/
418 :
419 0 : OGRErr OGREditableLayer::IUpsertFeature(OGRFeature *poFeature)
420 : {
421 : auto poFeatureExisting =
422 0 : std::unique_ptr<OGRFeature>(GetFeature(poFeature->GetFID()));
423 0 : if (poFeatureExisting)
424 : {
425 0 : return ISetFeature(poFeature);
426 : }
427 : else
428 : {
429 0 : return ICreateFeature(poFeature);
430 : }
431 : }
432 :
433 : /************************************************************************/
434 : /* IUpdateFeature() */
435 : /************************************************************************/
436 :
437 6 : OGRErr OGREditableLayer::IUpdateFeature(OGRFeature *poFeature,
438 : int nUpdatedFieldsCount,
439 : const int *panUpdatedFieldsIdx,
440 : int nUpdatedGeomFieldsCount,
441 : const int *panUpdatedGeomFieldsIdx,
442 : bool bUpdateStyleString)
443 : {
444 : // Do not use OGRLayerDecorator::IUpdateFeature() which will forward
445 : // to the decorated layer
446 6 : return OGRLayer::IUpdateFeature(
447 : poFeature, nUpdatedFieldsCount, panUpdatedFieldsIdx,
448 6 : nUpdatedGeomFieldsCount, panUpdatedGeomFieldsIdx, bUpdateStyleString);
449 : }
450 :
451 : /************************************************************************/
452 : /* DeleteFeature() */
453 : /************************************************************************/
454 :
455 19 : OGRErr OGREditableLayer::DeleteFeature(GIntBig nFID)
456 : {
457 19 : if (!m_poDecoratedLayer)
458 0 : return OGRERR_FAILURE;
459 :
460 : OGRErr eErr;
461 19 : if (m_oSetDeleted.find(nFID) != m_oSetDeleted.end())
462 : {
463 3 : eErr = OGRERR_NON_EXISTING_FEATURE;
464 : }
465 : // cppcheck-suppress redundantIfRemove
466 16 : else if (m_oSetCreated.find(nFID) != m_oSetCreated.end())
467 : {
468 1 : m_oSetCreated.erase(nFID);
469 1 : eErr = m_poMemLayer->DeleteFeature(nFID);
470 : }
471 : // cppcheck-suppress redundantIfRemove
472 15 : else if (m_oSetEdited.find(nFID) != m_oSetEdited.end())
473 : {
474 1 : m_oSetEdited.erase(nFID);
475 1 : m_oSetDeleted.insert(nFID);
476 1 : eErr = m_poMemLayer->DeleteFeature(nFID);
477 : }
478 : else
479 : {
480 14 : OGRFeature *poFeature = m_poDecoratedLayer->GetFeature(nFID);
481 14 : if (poFeature != nullptr)
482 : {
483 5 : m_oSetDeleted.insert(nFID);
484 5 : eErr = OGRERR_NONE;
485 5 : delete poFeature;
486 : }
487 : else
488 : {
489 9 : eErr = OGRERR_NON_EXISTING_FEATURE;
490 : }
491 : }
492 :
493 19 : ResetReading();
494 :
495 19 : return eErr;
496 : }
497 :
498 : /************************************************************************/
499 : /* GetGeomType() */
500 : /************************************************************************/
501 :
502 244 : OGRwkbGeometryType OGREditableLayer::GetGeomType()
503 : {
504 244 : return OGRLayer::GetGeomType();
505 : }
506 :
507 : /************************************************************************/
508 : /* GetLayerDefn() */
509 : /************************************************************************/
510 :
511 2988 : OGRFeatureDefn *OGREditableLayer::GetLayerDefn()
512 : {
513 2988 : return m_poEditableFeatureDefn;
514 : }
515 :
516 : /************************************************************************/
517 : /* GetSpatialRef() */
518 : /************************************************************************/
519 :
520 73 : OGRSpatialReference *OGREditableLayer::GetSpatialRef()
521 : {
522 73 : return OGRLayer::GetSpatialRef();
523 : }
524 :
525 : /************************************************************************/
526 : /* GetSpatialFilter() */
527 : /************************************************************************/
528 :
529 19 : OGRGeometry *OGREditableLayer::GetSpatialFilter()
530 : {
531 19 : return OGRLayer::GetSpatialFilter();
532 : }
533 :
534 : /************************************************************************/
535 : /* SetAttributeFilter() */
536 : /************************************************************************/
537 :
538 219 : OGRErr OGREditableLayer::SetAttributeFilter(const char *poAttrFilter)
539 : {
540 219 : return OGRLayer::SetAttributeFilter(poAttrFilter);
541 : }
542 :
543 : /************************************************************************/
544 : /* GetArrowStream() */
545 : /************************************************************************/
546 :
547 24 : bool OGREditableLayer::GetArrowStream(struct ArrowArrayStream *out_stream,
548 : CSLConstList papszOptions)
549 : {
550 24 : return OGRLayer::GetArrowStream(out_stream, papszOptions);
551 : }
552 :
553 : /************************************************************************/
554 : /* SetSpatialFilter() */
555 : /************************************************************************/
556 :
557 86 : void OGREditableLayer::SetSpatialFilter(OGRGeometry *poGeom)
558 : {
559 86 : SetSpatialFilter(0, poGeom);
560 86 : }
561 :
562 : /************************************************************************/
563 : /* SetSpatialFilter() */
564 : /************************************************************************/
565 :
566 159 : void OGREditableLayer::SetSpatialFilter(int iGeomField, OGRGeometry *poGeom)
567 : {
568 169 : if (iGeomField < 0 ||
569 10 : (iGeomField != 0 && iGeomField >= GetLayerDefn()->GetGeomFieldCount()))
570 : {
571 10 : CPLError(CE_Failure, CPLE_AppDefined,
572 : "Invalid geometry field index : %d", iGeomField);
573 10 : return;
574 : }
575 :
576 149 : m_iGeomFieldFilter = iGeomField;
577 149 : if (InstallFilter(poGeom))
578 50 : ResetReading();
579 :
580 149 : int iSrcGeomFieldIdx = GetSrcGeomFieldIndex(iGeomField);
581 149 : if (iSrcGeomFieldIdx >= 0)
582 : {
583 137 : m_poDecoratedLayer->SetSpatialFilter(iSrcGeomFieldIdx, poGeom);
584 : }
585 149 : m_poMemLayer->SetSpatialFilter(iGeomField, poGeom);
586 : }
587 :
588 : /************************************************************************/
589 : /* SetSpatialFilterRect() */
590 : /************************************************************************/
591 :
592 1 : void OGREditableLayer::SetSpatialFilterRect(double dfMinX, double dfMinY,
593 : double dfMaxX, double dfMaxY)
594 : {
595 1 : return OGRLayer::SetSpatialFilterRect(dfMinX, dfMinY, dfMaxX, dfMaxY);
596 : }
597 :
598 : /************************************************************************/
599 : /* SetSpatialFilterRect() */
600 : /************************************************************************/
601 :
602 2 : void OGREditableLayer::SetSpatialFilterRect(int iGeomField, double dfMinX,
603 : double dfMinY, double dfMaxX,
604 : double dfMaxY)
605 : {
606 2 : return OGRLayer::SetSpatialFilterRect(iGeomField, dfMinX, dfMinY, dfMaxX,
607 2 : dfMaxY);
608 : }
609 :
610 : /************************************************************************/
611 : /* GetFeatureCount() */
612 : /************************************************************************/
613 :
614 149 : GIntBig OGREditableLayer::GetFeatureCount(int bForce)
615 : {
616 149 : if (!m_poDecoratedLayer)
617 0 : return 0;
618 250 : if (m_poAttrQuery == nullptr && m_poFilterGeom == nullptr &&
619 399 : m_oSetDeleted.empty() && m_oSetEdited.empty())
620 : {
621 114 : GIntBig nFC = m_poDecoratedLayer->GetFeatureCount(bForce);
622 114 : if (nFC >= 0)
623 : {
624 114 : nFC += m_oSetCreated.size();
625 : }
626 114 : return nFC;
627 : }
628 35 : return OGRLayer::GetFeatureCount(bForce);
629 : }
630 :
631 : /************************************************************************/
632 : /* GetExtent() */
633 : /************************************************************************/
634 :
635 6 : OGRErr OGREditableLayer::GetExtent(OGREnvelope *psExtent, int bForce)
636 : {
637 6 : return GetExtent(0, psExtent, bForce);
638 : }
639 :
640 : /************************************************************************/
641 : /* GetExtent() */
642 : /************************************************************************/
643 :
644 27 : OGRErr OGREditableLayer::GetExtent(int iGeomField, OGREnvelope *psExtent,
645 : int bForce)
646 : {
647 27 : if (!m_poDecoratedLayer)
648 0 : return OGRERR_FAILURE;
649 27 : int iSrcGeomFieldIdx = GetSrcGeomFieldIndex(iGeomField);
650 27 : if (iSrcGeomFieldIdx >= 0 && m_oSetEdited.empty() && m_oSetDeleted.empty())
651 : {
652 : OGRErr eErr =
653 18 : m_poDecoratedLayer->GetExtent(iSrcGeomFieldIdx, psExtent, bForce);
654 18 : if (eErr == OGRERR_NONE)
655 : {
656 17 : OGREnvelope sExtentMemLayer;
657 17 : if (m_poMemLayer->GetExtent(iGeomField, &sExtentMemLayer, bForce) ==
658 : OGRERR_NONE)
659 : {
660 1 : psExtent->Merge(sExtentMemLayer);
661 : }
662 : }
663 18 : return eErr;
664 : }
665 9 : return GetExtentInternal(iGeomField, psExtent, bForce);
666 : }
667 :
668 : /************************************************************************/
669 : /* TestCapability() */
670 : /************************************************************************/
671 :
672 690 : int OGREditableLayer::TestCapability(const char *pszCap)
673 : {
674 690 : if (!m_poDecoratedLayer)
675 0 : return FALSE;
676 690 : if (EQUAL(pszCap, OLCSequentialWrite) || EQUAL(pszCap, OLCRandomWrite) ||
677 641 : EQUAL(pszCap, OLCCreateField) || EQUAL(pszCap, OLCDeleteField) ||
678 592 : EQUAL(pszCap, OLCReorderFields) || EQUAL(pszCap, OLCAlterFieldDefn) ||
679 576 : EQUAL(pszCap, OLCAlterGeomFieldDefn) || EQUAL(pszCap, OLCDeleteFeature))
680 : {
681 176 : return m_poDecoratedLayer->TestCapability(OLCCreateField) == TRUE ||
682 176 : m_poDecoratedLayer->TestCapability(OLCSequentialWrite) == TRUE;
683 : }
684 570 : if (EQUAL(pszCap, OLCCreateGeomField))
685 1 : return m_bSupportsCreateGeomField;
686 569 : if (EQUAL(pszCap, OLCCurveGeometries))
687 226 : return m_bSupportsCurveGeometries;
688 343 : if (EQUAL(pszCap, OLCTransactions))
689 8 : return FALSE;
690 :
691 335 : return m_poDecoratedLayer->TestCapability(pszCap);
692 : }
693 :
694 : /************************************************************************/
695 : /* CreateField() */
696 : /************************************************************************/
697 :
698 605 : OGRErr OGREditableLayer::CreateField(const OGRFieldDefn *poField, int bApproxOK)
699 : {
700 605 : if (!m_poDecoratedLayer)
701 0 : return OGRERR_FAILURE;
702 :
703 605 : m_oMapEditableFDefnFieldNameToIdx.clear();
704 :
705 1209 : if (!m_bStructureModified &&
706 604 : m_poDecoratedLayer->TestCapability(OLCCreateField))
707 : {
708 602 : OGRErr eErr = m_poDecoratedLayer->CreateField(poField, bApproxOK);
709 602 : if (eErr == OGRERR_NONE)
710 : {
711 602 : eErr = m_poMemLayer->CreateField(poField, bApproxOK);
712 602 : if (eErr == OGRERR_NONE)
713 : {
714 602 : m_poEditableFeatureDefn->AddFieldDefn(poField);
715 : }
716 : }
717 602 : return eErr;
718 : }
719 :
720 3 : OGRErr eErr = m_poMemLayer->CreateField(poField, bApproxOK);
721 3 : if (eErr == OGRERR_NONE)
722 : {
723 3 : m_poEditableFeatureDefn->AddFieldDefn(poField);
724 3 : m_bStructureModified = true;
725 : }
726 3 : return eErr;
727 : }
728 :
729 : /************************************************************************/
730 : /* DeleteField() */
731 : /************************************************************************/
732 :
733 4 : OGRErr OGREditableLayer::DeleteField(int iField)
734 : {
735 4 : if (!m_poDecoratedLayer)
736 0 : return OGRERR_FAILURE;
737 :
738 4 : m_oMapEditableFDefnFieldNameToIdx.clear();
739 :
740 4 : CPLString osDeletedField;
741 4 : if (iField >= 0 && iField < m_poEditableFeatureDefn->GetFieldCount())
742 : {
743 : osDeletedField =
744 3 : m_poEditableFeatureDefn->GetFieldDefn(iField)->GetNameRef();
745 : }
746 :
747 4 : OGRErr eErr = m_poMemLayer->DeleteField(iField);
748 4 : if (eErr == OGRERR_NONE)
749 : {
750 3 : m_poEditableFeatureDefn->DeleteFieldDefn(iField);
751 3 : m_bStructureModified = true;
752 3 : m_oSetDeletedFields.insert(osDeletedField);
753 : }
754 4 : return eErr;
755 : }
756 :
757 : /************************************************************************/
758 : /* ReorderFields() */
759 : /************************************************************************/
760 :
761 2 : OGRErr OGREditableLayer::ReorderFields(int *panMap)
762 : {
763 2 : if (!m_poDecoratedLayer)
764 0 : return OGRERR_FAILURE;
765 :
766 2 : m_oMapEditableFDefnFieldNameToIdx.clear();
767 :
768 2 : OGRErr eErr = m_poMemLayer->ReorderFields(panMap);
769 2 : if (eErr == OGRERR_NONE)
770 : {
771 1 : m_poEditableFeatureDefn->ReorderFieldDefns(panMap);
772 1 : m_bStructureModified = true;
773 : }
774 2 : return eErr;
775 : }
776 :
777 : /************************************************************************/
778 : /* AlterFieldDefn() */
779 : /************************************************************************/
780 :
781 2 : OGRErr OGREditableLayer::AlterFieldDefn(int iField,
782 : OGRFieldDefn *poNewFieldDefn,
783 : int nFlagsIn)
784 : {
785 2 : if (!m_poDecoratedLayer)
786 0 : return OGRERR_FAILURE;
787 :
788 2 : m_oMapEditableFDefnFieldNameToIdx.clear();
789 :
790 : OGRErr eErr =
791 2 : m_poMemLayer->AlterFieldDefn(iField, poNewFieldDefn, nFlagsIn);
792 2 : if (eErr == OGRERR_NONE)
793 : {
794 : OGRFieldDefn *poFieldDefn =
795 1 : m_poEditableFeatureDefn->GetFieldDefn(iField);
796 : OGRFieldDefn *poMemFieldDefn =
797 1 : m_poMemLayer->GetLayerDefn()->GetFieldDefn(iField);
798 1 : poFieldDefn->SetName(poMemFieldDefn->GetNameRef());
799 1 : poFieldDefn->SetType(poMemFieldDefn->GetType());
800 1 : poFieldDefn->SetSubType(poMemFieldDefn->GetSubType());
801 1 : poFieldDefn->SetWidth(poMemFieldDefn->GetWidth());
802 1 : poFieldDefn->SetPrecision(poMemFieldDefn->GetPrecision());
803 1 : poFieldDefn->SetDefault(poMemFieldDefn->GetDefault());
804 1 : poFieldDefn->SetNullable(poMemFieldDefn->IsNullable());
805 1 : poFieldDefn->SetUnique(poMemFieldDefn->IsUnique());
806 1 : poFieldDefn->SetDomainName(poMemFieldDefn->GetDomainName());
807 1 : poFieldDefn->SetComment(poMemFieldDefn->GetComment());
808 1 : m_bStructureModified = true;
809 : }
810 2 : return eErr;
811 : }
812 :
813 : /************************************************************************/
814 : /* AlterGeomFieldDefn() */
815 : /************************************************************************/
816 :
817 0 : OGRErr OGREditableLayer::AlterGeomFieldDefn(
818 : int iGeomField, const OGRGeomFieldDefn *poNewGeomFieldDefn, int nFlagsIn)
819 : {
820 0 : if (!m_poDecoratedLayer)
821 0 : return OGRERR_FAILURE;
822 :
823 0 : OGRErr eErr = m_poMemLayer->AlterGeomFieldDefn(
824 0 : iGeomField, poNewGeomFieldDefn, nFlagsIn);
825 0 : if (eErr == OGRERR_NONE)
826 : {
827 : OGRGeomFieldDefn *poFieldDefn =
828 0 : m_poEditableFeatureDefn->GetGeomFieldDefn(iGeomField);
829 : OGRGeomFieldDefn *poMemFieldDefn =
830 0 : m_poMemLayer->GetLayerDefn()->GetGeomFieldDefn(iGeomField);
831 0 : poFieldDefn->SetName(poMemFieldDefn->GetNameRef());
832 0 : poFieldDefn->SetType(poMemFieldDefn->GetType());
833 0 : poFieldDefn->SetNullable(poMemFieldDefn->IsNullable());
834 0 : poFieldDefn->SetSpatialRef(poMemFieldDefn->GetSpatialRef());
835 0 : m_bStructureModified = true;
836 : }
837 0 : return eErr;
838 : }
839 :
840 : /************************************************************************/
841 : /* CreateGeomField() */
842 : /************************************************************************/
843 :
844 16 : OGRErr OGREditableLayer::CreateGeomField(const OGRGeomFieldDefn *poField,
845 : int bApproxOK)
846 : {
847 16 : if (!m_poDecoratedLayer || !m_bSupportsCreateGeomField)
848 0 : return OGRERR_FAILURE;
849 :
850 31 : if (!m_bStructureModified &&
851 15 : m_poDecoratedLayer->TestCapability(OLCCreateGeomField))
852 : {
853 15 : OGRErr eErr = m_poDecoratedLayer->CreateGeomField(poField, bApproxOK);
854 15 : if (eErr == OGRERR_NONE)
855 : {
856 14 : eErr = m_poMemLayer->CreateGeomField(poField, bApproxOK);
857 14 : if (eErr == OGRERR_NONE)
858 : {
859 14 : m_poEditableFeatureDefn->AddGeomFieldDefn(poField);
860 : }
861 : }
862 15 : return eErr;
863 : }
864 :
865 1 : OGRErr eErr = m_poMemLayer->CreateGeomField(poField, bApproxOK);
866 1 : if (eErr == OGRERR_NONE)
867 : {
868 1 : m_poEditableFeatureDefn->AddGeomFieldDefn(poField);
869 1 : m_bStructureModified = true;
870 : }
871 1 : return eErr;
872 : }
873 :
874 : /************************************************************************/
875 : /* SyncToDisk() */
876 : /************************************************************************/
877 :
878 569 : OGRErr OGREditableLayer::SyncToDisk()
879 : {
880 569 : if (!m_poDecoratedLayer || m_poSynchronizer == nullptr)
881 0 : return OGRERR_FAILURE;
882 569 : OGRErr eErr = m_poDecoratedLayer->SyncToDisk();
883 569 : if (eErr == OGRERR_NONE)
884 : {
885 1692 : if (m_oSetCreated.empty() && m_oSetEdited.empty() &&
886 1692 : m_oSetDeleted.empty() && !m_bStructureModified)
887 : {
888 556 : return OGRERR_NONE;
889 : }
890 13 : eErr = m_poSynchronizer->EditableSyncToDisk(this, &m_poDecoratedLayer);
891 : }
892 13 : m_oSetCreated.clear();
893 13 : m_oSetEdited.clear();
894 13 : m_oSetDeleted.clear();
895 13 : m_oSetDeletedFields.clear();
896 13 : m_bStructureModified = false;
897 13 : return eErr;
898 : }
899 :
900 : /************************************************************************/
901 : /* StartTransaction() */
902 : /************************************************************************/
903 :
904 36 : OGRErr OGREditableLayer::StartTransaction()
905 :
906 : {
907 36 : return OGRLayer::StartTransaction();
908 : }
909 :
910 : /************************************************************************/
911 : /* CommitTransaction() */
912 : /************************************************************************/
913 :
914 33 : OGRErr OGREditableLayer::CommitTransaction()
915 :
916 : {
917 33 : return OGRLayer::CommitTransaction();
918 : }
919 :
920 : /************************************************************************/
921 : /* RollbackTransaction() */
922 : /************************************************************************/
923 :
924 4 : OGRErr OGREditableLayer::RollbackTransaction()
925 :
926 : {
927 4 : return OGRLayer::RollbackTransaction();
928 : }
929 :
930 : /************************************************************************/
931 : /* GetGeometryColumn() */
932 : /************************************************************************/
933 :
934 9 : const char *OGREditableLayer::GetGeometryColumn()
935 :
936 : {
937 9 : return OGRLayer::GetGeometryColumn();
938 : }
939 :
940 : //! @endcond
|