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