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