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