1 : /******************************************************************************
2 : * $Id: test_ogrsf.cpp 23539 2011-12-11 23:50:43Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Formal test harnass for OGRLayer implementations.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Frank Warmerdam
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 "cpl_conv.h"
32 : #include "ogr_api.h"
33 : #include "ogr_p.h"
34 :
35 : CPL_CVSID("$Id: test_ogrsf.cpp 23539 2011-12-11 23:50:43Z rouault $");
36 :
37 : int bReadOnly = FALSE;
38 : int bVerbose = TRUE;
39 :
40 : static void Usage();
41 : static int TestOGRLayer( OGRDataSource * poDS, OGRLayer * poLayer, int bIsSQLLayer );
42 : static int TestInterleavedReading( const char* pszDataSource, char** papszLayers );
43 :
44 : /************************************************************************/
45 : /* main() */
46 : /************************************************************************/
47 :
48 23 : int main( int nArgc, char ** papszArgv )
49 :
50 : {
51 23 : const char *pszDataSource = NULL;
52 23 : char** papszLayers = NULL;
53 23 : const char *pszSQLStatement = NULL;
54 23 : int bRet = TRUE;
55 :
56 : /* Must process OGR_SKIP before OGRRegisterAll(), but we can't call */
57 : /* OGRGeneralCmdLineProcessor before it needs the drivers to be registered */
58 : /* for the --format or --formats options */
59 75 : for( int iArg = 1; iArg < nArgc; iArg++ )
60 : {
61 57 : if( EQUAL(papszArgv[iArg], "--config") && iArg + 2 < nArgc &&
62 3 : EQUAL(papszArgv[iArg+1], "OGR_SKIP") )
63 : {
64 2 : CPLSetConfigOption(papszArgv[iArg+1], papszArgv[iArg+2]);
65 2 : break;
66 : }
67 : }
68 :
69 : /* -------------------------------------------------------------------- */
70 : /* Register format(s). */
71 : /* -------------------------------------------------------------------- */
72 23 : OGRRegisterAll();
73 :
74 : /* -------------------------------------------------------------------- */
75 : /* Processing command line arguments. */
76 : /* -------------------------------------------------------------------- */
77 23 : nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );
78 :
79 23 : if( nArgc < 1 )
80 0 : exit( -nArgc );
81 :
82 : /* -------------------------------------------------------------------- */
83 : /* Processing command line arguments. */
84 : /* -------------------------------------------------------------------- */
85 71 : for( int iArg = 1; iArg < nArgc; iArg++ )
86 : {
87 49 : if( EQUAL(papszArgv[iArg], "--utility_version") )
88 : {
89 : printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
90 1 : papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
91 1 : return 0;
92 : }
93 48 : else if( EQUAL(papszArgv[iArg],"-ro") )
94 12 : bReadOnly = TRUE;
95 36 : else if( EQUAL(papszArgv[iArg],"-q") || EQUAL(papszArgv[iArg],"-quiet"))
96 0 : bVerbose = FALSE;
97 40 : else if( EQUAL(papszArgv[iArg],"-sql") && iArg + 1 < nArgc)
98 4 : pszSQLStatement = papszArgv[++iArg];
99 32 : else if( papszArgv[iArg][0] == '-' )
100 : {
101 0 : Usage();
102 : }
103 32 : else if (pszDataSource == NULL)
104 22 : pszDataSource = papszArgv[iArg];
105 : else
106 10 : papszLayers = CSLAddString(papszLayers, papszArgv[iArg]);
107 : }
108 :
109 22 : if( pszDataSource == NULL )
110 0 : Usage();
111 :
112 : /* -------------------------------------------------------------------- */
113 : /* Open data source. */
114 : /* -------------------------------------------------------------------- */
115 : OGRDataSource *poDS;
116 : OGRSFDriver *poDriver;
117 :
118 22 : poDS = OGRSFDriverRegistrar::Open( pszDataSource, !bReadOnly, &poDriver );
119 22 : if( poDS == NULL && !bReadOnly )
120 : {
121 0 : poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, &poDriver );
122 0 : if( poDS != NULL && bVerbose )
123 : {
124 0 : printf( "Had to open data source read-only.\n" );
125 0 : bReadOnly = TRUE;
126 : }
127 : }
128 :
129 : /* -------------------------------------------------------------------- */
130 : /* Report failure */
131 : /* -------------------------------------------------------------------- */
132 22 : if( poDS == NULL )
133 : {
134 0 : OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
135 :
136 : printf( "FAILURE:\n"
137 : "Unable to open datasource `%s' with the following drivers.\n",
138 0 : pszDataSource );
139 :
140 0 : for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
141 : {
142 0 : printf( " -> %s\n", poR->GetDriver(iDriver)->GetName() );
143 : }
144 :
145 0 : exit( 1 );
146 : }
147 :
148 : /* -------------------------------------------------------------------- */
149 : /* Some information messages. */
150 : /* -------------------------------------------------------------------- */
151 22 : if( bVerbose )
152 : printf( "INFO: Open of `%s' using driver `%s' successful.\n",
153 22 : pszDataSource, poDriver->GetName() );
154 :
155 22 : if( bVerbose && !EQUAL(pszDataSource,poDS->GetName()) )
156 : {
157 : printf( "INFO: Internal data source name `%s'\n"
158 : " different from user name `%s'.\n",
159 0 : poDS->GetName(), pszDataSource );
160 : }
161 :
162 : /* -------------------------------------------------------------------- */
163 : /* Process optionnal SQL request. */
164 : /* -------------------------------------------------------------------- */
165 22 : if (pszSQLStatement != NULL)
166 : {
167 4 : OGRLayer *poResultSet = poDS->ExecuteSQL(pszSQLStatement, NULL, NULL);
168 4 : if (poResultSet == NULL)
169 0 : exit(1);
170 :
171 : printf( "INFO: Testing layer %s.\n",
172 4 : poResultSet->GetName() );
173 4 : bRet = TestOGRLayer( poDS, poResultSet, TRUE );
174 :
175 4 : poDS->ReleaseResultSet(poResultSet);
176 : }
177 : /* -------------------------------------------------------------------- */
178 : /* Process each data source layer. */
179 : /* -------------------------------------------------------------------- */
180 18 : else if (papszLayers == NULL)
181 : {
182 76 : for( int iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ )
183 : {
184 63 : OGRLayer *poLayer = poDS->GetLayer(iLayer);
185 :
186 63 : if( poLayer == NULL )
187 : {
188 : printf( "FAILURE: Couldn't fetch advertised layer %d!\n",
189 0 : iLayer );
190 0 : exit( 1 );
191 : }
192 :
193 : printf( "INFO: Testing layer %s.\n",
194 63 : poLayer->GetName() );
195 63 : bRet &= TestOGRLayer( poDS, poLayer, FALSE );
196 : }
197 :
198 13 : if (poDS->GetLayerCount() >= 2)
199 : {
200 7 : OGRDataSource::DestroyDataSource(poDS);
201 7 : poDS = NULL;
202 7 : bRet &= TestInterleavedReading( pszDataSource, NULL );
203 : }
204 : }
205 : else
206 : {
207 : /* -------------------------------------------------------------------- */
208 : /* Or process layers specified by the user */
209 : /* -------------------------------------------------------------------- */
210 5 : char** papszLayerIter = papszLayers;
211 20 : while (*papszLayerIter)
212 : {
213 10 : OGRLayer *poLayer = poDS->GetLayerByName(*papszLayerIter);
214 :
215 10 : if( poLayer == NULL )
216 : {
217 : printf( "FAILURE: Couldn't fetch requested layer %s!\n",
218 0 : *papszLayerIter );
219 0 : exit( 1 );
220 : }
221 :
222 : printf( "INFO: Testing layer %s.\n",
223 10 : poLayer->GetName() );
224 10 : bRet &= TestOGRLayer( poDS, poLayer, FALSE );
225 :
226 10 : papszLayerIter ++;
227 : }
228 :
229 5 : if (CSLCount(papszLayers) >= 2)
230 : {
231 3 : OGRDataSource::DestroyDataSource(poDS);
232 3 : poDS = NULL;
233 3 : bRet &= TestInterleavedReading( pszDataSource, papszLayers );
234 : }
235 : }
236 :
237 : /* -------------------------------------------------------------------- */
238 : /* Close down. */
239 : /* -------------------------------------------------------------------- */
240 22 : OGRDataSource::DestroyDataSource(poDS);
241 :
242 22 : OGRCleanupAll();
243 :
244 22 : CSLDestroy(papszLayers);
245 22 : CSLDestroy(papszArgv);
246 :
247 : #ifdef DBMALLOC
248 : malloc_dump(1);
249 : #endif
250 :
251 22 : return (bRet) ? 0 : 1;
252 : }
253 :
254 : /************************************************************************/
255 : /* Usage() */
256 : /************************************************************************/
257 :
258 0 : static void Usage()
259 :
260 : {
261 0 : printf( "Usage: test_ogrsf [-ro] [-q] datasource_name [[layer1_name, layer2_name, ...] | [-sql statement]]\n" );
262 0 : exit( 1 );
263 : }
264 :
265 : /************************************************************************/
266 : /* TestOGRLayerFeatureCount() */
267 : /* */
268 : /* Verify that the feature count matches the actual number of */
269 : /* features returned during sequential reading. */
270 : /************************************************************************/
271 :
272 77 : static int TestOGRLayerFeatureCount( OGRDataSource* poDS, OGRLayer *poLayer, int bIsSQLLayer )
273 :
274 : {
275 77 : int bRet = TRUE;
276 77 : int nFC = 0, nClaimedFC = poLayer->GetFeatureCount();
277 : OGRFeature *poFeature;
278 77 : OGRSpatialReference * poSRS = poLayer->GetSpatialRef();
279 77 : int bWarnAboutSRS = FALSE;
280 77 : OGRFeatureDefn* poLayerDefn = poLayer->GetLayerDefn();
281 :
282 77 : poLayer->ResetReading();
283 :
284 145469 : while( (poFeature = poLayer->GetNextFeature()) != NULL )
285 : {
286 145315 : nFC++;
287 :
288 145315 : if (poFeature->GetDefnRef() != poLayerDefn)
289 : {
290 0 : bRet = FALSE;
291 : printf( "ERROR: Feature defn differs from layer defn.\n"
292 : "Feature defn = %p\n"
293 : "Layer defn = %p\n",
294 0 : poFeature->GetDefnRef(), poLayerDefn);
295 : }
296 :
297 145315 : if( poFeature->GetGeometryRef() != NULL
298 : && poFeature->GetGeometryRef()->getSpatialReference() != poSRS
299 : && !bWarnAboutSRS )
300 : {
301 : char *pszLayerSRSWKT, *pszFeatureSRSWKT;
302 :
303 0 : bWarnAboutSRS = TRUE;
304 :
305 0 : if( poSRS != NULL )
306 0 : poSRS->exportToWkt( &pszLayerSRSWKT );
307 : else
308 0 : pszLayerSRSWKT = CPLStrdup("(NULL)");
309 :
310 0 : if( poFeature->GetGeometryRef()->getSpatialReference() != NULL )
311 : poFeature->GetGeometryRef()->
312 0 : getSpatialReference()->exportToWkt( &pszFeatureSRSWKT );
313 : else
314 0 : pszFeatureSRSWKT = CPLStrdup("(NULL)");
315 :
316 0 : bRet = FALSE;
317 : printf( "ERROR: Feature SRS differs from layer SRS.\n"
318 : "Feature SRS = %s (%p)\n"
319 : "Layer SRS = %s (%p)\n",
320 : pszFeatureSRSWKT, poFeature->GetGeometryRef()->getSpatialReference(),
321 0 : pszLayerSRSWKT, poSRS );
322 0 : CPLFree( pszLayerSRSWKT );
323 0 : CPLFree( pszFeatureSRSWKT );
324 : }
325 :
326 145315 : OGRFeature::DestroyFeature(poFeature);
327 : }
328 :
329 77 : if( nFC != nClaimedFC )
330 : {
331 0 : bRet = FALSE;
332 : printf( "ERROR: Claimed feature count %d doesn't match actual, %d.\n",
333 0 : nClaimedFC, nFC );
334 : }
335 77 : else if( nFC != poLayer->GetFeatureCount() )
336 : {
337 0 : bRet = FALSE;
338 : printf( "ERROR: Feature count at end of layer %d differs "
339 : "from at start, %d.\n",
340 0 : nFC, poLayer->GetFeatureCount() );
341 : }
342 77 : else if( bVerbose )
343 77 : printf( "INFO: Feature count verified.\n" );
344 :
345 77 : if (!bIsSQLLayer)
346 : {
347 73 : CPLString osSQL;
348 73 : const char* pszLayerName = poLayer->GetName();
349 : int i;
350 : char ch;
351 694 : for(i=0;(ch = pszLayerName[i]) != 0;i++)
352 : {
353 654 : if (ch >= '0' && ch <= '9')
354 : {
355 16 : if (i == 0)
356 0 : break;
357 : }
358 622 : else if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')))
359 17 : break;
360 : }
361 : /* Only quote if needed. Quoting conventions depend on the driver... */
362 73 : if (ch == 0)
363 56 : osSQL.Printf("SELECT COUNT(*) FROM %s", pszLayerName);
364 : else
365 : {
366 17 : if (EQUAL(poDS->GetDriver()->GetName(), "MYSQL"))
367 0 : osSQL.Printf("SELECT COUNT(*) FROM `%s`", pszLayerName);
368 17 : else if (EQUAL(poDS->GetDriver()->GetName(), "PostgreSQL") &&
369 : strchr(pszLayerName, '.'))
370 : {
371 0 : char** papszTokens = CSLTokenizeStringComplex(pszLayerName, ".", 0, 0);
372 0 : if (CSLCount(papszTokens) == 2)
373 : {
374 0 : osSQL.Printf("SELECT COUNT(*) FROM \"%s\".\"%s\"", papszTokens[0], papszTokens[1]);
375 : }
376 : else
377 0 : osSQL.Printf("SELECT COUNT(*) FROM \"%s\"", pszLayerName);
378 0 : CSLDestroy(papszTokens);
379 : }
380 : else
381 17 : osSQL.Printf("SELECT COUNT(*) FROM \"%s\"", pszLayerName);
382 : }
383 73 : OGRLayer* poSQLLyr = poDS->ExecuteSQL(osSQL.c_str(), NULL, NULL);
384 73 : if (poSQLLyr)
385 : {
386 73 : OGRFeature* poFeatCount = poSQLLyr->GetNextFeature();
387 73 : if (poFeatCount == NULL)
388 : {
389 0 : bRet = FALSE;
390 0 : printf( "ERROR: '%s' failed.\n", osSQL.c_str() );
391 : }
392 73 : else if (nClaimedFC != poFeatCount->GetFieldAsInteger(0))
393 : {
394 0 : bRet = FALSE;
395 : printf( "ERROR: Claimed feature count %d doesn't match '%s' one, %d.\n",
396 0 : nClaimedFC, osSQL.c_str(), poFeatCount->GetFieldAsInteger(0) );
397 : }
398 73 : OGRFeature::DestroyFeature(poFeatCount);
399 73 : poDS->ReleaseResultSet(poSQLLyr);
400 73 : }
401 : }
402 :
403 77 : if( bVerbose && !bWarnAboutSRS )
404 : {
405 77 : printf("INFO: Feature/layer spatial ref. consistency verified.\n");
406 : }
407 :
408 77 : return bRet;
409 : }
410 :
411 : /************************************************************************/
412 : /* TestOGRLayerRandomRead() */
413 : /* */
414 : /* Read the first 5 features, and then try to use random */
415 : /* reading to reread 2 and 5 and verify that this works OK. */
416 : /* Don't attempt if there aren't at least 5 features. */
417 : /************************************************************************/
418 :
419 48 : static int TestOGRLayerRandomRead( OGRLayer *poLayer )
420 :
421 : {
422 48 : int bRet = TRUE;
423 48 : OGRFeature *papoFeatures[5], *poFeature = NULL;
424 : int iFeature;
425 :
426 48 : poLayer->SetSpatialFilter( NULL );
427 :
428 48 : if( poLayer->GetFeatureCount() < 5 )
429 : {
430 22 : if( bVerbose )
431 : printf( "INFO: Only %d features on layer,"
432 : "skipping random read test.\n",
433 22 : poLayer->GetFeatureCount() );
434 :
435 22 : return bRet;
436 : }
437 :
438 : /* -------------------------------------------------------------------- */
439 : /* Fetch five features. */
440 : /* -------------------------------------------------------------------- */
441 26 : poLayer->ResetReading();
442 :
443 156 : for( iFeature = 0; iFeature < 5; iFeature++ )
444 : {
445 130 : papoFeatures[iFeature] = NULL;
446 : }
447 156 : for( iFeature = 0; iFeature < 5; iFeature++ )
448 : {
449 130 : papoFeatures[iFeature] = poLayer->GetNextFeature();
450 130 : if( papoFeatures[iFeature] == NULL )
451 : {
452 0 : if( bVerbose )
453 : printf( "INFO: Only %d features on layer,"
454 : "skipping random read test.\n",
455 0 : iFeature );
456 0 : goto end;
457 : }
458 : }
459 :
460 : /* -------------------------------------------------------------------- */
461 : /* Test feature 2. */
462 : /* -------------------------------------------------------------------- */
463 26 : poFeature = poLayer->GetFeature( papoFeatures[1]->GetFID() );
464 26 : if (poFeature == NULL)
465 : {
466 : printf( "ERROR: Cannot fetch feature %ld.\n",
467 0 : papoFeatures[1]->GetFID() );
468 0 : goto end;
469 : }
470 :
471 26 : if( !poFeature->Equal( papoFeatures[1] ) )
472 : {
473 0 : bRet = FALSE;
474 : printf( "ERROR: Attempt to randomly read feature %ld appears to\n"
475 : " have returned a different feature than sequential\n"
476 : " reading indicates should have happened.\n",
477 0 : papoFeatures[1]->GetFID() );
478 0 : poFeature->DumpReadable(stdout);
479 0 : papoFeatures[1]->DumpReadable(stdout);
480 :
481 0 : goto end;
482 : }
483 :
484 26 : OGRFeature::DestroyFeature(poFeature);
485 :
486 : /* -------------------------------------------------------------------- */
487 : /* Test feature 5. */
488 : /* -------------------------------------------------------------------- */
489 26 : poFeature = poLayer->GetFeature( papoFeatures[4]->GetFID() );
490 26 : if( !poFeature->Equal( papoFeatures[4] ) )
491 : {
492 0 : bRet = FALSE;
493 : printf( "ERROR: Attempt to randomly read feature %ld appears to\n"
494 : " have returned a different feature than sequential\n"
495 : " reading indicates should have happened.\n",
496 0 : papoFeatures[4]->GetFID() );
497 :
498 0 : goto end;
499 : }
500 :
501 26 : if( bVerbose )
502 26 : printf( "INFO: Random read test passed.\n" );
503 :
504 : end:
505 26 : OGRFeature::DestroyFeature(poFeature);
506 :
507 : /* -------------------------------------------------------------------- */
508 : /* Cleanup. */
509 : /* -------------------------------------------------------------------- */
510 156 : for( iFeature = 0; iFeature < 5; iFeature++ )
511 130 : OGRFeature::DestroyFeature(papoFeatures[iFeature]);
512 :
513 26 : return bRet;
514 : }
515 :
516 :
517 : /************************************************************************/
518 : /* TestOGRLayerSetNextByIndex() */
519 : /* */
520 : /************************************************************************/
521 :
522 9 : static int TestOGRLayerSetNextByIndex( OGRLayer *poLayer )
523 :
524 : {
525 9 : int bRet = TRUE;
526 9 : OGRFeature *papoFeatures[5], *poFeature = NULL;
527 : int iFeature;
528 :
529 9 : memset(papoFeatures, 0, sizeof(papoFeatures));
530 :
531 9 : poLayer->SetSpatialFilter( NULL );
532 :
533 9 : if( poLayer->GetFeatureCount() < 5 )
534 : {
535 2 : if( bVerbose )
536 : printf( "INFO: Only %d features on layer,"
537 : "skipping SetNextByIndex test.\n",
538 2 : poLayer->GetFeatureCount() );
539 :
540 2 : return bRet;
541 : }
542 :
543 : /* -------------------------------------------------------------------- */
544 : /* Fetch five features. */
545 : /* -------------------------------------------------------------------- */
546 7 : poLayer->ResetReading();
547 :
548 42 : for( iFeature = 0; iFeature < 5; iFeature++ )
549 : {
550 35 : papoFeatures[iFeature] = poLayer->GetNextFeature();
551 35 : if( papoFeatures[iFeature] == NULL )
552 : {
553 0 : bRet = FALSE;
554 0 : printf( "ERROR: Cannot get feature %d.\n", iFeature );
555 0 : goto end;
556 : }
557 : }
558 :
559 : /* -------------------------------------------------------------------- */
560 : /* Test feature at index 1. */
561 : /* -------------------------------------------------------------------- */
562 7 : if (poLayer->SetNextByIndex(1) != OGRERR_NONE)
563 : {
564 0 : bRet = FALSE;
565 0 : printf( "ERROR: SetNextByIndex(%d) failed.\n", 1 );
566 0 : goto end;
567 : }
568 :
569 7 : poFeature = poLayer->GetNextFeature();
570 7 : if( !poFeature->Equal( papoFeatures[1] ) )
571 : {
572 0 : bRet = FALSE;
573 : printf( "ERROR: Attempt to read feature at index %d appears to\n"
574 : " have returned a different feature than sequential\n"
575 : " reading indicates should have happened.\n",
576 0 : 1 );
577 :
578 0 : goto end;
579 : }
580 :
581 7 : OGRFeature::DestroyFeature(poFeature);
582 :
583 7 : poFeature = poLayer->GetNextFeature();
584 7 : if( !poFeature->Equal( papoFeatures[2] ) )
585 : {
586 0 : bRet = FALSE;
587 : printf( "ERROR: Attempt to read feature after feature at index %d appears to\n"
588 : " have returned a different feature than sequential\n"
589 : " reading indicates should have happened.\n",
590 0 : 1 );
591 :
592 0 : goto end;
593 : }
594 :
595 7 : OGRFeature::DestroyFeature(poFeature);
596 7 : poFeature = NULL;
597 :
598 : /* -------------------------------------------------------------------- */
599 : /* Test feature at index 3. */
600 : /* -------------------------------------------------------------------- */
601 7 : if (poLayer->SetNextByIndex(3) != OGRERR_NONE)
602 : {
603 0 : bRet = FALSE;
604 0 : printf( "ERROR: SetNextByIndex(%d) failed.\n", 3 );
605 0 : goto end;
606 : }
607 :
608 7 : poFeature = poLayer->GetNextFeature();
609 7 : if( !poFeature->Equal( papoFeatures[3] ) )
610 : {
611 0 : bRet = FALSE;
612 : printf( "ERROR: Attempt to read feature at index %d appears to\n"
613 : " have returned a different feature than sequential\n"
614 : " reading indicates should have happened.\n",
615 0 : 3 );
616 :
617 0 : goto end;
618 : }
619 :
620 7 : OGRFeature::DestroyFeature(poFeature);
621 :
622 7 : poFeature = poLayer->GetNextFeature();
623 7 : if( !poFeature->Equal( papoFeatures[4] ) )
624 : {
625 0 : bRet = FALSE;
626 : printf( "ERROR: Attempt to read feature after feature at index %d appears to\n"
627 : " have returned a different feature than sequential\n"
628 : " reading indicates should have happened.\n",
629 0 : 3 );
630 :
631 0 : goto end;
632 : }
633 :
634 :
635 7 : if( bVerbose )
636 7 : printf( "INFO: SetNextByIndex() read test passed.\n" );
637 :
638 : end:
639 7 : OGRFeature::DestroyFeature(poFeature);
640 :
641 : /* -------------------------------------------------------------------- */
642 : /* Cleanup. */
643 : /* -------------------------------------------------------------------- */
644 42 : for( iFeature = 0; iFeature < 5; iFeature++ )
645 35 : OGRFeature::DestroyFeature(papoFeatures[iFeature]);
646 :
647 7 : return bRet;
648 : }
649 :
650 : /************************************************************************/
651 : /* TestOGRLayerRandomWrite() */
652 : /* */
653 : /* Test random writing by trying to switch the 2nd and 5th */
654 : /* features. */
655 : /************************************************************************/
656 :
657 10 : static int TestOGRLayerRandomWrite( OGRLayer *poLayer )
658 :
659 : {
660 10 : int bRet = TRUE;
661 : OGRFeature *papoFeatures[5], *poFeature;
662 : int iFeature;
663 : long nFID2, nFID5;
664 :
665 10 : memset(papoFeatures, 0, sizeof(papoFeatures));
666 :
667 10 : poLayer->SetSpatialFilter( NULL );
668 :
669 10 : if( poLayer->GetFeatureCount() < 5 )
670 : {
671 7 : if( bVerbose )
672 : printf( "INFO: Only %d features on layer,"
673 : "skipping random write test.\n",
674 7 : poLayer->GetFeatureCount() );
675 :
676 7 : return bRet;
677 : }
678 :
679 3 : if( !poLayer->TestCapability( OLCRandomRead ) )
680 : {
681 0 : if( bVerbose )
682 : printf( "INFO: Skipping random write test since this layer "
683 0 : "doesn't support random read.\n" );
684 0 : return bRet;
685 : }
686 :
687 : /* -------------------------------------------------------------------- */
688 : /* Fetch five features. */
689 : /* -------------------------------------------------------------------- */
690 3 : poLayer->ResetReading();
691 :
692 18 : for( iFeature = 0; iFeature < 5; iFeature++ )
693 : {
694 15 : papoFeatures[iFeature] = poLayer->GetNextFeature();
695 15 : if( papoFeatures[iFeature] == NULL )
696 : {
697 0 : bRet = FALSE;
698 0 : printf( "ERROR: Cannot get feature %d.\n", iFeature );
699 0 : goto end;
700 : }
701 : }
702 :
703 : /* -------------------------------------------------------------------- */
704 : /* Switch feature ids of feature 2 and 5. */
705 : /* -------------------------------------------------------------------- */
706 3 : nFID2 = papoFeatures[1]->GetFID();
707 3 : nFID5 = papoFeatures[4]->GetFID();
708 :
709 3 : papoFeatures[1]->SetFID( nFID5 );
710 3 : papoFeatures[4]->SetFID( nFID2 );
711 :
712 : /* -------------------------------------------------------------------- */
713 : /* Rewrite them. */
714 : /* -------------------------------------------------------------------- */
715 3 : if( poLayer->SetFeature( papoFeatures[1] ) != OGRERR_NONE )
716 : {
717 0 : bRet = FALSE;
718 0 : printf( "ERROR: Attempt to SetFeature(1) failed.\n" );
719 0 : goto end;
720 : }
721 3 : if( poLayer->SetFeature( papoFeatures[4] ) != OGRERR_NONE )
722 : {
723 0 : bRet = FALSE;
724 0 : printf( "ERROR: Attempt to SetFeature(4) failed.\n" );
725 0 : goto end;
726 : }
727 :
728 : /* -------------------------------------------------------------------- */
729 : /* Now re-read feature 2 to verify the effect stuck. */
730 : /* -------------------------------------------------------------------- */
731 3 : poFeature = poLayer->GetFeature( nFID5 );
732 3 : if(poFeature == NULL)
733 : {
734 0 : bRet = FALSE;
735 0 : printf( "ERROR: Attempt to GetFeature( nFID5 ) failed.\n" );
736 0 : goto end;
737 : }
738 3 : if( !poFeature->Equal(papoFeatures[1]) )
739 : {
740 0 : bRet = FALSE;
741 0 : printf( "ERROR: Written feature didn't seem to retain value.\n" );
742 : }
743 : else
744 : {
745 3 : printf( "INFO: Random write test passed.\n" );
746 : }
747 3 : OGRFeature::DestroyFeature(poFeature);
748 :
749 : /* -------------------------------------------------------------------- */
750 : /* Re-invert the features to restore to original state */
751 : /* -------------------------------------------------------------------- */
752 :
753 3 : papoFeatures[1]->SetFID( nFID2 );
754 3 : papoFeatures[4]->SetFID( nFID5 );
755 :
756 3 : if( poLayer->SetFeature( papoFeatures[1] ) != OGRERR_NONE )
757 : {
758 0 : bRet = FALSE;
759 0 : printf( "ERROR: Attempt to restore SetFeature(1) failed.\n" );
760 : }
761 3 : if( poLayer->SetFeature( papoFeatures[4] ) != OGRERR_NONE )
762 : {
763 0 : bRet = FALSE;
764 0 : printf( "ERROR: Attempt to restore SetFeature(4) failed.\n" );
765 : }
766 :
767 : end:
768 : /* -------------------------------------------------------------------- */
769 : /* Cleanup. */
770 : /* -------------------------------------------------------------------- */
771 :
772 18 : for( iFeature = 0; iFeature < 5; iFeature++ )
773 15 : OGRFeature::DestroyFeature(papoFeatures[iFeature]);
774 :
775 3 : return bRet;
776 : }
777 :
778 : /************************************************************************/
779 : /* TestSpatialFilter() */
780 : /* */
781 : /* This is intended to be a simple test of the spatial */
782 : /* filtering. We read the first feature. Then construct a */
783 : /* spatial filter geometry which includes it, install and */
784 : /* verify that we get the feature. Next install a spatial */
785 : /* filter that doesn't include this feature, and test again. */
786 : /************************************************************************/
787 :
788 77 : static int TestSpatialFilter( OGRLayer *poLayer )
789 :
790 : {
791 77 : int bRet = TRUE;
792 : OGRFeature *poFeature, *poTargetFeature;
793 77 : OGRPolygon oInclusiveFilter, oExclusiveFilter;
794 77 : OGRLinearRing oRing;
795 77 : OGREnvelope sEnvelope;
796 : int nInclusiveCount;
797 :
798 : /* -------------------------------------------------------------------- */
799 : /* Read the target feature. */
800 : /* -------------------------------------------------------------------- */
801 77 : poLayer->ResetReading();
802 77 : poTargetFeature = poLayer->GetNextFeature();
803 :
804 77 : if( poTargetFeature == NULL )
805 : {
806 : printf( "INFO: Skipping Spatial Filter test for %s.\n"
807 : " No features in layer.\n",
808 6 : poLayer->GetName() );
809 6 : return bRet;
810 : }
811 :
812 71 : if( poTargetFeature->GetGeometryRef() == NULL )
813 : {
814 : printf( "INFO: Skipping Spatial Filter test for %s,\n"
815 : " target feature has no geometry.\n",
816 18 : poTargetFeature->GetDefnRef()->GetName() );
817 18 : OGRFeature::DestroyFeature(poTargetFeature);
818 18 : return bRet;
819 : }
820 :
821 53 : poTargetFeature->GetGeometryRef()->getEnvelope( &sEnvelope );
822 :
823 : /* -------------------------------------------------------------------- */
824 : /* Construct inclusive filter. */
825 : /* -------------------------------------------------------------------- */
826 :
827 53 : oRing.setPoint( 0, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
828 53 : oRing.setPoint( 1, sEnvelope.MinX - 20.0, sEnvelope.MaxY + 10.0 );
829 53 : oRing.setPoint( 2, sEnvelope.MaxX + 10.0, sEnvelope.MaxY + 10.0 );
830 53 : oRing.setPoint( 3, sEnvelope.MaxX + 10.0, sEnvelope.MinY - 20.0 );
831 53 : oRing.setPoint( 4, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
832 :
833 53 : oInclusiveFilter.addRing( &oRing );
834 :
835 53 : poLayer->SetSpatialFilter( &oInclusiveFilter );
836 :
837 : /* -------------------------------------------------------------------- */
838 : /* Verify that we can find the target feature. */
839 : /* -------------------------------------------------------------------- */
840 53 : poLayer->ResetReading();
841 :
842 106 : while( (poFeature = poLayer->GetNextFeature()) != NULL )
843 : {
844 53 : if( poFeature->Equal(poTargetFeature) )
845 : {
846 53 : OGRFeature::DestroyFeature(poFeature);
847 53 : break;
848 : }
849 : else
850 0 : OGRFeature::DestroyFeature(poFeature);
851 : }
852 :
853 53 : if( poFeature == NULL )
854 : {
855 0 : bRet = FALSE;
856 0 : printf( "ERROR: Spatial filter eliminated a feature unexpectedly!\n");
857 : }
858 53 : else if( bVerbose )
859 : {
860 53 : printf( "INFO: Spatial filter inclusion seems to work.\n" );
861 : }
862 :
863 53 : nInclusiveCount = poLayer->GetFeatureCount();
864 :
865 : /* -------------------------------------------------------------------- */
866 : /* Construct exclusive filter. */
867 : /* -------------------------------------------------------------------- */
868 53 : oRing.setPoint( 0, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
869 53 : oRing.setPoint( 1, sEnvelope.MinX - 10.0, sEnvelope.MinY - 20.0 );
870 53 : oRing.setPoint( 2, sEnvelope.MinX - 10.0, sEnvelope.MinY - 10.0 );
871 53 : oRing.setPoint( 3, sEnvelope.MinX - 20.0, sEnvelope.MinY - 10.0 );
872 53 : oRing.setPoint( 4, sEnvelope.MinX - 20.0, sEnvelope.MinY - 20.0 );
873 :
874 53 : oExclusiveFilter.addRing( &oRing );
875 :
876 53 : poLayer->SetSpatialFilter( &oExclusiveFilter );
877 :
878 : /* -------------------------------------------------------------------- */
879 : /* Verify that we can find the target feature. */
880 : /* -------------------------------------------------------------------- */
881 53 : poLayer->ResetReading();
882 :
883 261 : while( (poFeature = poLayer->GetNextFeature()) != NULL )
884 : {
885 155 : if( poFeature->Equal(poTargetFeature) )
886 : {
887 0 : OGRFeature::DestroyFeature(poFeature);
888 0 : break;
889 : }
890 : else
891 155 : OGRFeature::DestroyFeature(poFeature);
892 : }
893 :
894 53 : if( poFeature != NULL )
895 : {
896 0 : bRet = FALSE;
897 : printf( "ERROR: Spatial filter failed to eliminate"
898 0 : "a feature unexpectedly!\n");
899 : }
900 53 : else if( poLayer->GetFeatureCount() >= nInclusiveCount )
901 : {
902 0 : bRet = FALSE;
903 : printf( "ERROR: GetFeatureCount() may not be taking spatial "
904 0 : "filter into account.\n" );
905 : }
906 53 : else if( bVerbose )
907 : {
908 53 : printf( "INFO: Spatial filter exclusion seems to work.\n" );
909 : }
910 :
911 53 : OGRFeature::DestroyFeature(poTargetFeature);
912 :
913 53 : poLayer->SetSpatialFilter( NULL );
914 :
915 53 : return bRet;
916 : }
917 :
918 :
919 : /************************************************************************/
920 : /* TestAttributeFilter() */
921 : /* */
922 : /* This is intended to be a simple test of the attribute */
923 : /* filtering. We read the first feature. Then construct a */
924 : /* attribute filter which includes it, install and */
925 : /* verify that we get the feature. Next install a attribute */
926 : /* filter that doesn't include this feature, and test again. */
927 : /************************************************************************/
928 :
929 77 : static int TestAttributeFilter( OGRDataSource* poDS, OGRLayer *poLayer )
930 :
931 : {
932 77 : int bRet = TRUE;
933 : OGRFeature *poFeature, *poTargetFeature;
934 : int nInclusiveCount, nExclusiveCount, nTotalCount;
935 77 : CPLString osAttributeFilter;
936 :
937 : /* -------------------------------------------------------------------- */
938 : /* Read the target feature. */
939 : /* -------------------------------------------------------------------- */
940 77 : poLayer->ResetReading();
941 77 : poTargetFeature = poLayer->GetNextFeature();
942 :
943 77 : if( poTargetFeature == NULL )
944 : {
945 : printf( "INFO: Skipping Attribute Filter test for %s.\n"
946 : " No features in layer.\n",
947 6 : poLayer->GetName() );
948 6 : return bRet;
949 : }
950 :
951 : int i;
952 71 : OGRFieldType eType = OFTString;
953 71 : for(i=0;i<poTargetFeature->GetFieldCount();i++)
954 : {
955 66 : eType = poTargetFeature->GetFieldDefnRef(i)->GetType();
956 66 : if (poTargetFeature->IsFieldSet(i) &&
957 : (eType == OFTString || eType == OFTInteger || eType == OFTReal))
958 : {
959 66 : break;
960 : }
961 : }
962 71 : if( i == poTargetFeature->GetFieldCount() )
963 : {
964 : printf( "INFO: Skipping Attribute Filter test for %s.\n"
965 : " Could not find non NULL field.\n",
966 5 : poLayer->GetName() );
967 5 : OGRFeature::DestroyFeature(poTargetFeature);
968 5 : return bRet;
969 : }
970 :
971 66 : const char* pszFieldName = poTargetFeature->GetFieldDefnRef(i)->GetNameRef();
972 66 : CPLString osValue = poTargetFeature->GetFieldAsString(i);
973 :
974 : /* -------------------------------------------------------------------- */
975 : /* Construct inclusive filter. */
976 : /* -------------------------------------------------------------------- */
977 :
978 66 : if (EQUAL(poDS->GetDriver()->GetName(), "PostgreSQL") &&
979 : (strchr(pszFieldName, '_') || strchr(pszFieldName, ' ')))
980 : {
981 0 : osAttributeFilter = "\"";
982 0 : osAttributeFilter += pszFieldName;
983 0 : osAttributeFilter += "\"";
984 : }
985 66 : else if (strchr(pszFieldName, ' ') || pszFieldName[0] == '_')
986 : {
987 0 : osAttributeFilter = "'";
988 0 : osAttributeFilter += pszFieldName;
989 0 : osAttributeFilter += "'";
990 : }
991 : else
992 66 : osAttributeFilter = pszFieldName;
993 66 : osAttributeFilter += " = ";
994 66 : if (eType == OFTString)
995 47 : osAttributeFilter += "'";
996 66 : osAttributeFilter += osValue;
997 66 : if (eType == OFTString)
998 47 : osAttributeFilter += "'";
999 : /* Make sure that the literal will be recognized as a float value */
1000 : /* to avoid int underflow/overflow */
1001 19 : else if (eType == OFTReal && strchr(osValue, '.') == NULL)
1002 0 : osAttributeFilter += ".";
1003 66 : poLayer->SetAttributeFilter( osAttributeFilter );
1004 :
1005 : /* -------------------------------------------------------------------- */
1006 : /* Verify that we can find the target feature. */
1007 : /* -------------------------------------------------------------------- */
1008 66 : poLayer->ResetReading();
1009 :
1010 132 : while( (poFeature = poLayer->GetNextFeature()) != NULL )
1011 : {
1012 66 : if( poFeature->Equal(poTargetFeature) )
1013 : {
1014 66 : OGRFeature::DestroyFeature(poFeature);
1015 66 : break;
1016 : }
1017 : else
1018 0 : OGRFeature::DestroyFeature(poFeature);
1019 : }
1020 :
1021 66 : if( poFeature == NULL )
1022 : {
1023 0 : bRet = FALSE;
1024 0 : printf( "ERROR: Attribute filter eliminated a feature unexpectedly!\n");
1025 : }
1026 66 : else if( bVerbose )
1027 : {
1028 66 : printf( "INFO: Attribute filter inclusion seems to work.\n" );
1029 : }
1030 :
1031 66 : nInclusiveCount = poLayer->GetFeatureCount();
1032 :
1033 : /* -------------------------------------------------------------------- */
1034 : /* Construct exclusive filter. */
1035 : /* -------------------------------------------------------------------- */
1036 66 : if (EQUAL(poDS->GetDriver()->GetName(), "PostgreSQL") &&
1037 : (strchr(pszFieldName, '_') || strchr(pszFieldName, ' ')))
1038 : {
1039 0 : osAttributeFilter = "\"";
1040 0 : osAttributeFilter += pszFieldName;
1041 0 : osAttributeFilter += "\"";
1042 : }
1043 66 : else if (strchr(pszFieldName, ' ') || pszFieldName[0] == '_')
1044 : {
1045 0 : osAttributeFilter = "'";
1046 0 : osAttributeFilter += pszFieldName;
1047 0 : osAttributeFilter += "'";
1048 : }
1049 : else
1050 66 : osAttributeFilter = pszFieldName;
1051 66 : osAttributeFilter += " <> ";
1052 66 : if (eType == OFTString)
1053 47 : osAttributeFilter += "'";
1054 66 : osAttributeFilter += osValue;
1055 66 : if (eType == OFTString)
1056 47 : osAttributeFilter += "'";
1057 : /* Make sure that the literal will be recognized as a float value */
1058 : /* to avoid int underflow/overflow */
1059 19 : else if (eType == OFTReal && strchr(osValue, '.') == NULL)
1060 0 : osAttributeFilter += ".";
1061 66 : poLayer->SetAttributeFilter( osAttributeFilter );
1062 :
1063 : /* -------------------------------------------------------------------- */
1064 : /* Verify that we can find the target feature. */
1065 : /* -------------------------------------------------------------------- */
1066 66 : poLayer->ResetReading();
1067 :
1068 66 : int nExclusiveCountWhileIterating = 0;
1069 20586 : while( (poFeature = poLayer->GetNextFeature()) != NULL )
1070 : {
1071 20454 : if( poFeature->Equal(poTargetFeature) )
1072 : {
1073 0 : OGRFeature::DestroyFeature(poFeature);
1074 0 : break;
1075 : }
1076 : else
1077 20454 : OGRFeature::DestroyFeature(poFeature);
1078 20454 : nExclusiveCountWhileIterating ++;
1079 : }
1080 :
1081 66 : nExclusiveCount = poLayer->GetFeatureCount();
1082 :
1083 66 : poLayer->SetAttributeFilter( NULL );
1084 :
1085 66 : nTotalCount = poLayer->GetFeatureCount();
1086 :
1087 66 : if( poFeature != NULL )
1088 : {
1089 0 : bRet = FALSE;
1090 : printf( "ERROR: Attribute filter failed to eliminate "
1091 0 : "a feature unexpectedly!\n");
1092 : }
1093 66 : else if( nExclusiveCountWhileIterating != nExclusiveCount ||
1094 : nExclusiveCount >= nTotalCount ||
1095 : nInclusiveCount > nTotalCount ||
1096 : (nInclusiveCount == nTotalCount && nExclusiveCount != 0))
1097 : {
1098 0 : bRet = FALSE;
1099 : printf( "ERROR: GetFeatureCount() may not be taking attribute "
1100 : "filter into account (nInclusiveCount = %d, nExclusiveCount = %d, nExclusiveCountWhileIterating = %d, nTotalCount = %d).\n",
1101 0 : nInclusiveCount, nExclusiveCount, nExclusiveCountWhileIterating, nTotalCount);
1102 : }
1103 66 : else if( bVerbose )
1104 : {
1105 66 : printf( "INFO: Attribute filter exclusion seems to work.\n" );
1106 : }
1107 :
1108 66 : OGRFeature::DestroyFeature(poTargetFeature);
1109 :
1110 66 : return bRet;
1111 : }
1112 :
1113 : /************************************************************************/
1114 : /* TestOGRLayerUTF8() */
1115 : /************************************************************************/
1116 :
1117 77 : static int TestOGRLayerUTF8 ( OGRLayer *poLayer )
1118 : {
1119 77 : int bRet = TRUE;
1120 :
1121 77 : poLayer->SetSpatialFilter( NULL );
1122 77 : poLayer->SetAttributeFilter( NULL );
1123 77 : poLayer->ResetReading();
1124 :
1125 77 : int bIsAdvertizedAsUTF8 = poLayer->TestCapability( OLCStringsAsUTF8 );
1126 77 : int nFields = poLayer->GetLayerDefn()->GetFieldCount();
1127 77 : int bFoundString = FALSE;
1128 77 : int bFoundNonASCII = FALSE;
1129 77 : int bFoundUTF8 = FALSE;
1130 77 : int bCanAdvertizeUTF8 = TRUE;
1131 :
1132 77 : OGRFeature* poFeature = NULL;
1133 145469 : while( bRet && (poFeature = poLayer->GetNextFeature()) != NULL )
1134 : {
1135 2353683 : for(int i = 0; i<nFields; i++)
1136 : {
1137 2208368 : if (!poFeature->IsFieldSet(i))
1138 934034 : continue;
1139 1274334 : if (poFeature->GetFieldDefnRef(i)->GetType() == OFTString)
1140 : {
1141 468829 : const char* pszVal = poFeature->GetFieldAsString(i);
1142 468829 : if (pszVal[0] != 0)
1143 : {
1144 468297 : bFoundString = TRUE;
1145 468297 : const GByte* pszIter = (const GByte*) pszVal;
1146 468297 : int bIsASCII = TRUE;
1147 3595743 : while(*pszIter)
1148 : {
1149 2659170 : if (*pszIter >= 128)
1150 : {
1151 21 : bFoundNonASCII = TRUE;
1152 21 : bIsASCII = FALSE;
1153 21 : break;
1154 : }
1155 2659149 : pszIter ++;
1156 : }
1157 468297 : int bIsUTF8 = CPLIsUTF8(pszVal, -1);
1158 468297 : if (bIsUTF8 && !bIsASCII)
1159 21 : bFoundUTF8 = TRUE;
1160 468297 : if (bIsAdvertizedAsUTF8)
1161 : {
1162 251 : if (!bIsUTF8)
1163 : {
1164 : printf( "ERROR: Found non-UTF8 content at field %d of feature %ld, but layer is advertized as UTF-8.\n",
1165 0 : i, poFeature->GetFID() );
1166 0 : bRet = FALSE;
1167 0 : break;
1168 : }
1169 : }
1170 : else
1171 : {
1172 468046 : if (!bIsUTF8)
1173 0 : bCanAdvertizeUTF8 = FALSE;
1174 : }
1175 : }
1176 : }
1177 : }
1178 145315 : OGRFeature::DestroyFeature(poFeature);
1179 : }
1180 :
1181 77 : if (!bFoundString)
1182 : {
1183 : }
1184 66 : else if (bCanAdvertizeUTF8)
1185 : {
1186 66 : if (bIsAdvertizedAsUTF8)
1187 : {
1188 33 : if (bFoundUTF8)
1189 : {
1190 16 : printf( "INFO: Layer has UTF-8 content and is consistently declared as having UTF-8 content.\n" );
1191 : }
1192 17 : else if (!bFoundNonASCII)
1193 : {
1194 17 : printf( "INFO: Layer has ASCII only content and is consistently declared as having UTF-8 content.\n" );
1195 : }
1196 : }
1197 : else
1198 : {
1199 33 : if (bFoundUTF8)
1200 : {
1201 1 : printf( "INFO: Layer could perhaps be advertized as UTF-8 compatible (and it has non-ASCII UTF-8 content).\n" );
1202 : }
1203 32 : else if (!bFoundNonASCII)
1204 : {
1205 32 : printf( "INFO: Layer could perhaps be advertized as UTF-8 compatible (it has only ASCII content).\n" );
1206 : }
1207 : }
1208 : }
1209 : else
1210 : {
1211 0 : printf( "INFO: Layer has non UTF-8 content (and is consistently declared as not being UTF-8 compatible).\n" );
1212 : }
1213 :
1214 77 : return bRet;
1215 : }
1216 :
1217 : /************************************************************************/
1218 : /* TestGetExtent() */
1219 : /************************************************************************/
1220 :
1221 77 : static int TestGetExtent ( OGRLayer *poLayer )
1222 : {
1223 77 : int bRet = TRUE;
1224 :
1225 77 : poLayer->SetSpatialFilter( NULL );
1226 77 : poLayer->SetAttributeFilter( NULL );
1227 77 : poLayer->ResetReading();
1228 :
1229 77 : OGREnvelope sExtent;
1230 77 : OGREnvelope sExtentSlow;
1231 :
1232 77 : OGRErr eErr = poLayer->GetExtent(&sExtent, TRUE);
1233 77 : OGRErr eErr2 = poLayer->OGRLayer::GetExtent(&sExtentSlow, TRUE);
1234 :
1235 77 : if (eErr != eErr2)
1236 : {
1237 4 : if (eErr == OGRERR_NONE && eErr2 != OGRERR_NONE)
1238 : {
1239 : /* with the LIBKML driver and test_ogrsf ../autotest/ogr/data/samples.kml "Styles and Markup" */
1240 2 : printf("INFO: GetExtent() succeeded but OGRLayer::GetExtent() failed.\n");
1241 : }
1242 : else
1243 : {
1244 0 : bRet = FALSE;
1245 0 : printf("ERROR: GetExtent() failed but OGRLayer::GetExtent() succeeded.\n");
1246 : }
1247 : }
1248 75 : else if (eErr == OGRERR_NONE)
1249 : {
1250 103 : if (fabs(sExtentSlow.MinX - sExtent.MinX) < 1e-10 &&
1251 : fabs(sExtentSlow.MinY - sExtent.MinY) < 1e-10 &&
1252 : fabs(sExtentSlow.MaxX - sExtent.MaxX) < 1e-10 &&
1253 : fabs(sExtentSlow.MaxY - sExtent.MaxY) < 1e-10)
1254 : {
1255 50 : printf("INFO: GetExtent() test passed.\n");
1256 : }
1257 : else
1258 : {
1259 3 : if (sExtentSlow.Contains(sExtent))
1260 : {
1261 1 : printf("INFO: sExtentSlow.Contains(sExtent)\n");
1262 : }
1263 2 : else if (sExtent.Contains(sExtentSlow))
1264 : {
1265 1 : printf("INFO: sExtent.Contains(sExtentSlow)\n");
1266 : }
1267 : else
1268 : {
1269 1 : printf("INFO: unknown relationship between sExtent and sExentSlow.\n");
1270 : }
1271 3 : printf("INFO: sExtentSlow.MinX = %.15f\n", sExtentSlow.MinX);
1272 3 : printf("INFO: sExtentSlow.MinY = %.15f\n", sExtentSlow.MinY);
1273 3 : printf("INFO: sExtentSlow.MaxX = %.15f\n", sExtentSlow.MaxX);
1274 3 : printf("INFO: sExtentSlow.MaxY = %.15f\n", sExtentSlow.MaxY);
1275 3 : printf("INFO: sExtent.MinX = %.15f\n", sExtent.MinX);
1276 3 : printf("INFO: sExtent.MinY = %.15f\n", sExtent.MinY);
1277 3 : printf("INFO: sExtent.MaxX = %.15f\n", sExtent.MaxX);
1278 3 : printf("INFO: sExtent.MaxY = %.15f\n", sExtent.MaxY);
1279 : }
1280 : }
1281 :
1282 77 : return bRet;
1283 : }
1284 :
1285 : /************************************************************************/
1286 : /* TestOGRLayer() */
1287 : /************************************************************************/
1288 :
1289 77 : static int TestOGRLayer( OGRDataSource* poDS, OGRLayer * poLayer, int bIsSQLLayer )
1290 :
1291 : {
1292 77 : int bRet = TRUE;
1293 :
1294 : /* -------------------------------------------------------------------- */
1295 : /* Verify that there is no spatial filter in place by default. */
1296 : /* -------------------------------------------------------------------- */
1297 77 : if( poLayer->GetSpatialFilter() != NULL )
1298 : {
1299 : printf( "WARN: Spatial filter in place by default on layer %s.\n",
1300 0 : poLayer->GetName() );
1301 0 : poLayer->SetSpatialFilter( NULL );
1302 : }
1303 :
1304 : /* -------------------------------------------------------------------- */
1305 : /* Test feature count accuracy. */
1306 : /* -------------------------------------------------------------------- */
1307 77 : bRet &= TestOGRLayerFeatureCount( poDS, poLayer, bIsSQLLayer );
1308 :
1309 : /* -------------------------------------------------------------------- */
1310 : /* Test spatial filtering */
1311 : /* -------------------------------------------------------------------- */
1312 77 : bRet &= TestSpatialFilter( poLayer );
1313 :
1314 : /* -------------------------------------------------------------------- */
1315 : /* Test attribute filtering */
1316 : /* -------------------------------------------------------------------- */
1317 77 : bRet &= TestAttributeFilter( poDS, poLayer );
1318 :
1319 : /* -------------------------------------------------------------------- */
1320 : /* Test GetExtent() */
1321 : /* -------------------------------------------------------------------- */
1322 77 : bRet &= TestGetExtent( poLayer );
1323 :
1324 : /* -------------------------------------------------------------------- */
1325 : /* Test random reading. */
1326 : /* -------------------------------------------------------------------- */
1327 77 : if( poLayer->TestCapability( OLCRandomRead ) )
1328 : {
1329 48 : bRet &= TestOGRLayerRandomRead( poLayer );
1330 : }
1331 :
1332 : /* -------------------------------------------------------------------- */
1333 : /* Test SetNextByIndex. */
1334 : /* -------------------------------------------------------------------- */
1335 77 : if( poLayer->TestCapability( OLCFastSetNextByIndex ) )
1336 : {
1337 9 : bRet &= TestOGRLayerSetNextByIndex( poLayer );
1338 : }
1339 :
1340 : /* -------------------------------------------------------------------- */
1341 : /* Test random writing. */
1342 : /* -------------------------------------------------------------------- */
1343 77 : if( poLayer->TestCapability( OLCRandomWrite ) )
1344 : {
1345 10 : bRet &= TestOGRLayerRandomWrite( poLayer );
1346 : }
1347 :
1348 77 : bRet &= TestOGRLayerUTF8( poLayer );
1349 :
1350 77 : return bRet;
1351 : }
1352 :
1353 : /************************************************************************/
1354 : /* TestInterleavedReading() */
1355 : /************************************************************************/
1356 :
1357 10 : static int TestInterleavedReading( const char* pszDataSource, char** papszLayers )
1358 : {
1359 10 : int bRet = TRUE;
1360 10 : OGRDataSource* poDS = NULL;
1361 10 : OGRDataSource* poDS2 = NULL;
1362 10 : OGRLayer* poLayer1 = NULL;
1363 10 : OGRLayer* poLayer2 = NULL;
1364 10 : OGRFeature* poFeature11_Ref = NULL;
1365 10 : OGRFeature* poFeature12_Ref = NULL;
1366 10 : OGRFeature* poFeature21_Ref = NULL;
1367 10 : OGRFeature* poFeature22_Ref = NULL;
1368 10 : OGRFeature* poFeature11 = NULL;
1369 10 : OGRFeature* poFeature12 = NULL;
1370 10 : OGRFeature* poFeature21 = NULL;
1371 10 : OGRFeature* poFeature22 = NULL;
1372 :
1373 : /* Check that we have 2 layers with at least 2 features */
1374 10 : poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, NULL );
1375 10 : if (poDS == NULL)
1376 : {
1377 0 : printf( "INFO: Skipping TestInterleavedReading(). Cannot reopen datasource\n" );
1378 0 : goto bye;
1379 : }
1380 :
1381 10 : poLayer1 = papszLayers ? poDS->GetLayerByName(papszLayers[0]) : poDS->GetLayer(0);
1382 10 : poLayer2 = papszLayers ? poDS->GetLayerByName(papszLayers[1]) : poDS->GetLayer(1);
1383 28 : if (poLayer1 == NULL || poLayer2 == NULL ||
1384 18 : poLayer1->GetFeatureCount() < 2 || poLayer2->GetFeatureCount() < 2)
1385 : {
1386 6 : printf( "INFO: Skipping TestInterleavedReading(). Test conditions are not met\n" );
1387 6 : goto bye;
1388 : }
1389 :
1390 : /* Test normal reading */
1391 4 : OGRDataSource::DestroyDataSource(poDS);
1392 4 : poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, NULL );
1393 4 : poDS2 = OGRSFDriverRegistrar::Open( pszDataSource, FALSE, NULL );
1394 4 : if (poDS == NULL || poDS2 == NULL)
1395 : {
1396 0 : printf( "INFO: Skipping TestInterleavedReading(). Cannot reopen datasource\n" );
1397 0 : goto bye;
1398 : }
1399 :
1400 4 : poLayer1 = papszLayers ? poDS->GetLayerByName(papszLayers[0]) : poDS->GetLayer(0);
1401 4 : poLayer2 = papszLayers ? poDS->GetLayerByName(papszLayers[1]) : poDS->GetLayer(1);
1402 4 : if (poLayer1 == NULL || poLayer2 == NULL)
1403 : {
1404 0 : printf( "ERROR: Skipping TestInterleavedReading(). Test conditions are not met\n" );
1405 0 : bRet = FALSE;
1406 0 : goto bye;
1407 : }
1408 :
1409 4 : poFeature11_Ref = poLayer1->GetNextFeature();
1410 4 : poFeature12_Ref = poLayer1->GetNextFeature();
1411 4 : poFeature21_Ref = poLayer2->GetNextFeature();
1412 4 : poFeature22_Ref = poLayer2->GetNextFeature();
1413 4 : if (poFeature11_Ref == NULL || poFeature12_Ref == NULL || poFeature21_Ref == NULL || poFeature22_Ref == NULL)
1414 : {
1415 : printf( "ERROR: TestInterleavedReading() failed: poFeature11_Ref=%p, poFeature12_Ref=%p, poFeature21_Ref=%p, poFeature22_Ref=%p\n",
1416 0 : poFeature11_Ref, poFeature12_Ref, poFeature21_Ref, poFeature22_Ref);
1417 0 : bRet = FALSE;
1418 0 : goto bye;
1419 : }
1420 :
1421 : /* Test interleaved reading */
1422 4 : poLayer1 = papszLayers ? poDS2->GetLayerByName(papszLayers[0]) : poDS2->GetLayer(0);
1423 4 : poLayer2 = papszLayers ? poDS2->GetLayerByName(papszLayers[1]) : poDS2->GetLayer(1);
1424 4 : if (poLayer1 == NULL || poLayer2 == NULL)
1425 : {
1426 0 : printf( "ERROR: Skipping TestInterleavedReading(). Test conditions are not met\n" );
1427 0 : bRet = FALSE;
1428 0 : goto bye;
1429 : }
1430 :
1431 4 : poFeature11 = poLayer1->GetNextFeature();
1432 4 : poFeature21 = poLayer2->GetNextFeature();
1433 4 : poFeature12 = poLayer1->GetNextFeature();
1434 4 : poFeature22 = poLayer2->GetNextFeature();
1435 :
1436 4 : if (poFeature11 == NULL || poFeature21 == NULL || poFeature12 == NULL || poFeature22 == NULL)
1437 : {
1438 : printf( "ERROR: TestInterleavedReading() failed: poFeature11=%p, poFeature21=%p, poFeature12=%p, poFeature22=%p\n",
1439 0 : poFeature11, poFeature21, poFeature12, poFeature22);
1440 0 : bRet = FALSE;
1441 0 : goto bye;
1442 : }
1443 :
1444 4 : if (poFeature12->Equal(poFeature11))
1445 : {
1446 : printf( "WARN: TestInterleavedReading() failed: poFeature12 == poFeature11. "
1447 1 : "The datasource resets the layer reading when interleaved layer reading pattern is detected. Acceptable but could be improved\n" );
1448 1 : goto bye;
1449 : }
1450 :
1451 : /* We cannot directly compare the feature as they don't share */
1452 : /* the same (pointer) layer definition, so just compare FIDs */
1453 3 : if (poFeature12_Ref->GetFID() != poFeature12->GetFID())
1454 : {
1455 0 : printf( "ERROR: TestInterleavedReading() failed: poFeature12_Ref != poFeature12\n" );
1456 0 : poFeature12_Ref->DumpReadable(stdout, NULL);
1457 0 : poFeature12->DumpReadable(stdout, NULL);
1458 0 : bRet = FALSE;
1459 0 : goto bye;
1460 : }
1461 :
1462 3 : if( bVerbose )
1463 : {
1464 3 : printf("INFO: TestInterleavedReading() successfull.\n");
1465 : }
1466 :
1467 : bye:
1468 10 : OGRFeature::DestroyFeature(poFeature11_Ref);
1469 10 : OGRFeature::DestroyFeature(poFeature12_Ref);
1470 10 : OGRFeature::DestroyFeature(poFeature21_Ref);
1471 10 : OGRFeature::DestroyFeature(poFeature22_Ref);
1472 10 : OGRFeature::DestroyFeature(poFeature11);
1473 10 : OGRFeature::DestroyFeature(poFeature21);
1474 10 : OGRFeature::DestroyFeature(poFeature12);
1475 10 : OGRFeature::DestroyFeature(poFeature22);
1476 10 : OGRDataSource::DestroyDataSource(poDS);
1477 10 : OGRDataSource::DestroyDataSource(poDS2);
1478 10 : return bRet;
1479 : }
|