1 /************************************************************************
5 * 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 ***********************************************************************/
26 #define MAXWKTLEN 1047551
31 fprintf(stderr
, "Usage: %s <wktfile>\n", me
);
36 notice(const char *fmt
, ...) {
39 fprintf( stdout
, "NOTICE: ");
42 vfprintf( stdout
, fmt
, ap
);
44 fprintf( stdout
, "\n" );
48 log_and_exit(const char *fmt
, ...) {
51 fprintf( stdout
, "ERROR: ");
54 vfprintf( stdout
, fmt
, ap
);
56 fprintf( stdout
, "\n" );
61 fineGrainedReconstructionTest(const GEOSGeometry
* g1
)
63 GEOSCoordSequence
* cs
;
66 const GEOSGeometry
* gtmp
;
68 unsigned int ngeoms
, i
;
71 /* Geometry reconstruction from CoordSeq */
72 type
= GEOSGeomTypeId(g1
);
76 cs
= GEOSCoordSeq_clone(GEOSGeom_getCoordSeq(g1
));
77 g2
= GEOSGeom_createPoint(cs
);
81 cs
= GEOSCoordSeq_clone(GEOSGeom_getCoordSeq(g1
));
82 g2
= GEOSGeom_createLineString(cs
);
86 cs
= GEOSCoordSeq_clone(GEOSGeom_getCoordSeq(g1
));
87 g2
= GEOSGeom_createLinearRing(cs
);
91 gtmp
= GEOSGetExteriorRing(g1
);
92 cs
= GEOSCoordSeq_clone(GEOSGeom_getCoordSeq(gtmp
));
93 shell
= GEOSGeom_createLinearRing(cs
);
94 ngeoms
= GEOSGetNumInteriorRings(g1
);
95 geoms
= malloc(ngeoms
*sizeof(GEOSGeometry
*));
96 for (i
=0; i
<ngeoms
; i
++)
98 gtmp
= GEOSGetInteriorRingN(g1
, i
);
99 cs
= GEOSCoordSeq_clone(GEOSGeom_getCoordSeq(gtmp
));
100 geoms
[i
] = GEOSGeom_createLinearRing(cs
);
102 g2
= GEOSGeom_createPolygon(shell
, geoms
, ngeoms
);
106 case GEOS_MULTIPOINT
:
107 case GEOS_MULTILINESTRING
:
108 case GEOS_MULTIPOLYGON
:
109 case GEOS_GEOMETRYCOLLECTION
:
110 ngeoms
= GEOSGetNumGeometries(g1
);
111 geoms
= malloc(ngeoms
*sizeof(GEOSGeometry
*));
112 for (i
=0; i
<ngeoms
; i
++)
114 gtmp
= GEOSGetGeometryN(g1
, i
);
115 geoms
[i
] = fineGrainedReconstructionTest(gtmp
);
117 g2
= GEOSGeom_createCollection(type
, geoms
, ngeoms
);
122 log_and_exit("Unknown geometry type %d\n", type
);
128 printHEX(FILE *where
, const unsigned char *bytes
, size_t n
)
130 static char hex
[] = "0123456789ABCDEF";
135 fprintf(where
, "%c%c", hex
[bytes
[i
]>>4], hex
[bytes
[i
]&0x0F]);
140 do_all(char *inputfile
)
146 const GEOSGeometry
**gg
;
147 unsigned int npoints
, ndims
;
148 static char wkt
[MAXWKTLEN
];
155 input
= fopen(inputfile
, "r");
156 if ( ! input
) { perror("fopen"); exit(1); }
158 size
= fread(wkt
, 1, MAXWKTLEN
-1, input
);
160 if ( ! size
) { perror("fread"); exit(1); }
161 if ( size
== MAXWKTLEN
-1 ) { perror("WKT input too big!"); exit(1); }
162 wkt
[size
] = '\0'; /* ensure it is null terminated */
165 g1
= GEOSGeomFromWKT(wkt
);
168 ptr
= GEOSGeomToWKT(g1
);
169 printf("Input (WKT): %s\n", ptr
);
173 uptr
= GEOSGeomToWKB_buf(g1
, &size
);
174 printf("Input (WKB): "); printHEX(stdout
, uptr
, size
); putchar('\n');
177 g2
= GEOSGeomFromWKB_buf(uptr
, size
); free(uptr
);
178 if ( ! GEOSEquals(g1
, g2
) ) log_and_exit("Round WKB conversion failed");
179 GEOSGeom_destroy(g2
);
181 /* Size and dimension */
182 npoints
= GEOSGetNumCoordinates(g1
);
183 ndims
= GEOSGeom_getDimensions(g1
);
184 printf("Geometry coordinates: %dx%d\n", npoints
, ndims
);
186 /* Geometry fine-grained deconstruction/reconstruction test */
187 g2
= fineGrainedReconstructionTest(g1
);
188 if ( ! GEOSEquals(g1
, g2
) )
190 log_and_exit("Reconstruction test failed\n");
192 GEOSGeom_destroy(g2
);
194 /* Unary predicates */
195 if ( GEOSisEmpty(g1
) ) printf("isEmpty\n");
196 if ( GEOSisValid(g1
) ) printf("isValid\n");
197 if ( GEOSisSimple(g1
) ) printf("isSimple\n");
198 if ( GEOSisRing(g1
) ) printf("isRing\n");
201 g2
= GEOSConvexHull(g1
);
204 log_and_exit("GEOSConvexHull() raised an exception");
206 ptr
= GEOSGeomToWKT(g2
);
207 printf("ConvexHull: %s\n", ptr
);
211 GEOSGeom_destroy(g1
);
212 g1
= GEOSBuffer(g2
, 100, 30);
215 log_and_exit("GEOSBuffer() raised an exception");
217 ptr
= GEOSGeomToWKT(g1
);
218 printf("Buffer: %s\n", ptr
);
223 g3
= GEOSIntersection(g1
, g2
);
224 if ( ! GEOSEquals(g3
, g2
) )
226 GEOSGeom_destroy(g1
);
227 GEOSGeom_destroy(g2
);
228 GEOSGeom_destroy(g3
);
229 log_and_exit("Intersection(g, Buffer(g)) didn't return g");
231 ptr
= GEOSGeomToWKT(g3
);
232 printf("Intersection: %s\n", ptr
);
233 GEOSGeom_destroy(g3
);
237 g3
= GEOSDifference(g1
, g2
);
238 ptr
= GEOSGeomToWKT(g3
);
239 printf("Difference: %s\n", ptr
);
240 GEOSGeom_destroy(g3
);
244 g3
= GEOSSymDifference(g1
, g2
);
245 ptr
= GEOSGeomToWKT(g3
);
246 printf("SymDifference: %s\n", ptr
);
250 g4
= GEOSBoundary(g3
);
251 ptr
= GEOSGeomToWKT(g4
);
252 printf("Boundary: %s\n", ptr
);
253 GEOSGeom_destroy(g3
);
254 GEOSGeom_destroy(g4
);
258 g3
= GEOSUnion(g1
, g2
);
259 if ( ! GEOSEquals(g3
, g1
) )
261 GEOSGeom_destroy(g1
);
262 GEOSGeom_destroy(g2
);
263 GEOSGeom_destroy(g3
);
264 log_and_exit("Union(g, Buffer(g)) didn't return Buffer(g)");
266 ptr
= GEOSGeomToWKT(g3
);
267 printf("Union: %s\n", ptr
);
271 g4
= GEOSPointOnSurface(g3
);
272 ptr
= GEOSGeomToWKT(g4
);
273 printf("PointOnSurface: %s\n", ptr
);
274 GEOSGeom_destroy(g3
);
275 GEOSGeom_destroy(g4
);
279 g3
= GEOSGetCentroid(g2
);
280 ptr
= GEOSGeomToWKT(g3
);
281 printf("Centroid: %s\n", ptr
);
282 GEOSGeom_destroy(g3
);
285 /* Relate (and RelatePattern )*/
286 ptr
= GEOSRelate(g1
, g2
);
287 if ( ! GEOSRelatePattern(g1
, g2
, ptr
) )
289 GEOSGeom_destroy(g1
);
290 GEOSGeom_destroy(g2
);
292 log_and_exit("! RelatePattern(g1, g2, Relate(g1, g2))");
294 printf("Relate: %s\n", ptr
);
298 gg
= (const GEOSGeometry
**)malloc(2*sizeof(GEOSGeometry
*));
301 g3
= GEOSPolygonize(gg
, 2);
305 log_and_exit("Exception running GEOSPolygonize");
307 ptr
= GEOSGeomToWKT(g3
);
308 GEOSGeom_destroy(g3
);
309 printf("Polygonize: %s\n", ptr
);
313 g3
= GEOSLineMerge(g1
);
316 log_and_exit("Exception running GEOSLineMerge");
318 ptr
= GEOSGeomToWKT(g3
);
319 printf("LineMerge: %s\n", ptr
);
321 GEOSGeom_destroy(g3
);
323 /* Binary predicates */
324 if ( GEOSIntersects(g1
, g2
) ) printf("Intersect\n");
325 if ( GEOSDisjoint(g1
, g2
) ) printf("Disjoint\n");
326 if ( GEOSTouches(g1
, g2
) ) printf("Touches\n");
327 if ( GEOSCrosses(g1
, g2
) ) printf("Crosses\n");
328 if ( GEOSWithin(g1
, g2
) ) printf("Within\n");
329 if ( GEOSContains(g1
, g2
) ) printf("Contains\n");
330 if ( GEOSOverlaps(g1
, g2
) ) printf("Overlaps\n");
333 if ( GEOSDistance(g1
, g2
, &dist
) ) printf("Distance: %g\n", dist
);
336 if ( GEOSArea(g1
, &area
) ) printf("Area 1: %g\n", area
);
337 if ( GEOSArea(g2
, &area
) ) printf("Area 2: %g\n", area
);
339 GEOSGeom_destroy(g2
);
342 g3
= GEOSSimplify(g1
, 0.5);
343 ptr
= GEOSGeomToWKT(g3
);
344 printf("Simplify: %s\n", ptr
);
346 GEOSGeom_destroy(g3
);
348 /* Topology Preserve Simplify */
349 g3
= GEOSTopologyPreserveSimplify(g1
, 0.5);
350 ptr
= GEOSGeomToWKT(g3
);
351 printf("Simplify: %s\n", ptr
);
353 GEOSGeom_destroy(g3
);
355 GEOSGeom_destroy(g1
);
361 main(int argc
, char **argv
)
365 initGEOS(notice
, log_and_exit
);
366 printf("GEOS version %s\n", GEOSversion());
368 if ( argc
< 2 ) usage(argv
[0]);
369 if ( argc
> 2 ) n
=atoi(argv
[2]);
372 for (i
=0; i
<n
; i
++) {
373 putc('.', stderr
); fflush(stderr
);
375 putc('+', stderr
); fflush(stderr
);