typeName, typeId
[geos.git] / php / geos.c
blob55ae5981ad98fa9e35adc2045163418fe697b013
1 /***********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://trac.osgeo.org/geos
6 * Copyright (C) 2010 Sandro Santilli <strk@keybit.net>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301 USA
23 ***********************************************************************/
25 /* PHP stuff */
26 #include "php.h"
27 #include "ext/standard/info.h" /* for php_info_... */
28 #include "Zend/zend_exceptions.h" /* for zend_throw_exception_object */
30 /* GEOS stuff */
31 #include "geos_c.h"
33 /* Own stuff */
34 #include "php_geos.h"
36 PHP_MINIT_FUNCTION(geos);
37 PHP_RINIT_FUNCTION(geos);
38 PHP_RSHUTDOWN_FUNCTION(geos);
39 PHP_MINFO_FUNCTION(geos);
40 PHP_FUNCTION(GEOSVersion);
41 PHP_FUNCTION(GEOSPolygonize);
42 PHP_FUNCTION(GEOSLineMerge);
44 static function_entry geos_functions[] = {
45 PHP_FE(GEOSVersion, NULL)
46 PHP_FE(GEOSPolygonize, NULL)
47 PHP_FE(GEOSLineMerge, NULL)
48 {NULL, NULL, NULL}
51 zend_module_entry geos_module_entry = {
52 STANDARD_MODULE_HEADER,
53 PHP_GEOS_EXTNAME,
54 geos_functions,
55 PHP_MINIT(geos), /* module init function */
56 NULL, /* module shutdown function */
57 PHP_RINIT(geos), /* request init function */
58 PHP_RSHUTDOWN(geos), /* request shutdown function */
59 PHP_MINFO(geos), /* module info function */
60 PHP_GEOS_VERSION,
61 STANDARD_MODULE_PROPERTIES
64 #ifdef COMPILE_DL_GEOS
65 ZEND_GET_MODULE(geos)
66 #endif
68 /* -- Utility functions ---------------------- */
70 static void noticeHandler(const char *fmt, ...)
72 char message[256];
73 va_list args;
74 va_start(args, fmt);
75 vsnprintf(message, sizeof(message) - 1, fmt, args);
76 va_end(args);
78 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s", message);
81 static void errorHandler(const char *fmt, ...)
83 char message[256];
84 va_list args;
85 va_start(args, fmt);
86 vsnprintf(message, sizeof(message) - 1, fmt, args);
87 va_end(args);
89 /* TODO: use a GEOSException ? */
90 zend_throw_exception_ex(zend_exception_get_default(TSRMLS_CC),
91 1 TSRMLS_CC, "%s", message);
95 typedef struct Proxy_t {
96 zend_object std;
97 void* relay;
98 } Proxy;
100 static void
101 setRelay(zval* val, void* obj) {
102 Proxy* proxy = (Proxy*)zend_object_store_get_object(val TSRMLS_CC);
103 proxy->relay = obj;
106 static inline void *
107 getRelay(zval* val, zend_class_entry* ce) {
108 Proxy *proxy = (Proxy*)zend_object_store_get_object(val TSRMLS_CC);
109 if ( proxy->std.ce != ce ) {
110 php_error_docref(NULL TSRMLS_CC, E_ERROR,
111 "Relay object is not an %s", ce->name);
113 if ( ! proxy->relay ) {
114 php_error_docref(NULL TSRMLS_CC, E_ERROR,
115 "Relay object for object of type %s is not set", ce->name);
117 return proxy->relay;
120 static long getZvalAsLong(zval* val)
122 long ret;
123 zval tmp;
125 tmp = *val;
126 zval_copy_ctor(&tmp);
127 convert_to_long(&tmp);
128 ret = Z_LVAL(tmp);
129 zval_dtor(&tmp);
130 return ret;
133 static long getZvalAsDouble(zval* val)
135 double ret;
136 zval tmp;
138 tmp = *val;
139 zval_copy_ctor(&tmp);
140 convert_to_double(&tmp);
141 ret = Z_DVAL(tmp);
142 zval_dtor(&tmp);
143 return ret;
146 static zend_object_value
147 Gen_create_obj (zend_class_entry *type TSRMLS_DC,
148 zend_objects_free_object_storage_t st, zend_object_handlers* handlers)
150 zval *tmp;
151 zend_object_value retval;
153 Proxy *obj = (Proxy *)emalloc(sizeof(Proxy));
154 memset(obj, 0, sizeof(Proxy));
155 obj->std.ce = type;
157 ALLOC_HASHTABLE(obj->std.properties);
158 zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
159 zend_hash_copy(obj->std.properties, &type->default_properties,
160 (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
162 retval.handle = zend_objects_store_put(obj, NULL, st, NULL TSRMLS_CC);
163 retval.handlers = handlers;
165 return retval;
169 /* -- class GEOSGeometry -------------------- */
171 PHP_METHOD(Geometry, __construct);
172 PHP_METHOD(Geometry, __toString);
173 PHP_METHOD(Geometry, project);
174 PHP_METHOD(Geometry, interpolate);
175 PHP_METHOD(Geometry, buffer);
176 PHP_METHOD(Geometry, envelope);
177 PHP_METHOD(Geometry, intersection);
178 PHP_METHOD(Geometry, convexHull);
179 PHP_METHOD(Geometry, difference);
180 PHP_METHOD(Geometry, symDifference);
181 PHP_METHOD(Geometry, boundary);
182 PHP_METHOD(Geometry, union); /* also does union cascaded */
183 PHP_METHOD(Geometry, pointOnSurface);
184 PHP_METHOD(Geometry, centroid);
185 PHP_METHOD(Geometry, relate);
186 PHP_METHOD(Geometry, simplify); /* also does topology-preserving */
187 PHP_METHOD(Geometry, extractUniquePoints);
188 PHP_METHOD(Geometry, disjoint);
189 PHP_METHOD(Geometry, touches);
190 PHP_METHOD(Geometry, intersects);
191 PHP_METHOD(Geometry, crosses);
192 PHP_METHOD(Geometry, within);
193 PHP_METHOD(Geometry, contains);
194 PHP_METHOD(Geometry, overlaps);
195 PHP_METHOD(Geometry, equals);
196 PHP_METHOD(Geometry, equalsExact);
197 PHP_METHOD(Geometry, isEmpty);
198 PHP_METHOD(Geometry, checkValidity);
199 PHP_METHOD(Geometry, isSimple);
200 PHP_METHOD(Geometry, isRing);
201 PHP_METHOD(Geometry, hasZ);
202 PHP_METHOD(Geometry, isClosed);
203 PHP_METHOD(Geometry, typeName);
204 PHP_METHOD(Geometry, typeId);
206 PHP_METHOD(Geometry, numGeometries);
208 static function_entry Geometry_methods[] = {
209 PHP_ME(Geometry, __construct, NULL, 0)
210 PHP_ME(Geometry, __toString, NULL, 0)
211 PHP_ME(Geometry, project, NULL, 0)
212 PHP_ME(Geometry, interpolate, NULL, 0)
213 PHP_ME(Geometry, buffer, NULL, 0)
214 PHP_ME(Geometry, envelope, NULL, 0)
215 PHP_ME(Geometry, intersection, NULL, 0)
216 PHP_ME(Geometry, convexHull, NULL, 0)
217 PHP_ME(Geometry, difference, NULL, 0)
218 PHP_ME(Geometry, symDifference, NULL, 0)
219 PHP_ME(Geometry, boundary, NULL, 0)
220 PHP_ME(Geometry, union, NULL, 0)
221 PHP_ME(Geometry, pointOnSurface, NULL, 0)
222 PHP_ME(Geometry, centroid, NULL, 0)
223 PHP_ME(Geometry, relate, NULL, 0)
224 PHP_ME(Geometry, simplify, NULL, 0)
225 PHP_ME(Geometry, extractUniquePoints, NULL, 0)
226 PHP_ME(Geometry, disjoint, NULL, 0)
227 PHP_ME(Geometry, touches, NULL, 0)
228 PHP_ME(Geometry, intersects, NULL, 0)
229 PHP_ME(Geometry, crosses, NULL, 0)
230 PHP_ME(Geometry, within, NULL, 0)
231 PHP_ME(Geometry, contains, NULL, 0)
232 PHP_ME(Geometry, overlaps, NULL, 0)
233 PHP_ME(Geometry, equals, NULL, 0)
234 PHP_ME(Geometry, equalsExact, NULL, 0)
235 PHP_ME(Geometry, isEmpty, NULL, 0)
236 PHP_ME(Geometry, checkValidity, NULL, 0)
237 PHP_ME(Geometry, isSimple, NULL, 0)
238 PHP_ME(Geometry, isRing, NULL, 0)
239 PHP_ME(Geometry, hasZ, NULL, 0)
240 PHP_ME(Geometry, isClosed, NULL, 0)
241 PHP_ME(Geometry, typeName, NULL, 0)
242 PHP_ME(Geometry, typeId, NULL, 0)
244 PHP_ME(Geometry, numGeometries, NULL, 0)
245 {NULL, NULL, NULL}
248 static zend_class_entry *Geometry_ce_ptr;
250 static zend_object_handlers Geometry_object_handlers;
253 * Push components of the given geometry
254 * to the given array zval.
255 * Components geometries are cloned.
256 * NOTE: collection components are not descended into
258 static void
259 dumpGeometry(GEOSGeometry* g, zval* array)
261 int ngeoms, i;
264 MAKE_STD_ZVAL(array);
265 array_init(array);
268 ngeoms = GEOSGetNumGeometries(g);
269 for (i=0; i<ngeoms; ++i)
271 zval *tmp;
272 GEOSGeometry* cc;
273 const GEOSGeometry* c = GEOSGetGeometryN(g, i);
274 if ( ! c ) continue; /* should get an exception */
275 /* we _need_ to clone as this one is owned by 'g' */
276 cc = GEOSGeom_clone(c);
277 if ( ! cc ) continue; /* should get an exception */
279 MAKE_STD_ZVAL(tmp);
280 object_init_ex(tmp, Geometry_ce_ptr);
281 setRelay(tmp, cc);
282 add_next_index_zval(array, tmp);
287 static void
288 Geometry_dtor (void *object TSRMLS_DC)
290 Proxy *obj = (Proxy *)object;
291 GEOSGeom_destroy((GEOSGeometry*)obj->relay);
293 zend_hash_destroy(obj->std.properties);
294 FREE_HASHTABLE(obj->std.properties);
296 efree(obj);
299 static zend_object_value
300 Geometry_create_obj (zend_class_entry *type TSRMLS_DC)
302 return Gen_create_obj(type, Geometry_dtor, &Geometry_object_handlers);
306 PHP_METHOD(Geometry, __construct)
308 php_error_docref(NULL TSRMLS_CC, E_ERROR,
309 "GEOSGeometry can't be constructed using new, check WKTReader");
313 PHP_METHOD(Geometry, __toString)
315 GEOSGeometry *geom;
316 GEOSWKTWriter *writer;
317 char *wkt;
318 char *ret;
320 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
321 writer = GEOSWKTWriter_create();
322 /* NOTE: if we get an exception before reaching
323 * GEOSWKTWriter_destory below we'll be leaking memory.
324 * One fix could be storing the object in a refcounted
325 * zval.
327 GEOSWKTWriter_setTrim(writer, 1);
329 wkt = GEOSWKTWriter_write(writer, geom);
330 /* we'll probably get an exception if wkt is null */
331 if ( ! wkt ) RETURN_NULL();
333 GEOSWKTWriter_destroy(writer);
336 ret = estrdup(wkt);
337 GEOSFree(wkt);
339 RETURN_STRING(ret, 0);
342 PHP_METHOD(Geometry, numGeometries)
344 GEOSGeometry *geom;
345 long int ret;
347 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
349 ret = GEOSGetNumGeometries(geom);
350 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
352 RETURN_LONG(ret);
355 PHP_METHOD(Geometry, project)
357 GEOSGeometry *this;
358 GEOSGeometry *other;
359 zval *zobj;
360 zend_bool normalized = 0;
361 double ret;
363 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
365 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|b", &zobj,
366 &normalized) == FAILURE) {
367 RETURN_NULL();
369 other = getRelay(zobj, Geometry_ce_ptr);
371 if ( normalized ) {
372 ret = GEOSProjectNormalized(this, other);
373 } else {
374 ret = GEOSProject(this, other);
376 if ( ret < 0 ) RETURN_NULL(); /* should get an exception first */
378 RETURN_DOUBLE(ret);
381 PHP_METHOD(Geometry, interpolate)
383 GEOSGeometry *this;
384 double dist;
385 GEOSGeometry *ret;
386 zend_bool normalized = 0;
388 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
390 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|b",
391 &dist, &normalized) == FAILURE) {
392 RETURN_NULL();
395 if ( normalized ) {
396 ret = GEOSInterpolateNormalized(this, dist);
397 } else {
398 ret = GEOSInterpolate(this, dist);
400 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
402 /* return_value is a zval */
403 object_init_ex(return_value, Geometry_ce_ptr);
404 setRelay(return_value, ret);
408 * GEOSGeometry::buffer(dist, [<styleArray>])
410 * styleArray keys supported:
411 * 'quad_segs'
412 * Type: int
413 * Number of segments used to approximate
414 * a quarter circle (defaults to 8).
415 * 'endcap'
416 * Type: long
417 * Endcap style (defaults to GEOSBUF_CAP_ROUND)
418 * 'join'
419 * Type: long
420 * Join style (defaults to GEOSBUF_JOIN_ROUND)
421 * 'mitre_limit'
422 * Type: double
423 * mitre ratio limit (only affects joins with GEOSBUF_JOIN_MITRE style)
424 * 'miter_limit' is also accepted as a synonym for 'mitre_limit'.
426 PHP_METHOD(Geometry, buffer)
428 GEOSGeometry *this;
429 double dist;
430 GEOSGeometry *ret;
431 static const double default_mitreLimit = 5.0;
432 static const int default_endCapStyle = GEOSBUF_CAP_ROUND;
433 static const int default_joinStyle = GEOSBUF_JOIN_ROUND;
434 static const int default_quadSegs = 8;
435 long int quadSegs = default_quadSegs;
436 long int endCapStyle = default_endCapStyle;
437 long int joinStyle = default_joinStyle;
438 double mitreLimit = default_mitreLimit;
439 zval *style_val = NULL;
440 zval **data;
441 HashTable *style;
442 char *key;
443 ulong index;
445 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
447 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|a",
448 &dist, &style_val) == FAILURE) {
449 RETURN_NULL();
452 if ( style_val )
454 style = HASH_OF(style_val);
455 while(zend_hash_get_current_key(style, &key, &index, 0)
456 == HASH_KEY_IS_STRING)
458 if(!strcmp(key, "quad_segs"))
460 zend_hash_get_current_data(style, (void**)&data);
461 quadSegs = getZvalAsLong(*data);
463 else if(!strcmp(key, "endcap"))
465 zend_hash_get_current_data(style, (void**)&data);
466 endCapStyle = getZvalAsLong(*data);
468 else if(!strcmp(key, "join"))
470 zend_hash_get_current_data(style, (void**)&data);
471 joinStyle = getZvalAsLong(*data);
473 else if(!strcmp(key, "mitre_limit"))
475 zend_hash_get_current_data(style, (void**)&data);
476 mitreLimit = getZvalAsDouble(*data);
479 zend_hash_move_forward(style);
483 ret = GEOSBufferWithStyle(this, dist,
484 quadSegs, endCapStyle, joinStyle, mitreLimit);
485 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
487 /* return_value is a zval */
488 object_init_ex(return_value, Geometry_ce_ptr);
489 setRelay(return_value, ret);
492 PHP_METHOD(Geometry, envelope)
494 GEOSGeometry *this;
495 GEOSGeometry *ret;
497 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
499 ret = GEOSEnvelope(this);
500 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
502 /* return_value is a zval */
503 object_init_ex(return_value, Geometry_ce_ptr);
504 setRelay(return_value, ret);
507 PHP_METHOD(Geometry, intersection)
509 GEOSGeometry *this;
510 GEOSGeometry *other;
511 GEOSGeometry *ret;
512 zval *zobj;
514 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
516 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
517 == FAILURE) {
518 RETURN_NULL();
520 other = getRelay(zobj, Geometry_ce_ptr);
522 ret = GEOSIntersection(this, other);
523 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
525 /* return_value is a zval */
526 object_init_ex(return_value, Geometry_ce_ptr);
527 setRelay(return_value, ret);
530 PHP_METHOD(Geometry, convexHull)
532 GEOSGeometry *this;
533 GEOSGeometry *ret;
535 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
537 ret = GEOSConvexHull(this);
538 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
540 /* return_value is a zval */
541 object_init_ex(return_value, Geometry_ce_ptr);
542 setRelay(return_value, ret);
545 PHP_METHOD(Geometry, difference)
547 GEOSGeometry *this;
548 GEOSGeometry *other;
549 GEOSGeometry *ret;
550 zval *zobj;
552 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
554 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
555 == FAILURE) {
556 RETURN_NULL();
558 other = getRelay(zobj, Geometry_ce_ptr);
560 ret = GEOSDifference(this, other);
561 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
563 /* return_value is a zval */
564 object_init_ex(return_value, Geometry_ce_ptr);
565 setRelay(return_value, ret);
568 PHP_METHOD(Geometry, symDifference)
570 GEOSGeometry *this;
571 GEOSGeometry *other;
572 GEOSGeometry *ret;
573 zval *zobj;
575 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
577 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
578 == FAILURE) {
579 RETURN_NULL();
581 other = getRelay(zobj, Geometry_ce_ptr);
583 ret = GEOSSymDifference(this, other);
584 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
586 /* return_value is a zval */
587 object_init_ex(return_value, Geometry_ce_ptr);
588 setRelay(return_value, ret);
591 PHP_METHOD(Geometry, boundary)
593 GEOSGeometry *this;
594 GEOSGeometry *ret;
596 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
598 ret = GEOSBoundary(this);
599 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
601 /* return_value is a zval */
602 object_init_ex(return_value, Geometry_ce_ptr);
603 setRelay(return_value, ret);
607 * GEOSGeometry::union(otherGeom)
608 * GEOSGeometry::union()
610 PHP_METHOD(Geometry, union)
612 GEOSGeometry *this;
613 GEOSGeometry *other;
614 GEOSGeometry *ret;
615 zval *zobj = NULL;
617 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
619 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o", &zobj)
620 == FAILURE) {
621 RETURN_NULL();
624 if ( zobj ) {
625 other = getRelay(zobj, Geometry_ce_ptr);
626 ret = GEOSUnion(this, other);
627 } else {
628 ret = GEOSUnionCascaded(this);
631 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
633 /* return_value is a zval */
634 object_init_ex(return_value, Geometry_ce_ptr);
635 setRelay(return_value, ret);
639 * GEOSGeometry::pointOnSurface()
641 PHP_METHOD(Geometry, pointOnSurface)
643 GEOSGeometry *this;
644 GEOSGeometry *ret;
646 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
648 ret = GEOSPointOnSurface(this);
649 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
651 /* return_value is a zval */
652 object_init_ex(return_value, Geometry_ce_ptr);
653 setRelay(return_value, ret);
657 * GEOSGeometry::centroid()
659 PHP_METHOD(Geometry, centroid)
661 GEOSGeometry *this;
662 GEOSGeometry *ret;
664 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
666 ret = GEOSGetCentroid(this);
667 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
669 /* return_value is a zval */
670 object_init_ex(return_value, Geometry_ce_ptr);
671 setRelay(return_value, ret);
675 * GEOSGeometry::relate(otherGeom)
676 * GEOSGeometry::relate(otherGeom, pattern)
678 PHP_METHOD(Geometry, relate)
680 GEOSGeometry *this;
681 GEOSGeometry *other;
682 zval *zobj;
683 char* pat = NULL;
684 int patlen;
685 int retInt;
686 zend_bool retBool;
687 char* retStr;
689 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
691 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|s",
692 &zobj, &pat, &patlen) == FAILURE)
694 RETURN_NULL();
697 other = getRelay(zobj, Geometry_ce_ptr);
699 if ( ! pat ) {
700 /* we'll compute it */
701 pat = GEOSRelate(this, other);
702 if ( ! pat ) RETURN_NULL(); /* should get an exception first */
703 retStr = estrdup(pat);
704 GEOSFree(pat);
705 RETURN_STRING(retStr, 0);
706 } else {
707 retInt = GEOSRelatePattern(this, other, pat);
708 if ( retInt == 2 ) RETURN_NULL(); /* should get an exception first */
709 retBool = retInt;
710 RETURN_BOOL(retBool);
715 /* -- class GEOSWKTReader -------------------- */
717 PHP_METHOD(WKTReader, __construct);
718 PHP_METHOD(WKTReader, read);
720 static function_entry WKTReader_methods[] = {
721 PHP_ME(WKTReader, __construct, NULL, 0)
722 PHP_ME(WKTReader, read, NULL, 0)
723 {NULL, NULL, NULL}
726 static zend_class_entry *WKTReader_ce_ptr;
728 static zend_object_handlers WKTReader_object_handlers;
730 static void
731 WKTReader_dtor (void *object TSRMLS_DC)
733 Proxy *obj = (Proxy *)object;
734 GEOSWKTReader_destroy((GEOSWKTReader*)obj->relay);
736 zend_hash_destroy(obj->std.properties);
737 FREE_HASHTABLE(obj->std.properties);
739 efree(obj);
742 static zend_object_value
743 WKTReader_create_obj (zend_class_entry *type TSRMLS_DC)
745 return Gen_create_obj(type, WKTReader_dtor, &WKTReader_object_handlers);
749 PHP_METHOD(WKTReader, __construct)
751 GEOSWKTReader* obj;
752 zval *object = getThis();
754 obj = GEOSWKTReader_create();
755 if ( ! obj ) {
756 php_error_docref(NULL TSRMLS_CC, E_ERROR,
757 "GEOSWKTReader_create() failed (didn't initGEOS?)");
760 setRelay(object, obj);
763 PHP_METHOD(WKTReader, read)
765 GEOSWKTReader *reader;
766 GEOSGeometry *geom;
767 char* wkt;
768 int wktlen;
770 reader = (GEOSWKTReader*)getRelay(getThis(), WKTReader_ce_ptr);
772 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
773 &wkt, &wktlen) == FAILURE)
775 RETURN_NULL();
778 geom = GEOSWKTReader_read(reader, wkt);
779 /* we'll probably get an exception if geom is null */
780 if ( ! geom ) RETURN_NULL();
782 /* return_value is a zval */
783 object_init_ex(return_value, Geometry_ce_ptr);
784 setRelay(return_value, geom);
788 /* -- class GEOSWKTWriter -------------------- */
790 PHP_METHOD(WKTWriter, __construct);
791 PHP_METHOD(WKTWriter, write);
792 PHP_METHOD(WKTWriter, setTrim);
793 PHP_METHOD(WKTWriter, setRoundingPrecision);
794 PHP_METHOD(WKTWriter, setOutputDimension);
795 PHP_METHOD(WKTWriter, setOld3D);
797 static function_entry WKTWriter_methods[] = {
798 PHP_ME(WKTWriter, __construct, NULL, 0)
799 PHP_ME(WKTWriter, write, NULL, 0)
800 PHP_ME(WKTWriter, setTrim, NULL, 0)
801 PHP_ME(WKTWriter, setRoundingPrecision, NULL, 0)
802 PHP_ME(WKTWriter, setOutputDimension, NULL, 0)
803 PHP_ME(WKTWriter, setOld3D, NULL, 0)
804 {NULL, NULL, NULL}
807 static zend_class_entry *WKTWriter_ce_ptr;
809 static zend_object_handlers WKTWriter_object_handlers;
811 static void
812 WKTWriter_dtor (void *object TSRMLS_DC)
814 Proxy *obj = (Proxy *)object;
815 GEOSWKTWriter_destroy((GEOSWKTWriter*)obj->relay);
817 zend_hash_destroy(obj->std.properties);
818 FREE_HASHTABLE(obj->std.properties);
820 efree(obj);
823 static zend_object_value
824 WKTWriter_create_obj (zend_class_entry *type TSRMLS_DC)
826 return Gen_create_obj(type, WKTWriter_dtor, &WKTWriter_object_handlers);
829 PHP_METHOD(WKTWriter, __construct)
831 GEOSWKTWriter* obj;
832 zval *object = getThis();
834 obj = GEOSWKTWriter_create();
835 if ( ! obj ) {
836 php_error_docref(NULL TSRMLS_CC, E_ERROR,
837 "GEOSWKTWriter_create() failed (didn't initGEOS?)");
840 setRelay(object, obj);
843 PHP_METHOD(WKTWriter, write)
845 GEOSWKTWriter *writer;
846 zval *zobj;
847 GEOSGeometry *geom;
848 char* wkt;
849 char* retstr;
851 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
853 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
854 == FAILURE)
856 RETURN_NULL();
859 geom = getRelay(zobj, Geometry_ce_ptr);
861 wkt = GEOSWKTWriter_write(writer, geom);
862 /* we'll probably get an exception if wkt is null */
863 if ( ! wkt ) RETURN_NULL();
865 retstr = estrdup(wkt);
866 GEOSFree(wkt);
868 RETURN_STRING(retstr, 0);
870 /* return_value is a zval */
871 object_init_ex(return_value, Geometry_ce_ptr);
872 setRelay(return_value, geom);
876 PHP_METHOD(WKTWriter, setTrim)
878 GEOSWKTWriter *writer;
879 zend_bool trimval;
880 char trim;
882 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
884 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &trimval)
885 == FAILURE)
887 RETURN_NULL();
890 trim = trimval;
891 GEOSWKTWriter_setTrim(writer, trim);
894 PHP_METHOD(WKTWriter, setRoundingPrecision)
896 GEOSWKTWriter *writer;
897 long int prec;
899 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
901 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &prec)
902 == FAILURE)
904 RETURN_NULL();
907 GEOSWKTWriter_setRoundingPrecision(writer, prec);
910 PHP_METHOD(WKTWriter, setOutputDimension)
912 GEOSWKTWriter *writer;
913 long int dim;
915 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
917 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
918 == FAILURE)
920 RETURN_NULL();
923 GEOSWKTWriter_setOutputDimension(writer, dim);
926 PHP_METHOD(WKTWriter, setOld3D)
928 GEOSWKTWriter *writer;
929 zend_bool bval;
930 int val;
932 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
934 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &bval)
935 == FAILURE)
937 RETURN_NULL();
940 val = bval;
941 GEOSWKTWriter_setOld3D(writer, val);
944 /* -- Free functions ------------------------- */
947 * string GEOSVersion()
949 PHP_FUNCTION(GEOSVersion)
951 char *str;
953 str = estrdup(GEOSversion());
954 RETURN_STRING(str, 0);
958 * array GEOSPolygonize(GEOSGeometry $geom)
960 * The returned array contains the following elements:
962 * - 'rings'
963 * Type: array of GEOSGeometry
964 * Rings that can be formed by the costituent
965 * linework of geometry.
966 * - 'cut_edges' (optional)
967 * Type: array of GEOSGeometry
968 * Edges which are connected at both ends but
969 * which do not form part of polygon.
970 * - 'dangles'
971 * Type: array of GEOSGeometry
972 * Edges which have one or both ends which are
973 * not incident on another edge endpoint
974 * - 'invalid_rings'
975 * Type: array of GEOSGeometry
976 * Edges which form rings which are invalid
977 * (e.g. the component lines contain a self-intersection)
980 PHP_FUNCTION(GEOSPolygonize)
982 GEOSGeometry *this;
983 GEOSGeometry *rings;
984 GEOSGeometry *cut_edges;
985 GEOSGeometry *dangles;
986 GEOSGeometry *invalid_rings;
987 zval *array_elem;
988 zval *zobj;
990 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
991 == FAILURE)
993 RETURN_NULL();
995 this = getRelay(zobj, Geometry_ce_ptr);
997 rings = GEOSPolygonize_full(this, &cut_edges, &dangles, &invalid_rings);
998 if ( ! rings ) RETURN_NULL(); /* should get an exception first */
1000 /* return value should be an array */
1001 array_init(return_value);
1003 MAKE_STD_ZVAL(array_elem);
1004 array_init(array_elem);
1005 dumpGeometry(rings, array_elem);
1006 GEOSGeom_destroy(rings);
1007 add_assoc_zval(return_value, "rings", array_elem);
1009 MAKE_STD_ZVAL(array_elem);
1010 array_init(array_elem);
1011 dumpGeometry(cut_edges, array_elem);
1012 GEOSGeom_destroy(cut_edges);
1013 add_assoc_zval(return_value, "cut_edges", array_elem);
1015 MAKE_STD_ZVAL(array_elem);
1016 array_init(array_elem);
1017 dumpGeometry(dangles, array_elem);
1018 GEOSGeom_destroy(dangles);
1019 add_assoc_zval(return_value, "dangles", array_elem);
1021 MAKE_STD_ZVAL(array_elem);
1022 array_init(array_elem);
1023 dumpGeometry(invalid_rings, array_elem);
1024 GEOSGeom_destroy(invalid_rings);
1025 add_assoc_zval(return_value, "invalid_rings", array_elem);
1030 * array GEOSLineMerge(GEOSGeometry $geom)
1032 PHP_FUNCTION(GEOSLineMerge)
1034 GEOSGeometry *geom_in;
1035 GEOSGeometry *geom_out;
1036 zval *zobj;
1038 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1039 == FAILURE)
1041 RETURN_NULL();
1043 geom_in = getRelay(zobj, Geometry_ce_ptr);
1045 geom_out = GEOSLineMerge(geom_in);
1046 if ( ! geom_out ) RETURN_NULL(); /* should get an exception first */
1048 /* return value should be an array */
1049 array_init(return_value);
1050 dumpGeometry(geom_out, return_value);
1051 GEOSGeom_destroy(geom_out);
1055 * GEOSGeometry GEOSGeometry::simplify(tolerance)
1056 * GEOSGeometry GEOSGeometry::simplify(tolerance, preserveTopology)
1058 PHP_METHOD(Geometry, simplify)
1060 GEOSGeometry *this;
1061 double tolerance;
1062 zend_bool preserveTopology = 0;
1063 GEOSGeometry *ret;
1065 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1067 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|b",
1068 &tolerance, &preserveTopology) == FAILURE) {
1069 RETURN_NULL();
1072 if ( preserveTopology ) {
1073 ret = GEOSTopologyPreserveSimplify(this, tolerance);
1074 } else {
1075 ret = GEOSSimplify(this, tolerance);
1078 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1080 /* return_value is a zval */
1081 object_init_ex(return_value, Geometry_ce_ptr);
1082 setRelay(return_value, ret);
1086 * GEOSGeometry GEOSGeometry::extractUniquePoints()
1088 PHP_METHOD(Geometry, extractUniquePoints)
1090 GEOSGeometry *this;
1091 GEOSGeometry *ret;
1093 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1095 ret = GEOSGeom_extractUniquePoints(this);
1096 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
1098 /* return_value is a zval */
1099 object_init_ex(return_value, Geometry_ce_ptr);
1100 setRelay(return_value, ret);
1104 * bool GEOSGeometry::disjoint(GEOSGeometry)
1106 PHP_METHOD(Geometry, disjoint)
1108 GEOSGeometry *this;
1109 GEOSGeometry *other;
1110 int ret;
1111 zend_bool retBool;
1112 zval *zobj;
1114 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1116 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1117 == FAILURE) {
1118 RETURN_NULL();
1120 other = getRelay(zobj, Geometry_ce_ptr);
1122 ret = GEOSDisjoint(this, other);
1123 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1125 /* return_value is a zval */
1126 retBool = ret;
1127 RETURN_BOOL(retBool);
1131 * bool GEOSGeometry::touches(GEOSGeometry)
1133 PHP_METHOD(Geometry, touches)
1135 GEOSGeometry *this;
1136 GEOSGeometry *other;
1137 int ret;
1138 zend_bool retBool;
1139 zval *zobj;
1141 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1143 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1144 == FAILURE) {
1145 RETURN_NULL();
1147 other = getRelay(zobj, Geometry_ce_ptr);
1149 ret = GEOSTouches(this, other);
1150 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1152 /* return_value is a zval */
1153 retBool = ret;
1154 RETURN_BOOL(retBool);
1158 * bool GEOSGeometry::intersects(GEOSGeometry)
1160 PHP_METHOD(Geometry, intersects)
1162 GEOSGeometry *this;
1163 GEOSGeometry *other;
1164 int ret;
1165 zend_bool retBool;
1166 zval *zobj;
1168 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1170 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1171 == FAILURE) {
1172 RETURN_NULL();
1174 other = getRelay(zobj, Geometry_ce_ptr);
1176 ret = GEOSIntersects(this, other);
1177 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1179 /* return_value is a zval */
1180 retBool = ret;
1181 RETURN_BOOL(retBool);
1185 * bool GEOSGeometry::crosses(GEOSGeometry)
1187 PHP_METHOD(Geometry, crosses)
1189 GEOSGeometry *this;
1190 GEOSGeometry *other;
1191 int ret;
1192 zend_bool retBool;
1193 zval *zobj;
1195 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1197 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1198 == FAILURE) {
1199 RETURN_NULL();
1201 other = getRelay(zobj, Geometry_ce_ptr);
1203 ret = GEOSCrosses(this, other);
1204 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1206 /* return_value is a zval */
1207 retBool = ret;
1208 RETURN_BOOL(retBool);
1212 * bool GEOSGeometry::within(GEOSGeometry)
1214 PHP_METHOD(Geometry, within)
1216 GEOSGeometry *this;
1217 GEOSGeometry *other;
1218 int ret;
1219 zend_bool retBool;
1220 zval *zobj;
1222 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1224 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1225 == FAILURE) {
1226 RETURN_NULL();
1228 other = getRelay(zobj, Geometry_ce_ptr);
1230 ret = GEOSWithin(this, other);
1231 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1233 /* return_value is a zval */
1234 retBool = ret;
1235 RETURN_BOOL(retBool);
1239 * bool GEOSGeometry::contains(GEOSGeometry)
1241 PHP_METHOD(Geometry, contains)
1243 GEOSGeometry *this;
1244 GEOSGeometry *other;
1245 int ret;
1246 zend_bool retBool;
1247 zval *zobj;
1249 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1251 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1252 == FAILURE) {
1253 RETURN_NULL();
1255 other = getRelay(zobj, Geometry_ce_ptr);
1257 ret = GEOSContains(this, other);
1258 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1260 /* return_value is a zval */
1261 retBool = ret;
1262 RETURN_BOOL(retBool);
1266 * bool GEOSGeometry::overlaps(GEOSGeometry)
1268 PHP_METHOD(Geometry, overlaps)
1270 GEOSGeometry *this;
1271 GEOSGeometry *other;
1272 int ret;
1273 zend_bool retBool;
1274 zval *zobj;
1276 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1278 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1279 == FAILURE) {
1280 RETURN_NULL();
1282 other = getRelay(zobj, Geometry_ce_ptr);
1284 ret = GEOSOverlaps(this, other);
1285 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1287 /* return_value is a zval */
1288 retBool = ret;
1289 RETURN_BOOL(retBool);
1293 * bool GEOSGeometry::equals(GEOSGeometry)
1295 PHP_METHOD(Geometry, equals)
1297 GEOSGeometry *this;
1298 GEOSGeometry *other;
1299 int ret;
1300 zend_bool retBool;
1301 zval *zobj;
1303 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1305 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
1306 &zobj) == FAILURE) {
1307 RETURN_NULL();
1309 other = getRelay(zobj, Geometry_ce_ptr);
1311 ret = GEOSEquals(this, other);
1312 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1314 /* return_value is a zval */
1315 retBool = ret;
1316 RETURN_BOOL(retBool);
1320 * bool GEOSGeometry::equalsExact(GEOSGeometry)
1321 * bool GEOSGeometry::equalsExact(GEOSGeometry, double tolerance)
1323 PHP_METHOD(Geometry, equalsExact)
1325 GEOSGeometry *this;
1326 GEOSGeometry *other;
1327 int ret;
1328 double tolerance = 0;
1329 zend_bool retBool;
1330 zval *zobj;
1332 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1334 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|d",
1335 &zobj, &tolerance) == FAILURE) {
1336 RETURN_NULL();
1338 other = getRelay(zobj, Geometry_ce_ptr);
1340 ret = GEOSEqualsExact(this, other, tolerance);
1341 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1343 /* return_value is a zval */
1344 retBool = ret;
1345 RETURN_BOOL(retBool);
1349 * bool GEOSGeometry::isEmpty()
1351 PHP_METHOD(Geometry, isEmpty)
1353 GEOSGeometry *this;
1354 int ret;
1355 zend_bool retBool;
1357 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1359 ret = GEOSisEmpty(this);
1360 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1362 /* return_value is a zval */
1363 retBool = ret;
1364 RETURN_BOOL(retBool);
1368 * array GEOSGeometry::checkValidity()
1370 PHP_METHOD(Geometry, checkValidity)
1372 GEOSGeometry *this;
1373 GEOSGeometry *location = NULL;
1374 int ret;
1375 char *reason = NULL;
1376 zend_bool retBool;
1377 char *reasonVal = NULL;
1378 zval *locationVal = NULL;
1380 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1382 ret = GEOSisValidDetail(this, &reason, (const GEOSGeometry**)&location);
1383 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1385 if ( reason ) {
1386 reasonVal = estrdup(reason);
1387 GEOSFree(reason);
1390 if ( location ) {
1391 MAKE_STD_ZVAL(locationVal);
1392 object_init_ex(locationVal, Geometry_ce_ptr);
1393 setRelay(locationVal, location);
1396 retBool = ret;
1398 /* return value is an array */
1399 array_init(return_value);
1400 add_assoc_bool(return_value, "valid", retBool);
1401 if ( reasonVal ) add_assoc_string(return_value, "reason", reasonVal, 0);
1402 if ( locationVal ) add_assoc_zval(return_value, "location", locationVal);
1407 * bool GEOSGeometry::isSimple()
1409 PHP_METHOD(Geometry, isSimple)
1411 GEOSGeometry *this;
1412 int ret;
1413 zend_bool retBool;
1415 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1417 ret = GEOSisSimple(this);
1418 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1420 /* return_value is a zval */
1421 retBool = ret;
1422 RETURN_BOOL(retBool);
1426 * bool GEOSGeometry::isRing()
1428 PHP_METHOD(Geometry, isRing)
1430 GEOSGeometry *this;
1431 int ret;
1432 zend_bool retBool;
1434 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1436 ret = GEOSisRing(this);
1437 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1439 /* return_value is a zval */
1440 retBool = ret;
1441 RETURN_BOOL(retBool);
1445 * bool GEOSGeometry::hasZ()
1447 PHP_METHOD(Geometry, hasZ)
1449 GEOSGeometry *this;
1450 int ret;
1451 zend_bool retBool;
1453 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1455 ret = GEOSHasZ(this);
1456 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1458 /* return_value is a zval */
1459 retBool = ret;
1460 RETURN_BOOL(retBool);
1464 * bool GEOSGeometry::isClosed()
1466 PHP_METHOD(Geometry, isClosed)
1468 GEOSGeometry *this;
1469 int ret;
1470 zend_bool retBool;
1472 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1474 ret = GEOSisClosed(this);
1475 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1477 /* return_value is a zval */
1478 retBool = ret;
1479 RETURN_BOOL(retBool);
1483 * string GEOSGeometry::typeName()
1485 PHP_METHOD(Geometry, typeName)
1487 GEOSGeometry *this;
1488 char *typ;
1489 char *typVal;
1491 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1493 /* TODO: define constant strings instead... */
1495 typ = GEOSGeomType(this);
1496 if ( ! typ ) RETURN_NULL(); /* should get an exception first */
1498 typVal = estrdup(typ);
1499 GEOSFree(typ);
1501 RETURN_STRING(typVal, 0);
1505 * long GEOSGeometry::typeId()
1507 PHP_METHOD(Geometry, typeId)
1509 GEOSGeometry *this;
1510 long typ;
1512 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1514 /* TODO: define constant strings instead... */
1516 typ = GEOSGeomTypeId(this);
1517 if ( typ == -1 ) RETURN_NULL(); /* should get an exception first */
1519 RETURN_LONG(typ);
1523 /* ------ Initialization / Deinitialization / Meta ------------------ */
1525 /* per-module initialization */
1526 PHP_MINIT_FUNCTION(geos)
1528 zend_class_entry ce;
1530 /* WKTReader */
1531 INIT_CLASS_ENTRY(ce, "GEOSWKTReader", WKTReader_methods);
1532 WKTReader_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
1533 WKTReader_ce_ptr->create_object = WKTReader_create_obj;
1534 memcpy(&WKTReader_object_handlers,
1535 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1536 WKTReader_object_handlers.clone_obj = NULL;
1538 /* WKTWriter */
1539 INIT_CLASS_ENTRY(ce, "GEOSWKTWriter", WKTWriter_methods);
1540 WKTWriter_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
1541 WKTWriter_ce_ptr->create_object = WKTWriter_create_obj;
1542 memcpy(&WKTWriter_object_handlers,
1543 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1544 WKTWriter_object_handlers.clone_obj = NULL;
1546 /* Geometry */
1547 INIT_CLASS_ENTRY(ce, "GEOSGeometry", Geometry_methods);
1548 Geometry_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
1549 Geometry_ce_ptr->create_object = Geometry_create_obj;
1550 memcpy(&Geometry_object_handlers,
1551 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1552 Geometry_object_handlers.clone_obj = NULL;
1554 /* Constants */
1555 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_ROUND", GEOSBUF_CAP_ROUND,
1556 CONST_CS|CONST_PERSISTENT);
1557 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_FLAT", GEOSBUF_CAP_FLAT,
1558 CONST_CS|CONST_PERSISTENT);
1559 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_SQUARE", GEOSBUF_CAP_SQUARE,
1560 CONST_CS|CONST_PERSISTENT);
1561 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_ROUND", GEOSBUF_JOIN_ROUND,
1562 CONST_CS|CONST_PERSISTENT);
1563 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_MITRE", GEOSBUF_JOIN_MITRE,
1564 CONST_CS|CONST_PERSISTENT);
1565 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_BEVEL", GEOSBUF_JOIN_BEVEL,
1566 CONST_CS|CONST_PERSISTENT);
1568 REGISTER_LONG_CONSTANT("GEOS_POINT", GEOS_POINT,
1569 CONST_CS|CONST_PERSISTENT);
1570 REGISTER_LONG_CONSTANT("GEOS_LINESTRING", GEOS_LINESTRING,
1571 CONST_CS|CONST_PERSISTENT);
1572 REGISTER_LONG_CONSTANT("GEOS_LINEARRING", GEOS_LINEARRING,
1573 CONST_CS|CONST_PERSISTENT);
1574 REGISTER_LONG_CONSTANT("GEOS_POLYGON", GEOS_POLYGON,
1575 CONST_CS|CONST_PERSISTENT);
1576 REGISTER_LONG_CONSTANT("GEOS_MULTIPOINT", GEOS_MULTIPOINT,
1577 CONST_CS|CONST_PERSISTENT);
1578 REGISTER_LONG_CONSTANT("GEOS_MULTILINESTRING", GEOS_MULTILINESTRING,
1579 CONST_CS|CONST_PERSISTENT);
1580 REGISTER_LONG_CONSTANT("GEOS_MULTIPOLYGON", GEOS_MULTIPOLYGON,
1581 CONST_CS|CONST_PERSISTENT);
1582 REGISTER_LONG_CONSTANT("GEOS_GEOMETRYCOLLECTION", GEOS_GEOMETRYCOLLECTION,
1583 CONST_CS|CONST_PERSISTENT);
1585 return SUCCESS;
1588 /* per-request initialization */
1589 PHP_RINIT_FUNCTION(geos)
1591 initGEOS(noticeHandler, errorHandler);
1592 return SUCCESS;
1595 /* pre-request destruction */
1596 PHP_RSHUTDOWN_FUNCTION(geos)
1598 finishGEOS();
1599 return SUCCESS;
1602 /* module info */
1603 PHP_MINFO_FUNCTION(geos)
1605 php_info_print_table_start();
1606 php_info_print_table_row(2,
1607 "GEOS - Geometry Engine Open Source", "enabled");
1608 php_info_print_table_row(2,
1609 "Version", PHP_GEOS_VERSION);
1610 php_info_print_table_end();