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