1 /************************************************************************
3 * $Id: geostest.c 1892 2006-11-02 10:02:59Z strk $
5 * Multithreaded test for C-Wrapper of GEOS library
7 * Copyright (C) 2005 Refractions Research Inc.
9 * This is free software; you can redistribute and/or modify it under
10 * the terms of the GNU Lesser General Public Licence as published
11 * by the Free Software Foundation.
12 * See the COPYING file for more information.
14 * Author: Sandro Santilli <strk@refractions.net>
16 ***********************************************************************/
28 #define MAXWKTLEN 1047551
33 fprintf(stderr
, "Usage: %s <wktfile>\n", me
);
38 notice1(const char *fmt
, ...) {
41 fprintf( stdout
, "NOTICE1: ");
44 vfprintf( stdout
, fmt
, ap
);
46 fprintf( stdout
, "\n" );
50 notice2(const char *fmt
, ...) {
53 fprintf( stdout
, "NOTICE2: ");
56 vfprintf( stdout
, fmt
, ap
);
58 fprintf( stdout
, "\n" );
62 log_and_exit(const char *fmt
, ...) {
65 fprintf( stdout
, "ERROR: ");
68 vfprintf( stdout
, fmt
, ap
);
70 fprintf( stdout
, "\n" );
75 log_and_exit1(const char *fmt
, ...) {
78 fprintf( stdout
, "ERROR1: ");
81 vfprintf( stdout
, fmt
, ap
);
83 fprintf( stdout
, "\n" );
88 log_and_exit2(const char *fmt
, ...) {
91 fprintf( stdout
, "ERROR2: ");
94 vfprintf( stdout
, fmt
, ap
);
96 fprintf( stdout
, "\n" );
101 fineGrainedReconstructionTest(const GEOSGeometry
* g1
,
102 GEOSContextHandle_t handle
)
104 GEOSCoordSequence
* cs
;
107 const GEOSGeometry
* gtmp
;
109 unsigned int ngeoms
, i
;
112 /* Geometry reconstruction from CoordSeq */
113 type
= GEOSGeomTypeId_r(handle
, g1
);
117 cs
= GEOSCoordSeq_clone_r(handle
,
118 GEOSGeom_getCoordSeq_r(handle
, g1
));
119 g2
= GEOSGeom_createPoint_r(handle
, cs
);
122 case GEOS_LINESTRING
:
123 cs
= GEOSCoordSeq_clone_r(handle
,
124 GEOSGeom_getCoordSeq_r(handle
, g1
));
125 g2
= GEOSGeom_createLineString_r(handle
, cs
);
128 case GEOS_LINEARRING
:
129 cs
= GEOSCoordSeq_clone_r(handle
,
130 GEOSGeom_getCoordSeq_r(handle
, g1
));
131 g2
= GEOSGeom_createLinearRing_r(handle
, cs
);
135 gtmp
= GEOSGetExteriorRing_r(handle
, g1
);
136 cs
= GEOSCoordSeq_clone_r(handle
,
137 GEOSGeom_getCoordSeq_r(handle
, gtmp
));
138 shell
= GEOSGeom_createLinearRing_r(handle
, cs
);
139 ngeoms
= GEOSGetNumInteriorRings_r(handle
, g1
);
140 geoms
= malloc(ngeoms
*sizeof(GEOSGeometry
*));
141 for (i
=0; i
<ngeoms
; i
++)
143 gtmp
= GEOSGetInteriorRingN_r(handle
, g1
, i
);
144 cs
= GEOSCoordSeq_clone_r(handle
,
145 GEOSGeom_getCoordSeq_r(handle
, gtmp
));
146 geoms
[i
] = GEOSGeom_createLinearRing_r(handle
,
149 g2
= GEOSGeom_createPolygon_r(handle
, shell
, geoms
,
154 case GEOS_MULTIPOINT
:
155 case GEOS_MULTILINESTRING
:
156 case GEOS_MULTIPOLYGON
:
157 case GEOS_GEOMETRYCOLLECTION
:
158 ngeoms
= GEOSGetNumGeometries_r(handle
, g1
);
159 geoms
= malloc(ngeoms
*sizeof(GEOSGeometry
*));
160 for (i
=0; i
<ngeoms
; i
++)
162 gtmp
= GEOSGetGeometryN_r(handle
, g1
, i
);
163 geoms
[i
] = fineGrainedReconstructionTest(gtmp
,
166 g2
= GEOSGeom_createCollection_r(handle
, type
, geoms
,
172 log_and_exit("Unknown geometry type %d\n", type
);
178 printHEX(FILE *where
, const unsigned char *bytes
, size_t n
)
180 static char hex
[] = "0123456789ABCDEF";
185 fprintf(where
, "%c%c", hex
[bytes
[i
]>>4], hex
[bytes
[i
]&0x0F]);
190 do_all(char *inputfile
, GEOSContextHandle_t handle
)
196 const GEOSGeometry
**gg
;
197 unsigned int npoints
, ndims
;
198 static char wkt
[MAXWKTLEN
];
205 input
= fopen(inputfile
, "r");
206 if ( ! input
) { perror("fopen"); exit(1); }
208 size
= fread(wkt
, 1, MAXWKTLEN
-1, input
);
210 if ( ! size
) { perror("fread"); exit(1); }
211 if ( size
== MAXWKTLEN
-1 ) { perror("WKT input too big!"); exit(1); }
212 wkt
[size
] = '\0'; /* ensure it is null terminated */
215 g1
= GEOSGeomFromWKT_r(handle
, wkt
);
218 ptr
= GEOSGeomToWKT_r(handle
, g1
);
219 printf("Input (WKT): %s\n", ptr
);
223 uptr
= GEOSGeomToWKB_buf_r(handle
, g1
, &size
);
224 printf("Input (WKB): "); printHEX(stdout
, uptr
, size
); putchar('\n');
227 g2
= GEOSGeomFromWKB_buf_r(handle
, uptr
, size
); free(uptr
);
228 if ( ! GEOSEquals_r(handle
, g1
, g2
) ) log_and_exit("Round WKB conversion failed");
229 GEOSGeom_destroy_r(handle
, g2
);
231 /* Size and dimension */
232 npoints
= GEOSGetNumCoordinates_r(handle
, g1
);
233 ndims
= GEOSGeom_getDimensions_r(handle
, g1
);
234 printf("Geometry coordinates: %dx%d\n", npoints
, ndims
);
236 /* Geometry fine-grained deconstruction/reconstruction test */
237 g2
= fineGrainedReconstructionTest(g1
, handle
);
238 if ( ! GEOSEquals_r(handle
, g1
, g2
) )
240 log_and_exit("Reconstruction test failed\n");
242 GEOSGeom_destroy_r(handle
, g2
);
244 /* Unary predicates */
245 if ( GEOSisEmpty_r(handle
, g1
) ) printf("isEmpty\n");
246 if ( GEOSisValid_r(handle
, g1
) ) printf("isValid\n");
247 if ( GEOSisSimple_r(handle
, g1
) ) printf("isSimple\n");
248 if ( GEOSisRing_r(handle
, g1
) ) printf("isRing\n");
251 g2
= GEOSConvexHull_r(handle
, g1
);
254 log_and_exit("GEOSConvexHull() raised an exception");
256 ptr
= GEOSGeomToWKT_r(handle
, g2
);
257 printf("ConvexHull: %s\n", ptr
);
261 GEOSGeom_destroy_r(handle
, g1
);
262 g1
= GEOSBuffer_r(handle
, g2
, 100, 30);
265 log_and_exit("GEOSBuffer() raised an exception");
267 ptr
= GEOSGeomToWKT_r(handle
, g1
);
268 printf("Buffer: %s\n", ptr
);
273 g3
= GEOSIntersection_r(handle
, g1
, g2
);
274 if ( ! GEOSEquals_r(handle
, g3
, g2
) )
276 GEOSGeom_destroy_r(handle
, g1
);
277 GEOSGeom_destroy_r(handle
, g2
);
278 GEOSGeom_destroy_r(handle
, g3
);
279 log_and_exit("Intersection(g, Buffer(g)) didn't return g");
281 ptr
= GEOSGeomToWKT_r(handle
, g3
);
282 printf("Intersection: %s\n", ptr
);
283 GEOSGeom_destroy_r(handle
, g3
);
287 g3
= GEOSDifference_r(handle
, g1
, g2
);
288 ptr
= GEOSGeomToWKT_r(handle
, g3
);
289 printf("Difference: %s\n", ptr
);
290 GEOSGeom_destroy_r(handle
, g3
);
294 g3
= GEOSSymDifference_r(handle
, g1
, g2
);
295 ptr
= GEOSGeomToWKT_r(handle
, g3
);
296 printf("SymDifference: %s\n", ptr
);
300 g4
= GEOSBoundary_r(handle
, g3
);
301 ptr
= GEOSGeomToWKT_r(handle
, g4
);
302 printf("Boundary: %s\n", ptr
);
303 GEOSGeom_destroy_r(handle
, g3
);
304 GEOSGeom_destroy_r(handle
, g4
);
308 g3
= GEOSUnion_r(handle
, g1
, g2
);
309 if ( ! GEOSEquals_r(handle
, g3
, g1
) )
311 GEOSGeom_destroy_r(handle
, g1
);
312 GEOSGeom_destroy_r(handle
, g2
);
313 GEOSGeom_destroy_r(handle
, g3
);
314 log_and_exit("Union(g, Buffer(g)) didn't return Buffer(g)");
316 ptr
= GEOSGeomToWKT_r(handle
, g3
);
317 printf("Union: %s\n", ptr
);
321 g4
= GEOSPointOnSurface_r(handle
, g3
);
322 ptr
= GEOSGeomToWKT_r(handle
, g4
);
323 printf("PointOnSurface: %s\n", ptr
);
324 GEOSGeom_destroy_r(handle
, g3
);
325 GEOSGeom_destroy_r(handle
, g4
);
329 g3
= GEOSGetCentroid_r(handle
, g2
);
330 ptr
= GEOSGeomToWKT_r(handle
, g3
);
331 printf("Centroid: %s\n", ptr
);
332 GEOSGeom_destroy_r(handle
, g3
);
335 /* Relate (and RelatePattern )*/
336 ptr
= GEOSRelate_r(handle
, g1
, g2
);
337 if ( ! GEOSRelatePattern_r(handle
, g1
, g2
, ptr
) )
339 GEOSGeom_destroy_r(handle
, g1
);
340 GEOSGeom_destroy_r(handle
, g2
);
342 log_and_exit("! RelatePattern(g1, g2, Relate(g1, g2))");
344 printf("Relate: %s\n", ptr
);
348 gg
= (const GEOSGeometry
**)malloc(2*sizeof(GEOSGeometry
*));
351 g3
= GEOSPolygonize_r(handle
, gg
, 2);
355 log_and_exit("Exception running GEOSPolygonize");
357 ptr
= GEOSGeomToWKT_r(handle
, g3
);
358 GEOSGeom_destroy_r(handle
, g3
);
359 printf("Polygonize: %s\n", ptr
);
363 g3
= GEOSLineMerge_r(handle
, g1
);
366 log_and_exit("Exception running GEOSLineMerge");
368 ptr
= GEOSGeomToWKT_r(handle
, g3
);
369 printf("LineMerge: %s\n", ptr
);
371 GEOSGeom_destroy_r(handle
, g3
);
373 /* Binary predicates */
374 if ( GEOSIntersects_r(handle
, g1
, g2
) ) printf("Intersect\n");
375 if ( GEOSDisjoint_r(handle
, g1
, g2
) ) printf("Disjoint\n");
376 if ( GEOSTouches_r(handle
, g1
, g2
) ) printf("Touches\n");
377 if ( GEOSCrosses_r(handle
, g1
, g2
) ) printf("Crosses\n");
378 if ( GEOSWithin_r(handle
, g1
, g2
) ) printf("Within\n");
379 if ( GEOSContains_r(handle
, g1
, g2
) ) printf("Contains\n");
380 if ( GEOSOverlaps_r(handle
, g1
, g2
) ) printf("Overlaps\n");
383 if ( GEOSDistance_r(handle
, g1
, g2
, &dist
) ) printf("Distance: %g\n", dist
);
386 if ( GEOSArea_r(handle
, g1
, &area
) ) printf("Area 1: %g\n", area
);
387 if ( GEOSArea_r(handle
, g2
, &area
) ) printf("Area 2: %g\n", area
);
389 GEOSGeom_destroy_r(handle
, g2
);
392 g3
= GEOSSimplify_r(handle
, g1
, 0.5);
393 ptr
= GEOSGeomToWKT_r(handle
, g3
);
394 printf("Simplify: %s\n", ptr
);
396 GEOSGeom_destroy_r(handle
, g3
);
398 /* Topology Preserve Simplify */
399 g3
= GEOSTopologyPreserveSimplify_r(handle
, g1
, 0.5);
400 ptr
= GEOSGeomToWKT_r(handle
, g3
);
401 printf("Simplify: %s\n", ptr
);
403 GEOSGeom_destroy_r(handle
, g3
);
405 GEOSGeom_destroy_r(handle
, g1
);
410 void *threadfunc1( void *arg
)
412 GEOSContextHandle_t handle
= NULL
;
414 handle
= initGEOS_r( notice1
, log_and_exit1
);
415 printf("GEOS version %s\n", GEOSversion(handle
));
416 putc('.', stderr
); fflush(stderr
);
417 do_all((char*)arg
, handle
);
418 putc('+', stderr
); fflush(stderr
);
419 finishGEOS_r(handle
);
424 void *threadfunc2( void *arg
)
426 GEOSContextHandle_t handle
= NULL
;
428 handle
= initGEOS_r( notice2
, log_and_exit2
);
429 printf("GEOS version %s\n", GEOSversion(handle
));
430 putc('.', stderr
); fflush(stderr
);
431 do_all((char *)arg
, handle
);
432 putc('+', stderr
); fflush(stderr
);
433 finishGEOS_r(handle
);
439 main(int argc
, char **argv
)
441 pthread_t thread1
, thread2
;
443 if ( argc
< 2 ) usage(argv
[0]);
444 pthread_create( &thread1
, NULL
, threadfunc1
, argv
[1] );
445 pthread_create( &thread2
, NULL
, threadfunc2
, argv
[1] );
446 pthread_join( thread1
, NULL
);
447 pthread_join( thread2
, NULL
);