numInteriorRings
[geos.git] / php / geos.c
blob48724d18789a73548c7defdfe9892750888f6f4b
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);
205 PHP_METHOD(Geometry, getSRID);
206 PHP_METHOD(Geometry, setSRID);
207 PHP_METHOD(Geometry, numGeometries);
208 PHP_METHOD(Geometry, getGeometryN);
209 PHP_METHOD(Geometry, numInteriorRings);
211 static function_entry Geometry_methods[] = {
212 PHP_ME(Geometry, __construct, NULL, 0)
213 PHP_ME(Geometry, __toString, NULL, 0)
214 PHP_ME(Geometry, project, NULL, 0)
215 PHP_ME(Geometry, interpolate, NULL, 0)
216 PHP_ME(Geometry, buffer, NULL, 0)
217 PHP_ME(Geometry, envelope, NULL, 0)
218 PHP_ME(Geometry, intersection, NULL, 0)
219 PHP_ME(Geometry, convexHull, NULL, 0)
220 PHP_ME(Geometry, difference, NULL, 0)
221 PHP_ME(Geometry, symDifference, NULL, 0)
222 PHP_ME(Geometry, boundary, NULL, 0)
223 PHP_ME(Geometry, union, NULL, 0)
224 PHP_ME(Geometry, pointOnSurface, NULL, 0)
225 PHP_ME(Geometry, centroid, NULL, 0)
226 PHP_ME(Geometry, relate, NULL, 0)
227 PHP_ME(Geometry, simplify, NULL, 0)
228 PHP_ME(Geometry, extractUniquePoints, NULL, 0)
229 PHP_ME(Geometry, disjoint, NULL, 0)
230 PHP_ME(Geometry, touches, NULL, 0)
231 PHP_ME(Geometry, intersects, NULL, 0)
232 PHP_ME(Geometry, crosses, NULL, 0)
233 PHP_ME(Geometry, within, NULL, 0)
234 PHP_ME(Geometry, contains, NULL, 0)
235 PHP_ME(Geometry, overlaps, NULL, 0)
236 PHP_ME(Geometry, equals, NULL, 0)
237 PHP_ME(Geometry, equalsExact, NULL, 0)
238 PHP_ME(Geometry, isEmpty, NULL, 0)
239 PHP_ME(Geometry, checkValidity, NULL, 0)
240 PHP_ME(Geometry, isSimple, NULL, 0)
241 PHP_ME(Geometry, isRing, NULL, 0)
242 PHP_ME(Geometry, hasZ, NULL, 0)
243 PHP_ME(Geometry, isClosed, NULL, 0)
244 PHP_ME(Geometry, typeName, NULL, 0)
245 PHP_ME(Geometry, typeId, NULL, 0)
246 PHP_ME(Geometry, getSRID, NULL, 0)
247 PHP_ME(Geometry, setSRID, NULL, 0)
248 PHP_ME(Geometry, numGeometries, NULL, 0)
249 PHP_ME(Geometry, getGeometryN, NULL, 0)
250 PHP_ME(Geometry, numInteriorRings, NULL, 0)
251 {NULL, NULL, NULL}
254 static zend_class_entry *Geometry_ce_ptr;
256 static zend_object_handlers Geometry_object_handlers;
259 * Push components of the given geometry
260 * to the given array zval.
261 * Components geometries are cloned.
262 * NOTE: collection components are not descended into
264 static void
265 dumpGeometry(GEOSGeometry* g, zval* array)
267 int ngeoms, i;
270 MAKE_STD_ZVAL(array);
271 array_init(array);
274 ngeoms = GEOSGetNumGeometries(g);
275 for (i=0; i<ngeoms; ++i)
277 zval *tmp;
278 GEOSGeometry* cc;
279 const GEOSGeometry* c = GEOSGetGeometryN(g, i);
280 if ( ! c ) continue; /* should get an exception */
281 /* we _need_ to clone as this one is owned by 'g' */
282 cc = GEOSGeom_clone(c);
283 if ( ! cc ) continue; /* should get an exception */
285 MAKE_STD_ZVAL(tmp);
286 object_init_ex(tmp, Geometry_ce_ptr);
287 setRelay(tmp, cc);
288 add_next_index_zval(array, tmp);
293 static void
294 Geometry_dtor (void *object TSRMLS_DC)
296 Proxy *obj = (Proxy *)object;
297 GEOSGeom_destroy((GEOSGeometry*)obj->relay);
299 zend_hash_destroy(obj->std.properties);
300 FREE_HASHTABLE(obj->std.properties);
302 efree(obj);
305 static zend_object_value
306 Geometry_create_obj (zend_class_entry *type TSRMLS_DC)
308 return Gen_create_obj(type, Geometry_dtor, &Geometry_object_handlers);
312 PHP_METHOD(Geometry, __construct)
314 php_error_docref(NULL TSRMLS_CC, E_ERROR,
315 "GEOSGeometry can't be constructed using new, check WKTReader");
319 PHP_METHOD(Geometry, __toString)
321 GEOSGeometry *geom;
322 GEOSWKTWriter *writer;
323 char *wkt;
324 char *ret;
326 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
327 writer = GEOSWKTWriter_create();
328 /* NOTE: if we get an exception before reaching
329 * GEOSWKTWriter_destory below we'll be leaking memory.
330 * One fix could be storing the object in a refcounted
331 * zval.
333 GEOSWKTWriter_setTrim(writer, 1);
335 wkt = GEOSWKTWriter_write(writer, geom);
336 /* we'll probably get an exception if wkt is null */
337 if ( ! wkt ) RETURN_NULL();
339 GEOSWKTWriter_destroy(writer);
342 ret = estrdup(wkt);
343 GEOSFree(wkt);
345 RETURN_STRING(ret, 0);
348 PHP_METHOD(Geometry, project)
350 GEOSGeometry *this;
351 GEOSGeometry *other;
352 zval *zobj;
353 zend_bool normalized = 0;
354 double ret;
356 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
358 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|b", &zobj,
359 &normalized) == FAILURE) {
360 RETURN_NULL();
362 other = getRelay(zobj, Geometry_ce_ptr);
364 if ( normalized ) {
365 ret = GEOSProjectNormalized(this, other);
366 } else {
367 ret = GEOSProject(this, other);
369 if ( ret < 0 ) RETURN_NULL(); /* should get an exception first */
371 RETURN_DOUBLE(ret);
374 PHP_METHOD(Geometry, interpolate)
376 GEOSGeometry *this;
377 double dist;
378 GEOSGeometry *ret;
379 zend_bool normalized = 0;
381 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
383 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|b",
384 &dist, &normalized) == FAILURE) {
385 RETURN_NULL();
388 if ( normalized ) {
389 ret = GEOSInterpolateNormalized(this, dist);
390 } else {
391 ret = GEOSInterpolate(this, dist);
393 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
395 /* return_value is a zval */
396 object_init_ex(return_value, Geometry_ce_ptr);
397 setRelay(return_value, ret);
401 * GEOSGeometry::buffer(dist, [<styleArray>])
403 * styleArray keys supported:
404 * 'quad_segs'
405 * Type: int
406 * Number of segments used to approximate
407 * a quarter circle (defaults to 8).
408 * 'endcap'
409 * Type: long
410 * Endcap style (defaults to GEOSBUF_CAP_ROUND)
411 * 'join'
412 * Type: long
413 * Join style (defaults to GEOSBUF_JOIN_ROUND)
414 * 'mitre_limit'
415 * Type: double
416 * mitre ratio limit (only affects joins with GEOSBUF_JOIN_MITRE style)
417 * 'miter_limit' is also accepted as a synonym for 'mitre_limit'.
419 PHP_METHOD(Geometry, buffer)
421 GEOSGeometry *this;
422 double dist;
423 GEOSGeometry *ret;
424 static const double default_mitreLimit = 5.0;
425 static const int default_endCapStyle = GEOSBUF_CAP_ROUND;
426 static const int default_joinStyle = GEOSBUF_JOIN_ROUND;
427 static const int default_quadSegs = 8;
428 long int quadSegs = default_quadSegs;
429 long int endCapStyle = default_endCapStyle;
430 long int joinStyle = default_joinStyle;
431 double mitreLimit = default_mitreLimit;
432 zval *style_val = NULL;
433 zval **data;
434 HashTable *style;
435 char *key;
436 ulong index;
438 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
440 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|a",
441 &dist, &style_val) == FAILURE) {
442 RETURN_NULL();
445 if ( style_val )
447 style = HASH_OF(style_val);
448 while(zend_hash_get_current_key(style, &key, &index, 0)
449 == HASH_KEY_IS_STRING)
451 if(!strcmp(key, "quad_segs"))
453 zend_hash_get_current_data(style, (void**)&data);
454 quadSegs = getZvalAsLong(*data);
456 else if(!strcmp(key, "endcap"))
458 zend_hash_get_current_data(style, (void**)&data);
459 endCapStyle = getZvalAsLong(*data);
461 else if(!strcmp(key, "join"))
463 zend_hash_get_current_data(style, (void**)&data);
464 joinStyle = getZvalAsLong(*data);
466 else if(!strcmp(key, "mitre_limit"))
468 zend_hash_get_current_data(style, (void**)&data);
469 mitreLimit = getZvalAsDouble(*data);
472 zend_hash_move_forward(style);
476 ret = GEOSBufferWithStyle(this, dist,
477 quadSegs, endCapStyle, joinStyle, mitreLimit);
478 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
480 /* return_value is a zval */
481 object_init_ex(return_value, Geometry_ce_ptr);
482 setRelay(return_value, ret);
485 PHP_METHOD(Geometry, envelope)
487 GEOSGeometry *this;
488 GEOSGeometry *ret;
490 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
492 ret = GEOSEnvelope(this);
493 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
495 /* return_value is a zval */
496 object_init_ex(return_value, Geometry_ce_ptr);
497 setRelay(return_value, ret);
500 PHP_METHOD(Geometry, intersection)
502 GEOSGeometry *this;
503 GEOSGeometry *other;
504 GEOSGeometry *ret;
505 zval *zobj;
507 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
509 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
510 == FAILURE) {
511 RETURN_NULL();
513 other = getRelay(zobj, Geometry_ce_ptr);
515 ret = GEOSIntersection(this, other);
516 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
518 /* return_value is a zval */
519 object_init_ex(return_value, Geometry_ce_ptr);
520 setRelay(return_value, ret);
523 PHP_METHOD(Geometry, convexHull)
525 GEOSGeometry *this;
526 GEOSGeometry *ret;
528 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
530 ret = GEOSConvexHull(this);
531 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
533 /* return_value is a zval */
534 object_init_ex(return_value, Geometry_ce_ptr);
535 setRelay(return_value, ret);
538 PHP_METHOD(Geometry, difference)
540 GEOSGeometry *this;
541 GEOSGeometry *other;
542 GEOSGeometry *ret;
543 zval *zobj;
545 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
547 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
548 == FAILURE) {
549 RETURN_NULL();
551 other = getRelay(zobj, Geometry_ce_ptr);
553 ret = GEOSDifference(this, other);
554 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
556 /* return_value is a zval */
557 object_init_ex(return_value, Geometry_ce_ptr);
558 setRelay(return_value, ret);
561 PHP_METHOD(Geometry, symDifference)
563 GEOSGeometry *this;
564 GEOSGeometry *other;
565 GEOSGeometry *ret;
566 zval *zobj;
568 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
570 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
571 == FAILURE) {
572 RETURN_NULL();
574 other = getRelay(zobj, Geometry_ce_ptr);
576 ret = GEOSSymDifference(this, other);
577 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
579 /* return_value is a zval */
580 object_init_ex(return_value, Geometry_ce_ptr);
581 setRelay(return_value, ret);
584 PHP_METHOD(Geometry, boundary)
586 GEOSGeometry *this;
587 GEOSGeometry *ret;
589 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
591 ret = GEOSBoundary(this);
592 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
594 /* return_value is a zval */
595 object_init_ex(return_value, Geometry_ce_ptr);
596 setRelay(return_value, ret);
600 * GEOSGeometry::union(otherGeom)
601 * GEOSGeometry::union()
603 PHP_METHOD(Geometry, union)
605 GEOSGeometry *this;
606 GEOSGeometry *other;
607 GEOSGeometry *ret;
608 zval *zobj = NULL;
610 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
612 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o", &zobj)
613 == FAILURE) {
614 RETURN_NULL();
617 if ( zobj ) {
618 other = getRelay(zobj, Geometry_ce_ptr);
619 ret = GEOSUnion(this, other);
620 } else {
621 ret = GEOSUnionCascaded(this);
624 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
626 /* return_value is a zval */
627 object_init_ex(return_value, Geometry_ce_ptr);
628 setRelay(return_value, ret);
632 * GEOSGeometry::pointOnSurface()
634 PHP_METHOD(Geometry, pointOnSurface)
636 GEOSGeometry *this;
637 GEOSGeometry *ret;
639 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
641 ret = GEOSPointOnSurface(this);
642 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
644 /* return_value is a zval */
645 object_init_ex(return_value, Geometry_ce_ptr);
646 setRelay(return_value, ret);
650 * GEOSGeometry::centroid()
652 PHP_METHOD(Geometry, centroid)
654 GEOSGeometry *this;
655 GEOSGeometry *ret;
657 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
659 ret = GEOSGetCentroid(this);
660 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
662 /* return_value is a zval */
663 object_init_ex(return_value, Geometry_ce_ptr);
664 setRelay(return_value, ret);
668 * GEOSGeometry::relate(otherGeom)
669 * GEOSGeometry::relate(otherGeom, pattern)
671 PHP_METHOD(Geometry, relate)
673 GEOSGeometry *this;
674 GEOSGeometry *other;
675 zval *zobj;
676 char* pat = NULL;
677 int patlen;
678 int retInt;
679 zend_bool retBool;
680 char* retStr;
682 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
684 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|s",
685 &zobj, &pat, &patlen) == FAILURE)
687 RETURN_NULL();
690 other = getRelay(zobj, Geometry_ce_ptr);
692 if ( ! pat ) {
693 /* we'll compute it */
694 pat = GEOSRelate(this, other);
695 if ( ! pat ) RETURN_NULL(); /* should get an exception first */
696 retStr = estrdup(pat);
697 GEOSFree(pat);
698 RETURN_STRING(retStr, 0);
699 } else {
700 retInt = GEOSRelatePattern(this, other, pat);
701 if ( retInt == 2 ) RETURN_NULL(); /* should get an exception first */
702 retBool = retInt;
703 RETURN_BOOL(retBool);
708 /* -- class GEOSWKTReader -------------------- */
710 PHP_METHOD(WKTReader, __construct);
711 PHP_METHOD(WKTReader, read);
713 static function_entry WKTReader_methods[] = {
714 PHP_ME(WKTReader, __construct, NULL, 0)
715 PHP_ME(WKTReader, read, NULL, 0)
716 {NULL, NULL, NULL}
719 static zend_class_entry *WKTReader_ce_ptr;
721 static zend_object_handlers WKTReader_object_handlers;
723 static void
724 WKTReader_dtor (void *object TSRMLS_DC)
726 Proxy *obj = (Proxy *)object;
727 GEOSWKTReader_destroy((GEOSWKTReader*)obj->relay);
729 zend_hash_destroy(obj->std.properties);
730 FREE_HASHTABLE(obj->std.properties);
732 efree(obj);
735 static zend_object_value
736 WKTReader_create_obj (zend_class_entry *type TSRMLS_DC)
738 return Gen_create_obj(type, WKTReader_dtor, &WKTReader_object_handlers);
742 PHP_METHOD(WKTReader, __construct)
744 GEOSWKTReader* obj;
745 zval *object = getThis();
747 obj = GEOSWKTReader_create();
748 if ( ! obj ) {
749 php_error_docref(NULL TSRMLS_CC, E_ERROR,
750 "GEOSWKTReader_create() failed (didn't initGEOS?)");
753 setRelay(object, obj);
756 PHP_METHOD(WKTReader, read)
758 GEOSWKTReader *reader;
759 GEOSGeometry *geom;
760 char* wkt;
761 int wktlen;
763 reader = (GEOSWKTReader*)getRelay(getThis(), WKTReader_ce_ptr);
765 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
766 &wkt, &wktlen) == FAILURE)
768 RETURN_NULL();
771 geom = GEOSWKTReader_read(reader, wkt);
772 /* we'll probably get an exception if geom is null */
773 if ( ! geom ) RETURN_NULL();
775 /* return_value is a zval */
776 object_init_ex(return_value, Geometry_ce_ptr);
777 setRelay(return_value, geom);
781 /* -- class GEOSWKTWriter -------------------- */
783 PHP_METHOD(WKTWriter, __construct);
784 PHP_METHOD(WKTWriter, write);
785 PHP_METHOD(WKTWriter, setTrim);
786 PHP_METHOD(WKTWriter, setRoundingPrecision);
787 PHP_METHOD(WKTWriter, setOutputDimension);
788 PHP_METHOD(WKTWriter, setOld3D);
790 static function_entry WKTWriter_methods[] = {
791 PHP_ME(WKTWriter, __construct, NULL, 0)
792 PHP_ME(WKTWriter, write, NULL, 0)
793 PHP_ME(WKTWriter, setTrim, NULL, 0)
794 PHP_ME(WKTWriter, setRoundingPrecision, NULL, 0)
795 PHP_ME(WKTWriter, setOutputDimension, NULL, 0)
796 PHP_ME(WKTWriter, setOld3D, NULL, 0)
797 {NULL, NULL, NULL}
800 static zend_class_entry *WKTWriter_ce_ptr;
802 static zend_object_handlers WKTWriter_object_handlers;
804 static void
805 WKTWriter_dtor (void *object TSRMLS_DC)
807 Proxy *obj = (Proxy *)object;
808 GEOSWKTWriter_destroy((GEOSWKTWriter*)obj->relay);
810 zend_hash_destroy(obj->std.properties);
811 FREE_HASHTABLE(obj->std.properties);
813 efree(obj);
816 static zend_object_value
817 WKTWriter_create_obj (zend_class_entry *type TSRMLS_DC)
819 return Gen_create_obj(type, WKTWriter_dtor, &WKTWriter_object_handlers);
822 PHP_METHOD(WKTWriter, __construct)
824 GEOSWKTWriter* obj;
825 zval *object = getThis();
827 obj = GEOSWKTWriter_create();
828 if ( ! obj ) {
829 php_error_docref(NULL TSRMLS_CC, E_ERROR,
830 "GEOSWKTWriter_create() failed (didn't initGEOS?)");
833 setRelay(object, obj);
836 PHP_METHOD(WKTWriter, write)
838 GEOSWKTWriter *writer;
839 zval *zobj;
840 GEOSGeometry *geom;
841 char* wkt;
842 char* retstr;
844 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
846 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
847 == FAILURE)
849 RETURN_NULL();
852 geom = getRelay(zobj, Geometry_ce_ptr);
854 wkt = GEOSWKTWriter_write(writer, geom);
855 /* we'll probably get an exception if wkt is null */
856 if ( ! wkt ) RETURN_NULL();
858 retstr = estrdup(wkt);
859 GEOSFree(wkt);
861 RETURN_STRING(retstr, 0);
863 /* return_value is a zval */
864 object_init_ex(return_value, Geometry_ce_ptr);
865 setRelay(return_value, geom);
869 PHP_METHOD(WKTWriter, setTrim)
871 GEOSWKTWriter *writer;
872 zend_bool trimval;
873 char trim;
875 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
877 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &trimval)
878 == FAILURE)
880 RETURN_NULL();
883 trim = trimval;
884 GEOSWKTWriter_setTrim(writer, trim);
887 PHP_METHOD(WKTWriter, setRoundingPrecision)
889 GEOSWKTWriter *writer;
890 long int prec;
892 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
894 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &prec)
895 == FAILURE)
897 RETURN_NULL();
900 GEOSWKTWriter_setRoundingPrecision(writer, prec);
903 PHP_METHOD(WKTWriter, setOutputDimension)
905 GEOSWKTWriter *writer;
906 long int dim;
908 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
910 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
911 == FAILURE)
913 RETURN_NULL();
916 GEOSWKTWriter_setOutputDimension(writer, dim);
919 PHP_METHOD(WKTWriter, setOld3D)
921 GEOSWKTWriter *writer;
922 zend_bool bval;
923 int val;
925 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
927 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &bval)
928 == FAILURE)
930 RETURN_NULL();
933 val = bval;
934 GEOSWKTWriter_setOld3D(writer, val);
937 /* -- Free functions ------------------------- */
940 * string GEOSVersion()
942 PHP_FUNCTION(GEOSVersion)
944 char *str;
946 str = estrdup(GEOSversion());
947 RETURN_STRING(str, 0);
951 * array GEOSPolygonize(GEOSGeometry $geom)
953 * The returned array contains the following elements:
955 * - 'rings'
956 * Type: array of GEOSGeometry
957 * Rings that can be formed by the costituent
958 * linework of geometry.
959 * - 'cut_edges' (optional)
960 * Type: array of GEOSGeometry
961 * Edges which are connected at both ends but
962 * which do not form part of polygon.
963 * - 'dangles'
964 * Type: array of GEOSGeometry
965 * Edges which have one or both ends which are
966 * not incident on another edge endpoint
967 * - 'invalid_rings'
968 * Type: array of GEOSGeometry
969 * Edges which form rings which are invalid
970 * (e.g. the component lines contain a self-intersection)
973 PHP_FUNCTION(GEOSPolygonize)
975 GEOSGeometry *this;
976 GEOSGeometry *rings;
977 GEOSGeometry *cut_edges;
978 GEOSGeometry *dangles;
979 GEOSGeometry *invalid_rings;
980 zval *array_elem;
981 zval *zobj;
983 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
984 == FAILURE)
986 RETURN_NULL();
988 this = getRelay(zobj, Geometry_ce_ptr);
990 rings = GEOSPolygonize_full(this, &cut_edges, &dangles, &invalid_rings);
991 if ( ! rings ) RETURN_NULL(); /* should get an exception first */
993 /* return value should be an array */
994 array_init(return_value);
996 MAKE_STD_ZVAL(array_elem);
997 array_init(array_elem);
998 dumpGeometry(rings, array_elem);
999 GEOSGeom_destroy(rings);
1000 add_assoc_zval(return_value, "rings", array_elem);
1002 MAKE_STD_ZVAL(array_elem);
1003 array_init(array_elem);
1004 dumpGeometry(cut_edges, array_elem);
1005 GEOSGeom_destroy(cut_edges);
1006 add_assoc_zval(return_value, "cut_edges", array_elem);
1008 MAKE_STD_ZVAL(array_elem);
1009 array_init(array_elem);
1010 dumpGeometry(dangles, array_elem);
1011 GEOSGeom_destroy(dangles);
1012 add_assoc_zval(return_value, "dangles", array_elem);
1014 MAKE_STD_ZVAL(array_elem);
1015 array_init(array_elem);
1016 dumpGeometry(invalid_rings, array_elem);
1017 GEOSGeom_destroy(invalid_rings);
1018 add_assoc_zval(return_value, "invalid_rings", array_elem);
1023 * array GEOSLineMerge(GEOSGeometry $geom)
1025 PHP_FUNCTION(GEOSLineMerge)
1027 GEOSGeometry *geom_in;
1028 GEOSGeometry *geom_out;
1029 zval *zobj;
1031 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1032 == FAILURE)
1034 RETURN_NULL();
1036 geom_in = getRelay(zobj, Geometry_ce_ptr);
1038 geom_out = GEOSLineMerge(geom_in);
1039 if ( ! geom_out ) RETURN_NULL(); /* should get an exception first */
1041 /* return value should be an array */
1042 array_init(return_value);
1043 dumpGeometry(geom_out, return_value);
1044 GEOSGeom_destroy(geom_out);
1048 * GEOSGeometry GEOSGeometry::simplify(tolerance)
1049 * GEOSGeometry GEOSGeometry::simplify(tolerance, preserveTopology)
1051 PHP_METHOD(Geometry, simplify)
1053 GEOSGeometry *this;
1054 double tolerance;
1055 zend_bool preserveTopology = 0;
1056 GEOSGeometry *ret;
1058 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1060 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|b",
1061 &tolerance, &preserveTopology) == FAILURE) {
1062 RETURN_NULL();
1065 if ( preserveTopology ) {
1066 ret = GEOSTopologyPreserveSimplify(this, tolerance);
1067 } else {
1068 ret = GEOSSimplify(this, tolerance);
1071 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1073 /* return_value is a zval */
1074 object_init_ex(return_value, Geometry_ce_ptr);
1075 setRelay(return_value, ret);
1079 * GEOSGeometry GEOSGeometry::extractUniquePoints()
1081 PHP_METHOD(Geometry, extractUniquePoints)
1083 GEOSGeometry *this;
1084 GEOSGeometry *ret;
1086 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1088 ret = GEOSGeom_extractUniquePoints(this);
1089 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
1091 /* return_value is a zval */
1092 object_init_ex(return_value, Geometry_ce_ptr);
1093 setRelay(return_value, ret);
1097 * bool GEOSGeometry::disjoint(GEOSGeometry)
1099 PHP_METHOD(Geometry, disjoint)
1101 GEOSGeometry *this;
1102 GEOSGeometry *other;
1103 int ret;
1104 zend_bool retBool;
1105 zval *zobj;
1107 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1109 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1110 == FAILURE) {
1111 RETURN_NULL();
1113 other = getRelay(zobj, Geometry_ce_ptr);
1115 ret = GEOSDisjoint(this, other);
1116 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1118 /* return_value is a zval */
1119 retBool = ret;
1120 RETURN_BOOL(retBool);
1124 * bool GEOSGeometry::touches(GEOSGeometry)
1126 PHP_METHOD(Geometry, touches)
1128 GEOSGeometry *this;
1129 GEOSGeometry *other;
1130 int ret;
1131 zend_bool retBool;
1132 zval *zobj;
1134 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1136 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1137 == FAILURE) {
1138 RETURN_NULL();
1140 other = getRelay(zobj, Geometry_ce_ptr);
1142 ret = GEOSTouches(this, other);
1143 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1145 /* return_value is a zval */
1146 retBool = ret;
1147 RETURN_BOOL(retBool);
1151 * bool GEOSGeometry::intersects(GEOSGeometry)
1153 PHP_METHOD(Geometry, intersects)
1155 GEOSGeometry *this;
1156 GEOSGeometry *other;
1157 int ret;
1158 zend_bool retBool;
1159 zval *zobj;
1161 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1163 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1164 == FAILURE) {
1165 RETURN_NULL();
1167 other = getRelay(zobj, Geometry_ce_ptr);
1169 ret = GEOSIntersects(this, other);
1170 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1172 /* return_value is a zval */
1173 retBool = ret;
1174 RETURN_BOOL(retBool);
1178 * bool GEOSGeometry::crosses(GEOSGeometry)
1180 PHP_METHOD(Geometry, crosses)
1182 GEOSGeometry *this;
1183 GEOSGeometry *other;
1184 int ret;
1185 zend_bool retBool;
1186 zval *zobj;
1188 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1190 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1191 == FAILURE) {
1192 RETURN_NULL();
1194 other = getRelay(zobj, Geometry_ce_ptr);
1196 ret = GEOSCrosses(this, other);
1197 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1199 /* return_value is a zval */
1200 retBool = ret;
1201 RETURN_BOOL(retBool);
1205 * bool GEOSGeometry::within(GEOSGeometry)
1207 PHP_METHOD(Geometry, within)
1209 GEOSGeometry *this;
1210 GEOSGeometry *other;
1211 int ret;
1212 zend_bool retBool;
1213 zval *zobj;
1215 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1217 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1218 == FAILURE) {
1219 RETURN_NULL();
1221 other = getRelay(zobj, Geometry_ce_ptr);
1223 ret = GEOSWithin(this, other);
1224 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1226 /* return_value is a zval */
1227 retBool = ret;
1228 RETURN_BOOL(retBool);
1232 * bool GEOSGeometry::contains(GEOSGeometry)
1234 PHP_METHOD(Geometry, contains)
1236 GEOSGeometry *this;
1237 GEOSGeometry *other;
1238 int ret;
1239 zend_bool retBool;
1240 zval *zobj;
1242 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1244 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1245 == FAILURE) {
1246 RETURN_NULL();
1248 other = getRelay(zobj, Geometry_ce_ptr);
1250 ret = GEOSContains(this, other);
1251 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1253 /* return_value is a zval */
1254 retBool = ret;
1255 RETURN_BOOL(retBool);
1259 * bool GEOSGeometry::overlaps(GEOSGeometry)
1261 PHP_METHOD(Geometry, overlaps)
1263 GEOSGeometry *this;
1264 GEOSGeometry *other;
1265 int ret;
1266 zend_bool retBool;
1267 zval *zobj;
1269 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1271 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1272 == FAILURE) {
1273 RETURN_NULL();
1275 other = getRelay(zobj, Geometry_ce_ptr);
1277 ret = GEOSOverlaps(this, other);
1278 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1280 /* return_value is a zval */
1281 retBool = ret;
1282 RETURN_BOOL(retBool);
1286 * bool GEOSGeometry::equals(GEOSGeometry)
1288 PHP_METHOD(Geometry, equals)
1290 GEOSGeometry *this;
1291 GEOSGeometry *other;
1292 int ret;
1293 zend_bool retBool;
1294 zval *zobj;
1296 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1298 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
1299 &zobj) == FAILURE) {
1300 RETURN_NULL();
1302 other = getRelay(zobj, Geometry_ce_ptr);
1304 ret = GEOSEquals(this, other);
1305 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1307 /* return_value is a zval */
1308 retBool = ret;
1309 RETURN_BOOL(retBool);
1313 * bool GEOSGeometry::equalsExact(GEOSGeometry)
1314 * bool GEOSGeometry::equalsExact(GEOSGeometry, double tolerance)
1316 PHP_METHOD(Geometry, equalsExact)
1318 GEOSGeometry *this;
1319 GEOSGeometry *other;
1320 int ret;
1321 double tolerance = 0;
1322 zend_bool retBool;
1323 zval *zobj;
1325 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1327 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|d",
1328 &zobj, &tolerance) == FAILURE) {
1329 RETURN_NULL();
1331 other = getRelay(zobj, Geometry_ce_ptr);
1333 ret = GEOSEqualsExact(this, other, tolerance);
1334 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1336 /* return_value is a zval */
1337 retBool = ret;
1338 RETURN_BOOL(retBool);
1342 * bool GEOSGeometry::isEmpty()
1344 PHP_METHOD(Geometry, isEmpty)
1346 GEOSGeometry *this;
1347 int ret;
1348 zend_bool retBool;
1350 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1352 ret = GEOSisEmpty(this);
1353 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1355 /* return_value is a zval */
1356 retBool = ret;
1357 RETURN_BOOL(retBool);
1361 * array GEOSGeometry::checkValidity()
1363 PHP_METHOD(Geometry, checkValidity)
1365 GEOSGeometry *this;
1366 GEOSGeometry *location = NULL;
1367 int ret;
1368 char *reason = NULL;
1369 zend_bool retBool;
1370 char *reasonVal = NULL;
1371 zval *locationVal = NULL;
1373 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1375 ret = GEOSisValidDetail(this, &reason, (const GEOSGeometry**)&location);
1376 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1378 if ( reason ) {
1379 reasonVal = estrdup(reason);
1380 GEOSFree(reason);
1383 if ( location ) {
1384 MAKE_STD_ZVAL(locationVal);
1385 object_init_ex(locationVal, Geometry_ce_ptr);
1386 setRelay(locationVal, location);
1389 retBool = ret;
1391 /* return value is an array */
1392 array_init(return_value);
1393 add_assoc_bool(return_value, "valid", retBool);
1394 if ( reasonVal ) add_assoc_string(return_value, "reason", reasonVal, 0);
1395 if ( locationVal ) add_assoc_zval(return_value, "location", locationVal);
1400 * bool GEOSGeometry::isSimple()
1402 PHP_METHOD(Geometry, isSimple)
1404 GEOSGeometry *this;
1405 int ret;
1406 zend_bool retBool;
1408 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1410 ret = GEOSisSimple(this);
1411 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1413 /* return_value is a zval */
1414 retBool = ret;
1415 RETURN_BOOL(retBool);
1419 * bool GEOSGeometry::isRing()
1421 PHP_METHOD(Geometry, isRing)
1423 GEOSGeometry *this;
1424 int ret;
1425 zend_bool retBool;
1427 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1429 ret = GEOSisRing(this);
1430 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1432 /* return_value is a zval */
1433 retBool = ret;
1434 RETURN_BOOL(retBool);
1438 * bool GEOSGeometry::hasZ()
1440 PHP_METHOD(Geometry, hasZ)
1442 GEOSGeometry *this;
1443 int ret;
1444 zend_bool retBool;
1446 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1448 ret = GEOSHasZ(this);
1449 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1451 /* return_value is a zval */
1452 retBool = ret;
1453 RETURN_BOOL(retBool);
1457 * bool GEOSGeometry::isClosed()
1459 PHP_METHOD(Geometry, isClosed)
1461 GEOSGeometry *this;
1462 int ret;
1463 zend_bool retBool;
1465 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1467 ret = GEOSisClosed(this);
1468 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1470 /* return_value is a zval */
1471 retBool = ret;
1472 RETURN_BOOL(retBool);
1476 * string GEOSGeometry::typeName()
1478 PHP_METHOD(Geometry, typeName)
1480 GEOSGeometry *this;
1481 char *typ;
1482 char *typVal;
1484 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1486 /* TODO: define constant strings instead... */
1488 typ = GEOSGeomType(this);
1489 if ( ! typ ) RETURN_NULL(); /* should get an exception first */
1491 typVal = estrdup(typ);
1492 GEOSFree(typ);
1494 RETURN_STRING(typVal, 0);
1498 * long GEOSGeometry::typeId()
1500 PHP_METHOD(Geometry, typeId)
1502 GEOSGeometry *this;
1503 long typ;
1505 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1507 /* TODO: define constant strings instead... */
1509 typ = GEOSGeomTypeId(this);
1510 if ( typ == -1 ) RETURN_NULL(); /* should get an exception first */
1512 RETURN_LONG(typ);
1516 * long GEOSGeometry::getSRID()
1518 PHP_METHOD(Geometry, getSRID)
1520 GEOSGeometry *geom;
1521 long int ret;
1523 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1525 ret = GEOSGetSRID(geom);
1527 RETURN_LONG(ret);
1531 * void GEOSGeometry::setSRID(long)
1533 PHP_METHOD(Geometry, setSRID)
1535 GEOSGeometry *geom;
1536 long int srid;
1538 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1540 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1541 &srid) == FAILURE) {
1542 RETURN_NULL();
1545 GEOSSetSRID(geom, srid);
1549 * long GEOSGeometry::numGeometries()
1551 PHP_METHOD(Geometry, numGeometries)
1553 GEOSGeometry *geom;
1554 long int ret;
1556 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1558 ret = GEOSGetNumGeometries(geom);
1559 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1561 RETURN_LONG(ret);
1565 * GEOSGeometry GEOSGeometry::getGeometryN()
1567 PHP_METHOD(Geometry, getGeometryN)
1569 GEOSGeometry *geom;
1570 const GEOSGeometry *c;
1571 GEOSGeometry *cc;
1572 long int num;
1574 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1576 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1577 &num) == FAILURE) {
1578 RETURN_NULL();
1581 c = GEOSGetGeometryN(geom, num);
1582 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1583 cc = GEOSGeom_clone(c);
1584 if ( ! cc ) RETURN_NULL(); /* should get an exception first */
1586 object_init_ex(return_value, Geometry_ce_ptr);
1587 setRelay(return_value, cc);
1591 * long GEOSGeometry::numInteriorRings()
1593 PHP_METHOD(Geometry, numInteriorRings)
1595 GEOSGeometry *geom;
1596 long int ret;
1598 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1600 ret = GEOSGetNumInteriorRings(geom);
1601 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1603 RETURN_LONG(ret);
1608 /* ------ Initialization / Deinitialization / Meta ------------------ */
1610 /* per-module initialization */
1611 PHP_MINIT_FUNCTION(geos)
1613 zend_class_entry ce;
1615 /* WKTReader */
1616 INIT_CLASS_ENTRY(ce, "GEOSWKTReader", WKTReader_methods);
1617 WKTReader_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
1618 WKTReader_ce_ptr->create_object = WKTReader_create_obj;
1619 memcpy(&WKTReader_object_handlers,
1620 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1621 WKTReader_object_handlers.clone_obj = NULL;
1623 /* WKTWriter */
1624 INIT_CLASS_ENTRY(ce, "GEOSWKTWriter", WKTWriter_methods);
1625 WKTWriter_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
1626 WKTWriter_ce_ptr->create_object = WKTWriter_create_obj;
1627 memcpy(&WKTWriter_object_handlers,
1628 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1629 WKTWriter_object_handlers.clone_obj = NULL;
1631 /* Geometry */
1632 INIT_CLASS_ENTRY(ce, "GEOSGeometry", Geometry_methods);
1633 Geometry_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
1634 Geometry_ce_ptr->create_object = Geometry_create_obj;
1635 memcpy(&Geometry_object_handlers,
1636 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1637 Geometry_object_handlers.clone_obj = NULL;
1639 /* Constants */
1640 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_ROUND", GEOSBUF_CAP_ROUND,
1641 CONST_CS|CONST_PERSISTENT);
1642 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_FLAT", GEOSBUF_CAP_FLAT,
1643 CONST_CS|CONST_PERSISTENT);
1644 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_SQUARE", GEOSBUF_CAP_SQUARE,
1645 CONST_CS|CONST_PERSISTENT);
1646 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_ROUND", GEOSBUF_JOIN_ROUND,
1647 CONST_CS|CONST_PERSISTENT);
1648 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_MITRE", GEOSBUF_JOIN_MITRE,
1649 CONST_CS|CONST_PERSISTENT);
1650 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_BEVEL", GEOSBUF_JOIN_BEVEL,
1651 CONST_CS|CONST_PERSISTENT);
1653 REGISTER_LONG_CONSTANT("GEOS_POINT", GEOS_POINT,
1654 CONST_CS|CONST_PERSISTENT);
1655 REGISTER_LONG_CONSTANT("GEOS_LINESTRING", GEOS_LINESTRING,
1656 CONST_CS|CONST_PERSISTENT);
1657 REGISTER_LONG_CONSTANT("GEOS_LINEARRING", GEOS_LINEARRING,
1658 CONST_CS|CONST_PERSISTENT);
1659 REGISTER_LONG_CONSTANT("GEOS_POLYGON", GEOS_POLYGON,
1660 CONST_CS|CONST_PERSISTENT);
1661 REGISTER_LONG_CONSTANT("GEOS_MULTIPOINT", GEOS_MULTIPOINT,
1662 CONST_CS|CONST_PERSISTENT);
1663 REGISTER_LONG_CONSTANT("GEOS_MULTILINESTRING", GEOS_MULTILINESTRING,
1664 CONST_CS|CONST_PERSISTENT);
1665 REGISTER_LONG_CONSTANT("GEOS_MULTIPOLYGON", GEOS_MULTIPOLYGON,
1666 CONST_CS|CONST_PERSISTENT);
1667 REGISTER_LONG_CONSTANT("GEOS_GEOMETRYCOLLECTION", GEOS_GEOMETRYCOLLECTION,
1668 CONST_CS|CONST_PERSISTENT);
1670 return SUCCESS;
1673 /* per-request initialization */
1674 PHP_RINIT_FUNCTION(geos)
1676 initGEOS(noticeHandler, errorHandler);
1677 return SUCCESS;
1680 /* pre-request destruction */
1681 PHP_RSHUTDOWN_FUNCTION(geos)
1683 finishGEOS();
1684 return SUCCESS;
1687 /* module info */
1688 PHP_MINFO_FUNCTION(geos)
1690 php_info_print_table_start();
1691 php_info_print_table_row(2,
1692 "GEOS - Geometry Engine Open Source", "enabled");
1693 php_info_print_table_row(2,
1694 "Version", PHP_GEOS_VERSION);
1695 php_info_print_table_end();