1 /******************************************************************************
2 *
3 * Project: OpenGIS Simple Features Reference Implementation
4 * Purpose: Implements OGRUnionLayer class
5 * Author: Even Rouault, even dot rouault at spatialys.com
6 *
7 ******************************************************************************
8 * Copyright (c) 2012-2014, Even Rouault <even dot 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 #ifndef DOXYGEN_SKIP
30
31 #include "ogrunionlayer.h"
32 #include "ogrwarpedlayer.h"
33 #include "ogr_p.h"
34
35 CPL_CVSID("$Id: ogrunionlayer.cpp 355b41831cd2685c85d1aabe5b95665a2c6e99b7 2019-06-19 17:07:04 +0200 Even Rouault $")
36
37 /************************************************************************/
38 /* OGRUnionLayerGeomFieldDefn() */
39 /************************************************************************/
40
OGRUnionLayerGeomFieldDefn(const char * pszNameIn,OGRwkbGeometryType eType)41 OGRUnionLayerGeomFieldDefn::OGRUnionLayerGeomFieldDefn(
42 const char* pszNameIn,
43 OGRwkbGeometryType eType) :
44 OGRGeomFieldDefn(pszNameIn, eType)
45 {}
46
47 /************************************************************************/
48 /* OGRUnionLayerGeomFieldDefn() */
49 /************************************************************************/
50
OGRUnionLayerGeomFieldDefn(OGRGeomFieldDefn * poSrc)51 OGRUnionLayerGeomFieldDefn::OGRUnionLayerGeomFieldDefn(
52 OGRGeomFieldDefn* poSrc) :
53 OGRGeomFieldDefn(poSrc->GetNameRef(), poSrc->GetType())
54 {
55 SetSpatialRef(poSrc->GetSpatialRef());
56 }
57
58 /************************************************************************/
59 /* OGRUnionLayerGeomFieldDefn() */
60 /************************************************************************/
61
OGRUnionLayerGeomFieldDefn(OGRUnionLayerGeomFieldDefn * poSrc)62 OGRUnionLayerGeomFieldDefn::OGRUnionLayerGeomFieldDefn(
63 OGRUnionLayerGeomFieldDefn* poSrc) :
64 OGRGeomFieldDefn(poSrc->GetNameRef(), poSrc->GetType()),
65 bGeomTypeSet(poSrc->bGeomTypeSet),
66 bSRSSet(poSrc->bSRSSet)
67 {
68 SetSpatialRef(poSrc->GetSpatialRef());
69 sStaticEnvelope = poSrc->sStaticEnvelope;
70 }
71
72 /************************************************************************/
73 /* ~OGRUnionLayerGeomFieldDefn() */
74 /************************************************************************/
75
~OGRUnionLayerGeomFieldDefn()76 OGRUnionLayerGeomFieldDefn::~OGRUnionLayerGeomFieldDefn() {}
77
78 /************************************************************************/
79 /* OGRUnionLayer() */
80 /************************************************************************/
81
OGRUnionLayer(const char * pszName,int nSrcLayersIn,OGRLayer ** papoSrcLayersIn,int bTakeLayerOwnership)82 OGRUnionLayer::OGRUnionLayer( const char* pszName,
83 int nSrcLayersIn,
84 OGRLayer** papoSrcLayersIn,
85 int bTakeLayerOwnership ) :
86 osName(pszName),
87 nSrcLayers(nSrcLayersIn),
88 papoSrcLayers(papoSrcLayersIn),
89 bHasLayerOwnership(bTakeLayerOwnership),
90 poFeatureDefn(nullptr),
91 nFields(0),
92 papoFields(nullptr),
93 nGeomFields(0),
94 papoGeomFields(nullptr),
95 eFieldStrategy(FIELD_UNION_ALL_LAYERS),
96 bPreserveSrcFID(FALSE),
97 nFeatureCount(-1),
98 iCurLayer(-1),
99 pszAttributeFilter(nullptr),
100 nNextFID(0),
101 panMap(nullptr),
102 papszIgnoredFields(nullptr),
103 bAttrFilterPassThroughValue(-1),
104 pabModifiedLayers(static_cast<int*>(CPLCalloc(sizeof(int), nSrcLayers))),
105 pabCheckIfAutoWrap(static_cast<int*>(CPLCalloc(sizeof(int), nSrcLayers))),
106 poGlobalSRS(nullptr)
107 {
108 CPLAssert(nSrcLayersIn > 0);
109
110 SetDescription( pszName );
111 }
112
113 /************************************************************************/
114 /* ~OGRUnionLayer() */
115 /************************************************************************/
116
~OGRUnionLayer()117 OGRUnionLayer::~OGRUnionLayer()
118 {
119 if( bHasLayerOwnership )
120 {
121 for(int i = 0; i < nSrcLayers; i++)
122 delete papoSrcLayers[i];
123 }
124 CPLFree(papoSrcLayers);
125
126 for(int i = 0; i < nFields; i++)
127 delete papoFields[i];
128 CPLFree(papoFields);
129 for(int i = 0; i < nGeomFields; i++)
130 delete papoGeomFields[i];
131 CPLFree(papoGeomFields);
132
133 CPLFree(pszAttributeFilter);
134 CPLFree(panMap);
135 CSLDestroy(papszIgnoredFields);
136 CPLFree(pabModifiedLayers);
137 CPLFree(pabCheckIfAutoWrap);
138
139 if( poFeatureDefn )
140 poFeatureDefn->Release();
141 if( poGlobalSRS != nullptr )
142 poGlobalSRS->Release();
143 }
144
145 /************************************************************************/
146 /* SetFields() */
147 /************************************************************************/
148
SetFields(FieldUnionStrategy eFieldStrategyIn,int nFieldsIn,OGRFieldDefn ** papoFieldsIn,int nGeomFieldsIn,OGRUnionLayerGeomFieldDefn ** papoGeomFieldsIn)149 void OGRUnionLayer::SetFields(FieldUnionStrategy eFieldStrategyIn,
150 int nFieldsIn,
151 OGRFieldDefn** papoFieldsIn,
152 int nGeomFieldsIn,
153 OGRUnionLayerGeomFieldDefn** papoGeomFieldsIn)
154 {
155 CPLAssert(nFields == 0);
156 CPLAssert(poFeatureDefn == nullptr);
157
158 eFieldStrategy = eFieldStrategyIn;
159 if( nFieldsIn )
160 {
161 nFields = nFieldsIn;
162 papoFields = static_cast<OGRFieldDefn**>(CPLMalloc(nFields * sizeof(OGRFieldDefn*)));
163 for(int i=0;i<nFields;i++)
164 papoFields[i] = new OGRFieldDefn(papoFieldsIn[i]);
165 }
166 nGeomFields = nGeomFieldsIn;
167 if( nGeomFields > 0 )
168 {
169 papoGeomFields = static_cast<OGRUnionLayerGeomFieldDefn** >(CPLMalloc(
170 nGeomFields * sizeof(OGRUnionLayerGeomFieldDefn*)));
171 for(int i=0;i<nGeomFields;i++)
172 papoGeomFields[i] = new OGRUnionLayerGeomFieldDefn(papoGeomFieldsIn[i]);
173 }
174 }
175
176 /************************************************************************/
177 /* SetSourceLayerFieldName() */
178 /************************************************************************/
179
SetSourceLayerFieldName(const char * pszSourceLayerFieldName)180 void OGRUnionLayer::SetSourceLayerFieldName(const char* pszSourceLayerFieldName)
181 {
182 CPLAssert(poFeatureDefn == nullptr);
183
184 CPLAssert(osSourceLayerFieldName.empty());
185 if( pszSourceLayerFieldName != nullptr )
186 osSourceLayerFieldName = pszSourceLayerFieldName;
187 }
188
189 /************************************************************************/
190 /* SetPreserveSrcFID() */
191 /************************************************************************/
192
SetPreserveSrcFID(int bPreserveSrcFIDIn)193 void OGRUnionLayer::SetPreserveSrcFID(int bPreserveSrcFIDIn)
194 {
195 CPLAssert(poFeatureDefn == nullptr);
196
197 bPreserveSrcFID = bPreserveSrcFIDIn;
198 }
199
200 /************************************************************************/
201 /* SetFeatureCount() */
202 /************************************************************************/
203
SetFeatureCount(int nFeatureCountIn)204 void OGRUnionLayer::SetFeatureCount(int nFeatureCountIn)
205 {
206 CPLAssert(poFeatureDefn == nullptr);
207
208 nFeatureCount = nFeatureCountIn;
209 }
210
211 /************************************************************************/
212 /* MergeFieldDefn() */
213 /************************************************************************/
214
MergeFieldDefn(OGRFieldDefn * poFieldDefn,OGRFieldDefn * poSrcFieldDefn)215 static void MergeFieldDefn(OGRFieldDefn* poFieldDefn,
216 OGRFieldDefn* poSrcFieldDefn)
217 {
218 if( poFieldDefn->GetType() != poSrcFieldDefn->GetType() )
219 {
220 if( poSrcFieldDefn->GetType() == OFTReal &&
221 (poFieldDefn->GetType() == OFTInteger ||
222 poFieldDefn->GetType() == OFTInteger64) )
223 poFieldDefn->SetType(OFTReal);
224 if( poFieldDefn->GetType() == OFTReal &&
225 (poSrcFieldDefn->GetType() == OFTInteger ||
226 poSrcFieldDefn->GetType() == OFTInteger64) )
227 poFieldDefn->SetType(OFTReal);
228 else if( poSrcFieldDefn->GetType() == OFTInteger64 &&
229 poFieldDefn->GetType() == OFTInteger)
230 poFieldDefn->SetType(OFTInteger64);
231 else if( poFieldDefn->GetType() == OFTInteger64 &&
232 poSrcFieldDefn->GetType() == OFTInteger)
233 poFieldDefn->SetType(OFTInteger64);
234 else
235 poFieldDefn->SetType(OFTString);
236 }
237
238 if( poFieldDefn->GetWidth() != poSrcFieldDefn->GetWidth() ||
239 poFieldDefn->GetPrecision() != poSrcFieldDefn->GetPrecision() )
240 {
241 poFieldDefn->SetWidth(0);
242 poFieldDefn->SetPrecision(0);
243 }
244 }
245
246 /************************************************************************/
247 /* GetLayerDefn() */
248 /************************************************************************/
249
GetLayerDefn()250 OGRFeatureDefn *OGRUnionLayer::GetLayerDefn()
251 {
252 if( poFeatureDefn != nullptr )
253 return poFeatureDefn;
254
255 poFeatureDefn = new OGRFeatureDefn( osName );
256 poFeatureDefn->Reference();
257 poFeatureDefn->SetGeomType(wkbNone);
258
259 int iCompareFirstIndex = 0;
260 if( !osSourceLayerFieldName.empty() )
261 {
262 OGRFieldDefn oField(osSourceLayerFieldName, OFTString);
263 poFeatureDefn->AddFieldDefn(&oField);
264 iCompareFirstIndex = 1;
265 }
266
267 if( eFieldStrategy == FIELD_SPECIFIED )
268 {
269 for( int i = 0; i < nFields; i++ )
270 poFeatureDefn->AddFieldDefn(papoFields[i]);
271 for( int i = 0; i < nGeomFields; i++ )
272 {
273 poFeatureDefn->AddGeomFieldDefn(
274 new OGRUnionLayerGeomFieldDefn(papoGeomFields[i]), FALSE);
275 OGRUnionLayerGeomFieldDefn* poGeomFieldDefn =
276 cpl::down_cast<OGRUnionLayerGeomFieldDefn*>(poFeatureDefn->GetGeomFieldDefn(i));
277
278 if( poGeomFieldDefn->bGeomTypeSet == FALSE ||
279 poGeomFieldDefn->bSRSSet == FALSE )
280 {
281 for( int iLayer = 0; iLayer < nSrcLayers; iLayer++ )
282 {
283 OGRFeatureDefn* poSrcFeatureDefn =
284 papoSrcLayers[iLayer]->GetLayerDefn();
285 int nIndex =
286 poSrcFeatureDefn->GetGeomFieldIndex(poGeomFieldDefn->GetNameRef());
287 if( nIndex >= 0 )
288 {
289 OGRGeomFieldDefn* poSrcGeomFieldDefn =
290 poSrcFeatureDefn->GetGeomFieldDefn(nIndex);
291 if( poGeomFieldDefn->bGeomTypeSet == FALSE )
292 {
293 poGeomFieldDefn->bGeomTypeSet = TRUE;
294 poGeomFieldDefn->SetType(poSrcGeomFieldDefn->GetType());
295 }
296 if( poGeomFieldDefn->bSRSSet == FALSE )
297 {
298 poGeomFieldDefn->bSRSSet = TRUE;
299 poGeomFieldDefn->SetSpatialRef(poSrcGeomFieldDefn->GetSpatialRef());
300 if( i == 0 && poGlobalSRS == nullptr )
301 {
302 poGlobalSRS = poSrcGeomFieldDefn->GetSpatialRef();
303 if( poGlobalSRS != nullptr )
304 poGlobalSRS->Reference();
305 }
306 }
307 break;
308 }
309 }
310 }
311 }
312 }
313 else if( eFieldStrategy == FIELD_FROM_FIRST_LAYER )
314 {
315 OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn();
316 for( int i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++)
317 poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i));
318 for( int i = 0;
319 nGeomFields != - 1 && i < poSrcFeatureDefn->GetGeomFieldCount();
320 i++ )
321 {
322 OGRGeomFieldDefn* poFldDefn = poSrcFeatureDefn->GetGeomFieldDefn(i);
323 poFeatureDefn->AddGeomFieldDefn(
324 new OGRUnionLayerGeomFieldDefn(poFldDefn), FALSE);
325 }
326 }
327 else if (eFieldStrategy == FIELD_UNION_ALL_LAYERS )
328 {
329 if( nGeomFields == 1 )
330 {
331 poFeatureDefn->AddGeomFieldDefn(
332 new OGRUnionLayerGeomFieldDefn(papoGeomFields[0]), FALSE);
333 }
334
335 for(int iLayer = 0; iLayer < nSrcLayers; iLayer++)
336 {
337 OGRFeatureDefn* poSrcFeatureDefn =
338 papoSrcLayers[iLayer]->GetLayerDefn();
339
340 /* Add any field that is found in the source layers */
341 for( int i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++ )
342 {
343 OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i);
344 int nIndex =
345 poFeatureDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
346 if( nIndex < 0 )
347 poFeatureDefn->AddFieldDefn(poSrcFieldDefn);
348 else
349 {
350 OGRFieldDefn* poFieldDefn =
351 poFeatureDefn->GetFieldDefn(nIndex);
352 MergeFieldDefn(poFieldDefn, poSrcFieldDefn);
353 }
354 }
355
356 for( int i = 0;
357 nGeomFields != - 1 &&
358 i < poSrcFeatureDefn->GetGeomFieldCount();
359 i++)
360 {
361 OGRGeomFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetGeomFieldDefn(i);
362 int nIndex =
363 poFeatureDefn->GetGeomFieldIndex(poSrcFieldDefn->GetNameRef());
364 if( nIndex < 0 )
365 {
366 poFeatureDefn->AddGeomFieldDefn(
367 new OGRUnionLayerGeomFieldDefn(poSrcFieldDefn), FALSE);
368 if( poFeatureDefn->GetGeomFieldCount() == 1 && nGeomFields == 0 &&
369 GetSpatialRef() != nullptr )
370 {
371 OGRUnionLayerGeomFieldDefn* poGeomFieldDefn =
372 cpl::down_cast<OGRUnionLayerGeomFieldDefn*>(poFeatureDefn->GetGeomFieldDefn(0));
373 poGeomFieldDefn->bSRSSet = TRUE;
374 poGeomFieldDefn->SetSpatialRef(GetSpatialRef());
375 }
376 }
377 else
378 {
379 if( nIndex == 0 && nGeomFields == 1 )
380 {
381 OGRUnionLayerGeomFieldDefn* poGeomFieldDefn =
382 cpl::down_cast<OGRUnionLayerGeomFieldDefn*>(poFeatureDefn->GetGeomFieldDefn(0));
383 if( poGeomFieldDefn->bGeomTypeSet == FALSE )
384 {
385 poGeomFieldDefn->bGeomTypeSet = TRUE;
386 poGeomFieldDefn->SetType(poSrcFieldDefn->GetType());
387 }
388 if( poGeomFieldDefn->bSRSSet == FALSE )
389 {
390 poGeomFieldDefn->bSRSSet = TRUE;
391 poGeomFieldDefn->SetSpatialRef(poSrcFieldDefn->GetSpatialRef());
392 }
393 }
394 /* TODO: merge type, SRS, extent ? */
395 }
396 }
397 }
398 }
399 else if (eFieldStrategy == FIELD_INTERSECTION_ALL_LAYERS )
400 {
401 OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn();
402 for( int i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++ )
403 poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i));
404 for( int i = 0; i < poSrcFeatureDefn->GetGeomFieldCount(); i++ )
405 {
406 OGRGeomFieldDefn* poFldDefn = poSrcFeatureDefn->GetGeomFieldDefn(i);
407 poFeatureDefn->AddGeomFieldDefn(
408 new OGRUnionLayerGeomFieldDefn(poFldDefn), FALSE);
409 }
410
411 /* Remove any field that is not found in the source layers */
412 for( int iLayer = 1; iLayer < nSrcLayers; iLayer++ )
413 {
414 OGRFeatureDefn* l_poSrcFeatureDefn =
415 papoSrcLayers[iLayer]->GetLayerDefn();
416 for( int i = iCompareFirstIndex;
417 i < poFeatureDefn->GetFieldCount();
418 // No increment.
419 )
420 {
421 OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(i);
422 int nSrcIndex = l_poSrcFeatureDefn->GetFieldIndex(
423 poFieldDefn->GetNameRef());
424 if( nSrcIndex < 0 )
425 {
426 poFeatureDefn->DeleteFieldDefn(i);
427 }
428 else
429 {
430 OGRFieldDefn* poSrcFieldDefn =
431 l_poSrcFeatureDefn->GetFieldDefn(nSrcIndex);
432 MergeFieldDefn(poFieldDefn, poSrcFieldDefn);
433
434 i++;
435 }
436 }
437 for( int i = 0;
438 i < poFeatureDefn->GetGeomFieldCount();
439 // No increment.
440 )
441 {
442 OGRGeomFieldDefn* poFieldDefn = poFeatureDefn->GetGeomFieldDefn(i);
443 int nSrcIndex = l_poSrcFeatureDefn->GetGeomFieldIndex(
444 poFieldDefn->GetNameRef());
445 if( nSrcIndex < 0 )
446 {
447 poFeatureDefn->DeleteGeomFieldDefn(i);
448 }
449 else
450 {
451 /* TODO: merge type, SRS, extent ? */
452
453 i++;
454 }
455 }
456 }
457 }
458
459 return poFeatureDefn;
460 }
461
462 /************************************************************************/
463 /* GetGeomType() */
464 /************************************************************************/
465
GetGeomType()466 OGRwkbGeometryType OGRUnionLayer::GetGeomType()
467 {
468 if( nGeomFields < 0 )
469 return wkbNone;
470 if( nGeomFields >= 1 && papoGeomFields[0]->bGeomTypeSet )
471 {
472 return papoGeomFields[0]->GetType();
473 }
474
475 return OGRLayer::GetGeomType();
476 }
477
478 /************************************************************************/
479 /* SetSpatialFilterToSourceLayer() */
480 /************************************************************************/
481
SetSpatialFilterToSourceLayer(OGRLayer * poSrcLayer)482 void OGRUnionLayer::SetSpatialFilterToSourceLayer(OGRLayer* poSrcLayer)
483 {
484 if( m_iGeomFieldFilter >= 0 &&
485 m_iGeomFieldFilter < GetLayerDefn()->GetGeomFieldCount() )
486 {
487 int iSrcGeomField = poSrcLayer->GetLayerDefn()->GetGeomFieldIndex(
488 GetLayerDefn()->GetGeomFieldDefn(m_iGeomFieldFilter)->GetNameRef());
489 if( iSrcGeomField >= 0 )
490 {
491 poSrcLayer->SetSpatialFilter(iSrcGeomField, m_poFilterGeom);
492 }
493 else
494 {
495 poSrcLayer->SetSpatialFilter(nullptr);
496 }
497 }
498 else
499 {
500 poSrcLayer->SetSpatialFilter(nullptr);
501 }
502 }
503
504 /************************************************************************/
505 /* ConfigureActiveLayer() */
506 /************************************************************************/
507
ConfigureActiveLayer()508 void OGRUnionLayer::ConfigureActiveLayer()
509 {
510 AutoWarpLayerIfNecessary(iCurLayer);
511 ApplyAttributeFilterToSrcLayer(iCurLayer);
512 SetSpatialFilterToSourceLayer(papoSrcLayers[iCurLayer]);
513 papoSrcLayers[iCurLayer]->ResetReading();
514
515 /* Establish map */
516 GetLayerDefn();
517 OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iCurLayer]->GetLayerDefn();
518 CPLFree(panMap);
519 panMap = static_cast<int*>(CPLMalloc(poSrcFeatureDefn->GetFieldCount() * sizeof(int)));
520 for(int i=0; i < poSrcFeatureDefn->GetFieldCount(); i++)
521 {
522 OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i);
523 if( CSLFindString(papszIgnoredFields,
524 poSrcFieldDefn->GetNameRef() ) == -1 )
525 {
526 panMap[i] =
527 poFeatureDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
528 }
529 else
530 {
531 panMap[i] = -1;
532 }
533 }
534
535 if( papoSrcLayers[iCurLayer]->TestCapability(OLCIgnoreFields) )
536 {
537 char** papszIter = papszIgnoredFields;
538 char** papszFieldsSrc = nullptr;
539 while ( papszIter != nullptr && *papszIter != nullptr )
540 {
541 const char* pszFieldName = *papszIter;
542 if ( EQUAL(pszFieldName, "OGR_GEOMETRY") ||
543 EQUAL(pszFieldName, "OGR_STYLE") ||
544 poSrcFeatureDefn->GetFieldIndex(pszFieldName) >= 0 ||
545 poSrcFeatureDefn->GetGeomFieldIndex(pszFieldName) >= 0 )
546 {
547 papszFieldsSrc = CSLAddString(papszFieldsSrc, pszFieldName);
548 }
549 papszIter++;
550 }
551
552 /* Attribute fields */
553 int* panSrcFieldsUsed = static_cast<int*>(CPLCalloc(sizeof(int),
554 poSrcFeatureDefn->GetFieldCount()));
555 for(int iField = 0;
556 iField < poFeatureDefn->GetFieldCount(); iField++)
557 {
558 OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(iField);
559 int iSrcField =
560 poSrcFeatureDefn->GetFieldIndex(poFieldDefn->GetNameRef());
561 if (iSrcField >= 0)
562 panSrcFieldsUsed[iSrcField] = TRUE;
563 }
564 for(int iSrcField = 0;
565 iSrcField < poSrcFeatureDefn->GetFieldCount(); iSrcField ++)
566 {
567 if( !panSrcFieldsUsed[iSrcField] )
568 {
569 OGRFieldDefn *poSrcDefn =
570 poSrcFeatureDefn->GetFieldDefn( iSrcField );
571 papszFieldsSrc =
572 CSLAddString(papszFieldsSrc, poSrcDefn->GetNameRef());
573 }
574 }
575 CPLFree(panSrcFieldsUsed);
576
577 /* geometry fields now */
578 panSrcFieldsUsed = static_cast<int*>(CPLCalloc(sizeof(int),
579 poSrcFeatureDefn->GetGeomFieldCount()));
580 for(int iField = 0;
581 iField < poFeatureDefn->GetGeomFieldCount(); iField++)
582 {
583 OGRGeomFieldDefn* poFieldDefn = poFeatureDefn->GetGeomFieldDefn(iField);
584 int iSrcField =
585 poSrcFeatureDefn->GetGeomFieldIndex(poFieldDefn->GetNameRef());
586 if (iSrcField >= 0)
587 panSrcFieldsUsed[iSrcField] = TRUE;
588 }
589 for(int iSrcField = 0;
590 iSrcField < poSrcFeatureDefn->GetGeomFieldCount(); iSrcField ++)
591 {
592 if( !panSrcFieldsUsed[iSrcField] )
593 {
594 OGRGeomFieldDefn *poSrcDefn =
595 poSrcFeatureDefn->GetGeomFieldDefn( iSrcField );
596 papszFieldsSrc =
597 CSLAddString(papszFieldsSrc, poSrcDefn->GetNameRef());
598 }
599 }
600 CPLFree(panSrcFieldsUsed);
601
602 papoSrcLayers[iCurLayer]->SetIgnoredFields(
603 const_cast<const char**>(papszFieldsSrc));
604
605 CSLDestroy(papszFieldsSrc);
606 }
607 }
608
609 /************************************************************************/
610 /* ResetReading() */
611 /************************************************************************/
612
ResetReading()613 void OGRUnionLayer::ResetReading()
614 {
615 iCurLayer = 0;
616 ConfigureActiveLayer();
617 nNextFID = 0;
618 }
619
620 /************************************************************************/
621 /* AutoWarpLayerIfNecessary() */
622 /************************************************************************/
623
AutoWarpLayerIfNecessary(int iLayer)624 void OGRUnionLayer::AutoWarpLayerIfNecessary(int iLayer)
625 {
626 if( !pabCheckIfAutoWrap[iLayer] )
627 {
628 pabCheckIfAutoWrap[iLayer] = TRUE;
629
630 for(int i=0; i<GetLayerDefn()->GetGeomFieldCount();i++)
631 {
632 OGRSpatialReference* poSRS = GetLayerDefn()->GetGeomFieldDefn(i)->GetSpatialRef();
633 if( poSRS != nullptr )
634 poSRS->Reference();
635
636 OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iLayer]->GetLayerDefn();
637 int iSrcGeomField = poSrcFeatureDefn->GetGeomFieldIndex(
638 GetLayerDefn()->GetGeomFieldDefn(i)->GetNameRef());
639 if( iSrcGeomField >= 0 )
640 {
641 OGRSpatialReference* poSRS2 =
642 poSrcFeatureDefn->GetGeomFieldDefn(iSrcGeomField)->GetSpatialRef();
643
644 if( (poSRS == nullptr && poSRS2 != nullptr) ||
645 (poSRS != nullptr && poSRS2 == nullptr) )
646 {
647 CPLError(CE_Warning, CPLE_AppDefined,
648 "SRS of geometry field '%s' layer %s not consistent with UnionLayer SRS",
649 GetLayerDefn()->GetGeomFieldDefn(i)->GetNameRef(),
650 papoSrcLayers[iLayer]->GetName());
651 }
652 else if (poSRS != nullptr && poSRS2 != nullptr &&
653 poSRS != poSRS2 && !poSRS->IsSame(poSRS2))
654 {
655 CPLDebug("VRT", "SRS of geometry field '%s' layer %s not consistent with UnionLayer SRS. "
656 "Trying auto warping",
657 GetLayerDefn()->GetGeomFieldDefn(i)->GetNameRef(),
658 papoSrcLayers[iLayer]->GetName());
659 OGRCoordinateTransformation* poCT =
660 OGRCreateCoordinateTransformation( poSRS2, poSRS );
661 OGRCoordinateTransformation* poReversedCT = (poCT != nullptr) ?
662 OGRCreateCoordinateTransformation( poSRS, poSRS2 ) : nullptr;
663 if( poReversedCT != nullptr )
664 papoSrcLayers[iLayer] = new OGRWarpedLayer(
665 papoSrcLayers[iLayer], iSrcGeomField, TRUE, poCT, poReversedCT);
666 else
667 {
668 CPLError(CE_Warning, CPLE_AppDefined,
669 "AutoWarpLayerIfNecessary failed to create "
670 "poCT or poReversedCT.");
671 if ( poCT != nullptr )
672 delete poCT;
673 }
674 }
675 }
676
677 if( poSRS != nullptr )
678 poSRS->Release();
679 }
680 }
681 }
682
683 /************************************************************************/
684 /* GetNextFeature() */
685 /************************************************************************/
686
GetNextFeature()687 OGRFeature *OGRUnionLayer::GetNextFeature()
688 {
689 if( poFeatureDefn == nullptr ) GetLayerDefn();
690 if( iCurLayer < 0 )
691 ResetReading();
692
693 if( iCurLayer == nSrcLayers )
694 return nullptr;
695
696 while( true )
697 {
698 OGRFeature* poSrcFeature = papoSrcLayers[iCurLayer]->GetNextFeature();
699 if( poSrcFeature == nullptr )
700 {
701 iCurLayer ++;
702 if( iCurLayer < nSrcLayers )
703 {
704 ConfigureActiveLayer();
705 continue;
706 }
707 else
708 break;
709 }
710
711 OGRFeature* poFeature = TranslateFromSrcLayer(poSrcFeature);
712 delete poSrcFeature;
713
714 if( (m_poFilterGeom == nullptr ||
715 FilterGeometry( poFeature->GetGeomFieldRef(m_iGeomFieldFilter) ) ) &&
716 (m_poAttrQuery == nullptr ||
717 m_poAttrQuery->Evaluate( poFeature )) )
718 {
719 return poFeature;
720 }
721
722 delete poFeature;
723 }
724 return nullptr;
725 }
726
727 /************************************************************************/
728 /* GetFeature() */
729 /************************************************************************/
730
GetFeature(GIntBig nFeatureId)731 OGRFeature *OGRUnionLayer::GetFeature( GIntBig nFeatureId )
732 {
733 OGRFeature* poFeature = nullptr;
734
735 if( !bPreserveSrcFID )
736 {
737 poFeature = OGRLayer::GetFeature(nFeatureId);
738 }
739 else
740 {
741 int iGeomFieldFilterSave = m_iGeomFieldFilter;
742 OGRGeometry* poGeomSave = m_poFilterGeom;
743 m_poFilterGeom = nullptr;
744 SetSpatialFilter(nullptr);
745
746 for(int i=0;i<nSrcLayers;i++)
747 {
748 iCurLayer = i;
749 ConfigureActiveLayer();
750
751 OGRFeature* poSrcFeature = papoSrcLayers[i]->GetFeature(nFeatureId);
752 if( poSrcFeature != nullptr )
753 {
754 poFeature = TranslateFromSrcLayer(poSrcFeature);
755 delete poSrcFeature;
756
757 break;
758 }
759 }
760
761 SetSpatialFilter(iGeomFieldFilterSave, poGeomSave);
762 delete poGeomSave;
763
764 ResetReading();
765 }
766
767 return poFeature;
768 }
769
770 /************************************************************************/
771 /* ICreateFeature() */
772 /************************************************************************/
773
ICreateFeature(OGRFeature * poFeature)774 OGRErr OGRUnionLayer::ICreateFeature( OGRFeature* poFeature )
775 {
776 if( osSourceLayerFieldName.empty() )
777 {
778 CPLError(CE_Failure, CPLE_NotSupported,
779 "CreateFeature() not supported when SourceLayerFieldName is not set");
780 return OGRERR_FAILURE;
781 }
782
783 if( poFeature->GetFID() != OGRNullFID )
784 {
785 CPLError(CE_Failure, CPLE_NotSupported,
786 "CreateFeature() not supported when FID is set");
787 return OGRERR_FAILURE;
788 }
789
790 if( !poFeature->IsFieldSetAndNotNull(0) )
791 {
792 CPLError(CE_Failure, CPLE_NotSupported,
793 "CreateFeature() not supported when '%s' field is not set",
794 osSourceLayerFieldName.c_str());
795 return OGRERR_FAILURE;
796 }
797
798 const char* pszSrcLayerName = poFeature->GetFieldAsString(0);
799 for(int i=0;i<nSrcLayers;i++)
800 {
801 if( strcmp(pszSrcLayerName, papoSrcLayers[i]->GetName()) == 0)
802 {
803 pabModifiedLayers[i] = TRUE;
804
805 OGRFeature* poSrcFeature =
806 new OGRFeature(papoSrcLayers[i]->GetLayerDefn());
807 poSrcFeature->SetFrom(poFeature, TRUE);
808 OGRErr eErr = papoSrcLayers[i]->CreateFeature(poSrcFeature);
809 if( eErr == OGRERR_NONE )
810 poFeature->SetFID(poSrcFeature->GetFID());
811 delete poSrcFeature;
812 return eErr;
813 }
814 }
815
816 CPLError(CE_Failure, CPLE_NotSupported,
817 "CreateFeature() not supported : '%s' source layer does not exist",
818 pszSrcLayerName);
819 return OGRERR_FAILURE;
820 }
821
822 /************************************************************************/
823 /* ISetFeature() */
824 /************************************************************************/
825
ISetFeature(OGRFeature * poFeature)826 OGRErr OGRUnionLayer::ISetFeature( OGRFeature* poFeature )
827 {
828 if( !bPreserveSrcFID )
829 {
830 CPLError(CE_Failure, CPLE_NotSupported,
831 "SetFeature() not supported when PreserveSrcFID is OFF");
832 return OGRERR_FAILURE;
833 }
834
835 if( osSourceLayerFieldName.empty() )
836 {
837 CPLError(CE_Failure, CPLE_NotSupported,
838 "SetFeature() not supported when SourceLayerFieldName is not set");
839 return OGRERR_FAILURE;
840 }
841
842 if( poFeature->GetFID() == OGRNullFID )
843 {
844 CPLError(CE_Failure, CPLE_NotSupported,
845 "SetFeature() not supported when FID is not set");
846 return OGRERR_FAILURE;
847 }
848
849 if( !poFeature->IsFieldSetAndNotNull(0) )
850 {
851 CPLError(CE_Failure, CPLE_NotSupported,
852 "SetFeature() not supported when '%s' field is not set",
853 osSourceLayerFieldName.c_str());
854 return OGRERR_FAILURE;
855 }
856
857 const char* pszSrcLayerName = poFeature->GetFieldAsString(0);
858 for(int i=0;i<nSrcLayers;i++)
859 {
860 if( strcmp(pszSrcLayerName, papoSrcLayers[i]->GetName()) == 0)
861 {
862 pabModifiedLayers[i] = TRUE;
863
864 OGRFeature* poSrcFeature =
865 new OGRFeature(papoSrcLayers[i]->GetLayerDefn());
866 poSrcFeature->SetFrom(poFeature, TRUE);
867 poSrcFeature->SetFID(poFeature->GetFID());
868 OGRErr eErr = papoSrcLayers[i]->SetFeature(poSrcFeature);
869 delete poSrcFeature;
870 return eErr;
871 }
872 }
873
874 CPLError(CE_Failure, CPLE_NotSupported,
875 "SetFeature() not supported : '%s' source layer does not exist",
876 pszSrcLayerName);
877 return OGRERR_FAILURE;
878 }
879
880 /************************************************************************/
881 /* GetSpatialRef() */
882 /************************************************************************/
883
GetSpatialRef()884 OGRSpatialReference *OGRUnionLayer::GetSpatialRef()
885 {
886 if( nGeomFields < 0 )
887 return nullptr;
888 if( nGeomFields >= 1 &&
889 papoGeomFields[0]->bSRSSet )
890 return papoGeomFields[0]->GetSpatialRef();
891
892 if( poGlobalSRS == nullptr )
893 {
894 poGlobalSRS = papoSrcLayers[0]->GetSpatialRef();
895 if( poGlobalSRS != nullptr )
896 poGlobalSRS->Reference();
897 }
898 return poGlobalSRS;
899 }
900
901 /************************************************************************/
902 /* GetAttrFilterPassThroughValue() */
903 /************************************************************************/
904
GetAttrFilterPassThroughValue()905 int OGRUnionLayer::GetAttrFilterPassThroughValue()
906 {
907 if( m_poAttrQuery == nullptr )
908 return TRUE;
909
910 if( bAttrFilterPassThroughValue >= 0)
911 return bAttrFilterPassThroughValue;
912
913 char** papszUsedFields = m_poAttrQuery->GetUsedFields();
914 int bRet = TRUE;
915
916 for(int iLayer = 0; iLayer < nSrcLayers; iLayer++)
917 {
918 OGRFeatureDefn* poSrcFeatureDefn =
919 papoSrcLayers[iLayer]->GetLayerDefn();
920 char** papszIter = papszUsedFields;
921 while( papszIter != nullptr && *papszIter != nullptr )
922 {
923 int bIsSpecial = FALSE;
924 for(int i = 0; i < SPECIAL_FIELD_COUNT; i++)
925 {
926 if( EQUAL(*papszIter, SpecialFieldNames[i]) )
927 {
928 bIsSpecial = TRUE;
929 break;
930 }
931 }
932 if( !bIsSpecial &&
933 poSrcFeatureDefn->GetFieldIndex(*papszIter) < 0 )
934 {
935 bRet = FALSE;
936 break;
937 }
938 papszIter ++;
939 }
940 }
941
942 CSLDestroy(papszUsedFields);
943
944 bAttrFilterPassThroughValue = bRet;
945
946 return bRet;
947 }
948
949 /************************************************************************/
950 /* ApplyAttributeFilterToSrcLayer() */
951 /************************************************************************/
952
ApplyAttributeFilterToSrcLayer(int iSubLayer)953 void OGRUnionLayer::ApplyAttributeFilterToSrcLayer(int iSubLayer)
954 {
955 CPLAssert(iSubLayer >= 0 && iSubLayer < nSrcLayers);
956
957 if( GetAttrFilterPassThroughValue() )
958 papoSrcLayers[iSubLayer]->SetAttributeFilter(pszAttributeFilter);
959 else
960 papoSrcLayers[iSubLayer]->SetAttributeFilter(nullptr);
961 }
962
963 /************************************************************************/
964 /* GetFeatureCount() */
965 /************************************************************************/
966
GetFeatureCount(int bForce)967 GIntBig OGRUnionLayer::GetFeatureCount( int bForce )
968 {
969 if (nFeatureCount >= 0 &&
970 m_poFilterGeom == nullptr && m_poAttrQuery == nullptr)
971 {
972 return nFeatureCount;
973 }
974
975 if( !GetAttrFilterPassThroughValue() )
976 return OGRLayer::GetFeatureCount(bForce);
977
978 GIntBig nRet = 0;
979 for(int i = 0; i < nSrcLayers; i++)
980 {
981 AutoWarpLayerIfNecessary(i);
982 ApplyAttributeFilterToSrcLayer(i);
983 SetSpatialFilterToSourceLayer(papoSrcLayers[i]);
984 nRet += papoSrcLayers[i]->GetFeatureCount(bForce);
985 }
986 ResetReading();
987 return nRet;
988 }
989
990 /************************************************************************/
991 /* SetAttributeFilter() */
992 /************************************************************************/
993
SetAttributeFilter(const char * pszAttributeFilterIn)994 OGRErr OGRUnionLayer::SetAttributeFilter( const char * pszAttributeFilterIn )
995 {
996 if( pszAttributeFilterIn == nullptr && pszAttributeFilter == nullptr)
997 return OGRERR_NONE;
998 if( pszAttributeFilterIn != nullptr && pszAttributeFilter != nullptr &&
999 strcmp(pszAttributeFilterIn, pszAttributeFilter) == 0)
1000 return OGRERR_NONE;
1001
1002 if( poFeatureDefn == nullptr ) GetLayerDefn();
1003
1004 bAttrFilterPassThroughValue = -1;
1005
1006 OGRErr eErr = OGRLayer::SetAttributeFilter(pszAttributeFilterIn);
1007 if( eErr != OGRERR_NONE )
1008 return eErr;
1009
1010 CPLFree(pszAttributeFilter);
1011 pszAttributeFilter = pszAttributeFilterIn ?
1012 CPLStrdup(pszAttributeFilterIn) : nullptr;
1013
1014 if( iCurLayer >= 0 && iCurLayer < nSrcLayers)
1015 ApplyAttributeFilterToSrcLayer(iCurLayer);
1016
1017 return OGRERR_NONE;
1018 }
1019
1020 /************************************************************************/
1021 /* TestCapability() */
1022 /************************************************************************/
1023
TestCapability(const char * pszCap)1024 int OGRUnionLayer::TestCapability( const char * pszCap )
1025 {
1026 if( EQUAL(pszCap, OLCFastFeatureCount ) )
1027 {
1028 if( nFeatureCount >= 0 &&
1029 m_poFilterGeom == nullptr && m_poAttrQuery == nullptr )
1030 return TRUE;
1031
1032 if( !GetAttrFilterPassThroughValue() )
1033 return FALSE;
1034
1035 for(int i = 0; i < nSrcLayers; i++)
1036 {
1037 AutoWarpLayerIfNecessary(i);
1038 ApplyAttributeFilterToSrcLayer(i);
1039 SetSpatialFilterToSourceLayer(papoSrcLayers[i]);
1040 if( !papoSrcLayers[i]->TestCapability(pszCap) )
1041 return FALSE;
1042 }
1043 return TRUE;
1044 }
1045
1046 if( EQUAL(pszCap, OLCFastGetExtent ) )
1047 {
1048 if( nGeomFields >= 1 &&
1049 papoGeomFields[0]->sStaticEnvelope.IsInit() )
1050 return TRUE;
1051
1052 for(int i = 0; i < nSrcLayers; i++)
1053 {
1054 AutoWarpLayerIfNecessary(i);
1055 if( !papoSrcLayers[i]->TestCapability(pszCap) )
1056 return FALSE;
1057 }
1058 return TRUE;
1059 }
1060
1061 if( EQUAL(pszCap, OLCFastSpatialFilter) )
1062 {
1063 for(int i = 0; i < nSrcLayers; i++)
1064 {
1065 AutoWarpLayerIfNecessary(i);
1066 ApplyAttributeFilterToSrcLayer(i);
1067 if( !papoSrcLayers[i]->TestCapability(pszCap) )
1068 return FALSE;
1069 }
1070 return TRUE;
1071 }
1072
1073 if( EQUAL(pszCap, OLCStringsAsUTF8) )
1074 {
1075 for(int i = 0; i < nSrcLayers; i++)
1076 {
1077 if( !papoSrcLayers[i]->TestCapability(pszCap) )
1078 return FALSE;
1079 }
1080 return TRUE;
1081 }
1082
1083 if( EQUAL(pszCap, OLCRandomRead ) )
1084 {
1085 if( !bPreserveSrcFID )
1086 return FALSE;
1087
1088 for(int i = 0; i < nSrcLayers; i++)
1089 {
1090 if( !papoSrcLayers[i]->TestCapability(pszCap) )
1091 return FALSE;
1092 }
1093 return TRUE;
1094 }
1095
1096 if( EQUAL(pszCap, OLCRandomWrite ) )
1097 {
1098 if( !bPreserveSrcFID || osSourceLayerFieldName.empty())
1099 return FALSE;
1100
1101 for(int i = 0; i < nSrcLayers; i++)
1102 {
1103 if( !papoSrcLayers[i]->TestCapability(pszCap) )
1104 return FALSE;
1105 }
1106 return TRUE;
1107 }
1108
1109 if( EQUAL(pszCap, OLCSequentialWrite ) )
1110 {
1111 if( osSourceLayerFieldName.empty())
1112 return FALSE;
1113
1114 for(int i = 0; i < nSrcLayers; i++)
1115 {
1116 if( !papoSrcLayers[i]->TestCapability(pszCap) )
1117 return FALSE;
1118 }
1119 return TRUE;
1120 }
1121
1122 if( EQUAL(pszCap, OLCIgnoreFields) )
1123 return TRUE;
1124
1125 if( EQUAL(pszCap,OLCCurveGeometries) )
1126 return TRUE;
1127
1128 return FALSE;
1129 }
1130
1131 /************************************************************************/
1132 /* GetExtent() */
1133 /************************************************************************/
1134
GetExtent(int iGeomField,OGREnvelope * psExtent,int bForce)1135 OGRErr OGRUnionLayer::GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce)
1136 {
1137 if( iGeomField >= 0 && iGeomField < nGeomFields &&
1138 papoGeomFields[iGeomField]->sStaticEnvelope.IsInit() )
1139 {
1140 *psExtent = papoGeomFields[iGeomField]->sStaticEnvelope;
1141 return OGRERR_NONE;
1142 }
1143
1144 if( iGeomField < 0 || iGeomField >= GetLayerDefn()->GetGeomFieldCount() )
1145 {
1146 CPLError(CE_Failure, CPLE_AppDefined,
1147 "Invalid geometry field index : %d", iGeomField);
1148 return OGRERR_FAILURE;
1149 }
1150
1151 int bInit = FALSE;
1152 for(int i = 0; i < nSrcLayers; i++)
1153 {
1154 AutoWarpLayerIfNecessary(i);
1155 int iSrcGeomField = papoSrcLayers[i]->GetLayerDefn()->GetGeomFieldIndex(
1156 GetLayerDefn()->GetGeomFieldDefn(iGeomField)->GetNameRef());
1157 if( iSrcGeomField >= 0 )
1158 {
1159 if( !bInit )
1160 {
1161 if( papoSrcLayers[i]->GetExtent(iSrcGeomField, psExtent, bForce) == OGRERR_NONE )
1162 bInit = TRUE;
1163 }
1164 else
1165 {
1166 OGREnvelope sExtent;
1167 if( papoSrcLayers[i]->GetExtent(iSrcGeomField, &sExtent, bForce) == OGRERR_NONE )
1168 {
1169 psExtent->Merge(sExtent);
1170 }
1171 }
1172 }
1173 }
1174 return (bInit) ? OGRERR_NONE : OGRERR_FAILURE;
1175 }
1176
1177 /************************************************************************/
1178 /* GetExtent() */
1179 /************************************************************************/
1180
GetExtent(OGREnvelope * psExtent,int bForce)1181 OGRErr OGRUnionLayer::GetExtent( OGREnvelope *psExtent, int bForce )
1182 {
1183 return GetExtent(0, psExtent, bForce);
1184 }
1185
1186 /************************************************************************/
1187 /* SetSpatialFilter() */
1188 /************************************************************************/
1189
SetSpatialFilter(OGRGeometry * poGeomIn)1190 void OGRUnionLayer::SetSpatialFilter( OGRGeometry * poGeomIn )
1191 {
1192 SetSpatialFilter(0, poGeomIn);
1193 }
1194
1195 /************************************************************************/
1196 /* SetSpatialFilter() */
1197 /************************************************************************/
1198
SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)1199 void OGRUnionLayer::SetSpatialFilter( int iGeomField, OGRGeometry *poGeom )
1200 {
1201 if( iGeomField < 0 || iGeomField >= GetLayerDefn()->GetGeomFieldCount() )
1202 {
1203 if( poGeom != nullptr )
1204 {
1205 CPLError(CE_Failure, CPLE_AppDefined,
1206 "Invalid geometry field index : %d", iGeomField);
1207 return;
1208 }
1209 }
1210
1211 m_iGeomFieldFilter = iGeomField;
1212 if( InstallFilter( poGeom ) )
1213 ResetReading();
1214
1215 if( iCurLayer >= 0 && iCurLayer < nSrcLayers)
1216 {
1217 SetSpatialFilterToSourceLayer(papoSrcLayers[iCurLayer]);
1218 }
1219 }
1220
1221 /************************************************************************/
1222 /* TranslateFromSrcLayer() */
1223 /************************************************************************/
1224
TranslateFromSrcLayer(OGRFeature * poSrcFeature)1225 OGRFeature* OGRUnionLayer::TranslateFromSrcLayer(OGRFeature* poSrcFeature)
1226 {
1227 CPLAssert(poSrcFeature->GetFieldCount() == 0 || panMap != nullptr);
1228 CPLAssert(iCurLayer >= 0 && iCurLayer < nSrcLayers);
1229
1230 OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
1231 poFeature->SetFrom(poSrcFeature, panMap, TRUE);
1232
1233 if( !osSourceLayerFieldName.empty() &&
1234 !poFeatureDefn->GetFieldDefn(0)->IsIgnored() )
1235 {
1236 poFeature->SetField(0, papoSrcLayers[iCurLayer]->GetName());
1237 }
1238
1239 for(int i=0;i<poFeatureDefn->GetGeomFieldCount();i++)
1240 {
1241 if( poFeatureDefn->GetGeomFieldDefn(i)->IsIgnored() )
1242 poFeature->SetGeomFieldDirectly(i, nullptr);
1243 else
1244 {
1245 OGRGeometry* poGeom = poFeature->GetGeomFieldRef(i);
1246 if( poGeom != nullptr )
1247 {
1248 poGeom->assignSpatialReference(
1249 poFeatureDefn->GetGeomFieldDefn(i)->GetSpatialRef());
1250 }
1251 }
1252 }
1253
1254 if( bPreserveSrcFID )
1255 poFeature->SetFID(poSrcFeature->GetFID());
1256 else
1257 poFeature->SetFID(nNextFID ++);
1258 return poFeature;
1259 }
1260
1261 /************************************************************************/
1262 /* SetIgnoredFields() */
1263 /************************************************************************/
1264
SetIgnoredFields(const char ** papszFields)1265 OGRErr OGRUnionLayer::SetIgnoredFields( const char **papszFields )
1266 {
1267 OGRErr eErr = OGRLayer::SetIgnoredFields(papszFields);
1268 if( eErr != OGRERR_NONE )
1269 return eErr;
1270
1271 CSLDestroy(papszIgnoredFields);
1272 papszIgnoredFields = papszFields ? CSLDuplicate(papszFields) : nullptr;
1273
1274 return eErr;
1275 }
1276
1277 /************************************************************************/
1278 /* SyncToDisk() */
1279 /************************************************************************/
1280
SyncToDisk()1281 OGRErr OGRUnionLayer::SyncToDisk()
1282 {
1283 for(int i = 0; i < nSrcLayers; i++)
1284 {
1285 if (pabModifiedLayers[i])
1286 {
1287 papoSrcLayers[i]->SyncToDisk();
1288 pabModifiedLayers[i] = FALSE;
1289 }
1290 }
1291
1292 return OGRERR_NONE;
1293 }
1294
1295 #endif /* #ifndef DOXYGEN_SKIP */
1296