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