1 : /******************************************************************************
2 : * $Id: ogrlayer.cpp 17223 2009-06-07 19:41:08Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: The generic portions of the OGRSFLayer class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Les Technologies SoftMap Inc.
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 "ogrsf_frmts.h"
31 : #include "ogr_api.h"
32 : #include "ogr_p.h"
33 : #include "ogr_attrind.h"
34 :
35 : CPL_CVSID("$Id: ogrlayer.cpp 17223 2009-06-07 19:41:08Z rouault $");
36 :
37 : /************************************************************************/
38 : /* OGRLayer() */
39 : /************************************************************************/
40 :
41 1976 : OGRLayer::OGRLayer()
42 :
43 : {
44 1976 : m_poStyleTable = NULL;
45 1976 : m_poAttrQuery = NULL;
46 1976 : m_poAttrIndex = NULL;
47 1976 : m_nRefCount = 0;
48 :
49 1976 : m_nFeaturesRead = 0;
50 :
51 1976 : m_poFilterGeom = NULL;
52 1976 : m_bFilterIsEnvelope = FALSE;
53 1976 : }
54 :
55 : /************************************************************************/
56 : /* ~OGRLayer() */
57 : /************************************************************************/
58 :
59 1976 : OGRLayer::~OGRLayer()
60 :
61 : {
62 1976 : if ( m_poStyleTable )
63 : {
64 0 : delete m_poStyleTable;
65 0 : m_poStyleTable = NULL;
66 : }
67 :
68 1976 : if( m_poAttrIndex != NULL )
69 : {
70 914 : delete m_poAttrIndex;
71 914 : m_poAttrIndex = NULL;
72 : }
73 :
74 1976 : if( m_poAttrQuery != NULL )
75 : {
76 11 : delete m_poAttrQuery;
77 11 : m_poAttrQuery = NULL;
78 : }
79 :
80 1976 : if( m_poFilterGeom )
81 : {
82 13 : delete m_poFilterGeom;
83 13 : m_poFilterGeom = NULL;
84 : }
85 1976 : }
86 :
87 : /************************************************************************/
88 : /* Reference() */
89 : /************************************************************************/
90 :
91 0 : int OGRLayer::Reference()
92 :
93 : {
94 0 : return ++m_nRefCount;
95 : }
96 :
97 : /************************************************************************/
98 : /* OGR_L_Reference() */
99 : /************************************************************************/
100 :
101 0 : int OGR_L_Reference( OGRLayerH hLayer )
102 :
103 : {
104 0 : VALIDATE_POINTER1( hLayer, "OGR_L_Reference", 0 );
105 :
106 0 : return ((OGRLayer *) hLayer)->Reference();
107 : }
108 :
109 : /************************************************************************/
110 : /* Dereference() */
111 : /************************************************************************/
112 :
113 0 : int OGRLayer::Dereference()
114 :
115 : {
116 0 : return --m_nRefCount;
117 : }
118 :
119 : /************************************************************************/
120 : /* OGR_L_Dereference() */
121 : /************************************************************************/
122 :
123 0 : int OGR_L_Dereference( OGRLayerH hLayer )
124 :
125 : {
126 0 : VALIDATE_POINTER1( hLayer, "OGR_L_Dereference", 0 );
127 :
128 0 : return ((OGRLayer *) hLayer)->Dereference();
129 : }
130 :
131 : /************************************************************************/
132 : /* GetRefCount() */
133 : /************************************************************************/
134 :
135 8 : int OGRLayer::GetRefCount() const
136 :
137 : {
138 8 : return m_nRefCount;
139 : }
140 :
141 : /************************************************************************/
142 : /* OGR_L_GetRefCount() */
143 : /************************************************************************/
144 :
145 0 : int OGR_L_GetRefCount( OGRLayerH hLayer )
146 :
147 : {
148 0 : VALIDATE_POINTER1( hLayer, "OGR_L_GetRefCount", 0 );
149 :
150 0 : return ((OGRLayer *) hLayer)->GetRefCount();
151 : }
152 :
153 : /************************************************************************/
154 : /* GetFeatureCount() */
155 : /************************************************************************/
156 :
157 86 : int OGRLayer::GetFeatureCount( int bForce )
158 :
159 : {
160 : OGRFeature *poFeature;
161 86 : int nFeatureCount = 0;
162 :
163 86 : if( !bForce )
164 1 : return -1;
165 :
166 85 : ResetReading();
167 31956 : while( (poFeature = GetNextFeature()) != NULL )
168 : {
169 31786 : nFeatureCount++;
170 31786 : delete poFeature;
171 : }
172 85 : ResetReading();
173 :
174 85 : return nFeatureCount;
175 : }
176 :
177 : /************************************************************************/
178 : /* OGR_L_GetFeatureCount() */
179 : /************************************************************************/
180 :
181 271 : int OGR_L_GetFeatureCount( OGRLayerH hLayer, int bForce )
182 :
183 : {
184 271 : VALIDATE_POINTER1( hLayer, "OGR_L_GetFeature", 0 );
185 :
186 271 : return ((OGRLayer *) hLayer)->GetFeatureCount(bForce);
187 : }
188 :
189 : /************************************************************************/
190 : /* GetExtent() */
191 : /************************************************************************/
192 :
193 13 : OGRErr OGRLayer::GetExtent(OGREnvelope *psExtent, int bForce )
194 :
195 : {
196 : OGRFeature *poFeature;
197 13 : OGREnvelope oEnv;
198 13 : GBool bExtentSet = FALSE;
199 :
200 : /* -------------------------------------------------------------------- */
201 : /* If this layer has a none geometry type, then we can */
202 : /* reasonably assume there are not extents available. */
203 : /* -------------------------------------------------------------------- */
204 13 : if( GetLayerDefn()->GetGeomType() == wkbNone )
205 : {
206 0 : psExtent->MinX = 0.0;
207 0 : psExtent->MaxX = 0.0;
208 0 : psExtent->MinY = 0.0;
209 0 : psExtent->MaxY = 0.0;
210 :
211 0 : return OGRERR_FAILURE;
212 : }
213 :
214 : /* -------------------------------------------------------------------- */
215 : /* If not forced, we should avoid having to scan all the */
216 : /* features and just return a failure. */
217 : /* -------------------------------------------------------------------- */
218 13 : if( !bForce )
219 0 : return OGRERR_FAILURE;
220 :
221 : /* -------------------------------------------------------------------- */
222 : /* OK, we hate to do this, but go ahead and read through all */
223 : /* the features to collect geometries and build extents. */
224 : /* -------------------------------------------------------------------- */
225 13 : ResetReading();
226 61 : while( (poFeature = GetNextFeature()) != NULL )
227 : {
228 35 : OGRGeometry *poGeom = poFeature->GetGeometryRef();
229 48 : if (poGeom && !bExtentSet)
230 : {
231 13 : poGeom->getEnvelope(psExtent);
232 13 : bExtentSet = TRUE;
233 : }
234 22 : else if (poGeom)
235 : {
236 19 : poGeom->getEnvelope(&oEnv);
237 19 : if (oEnv.MinX < psExtent->MinX)
238 4 : psExtent->MinX = oEnv.MinX;
239 19 : if (oEnv.MinY < psExtent->MinY)
240 6 : psExtent->MinY = oEnv.MinY;
241 19 : if (oEnv.MaxX > psExtent->MaxX)
242 4 : psExtent->MaxX = oEnv.MaxX;
243 19 : if (oEnv.MaxY > psExtent->MaxY)
244 0 : psExtent->MaxY = oEnv.MaxY;
245 : }
246 35 : delete poFeature;
247 : }
248 13 : ResetReading();
249 :
250 13 : return (bExtentSet ? OGRERR_NONE : OGRERR_FAILURE);
251 : }
252 :
253 : /************************************************************************/
254 : /* OGR_L_GetExtent() */
255 : /************************************************************************/
256 :
257 17 : OGRErr OGR_L_GetExtent( OGRLayerH hLayer, OGREnvelope *psExtent, int bForce )
258 :
259 : {
260 17 : VALIDATE_POINTER1( hLayer, "OGR_L_GetExtent", OGRERR_INVALID_HANDLE );
261 :
262 17 : return ((OGRLayer *) hLayer)->GetExtent( psExtent, bForce );
263 : }
264 :
265 : /************************************************************************/
266 : /* SetAttributeFilter() */
267 : /************************************************************************/
268 :
269 270 : OGRErr OGRLayer::SetAttributeFilter( const char *pszQuery )
270 :
271 : {
272 : /* -------------------------------------------------------------------- */
273 : /* Are we just clearing any existing query? */
274 : /* -------------------------------------------------------------------- */
275 270 : if( pszQuery == NULL || strlen(pszQuery) == 0 )
276 : {
277 144 : if( m_poAttrQuery )
278 : {
279 49 : delete m_poAttrQuery;
280 49 : m_poAttrQuery = NULL;
281 49 : ResetReading();
282 : }
283 144 : return OGRERR_NONE;
284 : }
285 :
286 : /* -------------------------------------------------------------------- */
287 : /* Or are we installing a new query? */
288 : /* -------------------------------------------------------------------- */
289 : OGRErr eErr;
290 :
291 126 : if( !m_poAttrQuery )
292 60 : m_poAttrQuery = new OGRFeatureQuery();
293 :
294 126 : eErr = m_poAttrQuery->Compile( GetLayerDefn(), pszQuery );
295 126 : if( eErr != OGRERR_NONE )
296 : {
297 0 : delete m_poAttrQuery;
298 0 : m_poAttrQuery = NULL;
299 : }
300 :
301 126 : ResetReading();
302 :
303 126 : return eErr;
304 : }
305 :
306 : /************************************************************************/
307 : /* OGR_L_SetAttributeFilter() */
308 : /************************************************************************/
309 :
310 133 : OGRErr OGR_L_SetAttributeFilter( OGRLayerH hLayer, const char *pszQuery )
311 :
312 : {
313 133 : VALIDATE_POINTER1( hLayer, "OGR_L_SetAttributeFilter", OGRERR_INVALID_HANDLE );
314 :
315 133 : return ((OGRLayer *) hLayer)->SetAttributeFilter( pszQuery );
316 : }
317 :
318 : /************************************************************************/
319 : /* GetFeature() */
320 : /************************************************************************/
321 :
322 5 : OGRFeature *OGRLayer::GetFeature( long nFID )
323 :
324 : {
325 : OGRFeature *poFeature;
326 :
327 5 : ResetReading();
328 12 : while( (poFeature = GetNextFeature()) != NULL )
329 : {
330 7 : if( poFeature->GetFID() == nFID )
331 5 : return poFeature;
332 : else
333 2 : delete poFeature;
334 : }
335 :
336 0 : return NULL;
337 : }
338 :
339 : /************************************************************************/
340 : /* OGR_L_GetFeature() */
341 : /************************************************************************/
342 :
343 45 : OGRFeatureH OGR_L_GetFeature( OGRLayerH hLayer, long nFeatureId )
344 :
345 : {
346 45 : VALIDATE_POINTER1( hLayer, "OGR_L_GetFeature", NULL );
347 :
348 45 : return (OGRFeatureH) ((OGRLayer *)hLayer)->GetFeature( nFeatureId );
349 : }
350 :
351 : /************************************************************************/
352 : /* SetNextByIndex() */
353 : /************************************************************************/
354 :
355 0 : OGRErr OGRLayer::SetNextByIndex( long nIndex )
356 :
357 : {
358 : OGRFeature *poFeature;
359 :
360 0 : ResetReading();
361 0 : while( nIndex-- > 0 )
362 : {
363 0 : poFeature = GetNextFeature();
364 0 : if( poFeature == NULL )
365 0 : return OGRERR_FAILURE;
366 :
367 0 : delete poFeature;
368 : }
369 :
370 0 : return OGRERR_NONE;
371 : }
372 :
373 : /************************************************************************/
374 : /* OGR_L_SetNextByIndex() */
375 : /************************************************************************/
376 :
377 4 : OGRErr OGR_L_SetNextByIndex( OGRLayerH hLayer, long nIndex )
378 :
379 : {
380 4 : VALIDATE_POINTER1( hLayer, "OGR_L_SetNextByIndex", OGRERR_INVALID_HANDLE );
381 :
382 4 : return ((OGRLayer *)hLayer)->SetNextByIndex( nIndex );
383 : }
384 :
385 : /************************************************************************/
386 : /* OGR_L_GetNextFeature() */
387 : /************************************************************************/
388 :
389 18285 : OGRFeatureH OGR_L_GetNextFeature( OGRLayerH hLayer )
390 :
391 : {
392 18285 : VALIDATE_POINTER1( hLayer, "OGR_L_GetNextFeature", NULL );
393 :
394 18285 : return (OGRFeatureH) ((OGRLayer *)hLayer)->GetNextFeature();
395 : }
396 :
397 : /************************************************************************/
398 : /* SetFeature() */
399 : /************************************************************************/
400 :
401 0 : OGRErr OGRLayer::SetFeature( OGRFeature * )
402 :
403 : {
404 0 : return OGRERR_UNSUPPORTED_OPERATION;
405 : }
406 :
407 : /************************************************************************/
408 : /* OGR_L_SetFeature() */
409 : /************************************************************************/
410 :
411 2024 : OGRErr OGR_L_SetFeature( OGRLayerH hLayer, OGRFeatureH hFeat )
412 :
413 : {
414 2024 : VALIDATE_POINTER1( hLayer, "OGR_L_SetFeature", OGRERR_INVALID_HANDLE );
415 2024 : VALIDATE_POINTER1( hFeat, "OGR_L_SetFeature", OGRERR_INVALID_HANDLE );
416 :
417 2024 : return ((OGRLayer *)hLayer)->SetFeature( (OGRFeature *) hFeat );
418 : }
419 :
420 : /************************************************************************/
421 : /* CreateFeature() */
422 : /************************************************************************/
423 :
424 0 : OGRErr OGRLayer::CreateFeature( OGRFeature * )
425 :
426 : {
427 0 : return OGRERR_UNSUPPORTED_OPERATION;
428 : }
429 :
430 : /************************************************************************/
431 : /* OGR_L_CreateFeature() */
432 : /************************************************************************/
433 :
434 17370 : OGRErr OGR_L_CreateFeature( OGRLayerH hLayer, OGRFeatureH hFeat )
435 :
436 : {
437 17370 : VALIDATE_POINTER1( hLayer, "OGR_L_CreateFeature", OGRERR_INVALID_HANDLE );
438 17370 : VALIDATE_POINTER1( hFeat, "OGR_L_SetFeature", OGRERR_INVALID_HANDLE );
439 :
440 17370 : return ((OGRLayer *) hLayer)->CreateFeature( (OGRFeature *) hFeat );
441 : }
442 :
443 : /************************************************************************/
444 : /* GetInfo() */
445 : /************************************************************************/
446 :
447 0 : const char *OGRLayer::GetInfo( const char * pszTag )
448 :
449 : {
450 : (void) pszTag;
451 0 : return NULL;
452 : }
453 :
454 : /************************************************************************/
455 : /* CreateField() */
456 : /************************************************************************/
457 :
458 0 : OGRErr OGRLayer::CreateField( OGRFieldDefn * poField, int bApproxOK )
459 :
460 : {
461 : (void) poField;
462 : (void) bApproxOK;
463 :
464 : CPLError( CE_Failure, CPLE_NotSupported,
465 0 : "CreateField() not supported by this layer.\n" );
466 :
467 0 : return OGRERR_UNSUPPORTED_OPERATION;
468 : }
469 :
470 : /************************************************************************/
471 : /* OGR_L_CreateField() */
472 : /************************************************************************/
473 :
474 334 : OGRErr OGR_L_CreateField( OGRLayerH hLayer, OGRFieldDefnH hField,
475 : int bApproxOK )
476 :
477 : {
478 334 : VALIDATE_POINTER1( hLayer, "OGR_L_CreateField", OGRERR_INVALID_HANDLE );
479 334 : VALIDATE_POINTER1( hField, "OGR_L_CreateField", OGRERR_INVALID_HANDLE );
480 :
481 : return ((OGRLayer *) hLayer)->CreateField( (OGRFieldDefn *) hField,
482 334 : bApproxOK );
483 : }
484 :
485 : /************************************************************************/
486 : /* StartTransaction() */
487 : /************************************************************************/
488 :
489 21 : OGRErr OGRLayer::StartTransaction()
490 :
491 : {
492 21 : return OGRERR_NONE;
493 : }
494 :
495 : /************************************************************************/
496 : /* OGR_L_StartTransaction() */
497 : /************************************************************************/
498 :
499 6 : OGRErr OGR_L_StartTransaction( OGRLayerH hLayer )
500 :
501 : {
502 6 : VALIDATE_POINTER1( hLayer, "OGR_L_StartTransaction", OGRERR_INVALID_HANDLE );
503 :
504 6 : return ((OGRLayer *)hLayer)->StartTransaction();
505 : }
506 :
507 : /************************************************************************/
508 : /* CommitTransaction() */
509 : /************************************************************************/
510 :
511 21 : OGRErr OGRLayer::CommitTransaction()
512 :
513 : {
514 21 : return OGRERR_NONE;
515 : }
516 :
517 : /************************************************************************/
518 : /* OGR_L_CommitTransaction() */
519 : /************************************************************************/
520 :
521 5 : OGRErr OGR_L_CommitTransaction( OGRLayerH hLayer )
522 :
523 : {
524 5 : VALIDATE_POINTER1( hLayer, "OGR_L_CommitTransaction", OGRERR_INVALID_HANDLE );
525 :
526 5 : return ((OGRLayer *)hLayer)->CommitTransaction();
527 : }
528 :
529 : /************************************************************************/
530 : /* RollbackTransaction() */
531 : /************************************************************************/
532 :
533 0 : OGRErr OGRLayer::RollbackTransaction()
534 :
535 : {
536 0 : return OGRERR_UNSUPPORTED_OPERATION;
537 : }
538 :
539 : /************************************************************************/
540 : /* OGR_L_RollbackTransaction() */
541 : /************************************************************************/
542 :
543 1 : OGRErr OGR_L_RollbackTransaction( OGRLayerH hLayer )
544 :
545 : {
546 1 : VALIDATE_POINTER1( hLayer, "OGR_L_RollbackTransaction", OGRERR_INVALID_HANDLE );
547 :
548 1 : return ((OGRLayer *)hLayer)->RollbackTransaction();
549 : }
550 :
551 : /************************************************************************/
552 : /* OGR_L_GetLayerDefn() */
553 : /************************************************************************/
554 :
555 16019 : OGRFeatureDefnH OGR_L_GetLayerDefn( OGRLayerH hLayer )
556 :
557 : {
558 16019 : VALIDATE_POINTER1( hLayer, "OGR_L_GetLayerDefn", NULL );
559 :
560 16019 : return (OGRFeatureDefnH) ((OGRLayer *)hLayer)->GetLayerDefn();
561 : }
562 :
563 : /************************************************************************/
564 : /* OGR_L_GetSpatialRef() */
565 : /************************************************************************/
566 :
567 52 : OGRSpatialReferenceH OGR_L_GetSpatialRef( OGRLayerH hLayer )
568 :
569 : {
570 52 : VALIDATE_POINTER1( hLayer, "OGR_L_GetSpatialRef", NULL );
571 :
572 52 : return (OGRSpatialReferenceH) ((OGRLayer *) hLayer)->GetSpatialRef();
573 : }
574 :
575 : /************************************************************************/
576 : /* OGR_L_TestCapability() */
577 : /************************************************************************/
578 :
579 40 : int OGR_L_TestCapability( OGRLayerH hLayer, const char *pszCap )
580 :
581 : {
582 40 : VALIDATE_POINTER1( hLayer, "OGR_L_TestCapability", 0 );
583 40 : VALIDATE_POINTER1( pszCap, "OGR_L_TestCapability", 0 );
584 :
585 40 : return ((OGRLayer *) hLayer)->TestCapability( pszCap );
586 : }
587 :
588 : /************************************************************************/
589 : /* GetSpatialFilter() */
590 : /************************************************************************/
591 :
592 0 : OGRGeometry *OGRLayer::GetSpatialFilter()
593 :
594 : {
595 0 : return m_poFilterGeom;
596 : }
597 :
598 : /************************************************************************/
599 : /* OGR_L_GetSpatialFilter() */
600 : /************************************************************************/
601 :
602 0 : OGRGeometryH OGR_L_GetSpatialFilter( OGRLayerH hLayer )
603 :
604 : {
605 0 : VALIDATE_POINTER1( hLayer, "OGR_L_GetSpatialFilter", NULL );
606 :
607 0 : return (OGRGeometryH) ((OGRLayer *) hLayer)->GetSpatialFilter();
608 : }
609 :
610 : /************************************************************************/
611 : /* SetSpatialFilter() */
612 : /************************************************************************/
613 :
614 188 : void OGRLayer::SetSpatialFilter( OGRGeometry * poGeomIn )
615 :
616 : {
617 188 : if( InstallFilter( poGeomIn ) )
618 36 : ResetReading();
619 188 : }
620 :
621 : /************************************************************************/
622 : /* OGR_L_SetSpatialFilter() */
623 : /************************************************************************/
624 :
625 31 : void OGR_L_SetSpatialFilter( OGRLayerH hLayer, OGRGeometryH hGeom )
626 :
627 : {
628 31 : VALIDATE_POINTER0( hLayer, "OGR_L_SetSpatialFilter" );
629 :
630 31 : ((OGRLayer *) hLayer)->SetSpatialFilter( (OGRGeometry *) hGeom );
631 : }
632 :
633 : /************************************************************************/
634 : /* SetSpatialFilterRect() */
635 : /************************************************************************/
636 :
637 14 : void OGRLayer::SetSpatialFilterRect( double dfMinX, double dfMinY,
638 : double dfMaxX, double dfMaxY )
639 :
640 : {
641 14 : OGRLinearRing oRing;
642 14 : OGRPolygon oPoly;
643 :
644 14 : oRing.addPoint( dfMinX, dfMinY );
645 14 : oRing.addPoint( dfMinX, dfMaxY );
646 14 : oRing.addPoint( dfMaxX, dfMaxY );
647 14 : oRing.addPoint( dfMaxX, dfMinY );
648 14 : oRing.addPoint( dfMinX, dfMinY );
649 :
650 14 : oPoly.addRing( &oRing );
651 :
652 14 : SetSpatialFilter( &oPoly );
653 14 : }
654 :
655 : /************************************************************************/
656 : /* OGR_L_SetSpatialFilterRect() */
657 : /************************************************************************/
658 :
659 14 : void OGR_L_SetSpatialFilterRect( OGRLayerH hLayer,
660 : double dfMinX, double dfMinY,
661 : double dfMaxX, double dfMaxY )
662 :
663 : {
664 14 : VALIDATE_POINTER0( hLayer, "OGR_L_SetSpatialFilterRect" );
665 :
666 : ((OGRLayer *) hLayer)->SetSpatialFilterRect( dfMinX, dfMinY,
667 14 : dfMaxX, dfMaxY );
668 : }
669 :
670 : /************************************************************************/
671 : /* InstallFilter() */
672 : /* */
673 : /* This method is only intended to be used from within */
674 : /* drivers, normally from the SetSpatialFilter() method. */
675 : /* It installs a filter, and also tests it to see if it is */
676 : /* rectangular. If so, it this is kept track of alongside the */
677 : /* filter geometry itself so we can do cheaper comparisons in */
678 : /* the FilterGeometry() call. */
679 : /* */
680 : /* Returns TRUE if the newly installed filter differs in some */
681 : /* way from the current one. */
682 : /************************************************************************/
683 :
684 206 : int OGRLayer::InstallFilter( OGRGeometry * poFilter )
685 :
686 : {
687 206 : if( m_poFilterGeom == NULL && poFilter == NULL )
688 154 : return FALSE;
689 :
690 : /* -------------------------------------------------------------------- */
691 : /* Replace the existing filter. */
692 : /* -------------------------------------------------------------------- */
693 52 : if( m_poFilterGeom != NULL )
694 : {
695 24 : delete m_poFilterGeom;
696 24 : m_poFilterGeom = NULL;
697 : }
698 :
699 52 : if( poFilter != NULL )
700 37 : m_poFilterGeom = poFilter->clone();
701 :
702 52 : m_bFilterIsEnvelope = FALSE;
703 :
704 52 : if( m_poFilterGeom == NULL )
705 15 : return TRUE;
706 :
707 37 : if( m_poFilterGeom != NULL )
708 37 : m_poFilterGeom->getEnvelope( &m_sFilterEnvelope );
709 :
710 : /* -------------------------------------------------------------------- */
711 : /* Now try to determine if the filter is really a rectangle. */
712 : /* -------------------------------------------------------------------- */
713 37 : if( wkbFlatten(m_poFilterGeom->getGeometryType()) != wkbPolygon )
714 11 : return TRUE;
715 :
716 26 : OGRPolygon *poPoly = (OGRPolygon *) m_poFilterGeom;
717 :
718 26 : if( poPoly->getNumInteriorRings() != 0 )
719 0 : return TRUE;
720 :
721 26 : OGRLinearRing *poRing = poPoly->getExteriorRing();
722 26 : if (poRing == NULL)
723 0 : return TRUE;
724 :
725 26 : if( poRing->getNumPoints() > 5 || poRing->getNumPoints() < 4 )
726 0 : return TRUE;
727 :
728 : // If the ring has 5 points, the last should be the first.
729 26 : if( poRing->getNumPoints() == 5
730 : && ( poRing->getX(0) != poRing->getX(4)
731 : || poRing->getY(0) != poRing->getY(4) ) )
732 0 : return TRUE;
733 :
734 : // Polygon with first segment in "y" direction.
735 26 : if( poRing->getX(0) == poRing->getX(1)
736 : && poRing->getY(1) == poRing->getY(2)
737 : && poRing->getX(2) == poRing->getX(3)
738 : && poRing->getY(3) == poRing->getY(0) )
739 25 : m_bFilterIsEnvelope = TRUE;
740 :
741 : // Polygon with first segment in "x" direction.
742 26 : if( poRing->getY(0) == poRing->getY(1)
743 : && poRing->getX(1) == poRing->getX(2)
744 : && poRing->getY(2) == poRing->getY(3)
745 : && poRing->getX(3) == poRing->getX(0) )
746 1 : m_bFilterIsEnvelope = TRUE;
747 :
748 26 : return TRUE;
749 : }
750 :
751 : /************************************************************************/
752 : /* FilterGeometry() */
753 : /* */
754 : /* Compare the passed in geometry to the currently installed */
755 : /* filter. Optimize for case where filter is just an */
756 : /* envelope. */
757 : /************************************************************************/
758 :
759 191 : int OGRLayer::FilterGeometry( OGRGeometry *poGeometry )
760 :
761 : {
762 : /* -------------------------------------------------------------------- */
763 : /* In trivial cases of new filter or target geometry, we accept */
764 : /* an intersection. No geometry is taken to mean "the whole */
765 : /* world". */
766 : /* -------------------------------------------------------------------- */
767 191 : if( m_poFilterGeom == NULL )
768 28 : return TRUE;
769 :
770 163 : if( poGeometry == NULL )
771 2 : return TRUE;
772 :
773 : /* -------------------------------------------------------------------- */
774 : /* Compute the target geometry envelope, and if there is no */
775 : /* intersection between the envelopes we are sure not to have */
776 : /* any intersection. */
777 : /* -------------------------------------------------------------------- */
778 161 : OGREnvelope sGeomEnv;
779 :
780 161 : poGeometry->getEnvelope( &sGeomEnv );
781 :
782 161 : if( sGeomEnv.MaxX < m_sFilterEnvelope.MinX
783 : || sGeomEnv.MaxY < m_sFilterEnvelope.MinY
784 : || m_sFilterEnvelope.MaxX < sGeomEnv.MinX
785 : || m_sFilterEnvelope.MaxY < sGeomEnv.MinY )
786 108 : return FALSE;
787 :
788 :
789 : /* -------------------------------------------------------------------- */
790 : /* If the filter geometry is its own envelope and if the */
791 : /* envelope of the geometry is inside the filter geometry, */
792 : /* the geometry itself is inside the filter geometry */
793 : /* -------------------------------------------------------------------- */
794 53 : if( m_bFilterIsEnvelope &&
795 : sGeomEnv.MinX >= m_sFilterEnvelope.MinX &&
796 : sGeomEnv.MinY >= m_sFilterEnvelope.MinY &&
797 : sGeomEnv.MaxX <= m_sFilterEnvelope.MaxX &&
798 : sGeomEnv.MaxY <= m_sFilterEnvelope.MaxY)
799 : {
800 20 : return TRUE;
801 : }
802 : else
803 : {
804 : /* -------------------------------------------------------------------- */
805 : /* Fallback to full intersect test (using GEOS) if we still */
806 : /* don't know for sure. */
807 : /* -------------------------------------------------------------------- */
808 33 : if( OGRGeometryFactory::haveGEOS() )
809 33 : return m_poFilterGeom->Intersects( poGeometry );
810 : else
811 0 : return TRUE;
812 : }
813 : }
814 :
815 : /************************************************************************/
816 : /* OGR_L_ResetReading() */
817 : /************************************************************************/
818 :
819 175 : void OGR_L_ResetReading( OGRLayerH hLayer )
820 :
821 : {
822 175 : VALIDATE_POINTER0( hLayer, "OGR_L_ResetReading" );
823 :
824 175 : ((OGRLayer *) hLayer)->ResetReading();
825 : }
826 :
827 : /************************************************************************/
828 : /* InitializeIndexSupport() */
829 : /* */
830 : /* This is only intended to be called by driver layer */
831 : /* implementations but we don't make it protected so that the */
832 : /* datasources can do it too if that is more appropriate. */
833 : /************************************************************************/
834 :
835 914 : OGRErr OGRLayer::InitializeIndexSupport( const char *pszFilename )
836 :
837 : {
838 : OGRErr eErr;
839 :
840 914 : m_poAttrIndex = OGRCreateDefaultLayerIndex();
841 :
842 914 : eErr = m_poAttrIndex->Initialize( pszFilename, this );
843 914 : if( eErr != OGRERR_NONE )
844 : {
845 0 : delete m_poAttrIndex;
846 0 : m_poAttrIndex = NULL;
847 : }
848 :
849 914 : return eErr;
850 : }
851 :
852 : /************************************************************************/
853 : /* SyncToDisk() */
854 : /************************************************************************/
855 :
856 0 : OGRErr OGRLayer::SyncToDisk()
857 :
858 : {
859 0 : return OGRERR_NONE;
860 : }
861 :
862 : /************************************************************************/
863 : /* OGR_L_SyncToDisk() */
864 : /************************************************************************/
865 :
866 0 : OGRErr OGR_L_SyncToDisk( OGRLayerH hDS )
867 :
868 : {
869 0 : VALIDATE_POINTER1( hDS, "OGR_L_SyncToDisk", OGRERR_INVALID_HANDLE );
870 :
871 0 : return ((OGRLayer *) hDS)->SyncToDisk();
872 : }
873 :
874 : /************************************************************************/
875 : /* DeleteFeature() */
876 : /************************************************************************/
877 :
878 0 : OGRErr OGRLayer::DeleteFeature( long nFID )
879 :
880 : {
881 0 : return OGRERR_UNSUPPORTED_OPERATION;
882 : }
883 :
884 : /************************************************************************/
885 : /* OGR_L_DeleteFeature() */
886 : /************************************************************************/
887 :
888 7 : OGRErr OGR_L_DeleteFeature( OGRLayerH hDS, long nFID )
889 :
890 : {
891 7 : VALIDATE_POINTER1( hDS, "OGR_L_DeleteFeature", OGRERR_INVALID_HANDLE );
892 :
893 7 : return ((OGRLayer *) hDS)->DeleteFeature( nFID );
894 : }
895 :
896 : /************************************************************************/
897 : /* GetFeaturesRead() */
898 : /************************************************************************/
899 :
900 0 : GIntBig OGRLayer::GetFeaturesRead()
901 :
902 : {
903 0 : return m_nFeaturesRead;
904 : }
905 :
906 : /************************************************************************/
907 : /* OGR_L_GetFeaturesRead() */
908 : /************************************************************************/
909 :
910 0 : GIntBig OGR_L_GetFeaturesRead( OGRLayerH hLayer )
911 :
912 : {
913 0 : VALIDATE_POINTER1( hLayer, "OGR_L_GetFeaturesRead", 0 );
914 :
915 0 : return ((OGRLayer *) hLayer)->GetFeaturesRead();
916 : }
917 :
918 : /************************************************************************/
919 : /* GetFIDColumn */
920 : /************************************************************************/
921 :
922 8 : const char *OGRLayer::GetFIDColumn()
923 :
924 : {
925 8 : return "";
926 : }
927 :
928 : /************************************************************************/
929 : /* OGR_L_GetFIDColumn() */
930 : /************************************************************************/
931 :
932 0 : const char *OGR_L_GetFIDColumn( OGRLayerH hLayer )
933 :
934 : {
935 0 : VALIDATE_POINTER1( hLayer, "OGR_L_GetFIDColumn", NULL );
936 :
937 0 : return ((OGRLayer *) hLayer)->GetFIDColumn();
938 : }
939 :
940 : /************************************************************************/
941 : /* GetGeometryColumn() */
942 : /************************************************************************/
943 :
944 8 : const char *OGRLayer::GetGeometryColumn()
945 :
946 : {
947 8 : return "";
948 : }
949 :
950 : /************************************************************************/
951 : /* OGR_L_GetGeometryColumn() */
952 : /************************************************************************/
953 :
954 6 : const char *OGR_L_GetGeometryColumn( OGRLayerH hLayer )
955 :
956 : {
957 6 : VALIDATE_POINTER1( hLayer, "OGR_L_GetGeometryColumn", NULL );
958 :
959 6 : return ((OGRLayer *) hLayer)->GetGeometryColumn();
960 : }
961 :
962 : /************************************************************************/
963 : /* OGR_L_GetStyleTable() */
964 : /************************************************************************/
965 :
966 0 : OGRStyleTableH OGR_L_GetStyleTable( OGRLayerH hLayer )
967 :
968 : {
969 0 : VALIDATE_POINTER1( hLayer, "OGR_L_GetStyleTable", NULL );
970 :
971 0 : return (OGRStyleTableH) ((OGRLayer *) hLayer)->GetStyleTable( );
972 : }
973 :
974 : /************************************************************************/
975 : /* OGR_L_SetStyleTableDirectly() */
976 : /************************************************************************/
977 :
978 0 : void OGR_L_SetStyleTableDirectly( OGRLayerH hLayer,
979 : OGRStyleTableH hStyleTable )
980 :
981 : {
982 0 : VALIDATE_POINTER0( hLayer, "OGR_L_SetStyleTableDirectly" );
983 :
984 0 : ((OGRLayer *) hLayer)->SetStyleTableDirectly( (OGRStyleTable *) hStyleTable);
985 : }
986 :
987 : /************************************************************************/
988 : /* OGR_L_SetStyleTable() */
989 : /************************************************************************/
990 :
991 0 : void OGR_L_SetStyleTable( OGRLayerH hLayer,
992 : OGRStyleTableH hStyleTable )
993 :
994 : {
995 0 : VALIDATE_POINTER0( hLayer, "OGR_L_SetStyleTable" );
996 0 : VALIDATE_POINTER0( hStyleTable, "OGR_L_SetStyleTable" );
997 :
998 0 : ((OGRLayer *) hLayer)->SetStyleTable( (OGRStyleTable *) hStyleTable);
999 : }
|