1 : /******************************************************************************
2 : * $Id: ogrunionlayer.cpp 24640 2012-07-01 19:37:38Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implements OGRUnionLayer class
6 : * Author: Even Rouault, even dot rouault at mines dash paris dot org
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2012, Even Rouault <even dot rouault at mines dash paris dot org>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "ogrunionlayer.h"
31 : #include "ogrwarpedlayer.h"
32 : #include "ogr_p.h"
33 :
34 : CPL_CVSID("$Id: ogrunionlayer.cpp 24640 2012-07-01 19:37:38Z rouault $");
35 :
36 : /************************************************************************/
37 : /* OGRUnionLayer() */
38 : /************************************************************************/
39 :
40 59 : OGRUnionLayer::OGRUnionLayer( const char* pszName,
41 : int nSrcLayersIn,
42 : OGRLayer** papoSrcLayersIn,
43 59 : int bTakeLayerOwnership )
44 : {
45 59 : CPLAssert(nSrcLayersIn > 0);
46 :
47 59 : osName = pszName;
48 59 : nSrcLayers = nSrcLayersIn;
49 59 : papoSrcLayers = papoSrcLayersIn;
50 59 : bHasLayerOwnership = bTakeLayerOwnership;
51 :
52 59 : poFeatureDefn = NULL;
53 59 : nFields = 0;
54 59 : papoFields = NULL;
55 59 : eFieldStrategy = FIELD_UNION_ALL_LAYERS;
56 :
57 59 : eGeomType = wkbUnknown;
58 59 : eGeometryTypeStrategy = GEOMTYPE_UNION_ALL_LAYERS;
59 :
60 59 : bPreserveSrcFID = FALSE;
61 :
62 59 : nFeatureCount = -1;
63 :
64 59 : poSRS = NULL;
65 59 : bSRSSet = FALSE;
66 :
67 59 : iCurLayer = -1;
68 59 : pszAttributeFilter = NULL;
69 59 : nNextFID = 0;
70 59 : panMap = NULL;
71 59 : papszIgnoredFields = NULL;
72 59 : bAttrFilterPassThroughValue = -1;
73 :
74 59 : pabModifiedLayers = (int*)CPLCalloc(sizeof(int), nSrcLayers);
75 59 : pabCheckIfAutoWrap = (int*)CPLCalloc(sizeof(int), nSrcLayers);
76 59 : }
77 :
78 : /************************************************************************/
79 : /* ~OGRUnionLayer() */
80 : /************************************************************************/
81 :
82 59 : OGRUnionLayer::~OGRUnionLayer()
83 : {
84 : int i;
85 :
86 59 : if( bHasLayerOwnership )
87 : {
88 177 : for(i = 0; i < nSrcLayers; i++)
89 118 : delete papoSrcLayers[i];
90 : }
91 59 : CPLFree(papoSrcLayers);
92 :
93 59 : for(i = 0; i < nFields; i++)
94 0 : delete papoFields[i];
95 59 : CPLFree(papoFields);
96 :
97 59 : CPLFree(pszAttributeFilter);
98 59 : CPLFree(panMap);
99 59 : CSLDestroy(papszIgnoredFields);
100 59 : CPLFree(pabModifiedLayers);
101 59 : CPLFree(pabCheckIfAutoWrap);
102 :
103 59 : if( poSRS != NULL )
104 9 : poSRS->Release();
105 :
106 59 : if( poFeatureDefn )
107 50 : poFeatureDefn->Release();
108 59 : }
109 :
110 : /************************************************************************/
111 : /* SetSRS() */
112 : /************************************************************************/
113 :
114 9 : void OGRUnionLayer::SetSRS(OGRSpatialReference *poSRSIn)
115 : {
116 9 : CPLAssert(poFeatureDefn == NULL);
117 :
118 9 : bSRSSet = TRUE;
119 9 : if( poSRS )
120 0 : poSRS->Release();
121 9 : poSRS = (poSRSIn != NULL) ? poSRSIn->Clone() : NULL;
122 9 : }
123 :
124 : /************************************************************************/
125 : /* SetFields() */
126 : /************************************************************************/
127 :
128 57 : void OGRUnionLayer::SetFields(FieldUnionStrategy eFieldStrategyIn,
129 : int nFieldsIn,
130 : OGRFieldDefn** papoFieldsIn)
131 : {
132 57 : CPLAssert(nFields == 0);
133 57 : CPLAssert(poFeatureDefn == NULL);
134 :
135 57 : eFieldStrategy = eFieldStrategyIn;
136 57 : if( nFieldsIn )
137 : {
138 0 : nFields = nFieldsIn;
139 0 : papoFields = (OGRFieldDefn** )CPLMalloc(nFields * sizeof(OGRFieldDefn*));
140 0 : for(int i=0;i<nFields;i++)
141 0 : papoFields[i] = new OGRFieldDefn(papoFieldsIn[i]);
142 : }
143 57 : }
144 :
145 : /************************************************************************/
146 : /* SetGeometryType() */
147 : /************************************************************************/
148 :
149 57 : void OGRUnionLayer::SetGeometryType(GeometryTypeUnionStrategy
150 : eGeometryTypeStrategyIn,
151 : OGRwkbGeometryType eGeomTypeIn)
152 : {
153 57 : CPLAssert(poFeatureDefn == NULL);
154 :
155 57 : eGeometryTypeStrategy = eGeometryTypeStrategyIn;
156 57 : eGeomType = eGeomTypeIn;
157 57 : }
158 :
159 : /************************************************************************/
160 : /* SetSourceLayerFieldName() */
161 : /************************************************************************/
162 :
163 57 : void OGRUnionLayer::SetSourceLayerFieldName(const char* pszSourceLayerFieldName)
164 : {
165 57 : CPLAssert(poFeatureDefn == NULL);
166 :
167 57 : CPLAssert(osSourceLayerFieldName.size() == 0);
168 57 : if( pszSourceLayerFieldName != NULL )
169 9 : osSourceLayerFieldName = pszSourceLayerFieldName;
170 57 : }
171 :
172 : /************************************************************************/
173 : /* SetPreserveSrcFID() */
174 : /************************************************************************/
175 :
176 57 : void OGRUnionLayer::SetPreserveSrcFID(int bPreserveSrcFIDIn)
177 : {
178 57 : CPLAssert(poFeatureDefn == NULL);
179 :
180 57 : bPreserveSrcFID = bPreserveSrcFIDIn;
181 57 : }
182 :
183 : /************************************************************************/
184 : /* SetFeatureCount() */
185 : /************************************************************************/
186 :
187 9 : void OGRUnionLayer::SetFeatureCount(int nFeatureCountIn)
188 : {
189 9 : CPLAssert(poFeatureDefn == NULL);
190 :
191 9 : nFeatureCount = nFeatureCountIn;
192 9 : }
193 :
194 : /************************************************************************/
195 : /* SetExtent() */
196 : /************************************************************************/
197 :
198 9 : void OGRUnionLayer::SetExtent( double dfXMin, double dfYMin,
199 : double dfXMax, double dfYMax )
200 : {
201 9 : CPLAssert(poFeatureDefn == NULL);
202 :
203 9 : sStaticEnvelope.MinX = dfXMin;
204 9 : sStaticEnvelope.MinY = dfYMin;
205 9 : sStaticEnvelope.MaxX = dfXMax;
206 9 : sStaticEnvelope.MaxY = dfYMax;
207 9 : }
208 :
209 : /************************************************************************/
210 : /* MergeFieldDefn() */
211 : /************************************************************************/
212 :
213 16 : static void MergeFieldDefn(OGRFieldDefn* poFieldDefn,
214 : OGRFieldDefn* poSrcFieldDefn)
215 : {
216 16 : if( poFieldDefn->GetType() != poSrcFieldDefn->GetType() )
217 : {
218 2 : if( poSrcFieldDefn->GetType() == OFTReal &&
219 : poFieldDefn->GetType() == OFTInteger)
220 0 : poFieldDefn->SetType(OFTReal);
221 : else
222 2 : poFieldDefn->SetType(OFTString);
223 : }
224 :
225 16 : if( poFieldDefn->GetWidth() != poSrcFieldDefn->GetWidth() ||
226 : poFieldDefn->GetPrecision() != poSrcFieldDefn->GetPrecision() )
227 : {
228 4 : poFieldDefn->SetWidth(0);
229 4 : poFieldDefn->SetPrecision(0);
230 : }
231 16 : }
232 :
233 : /************************************************************************/
234 : /* GetLayerDefn() */
235 : /************************************************************************/
236 :
237 293 : OGRFeatureDefn *OGRUnionLayer::GetLayerDefn()
238 : {
239 293 : if( poFeatureDefn != NULL )
240 243 : return poFeatureDefn;
241 :
242 50 : poFeatureDefn = new OGRFeatureDefn( osName );
243 50 : poFeatureDefn->Reference();
244 :
245 50 : int iCompareFirstIndex = 0;
246 50 : if( osSourceLayerFieldName.size() )
247 : {
248 4 : OGRFieldDefn oField(osSourceLayerFieldName, OFTString);
249 4 : poFeatureDefn->AddFieldDefn(&oField);
250 4 : iCompareFirstIndex = 1;
251 : }
252 :
253 50 : if( eFieldStrategy == FIELD_SPECIFIED )
254 : {
255 0 : for(int i = 0; i < nFields; i++)
256 0 : poFeatureDefn->AddFieldDefn(papoFields[i]);
257 : }
258 50 : else if( eFieldStrategy == FIELD_FROM_FIRST_LAYER )
259 : {
260 0 : OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn();
261 0 : for(int i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++)
262 0 : poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i));
263 : }
264 50 : else if (eFieldStrategy == FIELD_UNION_ALL_LAYERS )
265 : {
266 138 : for(int iLayer = 0; iLayer < nSrcLayers; iLayer++)
267 : {
268 : OGRFeatureDefn* poSrcFeatureDefn =
269 92 : papoSrcLayers[iLayer]->GetLayerDefn();
270 :
271 : /* Add any field that is found in the source layers */
272 142 : for(int i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++)
273 : {
274 50 : OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i);
275 : int nIndex =
276 50 : poFeatureDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
277 50 : if( nIndex < 0 )
278 38 : poFeatureDefn->AddFieldDefn(poSrcFieldDefn);
279 : else
280 : {
281 : OGRFieldDefn* poFieldDefn =
282 12 : poFeatureDefn->GetFieldDefn(nIndex);
283 12 : MergeFieldDefn(poFieldDefn, poSrcFieldDefn);
284 : }
285 : }
286 : }
287 : }
288 4 : else if (eFieldStrategy == FIELD_INTERSECTION_ALL_LAYERS )
289 : {
290 4 : OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn();
291 : int i;
292 12 : for(i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++)
293 8 : poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i));
294 :
295 : /* Remove any field that is not found in the source layers */
296 8 : for(int iLayer = 1; iLayer < nSrcLayers; iLayer++)
297 : {
298 : OGRFeatureDefn* poSrcFeatureDefn =
299 4 : papoSrcLayers[iLayer]->GetLayerDefn();
300 16 : for(i = iCompareFirstIndex; i < poFeatureDefn->GetFieldCount();)
301 : {
302 8 : OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(i);
303 : int nSrcIndex = poSrcFeatureDefn->GetFieldIndex(
304 8 : poFieldDefn->GetNameRef());
305 8 : if( nSrcIndex < 0 )
306 : {
307 4 : poFeatureDefn->DeleteFieldDefn(i);
308 : }
309 : else
310 : {
311 : OGRFieldDefn* poSrcFieldDefn =
312 4 : poSrcFeatureDefn->GetFieldDefn(nSrcIndex);
313 4 : MergeFieldDefn(poFieldDefn, poSrcFieldDefn);
314 :
315 4 : i ++;
316 : }
317 : }
318 : }
319 : }
320 :
321 50 : poFeatureDefn->SetGeomType(GetGeomType());
322 :
323 50 : return poFeatureDefn;
324 : }
325 :
326 : /************************************************************************/
327 : /* GetGeomType() */
328 : /************************************************************************/
329 :
330 89 : OGRwkbGeometryType OGRUnionLayer::GetGeomType()
331 : {
332 89 : if( eGeometryTypeStrategy == GEOMTYPE_SPECIFIED )
333 42 : return eGeomType;
334 :
335 47 : if( eGeometryTypeStrategy == GEOMTYPE_FROM_FIRST_LAYER )
336 : {
337 0 : eGeomType = papoSrcLayers[0]->GetGeomType();
338 : }
339 47 : else if( eGeometryTypeStrategy == GEOMTYPE_UNION_ALL_LAYERS )
340 : {
341 47 : eGeomType = papoSrcLayers[0]->GetGeomType();
342 94 : for(int iLayer = 1; iLayer < nSrcLayers; iLayer++)
343 : {
344 : OGRwkbGeometryType eSrcGeomType =
345 47 : papoSrcLayers[iLayer]->GetGeomType();
346 47 : eGeomType = OGRMergeGeometryTypes(eGeomType, eSrcGeomType);
347 : }
348 : }
349 47 : eGeometryTypeStrategy = GEOMTYPE_SPECIFIED;
350 :
351 47 : return eGeomType;
352 : }
353 :
354 : /************************************************************************/
355 : /* ConfigureActiveLayer() */
356 : /************************************************************************/
357 :
358 129 : void OGRUnionLayer::ConfigureActiveLayer()
359 : {
360 129 : AutoWarpLayerIfNecessary(iCurLayer);
361 129 : ApplyAttributeFilterToSrcLayer(iCurLayer);
362 129 : papoSrcLayers[iCurLayer]->SetSpatialFilter(m_poFilterGeom);
363 129 : papoSrcLayers[iCurLayer]->ResetReading();
364 :
365 : /* Establish map */
366 129 : OGRFeatureDefn* poFeatureDefn = GetLayerDefn();
367 129 : OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iCurLayer]->GetLayerDefn();
368 129 : CPLFree(panMap);
369 129 : panMap = (int*) CPLMalloc(poSrcFeatureDefn->GetFieldCount() * sizeof(int));
370 375 : for(int i=0; i < poSrcFeatureDefn->GetFieldCount(); i++)
371 : {
372 246 : OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i);
373 246 : if( CSLFindString(papszIgnoredFields,
374 : poSrcFieldDefn->GetNameRef() ) == -1 )
375 : {
376 236 : panMap[i] =
377 236 : poFeatureDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
378 : }
379 : else
380 : {
381 10 : panMap[i] = -1;
382 : }
383 : }
384 :
385 129 : if( papoSrcLayers[iCurLayer]->TestCapability(OLCIgnoreFields) )
386 : {
387 122 : char** papszIter = papszIgnoredFields;
388 122 : char** papszFieldsSrc = NULL;
389 264 : while ( papszIter != NULL && *papszIter != NULL )
390 : {
391 20 : const char* pszFieldName = *papszIter;
392 20 : if ( EQUAL(pszFieldName, "OGR_GEOMETRY") ||
393 : EQUAL(pszFieldName, "OGR_STYLE") ||
394 : poSrcFeatureDefn->GetFieldIndex(pszFieldName) >= 0 )
395 : {
396 14 : papszFieldsSrc = CSLAddString(papszFieldsSrc, pszFieldName);
397 : }
398 20 : papszIter++;
399 : }
400 :
401 : int* panSrcFieldsUsed = (int*) CPLCalloc(sizeof(int),
402 122 : poSrcFeatureDefn->GetFieldCount());
403 475 : for(int iField = 0;
404 : iField < poFeatureDefn->GetFieldCount(); iField++)
405 : {
406 353 : OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(iField);
407 : int iSrcField =
408 353 : poSrcFeatureDefn->GetFieldIndex(poFieldDefn->GetNameRef());
409 353 : if (iSrcField >= 0)
410 232 : panSrcFieldsUsed[iSrcField] = TRUE;
411 : }
412 364 : for(int iSrcField = 0;
413 : iSrcField < poSrcFeatureDefn->GetFieldCount(); iSrcField ++)
414 : {
415 242 : if( !panSrcFieldsUsed[iSrcField] )
416 : {
417 : OGRFieldDefn *poSrcDefn =
418 10 : poSrcFeatureDefn->GetFieldDefn( iSrcField );
419 : papszFieldsSrc =
420 10 : CSLAddString(papszFieldsSrc, poSrcDefn->GetNameRef());
421 : }
422 : }
423 122 : CPLFree(panSrcFieldsUsed);
424 :
425 122 : papoSrcLayers[iCurLayer]->SetIgnoredFields((const char**)papszFieldsSrc);
426 :
427 122 : CSLDestroy(papszFieldsSrc);
428 : }
429 129 : }
430 :
431 : /************************************************************************/
432 : /* ResetReading() */
433 : /************************************************************************/
434 :
435 97 : void OGRUnionLayer::ResetReading()
436 : {
437 97 : iCurLayer = 0;
438 97 : ConfigureActiveLayer();
439 97 : nNextFID = 0;
440 97 : }
441 :
442 : /************************************************************************/
443 : /* AutoWarpLayerIfNecessary() */
444 : /************************************************************************/
445 :
446 187 : void OGRUnionLayer::AutoWarpLayerIfNecessary(int iLayer)
447 : {
448 187 : if( !pabCheckIfAutoWrap[iLayer] )
449 : {
450 38 : pabCheckIfAutoWrap[iLayer] = TRUE;
451 :
452 38 : OGRSpatialReference* poSRS = GetSpatialRef();
453 38 : if( poSRS != NULL )
454 26 : poSRS->Reference();
455 :
456 38 : OGRSpatialReference* poSRS2 = papoSrcLayers[iLayer]->GetSpatialRef();
457 :
458 38 : if( (poSRS == NULL && poSRS2 != NULL) ||
459 : (poSRS != NULL && poSRS2 == NULL) )
460 : {
461 : CPLError(CE_Warning, CPLE_AppDefined,
462 : "SRS of layer %s not consistant with layer SRS",
463 0 : papoSrcLayers[iLayer]->GetName());
464 : }
465 38 : else if (poSRS != NULL && poSRS2 != NULL &&
466 : poSRS != poSRS2 && !poSRS->IsSame(poSRS2))
467 : {
468 : CPLDebug("VRT", "SRS of layer %s not consistant with layer SRS. "
469 : "Trying auto warping",
470 8 : papoSrcLayers[iLayer]->GetName());
471 : OGRCoordinateTransformation* poCT =
472 8 : OGRCreateCoordinateTransformation( poSRS2, poSRS );
473 : OGRCoordinateTransformation* poReversedCT = (poCT != NULL) ?
474 8 : OGRCreateCoordinateTransformation( poSRS, poSRS2 ) : NULL;
475 8 : if( poCT != NULL && poReversedCT != NULL )
476 8 : papoSrcLayers[iLayer] = new OGRWarpedLayer(
477 8 : papoSrcLayers[iLayer], TRUE, poCT, poReversedCT);
478 : }
479 :
480 38 : if( poSRS != NULL )
481 26 : poSRS->Release();
482 : }
483 187 : }
484 :
485 : /************************************************************************/
486 : /* GetNextFeature() */
487 : /************************************************************************/
488 :
489 1040 : OGRFeature *OGRUnionLayer::GetNextFeature()
490 : {
491 1040 : if( poFeatureDefn == NULL ) GetLayerDefn();
492 1040 : if( iCurLayer < 0 )
493 2 : ResetReading();
494 :
495 1040 : if( iCurLayer == nSrcLayers )
496 0 : return NULL;
497 :
498 333 : while(TRUE)
499 : {
500 1373 : OGRFeature* poSrcFeature = papoSrcLayers[iCurLayer]->GetNextFeature();
501 1373 : if( poSrcFeature == NULL )
502 : {
503 62 : iCurLayer ++;
504 62 : if( iCurLayer < nSrcLayers )
505 : {
506 32 : ConfigureActiveLayer();
507 32 : continue;
508 : }
509 : else
510 : break;
511 : }
512 :
513 1311 : OGRFeature* poFeature = TranslateFromSrcLayer(poSrcFeature);
514 1311 : delete poSrcFeature;
515 :
516 1311 : if( (m_poFilterGeom == NULL ||
517 : FilterGeometry( poFeature->GetGeometryRef() ) ) &&
518 : (m_poAttrQuery == NULL ||
519 : m_poAttrQuery->Evaluate( poFeature )) )
520 : {
521 1010 : return poFeature;
522 : }
523 :
524 301 : delete poFeature;
525 : }
526 30 : return NULL;
527 : }
528 :
529 : /************************************************************************/
530 : /* GetFeature() */
531 : /************************************************************************/
532 :
533 4 : OGRFeature *OGRUnionLayer::GetFeature( long nFeatureId )
534 : {
535 4 : if( !bPreserveSrcFID )
536 4 : return OGRLayer::GetFeature(nFeatureId);
537 :
538 0 : for(int i=0;i<nSrcLayers;i++)
539 : {
540 0 : iCurLayer = i;
541 0 : ConfigureActiveLayer();
542 :
543 0 : OGRFeature* poSrcFeature = papoSrcLayers[i]->GetFeature(nFeatureId);
544 0 : if( poSrcFeature != NULL )
545 : {
546 0 : OGRFeature* poFeature = TranslateFromSrcLayer(poSrcFeature);
547 0 : delete poSrcFeature;
548 :
549 0 : return poFeature;
550 : }
551 : }
552 :
553 0 : ResetReading();
554 :
555 0 : return NULL;
556 : }
557 :
558 : /************************************************************************/
559 : /* CreateFeature() */
560 : /************************************************************************/
561 :
562 5 : OGRErr OGRUnionLayer::CreateFeature( OGRFeature* poFeature )
563 : {
564 5 : if( osSourceLayerFieldName.size() == 0 )
565 : {
566 : CPLError(CE_Failure, CPLE_NotSupported,
567 1 : "CreateFeature() not supported when SourceLayerFieldName is not set");
568 1 : return OGRERR_FAILURE;
569 : }
570 :
571 4 : if( poFeature->GetFID() != OGRNullFID )
572 : {
573 : CPLError(CE_Failure, CPLE_NotSupported,
574 1 : "CreateFeature() not supported when FID is set");
575 1 : return OGRERR_FAILURE;
576 : }
577 :
578 3 : if( !poFeature->IsFieldSet(0) )
579 : {
580 : CPLError(CE_Failure, CPLE_NotSupported,
581 : "CreateFeature() not supported when '%s' field is not set",
582 1 : osSourceLayerFieldName.c_str());
583 1 : return OGRERR_FAILURE;
584 : }
585 :
586 2 : const char* pszSrcLayerName = poFeature->GetFieldAsString(0);
587 5 : for(int i=0;i<nSrcLayers;i++)
588 : {
589 4 : if( strcmp(pszSrcLayerName, papoSrcLayers[i]->GetName()) == 0)
590 : {
591 1 : pabModifiedLayers[i] = TRUE;
592 :
593 : OGRFeature* poSrcFeature =
594 1 : new OGRFeature(papoSrcLayers[i]->GetLayerDefn());
595 1 : poSrcFeature->SetFrom(poFeature, TRUE);
596 1 : OGRErr eErr = papoSrcLayers[i]->CreateFeature(poSrcFeature);
597 1 : if( eErr == OGRERR_NONE )
598 1 : poFeature->SetFID(poSrcFeature->GetFID());
599 1 : delete poSrcFeature;
600 1 : return eErr;
601 : }
602 : }
603 :
604 : CPLError(CE_Failure, CPLE_NotSupported,
605 : "CreateFeature() not supported : '%s' source layer does not exist",
606 1 : pszSrcLayerName);
607 1 : return OGRERR_FAILURE;
608 : }
609 :
610 : /************************************************************************/
611 : /* SetFeature() */
612 : /************************************************************************/
613 :
614 5 : OGRErr OGRUnionLayer::SetFeature( OGRFeature* poFeature )
615 : {
616 5 : if( !bPreserveSrcFID )
617 : {
618 : CPLError(CE_Failure, CPLE_NotSupported,
619 1 : "SetFeature() not supported when PreserveSrcFID is OFF");
620 1 : return OGRERR_FAILURE;
621 : }
622 :
623 4 : if( osSourceLayerFieldName.size() == 0 )
624 : {
625 : CPLError(CE_Failure, CPLE_NotSupported,
626 0 : "SetFeature() not supported when SourceLayerFieldName is not set");
627 0 : return OGRERR_FAILURE;
628 : }
629 :
630 4 : if( poFeature->GetFID() == OGRNullFID )
631 : {
632 : CPLError(CE_Failure, CPLE_NotSupported,
633 1 : "SetFeature() not supported when FID is not set");
634 1 : return OGRERR_FAILURE;
635 : }
636 :
637 3 : if( !poFeature->IsFieldSet(0) )
638 : {
639 : CPLError(CE_Failure, CPLE_NotSupported,
640 : "SetFeature() not supported when '%s' field is not set",
641 1 : osSourceLayerFieldName.c_str());
642 1 : return OGRERR_FAILURE;
643 : }
644 :
645 2 : const char* pszSrcLayerName = poFeature->GetFieldAsString(0);
646 5 : for(int i=0;i<nSrcLayers;i++)
647 : {
648 4 : if( strcmp(pszSrcLayerName, papoSrcLayers[i]->GetName()) == 0)
649 : {
650 1 : pabModifiedLayers[i] = TRUE;
651 :
652 : OGRFeature* poSrcFeature =
653 1 : new OGRFeature(papoSrcLayers[i]->GetLayerDefn());
654 1 : poSrcFeature->SetFrom(poFeature, TRUE);
655 1 : poSrcFeature->SetFID(poFeature->GetFID());
656 1 : OGRErr eErr = papoSrcLayers[i]->SetFeature(poSrcFeature);
657 2 : delete poSrcFeature;
658 1 : return eErr;
659 : }
660 : }
661 :
662 : CPLError(CE_Failure, CPLE_NotSupported,
663 : "SetFeature() not supported : '%s' source layer does not exist",
664 1 : pszSrcLayerName);
665 1 : return OGRERR_FAILURE;
666 : }
667 :
668 : /************************************************************************/
669 : /* GetSpatialRef() */
670 : /************************************************************************/
671 :
672 1286 : OGRSpatialReference *OGRUnionLayer::GetSpatialRef()
673 : {
674 1286 : if( bSRSSet )
675 109 : return poSRS;
676 : else
677 1177 : return papoSrcLayers[0]->GetSpatialRef();
678 : }
679 :
680 : /************************************************************************/
681 : /* GetAttrFilterPassThroughValue() */
682 : /************************************************************************/
683 :
684 224 : int OGRUnionLayer::GetAttrFilterPassThroughValue()
685 : {
686 224 : if( m_poAttrQuery == NULL )
687 164 : return TRUE;
688 :
689 60 : if( bAttrFilterPassThroughValue >= 0)
690 50 : return bAttrFilterPassThroughValue;
691 :
692 10 : char** papszUsedFields = m_poAttrQuery->GetUsedFields();
693 10 : int bRet = TRUE;
694 :
695 30 : for(int iLayer = 0; iLayer < nSrcLayers; iLayer++)
696 : {
697 : OGRFeatureDefn* poSrcFeatureDefn =
698 20 : papoSrcLayers[iLayer]->GetLayerDefn();
699 20 : char** papszIter = papszUsedFields;
700 55 : while( papszIter != NULL && *papszIter != NULL )
701 : {
702 22 : int bIsSpecial = FALSE;
703 116 : for(int i = 0; i < SPECIAL_FIELD_COUNT; i++)
704 : {
705 98 : if( EQUAL(*papszIter, SpecialFieldNames[i]) )
706 : {
707 4 : bIsSpecial = TRUE;
708 4 : break;
709 : }
710 : }
711 22 : if( !bIsSpecial &&
712 : poSrcFeatureDefn->GetFieldIndex(*papszIter) < 0 )
713 : {
714 7 : bRet = FALSE;
715 7 : break;
716 : }
717 15 : papszIter ++;
718 : }
719 : }
720 :
721 10 : CSLDestroy(papszUsedFields);
722 :
723 10 : bAttrFilterPassThroughValue = bRet;
724 :
725 10 : return bRet;
726 : }
727 :
728 : /************************************************************************/
729 : /* ApplyAttributeFilterToSrcLayer() */
730 : /************************************************************************/
731 :
732 195 : void OGRUnionLayer::ApplyAttributeFilterToSrcLayer(int iSubLayer)
733 : {
734 195 : CPLAssert(iSubLayer >= 0 && iSubLayer < nSrcLayers);
735 :
736 195 : if( GetAttrFilterPassThroughValue() )
737 160 : papoSrcLayers[iSubLayer]->SetAttributeFilter(pszAttributeFilter);
738 : else
739 35 : papoSrcLayers[iSubLayer]->SetAttributeFilter(NULL);
740 195 : }
741 :
742 : /************************************************************************/
743 : /* GetFeatureCount() */
744 : /************************************************************************/
745 :
746 27 : int OGRUnionLayer::GetFeatureCount( int bForce )
747 : {
748 27 : if (nFeatureCount >= 0 &&
749 : m_poFilterGeom == NULL && m_poAttrQuery == NULL)
750 : {
751 1 : return nFeatureCount;
752 : }
753 :
754 26 : if( !GetAttrFilterPassThroughValue() )
755 5 : return OGRLayer::GetFeatureCount(bForce);
756 :
757 21 : int nRet = 0;
758 63 : for(int i = 0; i < nSrcLayers; i++)
759 : {
760 42 : AutoWarpLayerIfNecessary(i);
761 42 : ApplyAttributeFilterToSrcLayer(i);
762 42 : papoSrcLayers[i]->SetSpatialFilter(m_poFilterGeom);
763 42 : nRet += papoSrcLayers[i]->GetFeatureCount(bForce);
764 : }
765 21 : ResetReading();
766 21 : return nRet;
767 : }
768 :
769 : /************************************************************************/
770 : /* SetAttributeFilter() */
771 : /************************************************************************/
772 :
773 24 : OGRErr OGRUnionLayer::SetAttributeFilter( const char * pszAttributeFilterIn )
774 : {
775 24 : if( pszAttributeFilterIn == NULL && pszAttributeFilter == NULL)
776 8 : return OGRERR_NONE;
777 16 : if( pszAttributeFilterIn != NULL && pszAttributeFilter != NULL &&
778 : strcmp(pszAttributeFilterIn, pszAttributeFilter) == 0)
779 0 : return OGRERR_NONE;
780 :
781 16 : if( poFeatureDefn == NULL ) GetLayerDefn();
782 :
783 16 : bAttrFilterPassThroughValue = -1;
784 :
785 16 : OGRErr eErr = OGRLayer::SetAttributeFilter(pszAttributeFilterIn);
786 16 : if( eErr != OGRERR_NONE )
787 0 : return eErr;
788 :
789 16 : CPLFree(pszAttributeFilter);
790 : pszAttributeFilter = pszAttributeFilterIn ?
791 16 : CPLStrdup(pszAttributeFilterIn) : NULL;
792 :
793 16 : if( iCurLayer >= 0 && iCurLayer < nSrcLayers)
794 16 : ApplyAttributeFilterToSrcLayer(iCurLayer);
795 :
796 16 : return OGRERR_NONE;
797 : }
798 :
799 : /************************************************************************/
800 : /* TestCapability() */
801 : /************************************************************************/
802 :
803 37 : int OGRUnionLayer::TestCapability( const char * pszCap )
804 : {
805 37 : if( EQUAL(pszCap, OLCFastFeatureCount ) )
806 : {
807 4 : if( nFeatureCount >= 0 &&
808 : m_poFilterGeom == NULL && m_poAttrQuery == NULL )
809 1 : return TRUE;
810 :
811 3 : if( !GetAttrFilterPassThroughValue() )
812 1 : return FALSE;
813 :
814 6 : for(int i = 0; i < nSrcLayers; i++)
815 : {
816 4 : AutoWarpLayerIfNecessary(i);
817 4 : ApplyAttributeFilterToSrcLayer(i);
818 4 : papoSrcLayers[i]->SetSpatialFilter(m_poFilterGeom);
819 4 : if( !papoSrcLayers[i]->TestCapability(pszCap) )
820 0 : return FALSE;
821 : }
822 2 : return TRUE;
823 : }
824 :
825 33 : if( EQUAL(pszCap, OLCFastGetExtent ) )
826 : {
827 2 : if( sStaticEnvelope.IsInit() )
828 1 : return TRUE;
829 :
830 3 : for(int i = 0; i < nSrcLayers; i++)
831 : {
832 2 : AutoWarpLayerIfNecessary(i);
833 2 : if( !papoSrcLayers[i]->TestCapability(pszCap) )
834 0 : return FALSE;
835 : }
836 1 : return TRUE;
837 : }
838 :
839 31 : if( EQUAL(pszCap, OLCFastSpatialFilter) )
840 : {
841 6 : for(int i = 0; i < nSrcLayers; i++)
842 : {
843 4 : AutoWarpLayerIfNecessary(i);
844 4 : ApplyAttributeFilterToSrcLayer(i);
845 4 : if( !papoSrcLayers[i]->TestCapability(pszCap) )
846 0 : return FALSE;
847 : }
848 2 : return TRUE;
849 : }
850 :
851 29 : if( EQUAL(pszCap, OLCStringsAsUTF8) )
852 : {
853 12 : for(int i = 0; i < nSrcLayers; i++)
854 : {
855 8 : if( !papoSrcLayers[i]->TestCapability(pszCap) )
856 0 : return FALSE;
857 : }
858 4 : return TRUE;
859 : }
860 :
861 25 : if( EQUAL(pszCap, OLCRandomRead ) )
862 : {
863 2 : if( !bPreserveSrcFID )
864 2 : return FALSE;
865 :
866 0 : for(int i = 0; i < nSrcLayers; i++)
867 : {
868 0 : if( !papoSrcLayers[i]->TestCapability(pszCap) )
869 0 : return FALSE;
870 : }
871 0 : return TRUE;
872 : }
873 :
874 23 : if( EQUAL(pszCap, OLCRandomWrite ) )
875 : {
876 4 : if( !bPreserveSrcFID || osSourceLayerFieldName.size() == 0)
877 3 : return FALSE;
878 :
879 3 : for(int i = 0; i < nSrcLayers; i++)
880 : {
881 2 : if( !papoSrcLayers[i]->TestCapability(pszCap) )
882 0 : return FALSE;
883 : }
884 1 : return TRUE;
885 : }
886 :
887 19 : if( EQUAL(pszCap, OLCSequentialWrite ) )
888 : {
889 4 : if( osSourceLayerFieldName.size() == 0)
890 3 : return FALSE;
891 :
892 3 : for(int i = 0; i < nSrcLayers; i++)
893 : {
894 2 : if( !papoSrcLayers[i]->TestCapability(pszCap) )
895 0 : return FALSE;
896 : }
897 1 : return TRUE;
898 : }
899 :
900 15 : if( EQUAL(pszCap, OLCIgnoreFields) )
901 9 : return TRUE;
902 :
903 6 : return FALSE;
904 : }
905 :
906 : /************************************************************************/
907 : /* GetExtent() */
908 : /************************************************************************/
909 :
910 4 : OGRErr OGRUnionLayer::GetExtent( OGREnvelope *psExtent, int bForce )
911 : {
912 4 : if( sStaticEnvelope.IsInit() )
913 : {
914 1 : memcpy(psExtent, &sStaticEnvelope, sizeof(OGREnvelope));
915 1 : return OGRERR_NONE;
916 : }
917 :
918 3 : int bInit = FALSE;
919 9 : for(int i = 0; i < nSrcLayers; i++)
920 : {
921 6 : AutoWarpLayerIfNecessary(i);
922 6 : if( !bInit )
923 : {
924 3 : if( papoSrcLayers[i]->GetExtent(psExtent, bForce) == OGRERR_NONE )
925 3 : bInit = TRUE;
926 : }
927 : else
928 : {
929 3 : OGREnvelope sExtent;
930 3 : if( papoSrcLayers[i]->GetExtent(&sExtent, bForce) == OGRERR_NONE )
931 : {
932 3 : psExtent->Merge(sExtent);
933 : }
934 : }
935 : }
936 3 : return (bInit) ? OGRERR_NONE : OGRERR_FAILURE;
937 : }
938 :
939 : /************************************************************************/
940 : /* SetSpatialFilter() */
941 : /************************************************************************/
942 :
943 22 : void OGRUnionLayer::SetSpatialFilter( OGRGeometry * poGeomIn )
944 : {
945 22 : OGRLayer::SetSpatialFilter(poGeomIn);
946 :
947 22 : if( iCurLayer >= 0 && iCurLayer < nSrcLayers)
948 18 : papoSrcLayers[iCurLayer]->SetSpatialFilter(poGeomIn);
949 22 : }
950 :
951 : /************************************************************************/
952 : /* TranslateFromSrcLayer() */
953 : /************************************************************************/
954 :
955 1311 : OGRFeature* OGRUnionLayer::TranslateFromSrcLayer(OGRFeature* poSrcFeature)
956 : {
957 1311 : CPLAssert(panMap != NULL);
958 1311 : CPLAssert(iCurLayer >= 0 && iCurLayer < nSrcLayers);
959 :
960 1311 : OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
961 1311 : poFeature->SetFrom(poSrcFeature, panMap, TRUE);
962 :
963 1413 : if( osSourceLayerFieldName.size() &&
964 : !poFeatureDefn->GetFieldDefn(0)->IsIgnored() )
965 : {
966 102 : poFeature->SetField(0, papoSrcLayers[iCurLayer]->GetName());
967 : }
968 :
969 1311 : if( poFeatureDefn->IsGeometryIgnored() )
970 100 : poFeature->SetGeometryDirectly(NULL);
971 : else
972 : {
973 1211 : OGRGeometry* poGeom = poFeature->GetGeometryRef();
974 1211 : if( poGeom != NULL )
975 1209 : poGeom->assignSpatialReference(GetSpatialRef());
976 : }
977 :
978 1311 : if( bPreserveSrcFID )
979 102 : poFeature->SetFID(poSrcFeature->GetFID());
980 : else
981 1209 : poFeature->SetFID(nNextFID ++);
982 1311 : return poFeature;
983 : }
984 :
985 : /************************************************************************/
986 : /* SetIgnoredFields() */
987 : /************************************************************************/
988 :
989 16 : OGRErr OGRUnionLayer::SetIgnoredFields( const char **papszFields )
990 : {
991 16 : OGRErr eErr = OGRLayer::SetIgnoredFields(papszFields);
992 16 : if( eErr != OGRERR_NONE )
993 0 : return eErr;
994 :
995 16 : CSLDestroy(papszIgnoredFields);
996 16 : papszIgnoredFields = papszFields ? CSLDuplicate((char**)papszFields) : NULL;
997 :
998 16 : return eErr;
999 : }
1000 :
1001 : /************************************************************************/
1002 : /* SyncToDisk() */
1003 : /************************************************************************/
1004 :
1005 1 : OGRErr OGRUnionLayer::SyncToDisk()
1006 : {
1007 3 : for(int i = 0; i < nSrcLayers; i++)
1008 : {
1009 2 : if (pabModifiedLayers[i])
1010 : {
1011 1 : papoSrcLayers[i]->SyncToDisk();
1012 1 : pabModifiedLayers[i] = FALSE;
1013 : }
1014 : }
1015 :
1016 1 : return OGRERR_NONE;
1017 : }
|