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 125 : OGRUnionLayer::OGRUnionLayer(const char *pszName, int nSrcLayersIn,
69 : OGRLayer **papoSrcLayersIn,
70 125 : int bTakeLayerOwnership)
71 125 : : osName(pszName)
72 : {
73 125 : CPLAssert(nSrcLayersIn > 0);
74 :
75 125 : SetDescription(pszName);
76 :
77 350 : for (int i = 0; i < nSrcLayersIn; ++i)
78 : {
79 225 : m_apoSrcLayers.emplace_back(papoSrcLayersIn[i],
80 225 : CPL_TO_BOOL(bTakeLayerOwnership));
81 : }
82 125 : CPLFree(papoSrcLayersIn);
83 125 : }
84 :
85 : /************************************************************************/
86 : /* ~OGRUnionLayer() */
87 : /************************************************************************/
88 :
89 250 : OGRUnionLayer::~OGRUnionLayer()
90 : {
91 125 : m_apoSrcLayers.clear();
92 :
93 157 : for (int i = 0; i < nFields; i++)
94 32 : delete papoFields[i];
95 125 : CPLFree(papoFields);
96 148 : for (int i = 0; i < nGeomFields; i++)
97 23 : delete papoGeomFields[i];
98 125 : CPLFree(papoGeomFields);
99 :
100 125 : CPLFree(pszAttributeFilter);
101 125 : CPLFree(panMap);
102 :
103 125 : if (poFeatureDefn)
104 109 : poFeatureDefn->Release();
105 125 : if (poGlobalSRS != nullptr)
106 36 : const_cast<OGRSpatialReference *>(poGlobalSRS)->Release();
107 250 : }
108 :
109 : /************************************************************************/
110 : /* SetFields() */
111 : /************************************************************************/
112 :
113 119 : void OGRUnionLayer::SetFields(FieldUnionStrategy eFieldStrategyIn,
114 : int nFieldsIn, OGRFieldDefn **papoFieldsIn,
115 : int nGeomFieldsIn,
116 : OGRUnionLayerGeomFieldDefn **papoGeomFieldsIn)
117 : {
118 119 : CPLAssert(nFields == 0);
119 119 : CPLAssert(poFeatureDefn == nullptr);
120 :
121 119 : eFieldStrategy = eFieldStrategyIn;
122 119 : 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 119 : nGeomFields = nGeomFieldsIn;
131 119 : 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 119 : }
140 :
141 : /************************************************************************/
142 : /* SetSourceLayerFieldName() */
143 : /************************************************************************/
144 :
145 91 : void OGRUnionLayer::SetSourceLayerFieldName(const char *pszSourceLayerFieldName)
146 : {
147 91 : CPLAssert(poFeatureDefn == nullptr);
148 :
149 91 : CPLAssert(osSourceLayerFieldName.empty());
150 91 : if (pszSourceLayerFieldName != nullptr)
151 17 : osSourceLayerFieldName = pszSourceLayerFieldName;
152 91 : }
153 :
154 : /************************************************************************/
155 : /* SetPreserveSrcFID() */
156 : /************************************************************************/
157 :
158 84 : void OGRUnionLayer::SetPreserveSrcFID(int bPreserveSrcFIDIn)
159 : {
160 84 : CPLAssert(poFeatureDefn == nullptr);
161 :
162 84 : bPreserveSrcFID = bPreserveSrcFIDIn;
163 84 : }
164 :
165 : /************************************************************************/
166 : /* SetFeatureCount() */
167 : /************************************************************************/
168 :
169 9 : void OGRUnionLayer::SetFeatureCount(int nFeatureCountIn)
170 : {
171 9 : CPLAssert(poFeatureDefn == nullptr);
172 :
173 9 : nFeatureCount = nFeatureCountIn;
174 9 : }
175 :
176 : /************************************************************************/
177 : /* MergeFieldDefn() */
178 : /************************************************************************/
179 :
180 69 : static void MergeFieldDefn(OGRFieldDefn *poFieldDefn,
181 : const OGRFieldDefn *poSrcFieldDefn)
182 : {
183 69 : 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 113 : if (poFieldDefn->GetWidth() != poSrcFieldDefn->GetWidth() ||
204 44 : poFieldDefn->GetPrecision() != poSrcFieldDefn->GetPrecision())
205 : {
206 25 : poFieldDefn->SetWidth(0);
207 25 : poFieldDefn->SetPrecision(0);
208 : }
209 69 : }
210 :
211 : /************************************************************************/
212 : /* GetLayerDefn() */
213 : /************************************************************************/
214 :
215 7690 : const OGRFeatureDefn *OGRUnionLayer::GetLayerDefn() const
216 : {
217 7690 : if (poFeatureDefn != nullptr)
218 7581 : return poFeatureDefn;
219 :
220 109 : poFeatureDefn = new OGRFeatureDefn(osName);
221 109 : poFeatureDefn->Reference();
222 109 : poFeatureDefn->SetGeomType(wkbNone);
223 :
224 109 : int iCompareFirstIndex = 0;
225 109 : if (!osSourceLayerFieldName.empty())
226 : {
227 14 : OGRFieldDefn oField(osSourceLayerFieldName, OFTString);
228 14 : poFeatureDefn->AddFieldDefn(&oField);
229 14 : iCompareFirstIndex = 1;
230 : }
231 :
232 109 : 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 105 : 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 101 : else if (eFieldStrategy == FIELD_UNION_ALL_LAYERS)
303 : {
304 92 : if (nGeomFields == 1)
305 : {
306 0 : poFeatureDefn->AddGeomFieldDefn(
307 0 : std::make_unique<OGRUnionLayerGeomFieldDefn>(
308 0 : papoGeomFields[0]));
309 : }
310 :
311 92 : int nDstFieldCount = 0;
312 184 : std::map<std::string, int> oMapDstFieldNameToIdx;
313 :
314 255 : for (auto &oLayer : m_apoSrcLayers)
315 : {
316 163 : const OGRFeatureDefn *poSrcFeatureDefn = oLayer->GetLayerDefn();
317 :
318 : /* Add any field that is found in the source layers */
319 163 : const int nSrcFieldCount = poSrcFeatureDefn->GetFieldCount();
320 349 : for (int i = 0; i < nSrcFieldCount; i++)
321 : {
322 : const OGRFieldDefn *poSrcFieldDefn =
323 186 : poSrcFeatureDefn->GetFieldDefn(i);
324 : const auto oIter =
325 186 : oMapDstFieldNameToIdx.find(poSrcFieldDefn->GetNameRef());
326 : const int nIndex =
327 186 : oIter == oMapDstFieldNameToIdx.end() ? -1 : oIter->second;
328 186 : if (nIndex < 0)
329 : {
330 132 : oMapDstFieldNameToIdx[poSrcFieldDefn->GetNameRef()] =
331 : nDstFieldCount;
332 132 : nDstFieldCount++;
333 132 : poFeatureDefn->AddFieldDefn(poSrcFieldDefn);
334 : }
335 : else
336 : {
337 : OGRFieldDefn *poFieldDefn =
338 54 : poFeatureDefn->GetFieldDefn(nIndex);
339 54 : MergeFieldDefn(poFieldDefn, poSrcFieldDefn);
340 : }
341 : }
342 :
343 322 : for (int i = 0;
344 322 : 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 109 : 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 1849 : void OGRUnionLayer::SetSpatialFilterToSourceLayer(OGRLayer *poSrcLayer)
476 : {
477 3698 : if (m_iGeomFieldFilter >= 0 &&
478 1849 : m_iGeomFieldFilter < GetLayerDefn()->GetGeomFieldCount())
479 : {
480 3440 : int iSrcGeomField = poSrcLayer->GetLayerDefn()->GetGeomFieldIndex(
481 1720 : GetLayerDefn()->GetGeomFieldDefn(m_iGeomFieldFilter)->GetNameRef());
482 1720 : if (iSrcGeomField >= 0)
483 : {
484 1719 : poSrcLayer->SetSpatialFilter(iSrcGeomField, m_poFilterGeom);
485 : }
486 : else
487 : {
488 1 : poSrcLayer->SetSpatialFilter(nullptr);
489 : }
490 : }
491 : else
492 : {
493 129 : poSrcLayer->SetSpatialFilter(nullptr);
494 : }
495 1849 : }
496 :
497 : /************************************************************************/
498 : /* ConfigureActiveLayer() */
499 : /************************************************************************/
500 :
501 1271 : void OGRUnionLayer::ConfigureActiveLayer()
502 : {
503 1271 : AutoWarpLayerIfNecessary(iCurLayer);
504 1271 : ApplyAttributeFilterToSrcLayer(iCurLayer);
505 1271 : SetSpatialFilterToSourceLayer(m_apoSrcLayers[iCurLayer].poLayer);
506 1271 : m_apoSrcLayers[iCurLayer]->ResetReading();
507 :
508 : /* Establish map */
509 1271 : GetLayerDefn();
510 : const OGRFeatureDefn *poSrcFeatureDefn =
511 1271 : m_apoSrcLayers[iCurLayer]->GetLayerDefn();
512 1271 : const int nSrcFieldCount = poSrcFeatureDefn->GetFieldCount();
513 1271 : const int nDstFieldCount = poFeatureDefn->GetFieldCount();
514 :
515 2542 : std::map<std::string, int> oMapDstFieldNameToIdx;
516 5459 : for (int i = 0; i < nDstFieldCount; i++)
517 : {
518 4188 : const OGRFieldDefn *poDstFieldDefn = poFeatureDefn->GetFieldDefn(i);
519 4188 : oMapDstFieldNameToIdx[poDstFieldDefn->GetNameRef()] = i;
520 : }
521 :
522 1271 : CPLFree(panMap);
523 1271 : panMap = static_cast<int *>(CPLMalloc(nSrcFieldCount * sizeof(int)));
524 6350 : for (int i = 0; i < nSrcFieldCount; i++)
525 : {
526 5079 : const OGRFieldDefn *poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i);
527 5079 : if (m_aosIgnoredFields.FindString(poSrcFieldDefn->GetNameRef()) == -1)
528 : {
529 : const auto oIter =
530 5068 : oMapDstFieldNameToIdx.find(poSrcFieldDefn->GetNameRef());
531 5068 : panMap[i] =
532 5068 : oIter == oMapDstFieldNameToIdx.end() ? -1 : oIter->second;
533 : }
534 : else
535 : {
536 11 : panMap[i] = -1;
537 : }
538 : }
539 :
540 1271 : if (m_apoSrcLayers[iCurLayer]->TestCapability(OLCIgnoreFields))
541 : {
542 2446 : CPLStringList aosFieldSrc;
543 1251 : 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 2446 : std::map<std::string, int> oMapSrcFieldNameToIdx;
555 6236 : for (int i = 0; i < nSrcFieldCount; i++)
556 : {
557 : const OGRFieldDefn *poSrcFieldDefn =
558 5013 : poSrcFeatureDefn->GetFieldDefn(i);
559 5013 : oMapSrcFieldNameToIdx[poSrcFieldDefn->GetNameRef()] = i;
560 : }
561 :
562 : /* Attribute fields */
563 2446 : std::vector<bool> abSrcFieldsUsed(nSrcFieldCount);
564 5312 : for (int iField = 0; iField < nDstFieldCount; iField++)
565 : {
566 : const OGRFieldDefn *poFieldDefn =
567 4089 : poFeatureDefn->GetFieldDefn(iField);
568 : const auto oIter =
569 4089 : oMapSrcFieldNameToIdx.find(poFieldDefn->GetNameRef());
570 : const int iSrcField =
571 4089 : oIter == oMapSrcFieldNameToIdx.end() ? -1 : oIter->second;
572 4089 : if (iSrcField >= 0)
573 3525 : abSrcFieldsUsed[iSrcField] = true;
574 : }
575 6236 : for (int iSrcField = 0; iSrcField < nSrcFieldCount; iSrcField++)
576 : {
577 5013 : if (!abSrcFieldsUsed[iSrcField])
578 : {
579 : const OGRFieldDefn *poSrcDefn =
580 1488 : poSrcFeatureDefn->GetFieldDefn(iSrcField);
581 1488 : aosFieldSrc.AddString(poSrcDefn->GetNameRef());
582 : }
583 : }
584 :
585 : /* geometry fields now */
586 1223 : abSrcFieldsUsed.clear();
587 1223 : abSrcFieldsUsed.resize(poSrcFeatureDefn->GetGeomFieldCount());
588 3571 : for (int iField = 0; iField < poFeatureDefn->GetGeomFieldCount();
589 : iField++)
590 : {
591 : const OGRGeomFieldDefn *poFieldDefn =
592 2348 : poFeatureDefn->GetGeomFieldDefn(iField);
593 : const int iSrcField =
594 2348 : poSrcFeatureDefn->GetGeomFieldIndex(poFieldDefn->GetNameRef());
595 2348 : if (iSrcField >= 0)
596 2156 : abSrcFieldsUsed[iSrcField] = true;
597 : }
598 4077 : for (int iSrcField = 0;
599 4077 : iSrcField < poSrcFeatureDefn->GetGeomFieldCount(); iSrcField++)
600 : {
601 2854 : if (!abSrcFieldsUsed[iSrcField])
602 : {
603 : const OGRGeomFieldDefn *poSrcDefn =
604 698 : poSrcFeatureDefn->GetGeomFieldDefn(iSrcField);
605 698 : aosFieldSrc.AddString(poSrcDefn->GetNameRef());
606 : }
607 : }
608 :
609 1223 : m_apoSrcLayers[iCurLayer]->SetIgnoredFields(aosFieldSrc.List());
610 : }
611 1271 : }
612 :
613 : /************************************************************************/
614 : /* ResetReading() */
615 : /************************************************************************/
616 :
617 1029 : void OGRUnionLayer::ResetReading()
618 : {
619 1029 : iCurLayer = 0;
620 1029 : ConfigureActiveLayer();
621 1029 : nNextFID = 0;
622 1029 : }
623 :
624 : /************************************************************************/
625 : /* AutoWarpLayerIfNecessary() */
626 : /************************************************************************/
627 :
628 1667 : void OGRUnionLayer::AutoWarpLayerIfNecessary(int iLayer)
629 : {
630 3334 : std::lock_guard oLock(m_oMutex);
631 :
632 1667 : if (!m_apoSrcLayers[iLayer].bCheckIfAutoWrap)
633 : {
634 120 : m_apoSrcLayers[iLayer].bCheckIfAutoWrap = true;
635 :
636 264 : for (int iField = 0; iField < GetLayerDefn()->GetGeomFieldCount();
637 : iField++)
638 : {
639 : const OGRSpatialReference *poSRS =
640 144 : GetLayerDefn()->GetGeomFieldDefn(iField)->GetSpatialRef();
641 :
642 : OGRFeatureDefn *poSrcFeatureDefn =
643 144 : m_apoSrcLayers[iLayer]->GetLayerDefn();
644 144 : int iSrcGeomField = poSrcFeatureDefn->GetGeomFieldIndex(
645 144 : GetLayerDefn()->GetGeomFieldDefn(iField)->GetNameRef());
646 144 : if (iSrcGeomField >= 0)
647 : {
648 : const OGRSpatialReference *poSRS2 =
649 135 : poSrcFeatureDefn->GetGeomFieldDefn(iSrcGeomField)
650 135 : ->GetSpatialRef();
651 :
652 135 : if ((poSRS == nullptr && poSRS2 != nullptr) ||
653 101 : (poSRS != nullptr && poSRS2 == nullptr))
654 : {
655 0 : CPLError(
656 : CE_Warning, CPLE_AppDefined,
657 : "SRS of geometry field '%s' layer %s not "
658 : "consistent with UnionLayer SRS",
659 0 : GetLayerDefn()->GetGeomFieldDefn(iField)->GetNameRef(),
660 0 : m_apoSrcLayers[iLayer]->GetName());
661 : }
662 101 : else if (poSRS != nullptr && poSRS2 != nullptr &&
663 236 : poSRS != poSRS2 && !poSRS->IsSame(poSRS2))
664 : {
665 4 : CPLDebug(
666 : "VRT",
667 : "SRS of geometry field '%s' layer %s not "
668 : "consistent with UnionLayer SRS. "
669 : "Trying auto warping",
670 4 : GetLayerDefn()->GetGeomFieldDefn(iField)->GetNameRef(),
671 4 : m_apoSrcLayers[iLayer]->GetName());
672 : std::unique_ptr<OGRCoordinateTransformation> poCT(
673 8 : OGRCreateCoordinateTransformation(poSRS2, poSRS));
674 : std::unique_ptr<OGRCoordinateTransformation> poReversedCT(
675 8 : (poCT != nullptr) ? poCT->GetInverse() : nullptr);
676 4 : if (poReversedCT != nullptr)
677 : {
678 4 : auto [poSrcLayer, bOwned] =
679 4 : m_apoSrcLayers[iLayer].release();
680 8 : m_apoSrcLayers[iLayer].reset(
681 4 : std::make_unique<OGRWarpedLayer>(
682 : poSrcLayer, iSrcGeomField, bOwned,
683 8 : poCT.release(), poReversedCT.release()));
684 : }
685 : else
686 : {
687 0 : CPLError(CE_Warning, CPLE_AppDefined,
688 : "AutoWarpLayerIfNecessary failed to create "
689 : "poCT or poReversedCT.");
690 : }
691 : }
692 : }
693 : }
694 : }
695 1667 : }
696 :
697 : /************************************************************************/
698 : /* GetNextFeature() */
699 : /************************************************************************/
700 :
701 2816 : OGRFeature *OGRUnionLayer::GetNextFeature()
702 : {
703 2816 : if (poFeatureDefn == nullptr)
704 3 : GetLayerDefn();
705 2816 : if (iCurLayer < 0)
706 10 : ResetReading();
707 :
708 2816 : if (iCurLayer == static_cast<int>(m_apoSrcLayers.size()))
709 27 : return nullptr;
710 :
711 : while (true)
712 : {
713 3534 : OGRFeature *poSrcFeature = m_apoSrcLayers[iCurLayer]->GetNextFeature();
714 3534 : if (poSrcFeature == nullptr)
715 : {
716 522 : iCurLayer++;
717 522 : if (iCurLayer < static_cast<int>(m_apoSrcLayers.size()))
718 : {
719 242 : ConfigureActiveLayer();
720 242 : continue;
721 : }
722 : else
723 280 : break;
724 : }
725 :
726 3012 : OGRFeature *poFeature = TranslateFromSrcLayer(poSrcFeature);
727 3012 : delete poSrcFeature;
728 :
729 6340 : if ((m_poFilterGeom == nullptr ||
730 6024 : FilterGeometry(poFeature->GetGeomFieldRef(m_iGeomFieldFilter))) &&
731 3012 : (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)))
732 : {
733 2509 : return poFeature;
734 : }
735 :
736 503 : delete poFeature;
737 745 : }
738 280 : return nullptr;
739 : }
740 :
741 : /************************************************************************/
742 : /* GetFeature() */
743 : /************************************************************************/
744 :
745 56 : OGRFeature *OGRUnionLayer::GetFeature(GIntBig nFeatureId)
746 : {
747 56 : OGRFeature *poFeature = nullptr;
748 :
749 56 : if (!bPreserveSrcFID)
750 : {
751 56 : poFeature = OGRLayer::GetFeature(nFeatureId);
752 : }
753 : else
754 : {
755 0 : int iGeomFieldFilterSave = m_iGeomFieldFilter;
756 0 : OGRGeometry *poGeomSave = m_poFilterGeom;
757 0 : m_poFilterGeom = nullptr;
758 0 : SetSpatialFilter(nullptr);
759 :
760 0 : for (int i = 0; i < static_cast<int>(m_apoSrcLayers.size()); i++)
761 : {
762 0 : iCurLayer = i;
763 0 : ConfigureActiveLayer();
764 :
765 : OGRFeature *poSrcFeature =
766 0 : m_apoSrcLayers[i]->GetFeature(nFeatureId);
767 0 : if (poSrcFeature != nullptr)
768 : {
769 0 : poFeature = TranslateFromSrcLayer(poSrcFeature);
770 0 : delete poSrcFeature;
771 :
772 0 : break;
773 : }
774 : }
775 :
776 0 : SetSpatialFilter(iGeomFieldFilterSave, poGeomSave);
777 0 : delete poGeomSave;
778 :
779 0 : ResetReading();
780 : }
781 :
782 56 : return poFeature;
783 : }
784 :
785 : /************************************************************************/
786 : /* ICreateFeature() */
787 : /************************************************************************/
788 :
789 5 : OGRErr OGRUnionLayer::ICreateFeature(OGRFeature *poFeature)
790 : {
791 5 : if (osSourceLayerFieldName.empty())
792 : {
793 1 : CPLError(CE_Failure, CPLE_NotSupported,
794 : "CreateFeature() not supported when SourceLayerFieldName is "
795 : "not set");
796 1 : return OGRERR_FAILURE;
797 : }
798 :
799 4 : if (poFeature->GetFID() != OGRNullFID)
800 : {
801 1 : CPLError(CE_Failure, CPLE_NotSupported,
802 : "CreateFeature() not supported when FID is set");
803 1 : return OGRERR_FAILURE;
804 : }
805 :
806 3 : if (!poFeature->IsFieldSetAndNotNull(0))
807 : {
808 1 : CPLError(CE_Failure, CPLE_NotSupported,
809 : "CreateFeature() not supported when '%s' field is not set",
810 : osSourceLayerFieldName.c_str());
811 1 : return OGRERR_FAILURE;
812 : }
813 :
814 2 : const char *pszSrcLayerName = poFeature->GetFieldAsString(0);
815 5 : for (auto &oLayer : m_apoSrcLayers)
816 : {
817 4 : if (strcmp(pszSrcLayerName, oLayer->GetName()) == 0)
818 : {
819 1 : oLayer.bModified = true;
820 :
821 1 : OGRFeature *poSrcFeature = new OGRFeature(oLayer->GetLayerDefn());
822 1 : poSrcFeature->SetFrom(poFeature, TRUE);
823 1 : OGRErr eErr = oLayer->CreateFeature(poSrcFeature);
824 1 : if (eErr == OGRERR_NONE)
825 1 : poFeature->SetFID(poSrcFeature->GetFID());
826 1 : delete poSrcFeature;
827 1 : return eErr;
828 : }
829 : }
830 :
831 1 : CPLError(CE_Failure, CPLE_NotSupported,
832 : "CreateFeature() not supported : '%s' source layer does not exist",
833 : pszSrcLayerName);
834 1 : return OGRERR_FAILURE;
835 : }
836 :
837 : /************************************************************************/
838 : /* ISetFeature() */
839 : /************************************************************************/
840 :
841 14 : OGRErr OGRUnionLayer::ISetFeature(OGRFeature *poFeature)
842 : {
843 14 : if (!bPreserveSrcFID)
844 : {
845 10 : CPLError(CE_Failure, CPLE_NotSupported,
846 : "SetFeature() not supported when PreserveSrcFID is OFF");
847 10 : return OGRERR_FAILURE;
848 : }
849 :
850 4 : if (osSourceLayerFieldName.empty())
851 : {
852 0 : CPLError(
853 : CE_Failure, CPLE_NotSupported,
854 : "SetFeature() not supported when SourceLayerFieldName is not set");
855 0 : return OGRERR_FAILURE;
856 : }
857 :
858 4 : if (poFeature->GetFID() == OGRNullFID)
859 : {
860 1 : CPLError(CE_Failure, CPLE_NotSupported,
861 : "SetFeature() not supported when FID is not set");
862 1 : return OGRERR_FAILURE;
863 : }
864 :
865 3 : if (!poFeature->IsFieldSetAndNotNull(0))
866 : {
867 1 : CPLError(CE_Failure, CPLE_NotSupported,
868 : "SetFeature() not supported when '%s' field is not set",
869 : osSourceLayerFieldName.c_str());
870 1 : return OGRERR_FAILURE;
871 : }
872 :
873 2 : const char *pszSrcLayerName = poFeature->GetFieldAsString(0);
874 5 : for (auto &oLayer : m_apoSrcLayers)
875 : {
876 4 : if (strcmp(pszSrcLayerName, oLayer->GetName()) == 0)
877 : {
878 1 : oLayer.bModified = true;
879 :
880 1 : OGRFeature *poSrcFeature = new OGRFeature(oLayer->GetLayerDefn());
881 1 : poSrcFeature->SetFrom(poFeature, TRUE);
882 1 : poSrcFeature->SetFID(poFeature->GetFID());
883 1 : OGRErr eErr = oLayer->SetFeature(poSrcFeature);
884 1 : delete poSrcFeature;
885 1 : return eErr;
886 : }
887 : }
888 :
889 1 : CPLError(CE_Failure, CPLE_NotSupported,
890 : "SetFeature() not supported : '%s' source layer does not exist",
891 : pszSrcLayerName);
892 1 : return OGRERR_FAILURE;
893 : }
894 :
895 : /************************************************************************/
896 : /* IUpsertFeature() */
897 : /************************************************************************/
898 :
899 0 : OGRErr OGRUnionLayer::IUpsertFeature(OGRFeature *poFeature)
900 : {
901 0 : if (GetFeature(poFeature->GetFID()))
902 : {
903 0 : return ISetFeature(poFeature);
904 : }
905 : else
906 : {
907 0 : return ICreateFeature(poFeature);
908 : }
909 : }
910 :
911 : /************************************************************************/
912 : /* IUpdateFeature() */
913 : /************************************************************************/
914 :
915 0 : OGRErr OGRUnionLayer::IUpdateFeature(OGRFeature *poFeature,
916 : int nUpdatedFieldsCount,
917 : const int *panUpdatedFieldsIdx,
918 : int nUpdatedGeomFieldsCount,
919 : const int *panUpdatedGeomFieldsIdx,
920 : bool bUpdateStyleString)
921 : {
922 0 : if (!bPreserveSrcFID)
923 : {
924 0 : CPLError(CE_Failure, CPLE_NotSupported,
925 : "UpdateFeature() not supported when PreserveSrcFID is OFF");
926 0 : return OGRERR_FAILURE;
927 : }
928 :
929 0 : if (osSourceLayerFieldName.empty())
930 : {
931 0 : CPLError(CE_Failure, CPLE_NotSupported,
932 : "UpdateFeature() not supported when SourceLayerFieldName is "
933 : "not set");
934 0 : return OGRERR_FAILURE;
935 : }
936 :
937 0 : if (poFeature->GetFID() == OGRNullFID)
938 : {
939 0 : CPLError(CE_Failure, CPLE_NotSupported,
940 : "UpdateFeature() not supported when FID is not set");
941 0 : return OGRERR_FAILURE;
942 : }
943 :
944 0 : if (!poFeature->IsFieldSetAndNotNull(0))
945 : {
946 0 : CPLError(CE_Failure, CPLE_NotSupported,
947 : "UpdateFeature() not supported when '%s' field is not set",
948 : osSourceLayerFieldName.c_str());
949 0 : return OGRERR_FAILURE;
950 : }
951 :
952 0 : const char *pszSrcLayerName = poFeature->GetFieldAsString(0);
953 0 : for (int i = 0; i < static_cast<int>(m_apoSrcLayers.size()); i++)
954 : {
955 0 : if (strcmp(pszSrcLayerName, m_apoSrcLayers[i]->GetName()) == 0)
956 : {
957 0 : m_apoSrcLayers[i].bModified = true;
958 :
959 0 : const auto poSrcLayerDefn = m_apoSrcLayers[i]->GetLayerDefn();
960 0 : OGRFeature *poSrcFeature = new OGRFeature(poSrcLayerDefn);
961 0 : poSrcFeature->SetFrom(poFeature, TRUE);
962 0 : poSrcFeature->SetFID(poFeature->GetFID());
963 :
964 : // We could potentially have a pre-computed map from indices in
965 : // poLayerDefn to indices in poSrcLayerDefn
966 0 : std::vector<int> anSrcUpdatedFieldIdx;
967 0 : const auto poLayerDefn = GetLayerDefn();
968 0 : for (int j = 0; j < nUpdatedFieldsCount; ++j)
969 : {
970 0 : if (panUpdatedFieldsIdx[j] != 0)
971 : {
972 0 : const int nNewIdx = poSrcLayerDefn->GetFieldIndex(
973 0 : poLayerDefn->GetFieldDefn(panUpdatedFieldsIdx[j])
974 0 : ->GetNameRef());
975 0 : if (nNewIdx >= 0)
976 : {
977 0 : anSrcUpdatedFieldIdx.push_back(nNewIdx);
978 : }
979 : }
980 : }
981 0 : std::vector<int> anSrcUpdatedGeomFieldIdx;
982 0 : for (int j = 0; j < nUpdatedGeomFieldsCount; ++j)
983 : {
984 0 : if (panUpdatedGeomFieldsIdx[j] != 0)
985 : {
986 0 : const int nNewIdx = poSrcLayerDefn->GetGeomFieldIndex(
987 : poLayerDefn
988 0 : ->GetGeomFieldDefn(panUpdatedGeomFieldsIdx[j])
989 0 : ->GetNameRef());
990 0 : if (nNewIdx >= 0)
991 : {
992 0 : anSrcUpdatedGeomFieldIdx.push_back(nNewIdx);
993 : }
994 : }
995 : }
996 :
997 0 : OGRErr eErr = m_apoSrcLayers[i]->UpdateFeature(
998 0 : poSrcFeature, static_cast<int>(anSrcUpdatedFieldIdx.size()),
999 0 : anSrcUpdatedFieldIdx.data(),
1000 0 : static_cast<int>(anSrcUpdatedGeomFieldIdx.size()),
1001 0 : anSrcUpdatedGeomFieldIdx.data(), bUpdateStyleString);
1002 0 : delete poSrcFeature;
1003 0 : return eErr;
1004 : }
1005 : }
1006 :
1007 0 : CPLError(CE_Failure, CPLE_NotSupported,
1008 : "UpdateFeature() not supported : '%s' source layer does not exist",
1009 : pszSrcLayerName);
1010 0 : return OGRERR_FAILURE;
1011 : }
1012 :
1013 : /************************************************************************/
1014 : /* GetSpatialRef() */
1015 : /************************************************************************/
1016 :
1017 223 : const OGRSpatialReference *OGRUnionLayer::GetSpatialRef() const
1018 : {
1019 223 : if (nGeomFields < 0)
1020 0 : return nullptr;
1021 223 : if (nGeomFields >= 1 && papoGeomFields[0]->bSRSSet)
1022 1 : return papoGeomFields[0]->GetSpatialRef();
1023 :
1024 222 : if (poGlobalSRS == nullptr)
1025 : {
1026 151 : poGlobalSRS = m_apoSrcLayers[0]->GetSpatialRef();
1027 151 : if (poGlobalSRS != nullptr)
1028 32 : const_cast<OGRSpatialReference *>(poGlobalSRS)->Reference();
1029 : }
1030 222 : return poGlobalSRS;
1031 : }
1032 :
1033 : /************************************************************************/
1034 : /* GetAttrFilterPassThroughValue() */
1035 : /************************************************************************/
1036 :
1037 1960 : int OGRUnionLayer::GetAttrFilterPassThroughValue() const
1038 : {
1039 1960 : if (m_poAttrQuery == nullptr)
1040 1420 : return TRUE;
1041 :
1042 540 : if (bAttrFilterPassThroughValue >= 0)
1043 439 : return bAttrFilterPassThroughValue;
1044 :
1045 101 : char **papszUsedFields = m_poAttrQuery->GetUsedFields();
1046 101 : int bRet = TRUE;
1047 :
1048 292 : for (auto &oLayer : m_apoSrcLayers)
1049 : {
1050 191 : const OGRFeatureDefn *poSrcFeatureDefn = oLayer->GetLayerDefn();
1051 191 : char **papszIter = papszUsedFields;
1052 257 : while (papszIter != nullptr && *papszIter != nullptr)
1053 : {
1054 79 : int bIsSpecial = FALSE;
1055 458 : for (int i = 0; i < SPECIAL_FIELD_COUNT; i++)
1056 : {
1057 383 : if (EQUAL(*papszIter, SpecialFieldNames[i]))
1058 : {
1059 4 : bIsSpecial = TRUE;
1060 4 : break;
1061 : }
1062 : }
1063 79 : if (!bIsSpecial && poSrcFeatureDefn->GetFieldIndex(*papszIter) < 0)
1064 : {
1065 13 : bRet = FALSE;
1066 13 : break;
1067 : }
1068 66 : papszIter++;
1069 : }
1070 : }
1071 :
1072 101 : CSLDestroy(papszUsedFields);
1073 :
1074 101 : bAttrFilterPassThroughValue = bRet;
1075 :
1076 101 : return bRet;
1077 : }
1078 :
1079 : /************************************************************************/
1080 : /* ApplyAttributeFilterToSrcLayer() */
1081 : /************************************************************************/
1082 :
1083 1799 : void OGRUnionLayer::ApplyAttributeFilterToSrcLayer(int iSubLayer)
1084 : {
1085 3598 : std::lock_guard oLock(m_oMutex);
1086 :
1087 1799 : CPLAssert(iSubLayer >= 0 &&
1088 : iSubLayer < static_cast<int>(m_apoSrcLayers.size()));
1089 :
1090 1799 : if (GetAttrFilterPassThroughValue())
1091 1740 : m_apoSrcLayers[iSubLayer]->SetAttributeFilter(pszAttributeFilter);
1092 : else
1093 59 : m_apoSrcLayers[iSubLayer]->SetAttributeFilter(nullptr);
1094 1799 : }
1095 :
1096 : /************************************************************************/
1097 : /* GetFeatureCount() */
1098 : /************************************************************************/
1099 :
1100 156 : GIntBig OGRUnionLayer::GetFeatureCount(int bForce)
1101 : {
1102 156 : if (nFeatureCount >= 0 && m_poFilterGeom == nullptr &&
1103 1 : m_poAttrQuery == nullptr)
1104 : {
1105 1 : return nFeatureCount;
1106 : }
1107 :
1108 155 : if (!GetAttrFilterPassThroughValue())
1109 5 : return OGRLayer::GetFeatureCount(bForce);
1110 :
1111 150 : GIntBig nRet = 0;
1112 436 : for (int i = 0; i < static_cast<int>(m_apoSrcLayers.size()); i++)
1113 : {
1114 287 : AutoWarpLayerIfNecessary(i);
1115 287 : ApplyAttributeFilterToSrcLayer(i);
1116 287 : SetSpatialFilterToSourceLayer(m_apoSrcLayers[i].poLayer);
1117 287 : const GIntBig nThisLayerFC = m_apoSrcLayers[i]->GetFeatureCount(bForce);
1118 574 : if (nThisLayerFC < 0 ||
1119 287 : nThisLayerFC > std::numeric_limits<GIntBig>::max() - nRet)
1120 1 : return 0;
1121 286 : nRet += nThisLayerFC;
1122 : }
1123 149 : ResetReading();
1124 149 : return nRet;
1125 : }
1126 :
1127 : /************************************************************************/
1128 : /* SetAttributeFilter() */
1129 : /************************************************************************/
1130 :
1131 436 : OGRErr OGRUnionLayer::SetAttributeFilter(const char *pszAttributeFilterIn)
1132 : {
1133 436 : if (pszAttributeFilterIn == nullptr && pszAttributeFilter == nullptr)
1134 201 : return OGRERR_NONE;
1135 235 : if (pszAttributeFilterIn != nullptr && pszAttributeFilter != nullptr &&
1136 61 : strcmp(pszAttributeFilterIn, pszAttributeFilter) == 0)
1137 8 : return OGRERR_NONE;
1138 :
1139 227 : if (poFeatureDefn == nullptr)
1140 1 : GetLayerDefn();
1141 :
1142 227 : bAttrFilterPassThroughValue = -1;
1143 :
1144 227 : OGRErr eErr = OGRLayer::SetAttributeFilter(pszAttributeFilterIn);
1145 227 : if (eErr != OGRERR_NONE)
1146 0 : return eErr;
1147 :
1148 227 : CPLFree(pszAttributeFilter);
1149 227 : pszAttributeFilter =
1150 227 : pszAttributeFilterIn ? CPLStrdup(pszAttributeFilterIn) : nullptr;
1151 :
1152 227 : if (iCurLayer >= 0 && iCurLayer < static_cast<int>(m_apoSrcLayers.size()))
1153 227 : ApplyAttributeFilterToSrcLayer(iCurLayer);
1154 :
1155 227 : return OGRERR_NONE;
1156 : }
1157 :
1158 : /************************************************************************/
1159 : /* TestCapability() */
1160 : /************************************************************************/
1161 :
1162 386 : int OGRUnionLayer::TestCapability(const char *pszCap) const
1163 : {
1164 386 : if (EQUAL(pszCap, OLCFastFeatureCount))
1165 : {
1166 7 : if (nFeatureCount >= 0 && m_poFilterGeom == nullptr &&
1167 3 : m_poAttrQuery == nullptr)
1168 1 : return TRUE;
1169 :
1170 6 : if (!GetAttrFilterPassThroughValue())
1171 1 : return FALSE;
1172 :
1173 15 : for (int i = 0; i < static_cast<int>(m_apoSrcLayers.size()); i++)
1174 : {
1175 10 : const_cast<OGRUnionLayer *>(this)->AutoWarpLayerIfNecessary(i);
1176 10 : const_cast<OGRUnionLayer *>(this)->ApplyAttributeFilterToSrcLayer(
1177 : i);
1178 10 : const_cast<OGRUnionLayer *>(this)->SetSpatialFilterToSourceLayer(
1179 10 : m_apoSrcLayers[i].poLayer);
1180 10 : if (!m_apoSrcLayers[i]->TestCapability(pszCap))
1181 0 : return FALSE;
1182 : }
1183 5 : return TRUE;
1184 : }
1185 :
1186 379 : if (EQUAL(pszCap, OLCFastGetExtent))
1187 : {
1188 21 : if (nGeomFields >= 1 && papoGeomFields[0]->sStaticEnvelope.IsInit())
1189 1 : return TRUE;
1190 :
1191 32 : for (int i = 0; i < static_cast<int>(m_apoSrcLayers.size()); i++)
1192 : {
1193 25 : const_cast<OGRUnionLayer *>(this)->AutoWarpLayerIfNecessary(i);
1194 25 : if (!m_apoSrcLayers[i]->TestCapability(pszCap))
1195 13 : return FALSE;
1196 : }
1197 7 : return TRUE;
1198 : }
1199 :
1200 358 : if (EQUAL(pszCap, OLCFastSpatialFilter))
1201 : {
1202 6 : for (int i = 0; i < static_cast<int>(m_apoSrcLayers.size()); i++)
1203 : {
1204 4 : const_cast<OGRUnionLayer *>(this)->AutoWarpLayerIfNecessary(i);
1205 4 : const_cast<OGRUnionLayer *>(this)->ApplyAttributeFilterToSrcLayer(
1206 : i);
1207 4 : if (!m_apoSrcLayers[i]->TestCapability(pszCap))
1208 0 : return FALSE;
1209 : }
1210 2 : return TRUE;
1211 : }
1212 :
1213 356 : if (EQUAL(pszCap, OLCStringsAsUTF8))
1214 : {
1215 172 : for (auto &oLayer : m_apoSrcLayers)
1216 : {
1217 142 : if (!oLayer->TestCapability(pszCap))
1218 82 : return FALSE;
1219 : }
1220 30 : return TRUE;
1221 : }
1222 :
1223 244 : if (EQUAL(pszCap, OLCRandomRead))
1224 : {
1225 0 : if (!bPreserveSrcFID)
1226 0 : return FALSE;
1227 :
1228 0 : for (auto &oLayer : m_apoSrcLayers)
1229 : {
1230 0 : if (!oLayer->TestCapability(pszCap))
1231 0 : return FALSE;
1232 : }
1233 0 : return TRUE;
1234 : }
1235 :
1236 244 : if (EQUAL(pszCap, OLCRandomWrite))
1237 : {
1238 11 : if (!bPreserveSrcFID || osSourceLayerFieldName.empty())
1239 10 : return FALSE;
1240 :
1241 3 : for (auto &oLayer : m_apoSrcLayers)
1242 : {
1243 2 : if (!oLayer->TestCapability(pszCap))
1244 0 : return FALSE;
1245 : }
1246 1 : return TRUE;
1247 : }
1248 :
1249 233 : if (EQUAL(pszCap, OLCSequentialWrite))
1250 : {
1251 11 : if (osSourceLayerFieldName.empty())
1252 10 : return FALSE;
1253 :
1254 3 : for (auto &oLayer : m_apoSrcLayers)
1255 : {
1256 2 : if (!oLayer->TestCapability(pszCap))
1257 0 : return FALSE;
1258 : }
1259 1 : return TRUE;
1260 : }
1261 :
1262 222 : if (EQUAL(pszCap, OLCIgnoreFields))
1263 12 : return TRUE;
1264 :
1265 210 : if (EQUAL(pszCap, OLCCurveGeometries))
1266 38 : return TRUE;
1267 :
1268 172 : return FALSE;
1269 : }
1270 :
1271 : /************************************************************************/
1272 : /* IGetExtent() */
1273 : /************************************************************************/
1274 :
1275 41 : OGRErr OGRUnionLayer::IGetExtent(int iGeomField, OGREnvelope *psExtent,
1276 : bool bForce)
1277 : {
1278 51 : if (iGeomField >= 0 && iGeomField < nGeomFields &&
1279 10 : papoGeomFields[iGeomField]->sStaticEnvelope.IsInit())
1280 : {
1281 4 : *psExtent = papoGeomFields[iGeomField]->sStaticEnvelope;
1282 4 : return OGRERR_NONE;
1283 : }
1284 :
1285 37 : if (iGeomField < 0 || iGeomField >= GetLayerDefn()->GetGeomFieldCount())
1286 : {
1287 0 : if (iGeomField != 0)
1288 : {
1289 0 : CPLError(CE_Failure, CPLE_AppDefined,
1290 : "Invalid geometry field index : %d", iGeomField);
1291 : }
1292 0 : return OGRERR_FAILURE;
1293 : }
1294 :
1295 37 : int bInit = FALSE;
1296 107 : for (int i = 0; i < static_cast<int>(m_apoSrcLayers.size()); i++)
1297 : {
1298 70 : AutoWarpLayerIfNecessary(i);
1299 : int iSrcGeomField =
1300 140 : m_apoSrcLayers[i]->GetLayerDefn()->GetGeomFieldIndex(
1301 70 : GetLayerDefn()->GetGeomFieldDefn(iGeomField)->GetNameRef());
1302 70 : if (iSrcGeomField >= 0)
1303 : {
1304 64 : if (!bInit)
1305 : {
1306 37 : if (m_apoSrcLayers[i]->GetExtent(iSrcGeomField, psExtent,
1307 37 : bForce) == OGRERR_NONE)
1308 33 : bInit = TRUE;
1309 : }
1310 : else
1311 : {
1312 27 : OGREnvelope sExtent;
1313 27 : if (m_apoSrcLayers[i]->GetExtent(iSrcGeomField, &sExtent,
1314 27 : bForce) == OGRERR_NONE)
1315 : {
1316 27 : psExtent->Merge(sExtent);
1317 : }
1318 : }
1319 : }
1320 : }
1321 37 : return (bInit) ? OGRERR_NONE : OGRERR_FAILURE;
1322 : }
1323 :
1324 : /************************************************************************/
1325 : /* ISetSpatialFilter() */
1326 : /************************************************************************/
1327 :
1328 377 : OGRErr OGRUnionLayer::ISetSpatialFilter(int iGeomField,
1329 : const OGRGeometry *poGeom)
1330 : {
1331 377 : m_iGeomFieldFilter = iGeomField;
1332 377 : if (InstallFilter(poGeom))
1333 129 : ResetReading();
1334 :
1335 377 : if (iCurLayer >= 0 && iCurLayer < static_cast<int>(m_apoSrcLayers.size()))
1336 : {
1337 281 : SetSpatialFilterToSourceLayer(m_apoSrcLayers[iCurLayer].poLayer);
1338 : }
1339 :
1340 377 : return OGRERR_NONE;
1341 : }
1342 :
1343 : /************************************************************************/
1344 : /* TranslateFromSrcLayer() */
1345 : /************************************************************************/
1346 :
1347 3012 : OGRFeature *OGRUnionLayer::TranslateFromSrcLayer(OGRFeature *poSrcFeature)
1348 : {
1349 3012 : CPLAssert(poSrcFeature->GetFieldCount() == 0 || panMap != nullptr);
1350 3012 : CPLAssert(iCurLayer >= 0 &&
1351 : iCurLayer < static_cast<int>(m_apoSrcLayers.size()));
1352 :
1353 3012 : OGRFeature *poFeature = new OGRFeature(poFeatureDefn);
1354 3012 : poFeature->SetFrom(poSrcFeature, panMap, TRUE);
1355 :
1356 3122 : if (!osSourceLayerFieldName.empty() &&
1357 110 : !poFeatureDefn->GetFieldDefn(0)->IsIgnored())
1358 : {
1359 110 : poFeature->SetField(0, m_apoSrcLayers[iCurLayer]->GetName());
1360 : }
1361 :
1362 6463 : for (int i = 0; i < poFeatureDefn->GetGeomFieldCount(); i++)
1363 : {
1364 3451 : if (poFeatureDefn->GetGeomFieldDefn(i)->IsIgnored())
1365 120 : poFeature->SetGeomFieldDirectly(i, nullptr);
1366 : else
1367 : {
1368 3331 : OGRGeometry *poGeom = poFeature->GetGeomFieldRef(i);
1369 3331 : if (poGeom != nullptr)
1370 : {
1371 3134 : poGeom->assignSpatialReference(
1372 3134 : poFeatureDefn->GetGeomFieldDefn(i)->GetSpatialRef());
1373 : }
1374 : }
1375 : }
1376 :
1377 3012 : if (bPreserveSrcFID)
1378 102 : poFeature->SetFID(poSrcFeature->GetFID());
1379 : else
1380 2910 : poFeature->SetFID(nNextFID++);
1381 3012 : return poFeature;
1382 : }
1383 :
1384 : /************************************************************************/
1385 : /* SetIgnoredFields() */
1386 : /************************************************************************/
1387 :
1388 142 : OGRErr OGRUnionLayer::SetIgnoredFields(CSLConstList papszFields)
1389 : {
1390 142 : OGRErr eErr = OGRLayer::SetIgnoredFields(papszFields);
1391 142 : if (eErr != OGRERR_NONE)
1392 0 : return eErr;
1393 :
1394 142 : m_aosIgnoredFields = papszFields;
1395 :
1396 142 : return eErr;
1397 : }
1398 :
1399 : /************************************************************************/
1400 : /* SyncToDisk() */
1401 : /************************************************************************/
1402 :
1403 1 : OGRErr OGRUnionLayer::SyncToDisk()
1404 : {
1405 3 : for (auto &oLayer : m_apoSrcLayers)
1406 : {
1407 2 : if (oLayer.bModified)
1408 : {
1409 1 : oLayer->SyncToDisk();
1410 1 : oLayer.bModified = false;
1411 : }
1412 : }
1413 :
1414 1 : return OGRERR_NONE;
1415 : }
1416 :
1417 : #endif /* #ifndef DOXYGEN_SKIP */
|