Expose Geometry.voronoiDiagram in PHP interface
[geos.git] / php / geos.c
blob316898455ec967dfd0c42889876d784ecd9e80c1
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_MSHUTDOWN_FUNCTION(geos);
38 PHP_RINIT_FUNCTION(geos);
39 PHP_RSHUTDOWN_FUNCTION(geos);
40 PHP_MINFO_FUNCTION(geos);
41 PHP_FUNCTION(GEOSVersion);
42 PHP_FUNCTION(GEOSPolygonize);
43 PHP_FUNCTION(GEOSLineMerge);
44 PHP_FUNCTION(GEOSSharedPaths);
45 PHP_FUNCTION(GEOSRelateMatch);
47 #if PHP_VERSION_ID < 50399
48 #define zend_function_entry function_entry
49 #endif
51 static zend_function_entry geos_functions[] = {
52 PHP_FE(GEOSVersion, NULL)
53 PHP_FE(GEOSPolygonize, NULL)
54 PHP_FE(GEOSLineMerge, NULL)
55 PHP_FE(GEOSSharedPaths, NULL)
56 PHP_FE(GEOSRelateMatch, NULL)
57 {NULL, NULL, NULL}
60 zend_module_entry geos_module_entry = {
61 STANDARD_MODULE_HEADER,
62 PHP_GEOS_EXTNAME,
63 geos_functions,
64 PHP_MINIT(geos), /* module init function */
65 PHP_MSHUTDOWN(geos), /* module shutdown function */
66 PHP_RINIT(geos), /* request init function */
67 PHP_RSHUTDOWN(geos), /* request shutdown function */
68 PHP_MINFO(geos), /* module info function */
69 PHP_GEOS_VERSION,
70 STANDARD_MODULE_PROPERTIES
73 #ifdef COMPILE_DL_GEOS
74 ZEND_GET_MODULE(geos)
75 #endif
77 /* -- Utility functions ---------------------- */
79 static void noticeHandler(const char *fmt, ...)
81 char message[256];
82 va_list args;
83 va_start(args, fmt);
84 vsnprintf(message, sizeof(message) - 1, fmt, args);
85 va_end(args);
87 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s", message);
90 static void errorHandler(const char *fmt, ...)
92 char message[256];
93 va_list args;
94 va_start(args, fmt);
95 vsnprintf(message, sizeof(message) - 1, fmt, args);
96 va_end(args);
98 /* TODO: use a GEOSException ? */
99 zend_throw_exception_ex(zend_exception_get_default(TSRMLS_CC),
100 1 TSRMLS_CC, "%s", message);
104 typedef struct Proxy_t {
105 zend_object std;
106 void* relay;
107 } Proxy;
109 static void
110 setRelay(zval* val, void* obj) {
111 Proxy* proxy = (Proxy*)zend_object_store_get_object(val TSRMLS_CC);
112 proxy->relay = obj;
115 static inline void *
116 getRelay(zval* val, zend_class_entry* ce) {
117 Proxy *proxy = (Proxy*)zend_object_store_get_object(val TSRMLS_CC);
118 if ( proxy->std.ce != ce ) {
119 php_error_docref(NULL TSRMLS_CC, E_ERROR,
120 "Relay object is not an %s", ce->name);
122 if ( ! proxy->relay ) {
123 php_error_docref(NULL TSRMLS_CC, E_ERROR,
124 "Relay object for object of type %s is not set", ce->name);
126 return proxy->relay;
129 static long getZvalAsLong(zval* val)
131 long ret;
132 zval tmp;
134 tmp = *val;
135 zval_copy_ctor(&tmp);
136 convert_to_long(&tmp);
137 ret = Z_LVAL(tmp);
138 zval_dtor(&tmp);
139 return ret;
142 static long getZvalAsDouble(zval* val)
144 double ret;
145 zval tmp;
147 tmp = *val;
148 zval_copy_ctor(&tmp);
149 convert_to_double(&tmp);
150 ret = Z_DVAL(tmp);
151 zval_dtor(&tmp);
152 return ret;
155 static zend_object_value
156 Gen_create_obj (zend_class_entry *type TSRMLS_DC,
157 zend_objects_free_object_storage_t st, zend_object_handlers* handlers)
159 zval *tmp;
160 zend_object_value retval;
162 Proxy *obj = (Proxy *)emalloc(sizeof(Proxy));
163 memset(obj, 0, sizeof(Proxy));
164 obj->std.ce = type;
166 ALLOC_HASHTABLE(obj->std.properties);
167 zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
168 #if PHP_VERSION_ID < 50399
169 zend_hash_copy(obj->std.properties, &type->default_properties,
170 (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
171 #else
172 object_properties_init(&(obj->std), type);
173 #endif
175 retval.handle = zend_objects_store_put(obj, NULL, st, NULL TSRMLS_CC);
176 retval.handlers = handlers;
178 return retval;
182 /* -- class GEOSGeometry -------------------- */
184 PHP_METHOD(Geometry, __construct);
185 PHP_METHOD(Geometry, __toString);
186 PHP_METHOD(Geometry, project);
187 PHP_METHOD(Geometry, interpolate);
188 PHP_METHOD(Geometry, buffer);
189 PHP_METHOD(Geometry, offsetCurve);
190 PHP_METHOD(Geometry, envelope);
191 PHP_METHOD(Geometry, intersection);
192 PHP_METHOD(Geometry, convexHull);
193 PHP_METHOD(Geometry, difference);
194 PHP_METHOD(Geometry, symDifference);
195 PHP_METHOD(Geometry, boundary);
196 PHP_METHOD(Geometry, union); /* also does union cascaded */
197 PHP_METHOD(Geometry, pointOnSurface);
198 PHP_METHOD(Geometry, centroid);
199 PHP_METHOD(Geometry, relate);
200 PHP_METHOD(Geometry, relateBoundaryNodeRule);
201 PHP_METHOD(Geometry, simplify); /* also does topology-preserving */
202 PHP_METHOD(Geometry, extractUniquePoints);
203 PHP_METHOD(Geometry, disjoint);
204 PHP_METHOD(Geometry, touches);
205 PHP_METHOD(Geometry, intersects);
206 PHP_METHOD(Geometry, crosses);
207 PHP_METHOD(Geometry, within);
208 PHP_METHOD(Geometry, contains);
209 PHP_METHOD(Geometry, overlaps);
210 PHP_METHOD(Geometry, covers);
211 PHP_METHOD(Geometry, coveredBy);
212 PHP_METHOD(Geometry, equals);
213 PHP_METHOD(Geometry, equalsExact);
214 PHP_METHOD(Geometry, isEmpty);
215 PHP_METHOD(Geometry, checkValidity);
216 PHP_METHOD(Geometry, isSimple);
217 PHP_METHOD(Geometry, isRing);
218 PHP_METHOD(Geometry, hasZ);
219 PHP_METHOD(Geometry, isClosed);
220 PHP_METHOD(Geometry, typeName);
221 PHP_METHOD(Geometry, typeId);
222 PHP_METHOD(Geometry, getSRID);
223 PHP_METHOD(Geometry, setSRID);
224 PHP_METHOD(Geometry, numGeometries);
225 PHP_METHOD(Geometry, geometryN);
226 PHP_METHOD(Geometry, numInteriorRings);
227 PHP_METHOD(Geometry, numPoints);
228 PHP_METHOD(Geometry, getX);
229 PHP_METHOD(Geometry, getY);
230 PHP_METHOD(Geometry, interiorRingN);
231 PHP_METHOD(Geometry, exteriorRing);
232 PHP_METHOD(Geometry, numCoordinates);
233 PHP_METHOD(Geometry, dimension);
234 PHP_METHOD(Geometry, coordinateDimension);
235 PHP_METHOD(Geometry, pointN);
236 PHP_METHOD(Geometry, startPoint);
237 PHP_METHOD(Geometry, endPoint);
238 PHP_METHOD(Geometry, area);
239 PHP_METHOD(Geometry, length);
240 PHP_METHOD(Geometry, distance);
241 PHP_METHOD(Geometry, hausdorffDistance);
242 PHP_METHOD(Geometry, snapTo);
243 PHP_METHOD(Geometry, node);
244 PHP_METHOD(Geometry, delaunayTriangulation);
245 PHP_METHOD(Geometry, voronoiDiagram);
247 static zend_function_entry Geometry_methods[] = {
248 PHP_ME(Geometry, __construct, NULL, 0)
249 PHP_ME(Geometry, __toString, NULL, 0)
250 PHP_ME(Geometry, project, NULL, 0)
251 PHP_ME(Geometry, interpolate, NULL, 0)
252 PHP_ME(Geometry, buffer, NULL, 0)
253 PHP_ME(Geometry, offsetCurve, NULL, 0)
254 PHP_ME(Geometry, envelope, NULL, 0)
255 PHP_ME(Geometry, intersection, NULL, 0)
256 PHP_ME(Geometry, convexHull, NULL, 0)
257 PHP_ME(Geometry, difference, NULL, 0)
258 PHP_ME(Geometry, symDifference, NULL, 0)
259 PHP_ME(Geometry, boundary, NULL, 0)
260 PHP_ME(Geometry, union, NULL, 0)
261 PHP_ME(Geometry, pointOnSurface, NULL, 0)
262 PHP_ME(Geometry, centroid, NULL, 0)
263 PHP_ME(Geometry, relate, NULL, 0)
264 PHP_ME(Geometry, relateBoundaryNodeRule, NULL, 0)
265 PHP_ME(Geometry, simplify, NULL, 0)
266 PHP_ME(Geometry, extractUniquePoints, NULL, 0)
267 PHP_ME(Geometry, disjoint, NULL, 0)
268 PHP_ME(Geometry, touches, NULL, 0)
269 PHP_ME(Geometry, intersects, NULL, 0)
270 PHP_ME(Geometry, crosses, NULL, 0)
271 PHP_ME(Geometry, within, NULL, 0)
272 PHP_ME(Geometry, contains, NULL, 0)
273 PHP_ME(Geometry, overlaps, NULL, 0)
274 PHP_ME(Geometry, covers, NULL, 0)
275 PHP_ME(Geometry, coveredBy, NULL, 0)
276 PHP_ME(Geometry, equals, NULL, 0)
277 PHP_ME(Geometry, equalsExact, NULL, 0)
278 PHP_ME(Geometry, isEmpty, NULL, 0)
279 PHP_ME(Geometry, checkValidity, NULL, 0)
280 PHP_ME(Geometry, isSimple, NULL, 0)
281 PHP_ME(Geometry, isRing, NULL, 0)
282 PHP_ME(Geometry, hasZ, NULL, 0)
283 PHP_ME(Geometry, isClosed, NULL, 0)
284 PHP_ME(Geometry, typeName, NULL, 0)
285 PHP_ME(Geometry, typeId, NULL, 0)
286 PHP_ME(Geometry, getSRID, NULL, 0)
287 PHP_ME(Geometry, setSRID, NULL, 0)
288 PHP_ME(Geometry, numGeometries, NULL, 0)
289 PHP_ME(Geometry, geometryN, NULL, 0)
290 PHP_ME(Geometry, numInteriorRings, NULL, 0)
291 PHP_ME(Geometry, numPoints, NULL, 0)
292 PHP_ME(Geometry, getX, NULL, 0)
293 PHP_ME(Geometry, getY, NULL, 0)
294 PHP_ME(Geometry, interiorRingN, NULL, 0)
295 PHP_ME(Geometry, exteriorRing, NULL, 0)
296 PHP_ME(Geometry, numCoordinates, NULL, 0)
297 PHP_ME(Geometry, dimension, NULL, 0)
298 PHP_ME(Geometry, coordinateDimension, NULL, 0)
299 PHP_ME(Geometry, pointN, NULL, 0)
300 PHP_ME(Geometry, startPoint, NULL, 0)
301 PHP_ME(Geometry, endPoint, NULL, 0)
302 PHP_ME(Geometry, area, NULL, 0)
303 PHP_ME(Geometry, length, NULL, 0)
304 PHP_ME(Geometry, distance, NULL, 0)
305 PHP_ME(Geometry, hausdorffDistance, NULL, 0)
306 PHP_ME(Geometry, snapTo, NULL, 0)
307 PHP_ME(Geometry, node, NULL, 0)
308 PHP_ME(Geometry, delaunayTriangulation, NULL, 0)
309 PHP_ME(Geometry, voronoiDiagram, NULL, 0)
310 {NULL, NULL, NULL}
313 static zend_class_entry *Geometry_ce_ptr;
315 static zend_object_handlers Geometry_object_handlers;
317 /* Geometry serializer */
319 static GEOSWKBWriter* Geometry_serializer = 0;
321 static GEOSWKBWriter* getGeometrySerializer()
323 if ( ! Geometry_serializer ) {
324 Geometry_serializer = GEOSWKBWriter_create();
325 GEOSWKBWriter_setIncludeSRID(Geometry_serializer, 1);
326 GEOSWKBWriter_setOutputDimension(Geometry_serializer, 3);
328 return Geometry_serializer;
331 static void delGeometrySerializer()
333 if ( Geometry_serializer ) {
334 GEOSWKBWriter_destroy(Geometry_serializer);
338 /* Geometry deserializer */
340 static GEOSWKBReader* Geometry_deserializer = 0;
342 static GEOSWKBReader* getGeometryDeserializer()
344 if ( ! Geometry_deserializer ) {
345 Geometry_deserializer = GEOSWKBReader_create();
347 return Geometry_deserializer;
350 static void delGeometryDeserializer()
352 if ( Geometry_deserializer ) {
353 GEOSWKBReader_destroy(Geometry_deserializer);
357 /* Serializer function for GEOSGeometry */
359 static int
360 Geometry_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len,
361 zend_serialize_data *data TSRMLS_DC)
363 GEOSWKBWriter *serializer;
364 GEOSGeometry *geom;
365 char* ret;
366 size_t retsize;
369 serializer = getGeometrySerializer();
370 geom = (GEOSGeometry*)getRelay(object, Geometry_ce_ptr);
372 /* NOTE: we might be fine using binary here */
373 ret = (char*)GEOSWKBWriter_writeHEX(serializer, geom, &retsize);
374 /* we'll probably get an exception if ret is null */
375 if ( ! ret ) return FAILURE;
377 *buffer = (unsigned char*)estrndup(ret, retsize);
378 GEOSFree(ret);
380 *buf_len = retsize;
382 return SUCCESS;
385 static int
386 Geometry_deserialize(zval **object, zend_class_entry *ce, const unsigned char *buf,
387 zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
389 GEOSWKBReader* deserializer;
390 GEOSGeometry* geom;
392 deserializer = getGeometryDeserializer();
393 geom = GEOSWKBReader_readHEX(deserializer, buf, buf_len);
395 /* TODO: check zend_class_entry being what we expect! */
396 if ( ce != Geometry_ce_ptr ) {
397 php_error_docref(NULL TSRMLS_CC, E_ERROR,
398 "Geometry_deserialize called with unexpected zend_class_entry");
399 return FAILURE;
401 object_init_ex(*object, ce);
402 setRelay(*object, geom);
404 return SUCCESS;
408 * Push components of the given geometry
409 * to the given array zval.
410 * Components geometries are cloned.
411 * NOTE: collection components are not descended into
413 static void
414 dumpGeometry(GEOSGeometry* g, zval* array)
416 int ngeoms, i;
419 MAKE_STD_ZVAL(array);
420 array_init(array);
423 ngeoms = GEOSGetNumGeometries(g);
424 for (i=0; i<ngeoms; ++i)
426 zval *tmp;
427 GEOSGeometry* cc;
428 const GEOSGeometry* c = GEOSGetGeometryN(g, i);
429 if ( ! c ) continue; /* should get an exception */
430 /* we _need_ to clone as this one is owned by 'g' */
431 cc = GEOSGeom_clone(c);
432 if ( ! cc ) continue; /* should get an exception */
434 MAKE_STD_ZVAL(tmp);
435 object_init_ex(tmp, Geometry_ce_ptr);
436 setRelay(tmp, cc);
437 add_next_index_zval(array, tmp);
442 static void
443 Geometry_dtor (void *object TSRMLS_DC)
445 Proxy *obj = (Proxy *)object;
446 GEOSGeom_destroy((GEOSGeometry*)obj->relay);
448 zend_hash_destroy(obj->std.properties);
449 FREE_HASHTABLE(obj->std.properties);
451 efree(obj);
454 static zend_object_value
455 Geometry_create_obj (zend_class_entry *type TSRMLS_DC)
457 return Gen_create_obj(type, Geometry_dtor, &Geometry_object_handlers);
461 PHP_METHOD(Geometry, __construct)
463 php_error_docref(NULL TSRMLS_CC, E_ERROR,
464 "GEOSGeometry can't be constructed using new, check WKTReader");
468 PHP_METHOD(Geometry, __toString)
470 GEOSGeometry *geom;
471 GEOSWKTWriter *writer;
472 char *wkt;
473 char *ret;
475 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
476 writer = GEOSWKTWriter_create();
477 /* NOTE: if we get an exception before reaching
478 * GEOSWKTWriter_destory below we'll be leaking memory.
479 * One fix could be storing the object in a refcounted
480 * zval.
482 GEOSWKTWriter_setTrim(writer, 1);
484 wkt = GEOSWKTWriter_write(writer, geom);
485 /* we'll probably get an exception if wkt is null */
486 if ( ! wkt ) RETURN_NULL();
488 GEOSWKTWriter_destroy(writer);
491 ret = estrdup(wkt);
492 GEOSFree(wkt);
494 RETURN_STRING(ret, 0);
497 PHP_METHOD(Geometry, project)
499 GEOSGeometry *this;
500 GEOSGeometry *other;
501 zval *zobj;
502 zend_bool normalized = 0;
503 double ret;
505 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
507 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|b", &zobj,
508 &normalized) == FAILURE) {
509 RETURN_NULL();
511 other = getRelay(zobj, Geometry_ce_ptr);
513 if ( normalized ) {
514 ret = GEOSProjectNormalized(this, other);
515 } else {
516 ret = GEOSProject(this, other);
518 if ( ret < 0 ) RETURN_NULL(); /* should get an exception first */
520 RETURN_DOUBLE(ret);
523 PHP_METHOD(Geometry, interpolate)
525 GEOSGeometry *this;
526 double dist;
527 GEOSGeometry *ret;
528 zend_bool normalized = 0;
530 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
532 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|b",
533 &dist, &normalized) == FAILURE) {
534 RETURN_NULL();
537 if ( normalized ) {
538 ret = GEOSInterpolateNormalized(this, dist);
539 } else {
540 ret = GEOSInterpolate(this, dist);
542 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
544 /* return_value is a zval */
545 object_init_ex(return_value, Geometry_ce_ptr);
546 setRelay(return_value, ret);
550 * GEOSGeometry::buffer(dist, [<styleArray>])
552 * styleArray keys supported:
553 * 'quad_segs'
554 * Type: int
555 * Number of segments used to approximate
556 * a quarter circle (defaults to 8).
557 * 'endcap'
558 * Type: long
559 * Endcap style (defaults to GEOSBUF_CAP_ROUND)
560 * 'join'
561 * Type: long
562 * Join style (defaults to GEOSBUF_JOIN_ROUND)
563 * 'mitre_limit'
564 * Type: double
565 * mitre ratio limit (only affects joins with GEOSBUF_JOIN_MITRE style)
566 * 'miter_limit' is also accepted as a synonym for 'mitre_limit'.
567 * 'single_sided'
568 * Type: bool
569 * If true buffer lines only on one side, so that the input line
570 * will be a portion of the boundary of the returned polygon.
571 * Only applies to lineal input. Defaults to false.
573 PHP_METHOD(Geometry, buffer)
575 GEOSGeometry *this;
576 double dist;
577 GEOSGeometry *ret;
578 GEOSBufferParams *params;
579 static const double default_mitreLimit = 5.0;
580 static const int default_endCapStyle = GEOSBUF_CAP_ROUND;
581 static const int default_joinStyle = GEOSBUF_JOIN_ROUND;
582 static const int default_quadSegs = 8;
583 long int quadSegs = default_quadSegs;
584 long int endCapStyle = default_endCapStyle;
585 long int joinStyle = default_joinStyle;
586 double mitreLimit = default_mitreLimit;
587 long singleSided = 0;
588 zval *style_val = NULL;
589 zval **data;
590 HashTable *style;
591 char *key;
592 ulong index;
594 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
596 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|a",
597 &dist, &style_val) == FAILURE) {
598 RETURN_NULL();
601 params = GEOSBufferParams_create();
603 if ( style_val )
605 style = HASH_OF(style_val);
606 while(zend_hash_get_current_key(style, &key, &index, 0)
607 == HASH_KEY_IS_STRING)
609 if(!strcmp(key, "quad_segs"))
611 zend_hash_get_current_data(style, (void**)&data);
612 quadSegs = getZvalAsLong(*data);
613 GEOSBufferParams_setQuadrantSegments(params, quadSegs);
615 else if(!strcmp(key, "endcap"))
617 zend_hash_get_current_data(style, (void**)&data);
618 endCapStyle = getZvalAsLong(*data);
619 GEOSBufferParams_setEndCapStyle(params, endCapStyle);
621 else if(!strcmp(key, "join"))
623 zend_hash_get_current_data(style, (void**)&data);
624 joinStyle = getZvalAsLong(*data);
625 GEOSBufferParams_setJoinStyle(params, joinStyle);
627 else if(!strcmp(key, "mitre_limit"))
629 zend_hash_get_current_data(style, (void**)&data);
630 mitreLimit = getZvalAsDouble(*data);
631 GEOSBufferParams_setMitreLimit(params, mitreLimit);
633 else if(!strcmp(key, "single_sided"))
635 zend_hash_get_current_data(style, (void**)&data);
636 singleSided = getZvalAsLong(*data);
637 GEOSBufferParams_setSingleSided(params, singleSided);
640 zend_hash_move_forward(style);
644 ret = GEOSBufferWithParams(this, params, dist);
645 GEOSBufferParams_destroy(params);
646 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
648 /* return_value is a zval */
649 object_init_ex(return_value, Geometry_ce_ptr);
650 setRelay(return_value, ret);
654 * GEOSGeometry::offsetCurve(dist, [<styleArray>])
656 * styleArray keys supported:
657 * 'quad_segs'
658 * Type: int
659 * Number of segments used to approximate
660 * a quarter circle (defaults to 8).
661 * 'join'
662 * Type: long
663 * Join style (defaults to GEOSBUF_JOIN_ROUND)
664 * 'mitre_limit'
665 * Type: double
666 * mitre ratio limit (only affects joins with GEOSBUF_JOIN_MITRE style)
667 * 'miter_limit' is also accepted as a synonym for 'mitre_limit'.
669 PHP_METHOD(Geometry, offsetCurve)
671 GEOSGeometry *this;
672 double dist;
673 GEOSGeometry *ret;
674 static const double default_mitreLimit = 5.0;
675 static const int default_joinStyle = GEOSBUF_JOIN_ROUND;
676 static const int default_quadSegs = 8;
677 long int quadSegs = default_quadSegs;
678 long int joinStyle = default_joinStyle;
679 double mitreLimit = default_mitreLimit;
680 zval *style_val = NULL;
681 zval **data;
682 HashTable *style;
683 char *key;
684 ulong index;
686 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
688 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|a",
689 &dist, &style_val) == FAILURE) {
690 RETURN_NULL();
693 if ( style_val )
695 style = HASH_OF(style_val);
696 while(zend_hash_get_current_key(style, &key, &index, 0)
697 == HASH_KEY_IS_STRING)
699 if(!strcmp(key, "quad_segs"))
701 zend_hash_get_current_data(style, (void**)&data);
702 quadSegs = getZvalAsLong(*data);
704 else if(!strcmp(key, "join"))
706 zend_hash_get_current_data(style, (void**)&data);
707 joinStyle = getZvalAsLong(*data);
709 else if(!strcmp(key, "mitre_limit"))
711 zend_hash_get_current_data(style, (void**)&data);
712 mitreLimit = getZvalAsDouble(*data);
715 zend_hash_move_forward(style);
719 ret = GEOSOffsetCurve(this, dist, quadSegs, joinStyle, mitreLimit);
720 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
722 /* return_value is a zval */
723 object_init_ex(return_value, Geometry_ce_ptr);
724 setRelay(return_value, ret);
727 PHP_METHOD(Geometry, envelope)
729 GEOSGeometry *this;
730 GEOSGeometry *ret;
732 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
734 ret = GEOSEnvelope(this);
735 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
737 /* return_value is a zval */
738 object_init_ex(return_value, Geometry_ce_ptr);
739 setRelay(return_value, ret);
742 PHP_METHOD(Geometry, intersection)
744 GEOSGeometry *this;
745 GEOSGeometry *other;
746 GEOSGeometry *ret;
747 zval *zobj;
749 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
751 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
752 == FAILURE) {
753 RETURN_NULL();
755 other = getRelay(zobj, Geometry_ce_ptr);
757 ret = GEOSIntersection(this, other);
758 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
760 /* return_value is a zval */
761 object_init_ex(return_value, Geometry_ce_ptr);
762 setRelay(return_value, ret);
765 PHP_METHOD(Geometry, convexHull)
767 GEOSGeometry *this;
768 GEOSGeometry *ret;
770 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
772 ret = GEOSConvexHull(this);
773 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
775 /* return_value is a zval */
776 object_init_ex(return_value, Geometry_ce_ptr);
777 setRelay(return_value, ret);
780 PHP_METHOD(Geometry, difference)
782 GEOSGeometry *this;
783 GEOSGeometry *other;
784 GEOSGeometry *ret;
785 zval *zobj;
787 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
789 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
790 == FAILURE) {
791 RETURN_NULL();
793 other = getRelay(zobj, Geometry_ce_ptr);
795 ret = GEOSDifference(this, other);
796 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
798 /* return_value is a zval */
799 object_init_ex(return_value, Geometry_ce_ptr);
800 setRelay(return_value, ret);
803 PHP_METHOD(Geometry, symDifference)
805 GEOSGeometry *this;
806 GEOSGeometry *other;
807 GEOSGeometry *ret;
808 zval *zobj;
810 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
812 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
813 == FAILURE) {
814 RETURN_NULL();
816 other = getRelay(zobj, Geometry_ce_ptr);
818 ret = GEOSSymDifference(this, other);
819 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
821 /* return_value is a zval */
822 object_init_ex(return_value, Geometry_ce_ptr);
823 setRelay(return_value, ret);
826 PHP_METHOD(Geometry, boundary)
828 GEOSGeometry *this;
829 GEOSGeometry *ret;
831 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
833 ret = GEOSBoundary(this);
834 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
836 /* return_value is a zval */
837 object_init_ex(return_value, Geometry_ce_ptr);
838 setRelay(return_value, ret);
842 * GEOSGeometry::union(otherGeom)
843 * GEOSGeometry::union()
845 PHP_METHOD(Geometry, union)
847 GEOSGeometry *this;
848 GEOSGeometry *other;
849 GEOSGeometry *ret;
850 zval *zobj = NULL;
852 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
854 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o", &zobj)
855 == FAILURE) {
856 RETURN_NULL();
859 if ( zobj ) {
860 other = getRelay(zobj, Geometry_ce_ptr);
861 ret = GEOSUnion(this, other);
862 } else {
863 ret = GEOSUnaryUnion(this);
866 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
868 /* return_value is a zval */
869 object_init_ex(return_value, Geometry_ce_ptr);
870 setRelay(return_value, ret);
874 * GEOSGeometry::pointOnSurface()
876 PHP_METHOD(Geometry, pointOnSurface)
878 GEOSGeometry *this;
879 GEOSGeometry *ret;
881 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
883 ret = GEOSPointOnSurface(this);
884 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
886 /* return_value is a zval */
887 object_init_ex(return_value, Geometry_ce_ptr);
888 setRelay(return_value, ret);
892 * GEOSGeometry::centroid()
894 PHP_METHOD(Geometry, centroid)
896 GEOSGeometry *this;
897 GEOSGeometry *ret;
899 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
901 ret = GEOSGetCentroid(this);
902 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
904 /* return_value is a zval */
905 object_init_ex(return_value, Geometry_ce_ptr);
906 setRelay(return_value, ret);
910 * GEOSGeometry::relate(otherGeom)
911 * GEOSGeometry::relate(otherGeom, pattern)
913 PHP_METHOD(Geometry, relate)
915 GEOSGeometry *this;
916 GEOSGeometry *other;
917 zval *zobj;
918 char* pat = NULL;
919 int patlen;
920 int retInt;
921 zend_bool retBool;
922 char* retStr;
924 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
926 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|s",
927 &zobj, &pat, &patlen) == FAILURE)
929 RETURN_NULL();
932 other = getRelay(zobj, Geometry_ce_ptr);
934 if ( ! pat ) {
935 /* we'll compute it */
936 pat = GEOSRelate(this, other);
937 if ( ! pat ) RETURN_NULL(); /* should get an exception first */
938 retStr = estrdup(pat);
939 GEOSFree(pat);
940 RETURN_STRING(retStr, 0);
941 } else {
942 retInt = GEOSRelatePattern(this, other, pat);
943 if ( retInt == 2 ) RETURN_NULL(); /* should get an exception first */
944 retBool = retInt;
945 RETURN_BOOL(retBool);
951 * GEOSGeometry::relateBoundaryNodeRule(otherGeom, rule)
953 PHP_METHOD(Geometry, relateBoundaryNodeRule)
955 GEOSGeometry *this;
956 GEOSGeometry *other;
957 zval *zobj;
958 char* pat;
959 long int bnr = GEOSRELATE_BNR_OGC;
960 char* retStr;
962 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
964 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ol",
965 &zobj, &bnr) == FAILURE)
967 RETURN_NULL();
970 other = getRelay(zobj, Geometry_ce_ptr);
972 /* we'll compute it */
973 pat = GEOSRelateBoundaryNodeRule(this, other, bnr);
974 if ( ! pat ) RETURN_NULL(); /* should get an exception first */
975 retStr = estrdup(pat);
976 GEOSFree(pat);
977 RETURN_STRING(retStr, 0);
981 * GEOSGeometry GEOSGeometry::simplify(tolerance)
982 * GEOSGeometry GEOSGeometry::simplify(tolerance, preserveTopology)
984 PHP_METHOD(Geometry, simplify)
986 GEOSGeometry *this;
987 double tolerance;
988 zend_bool preserveTopology = 0;
989 GEOSGeometry *ret;
991 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
993 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|b",
994 &tolerance, &preserveTopology) == FAILURE) {
995 RETURN_NULL();
998 if ( preserveTopology ) {
999 ret = GEOSTopologyPreserveSimplify(this, tolerance);
1000 } else {
1001 ret = GEOSSimplify(this, tolerance);
1004 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1006 /* return_value is a zval */
1007 object_init_ex(return_value, Geometry_ce_ptr);
1008 setRelay(return_value, ret);
1012 * GEOSGeometry GEOSGeometry::extractUniquePoints()
1014 PHP_METHOD(Geometry, extractUniquePoints)
1016 GEOSGeometry *this;
1017 GEOSGeometry *ret;
1019 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1021 ret = GEOSGeom_extractUniquePoints(this);
1022 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
1024 /* return_value is a zval */
1025 object_init_ex(return_value, Geometry_ce_ptr);
1026 setRelay(return_value, ret);
1030 * bool GEOSGeometry::disjoint(GEOSGeometry)
1032 PHP_METHOD(Geometry, disjoint)
1034 GEOSGeometry *this;
1035 GEOSGeometry *other;
1036 int ret;
1037 zend_bool retBool;
1038 zval *zobj;
1040 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1042 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1043 == FAILURE) {
1044 RETURN_NULL();
1046 other = getRelay(zobj, Geometry_ce_ptr);
1048 ret = GEOSDisjoint(this, other);
1049 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1051 /* return_value is a zval */
1052 retBool = ret;
1053 RETURN_BOOL(retBool);
1057 * bool GEOSGeometry::touches(GEOSGeometry)
1059 PHP_METHOD(Geometry, touches)
1061 GEOSGeometry *this;
1062 GEOSGeometry *other;
1063 int ret;
1064 zend_bool retBool;
1065 zval *zobj;
1067 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1069 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1070 == FAILURE) {
1071 RETURN_NULL();
1073 other = getRelay(zobj, Geometry_ce_ptr);
1075 ret = GEOSTouches(this, other);
1076 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1078 /* return_value is a zval */
1079 retBool = ret;
1080 RETURN_BOOL(retBool);
1084 * bool GEOSGeometry::intersects(GEOSGeometry)
1086 PHP_METHOD(Geometry, intersects)
1088 GEOSGeometry *this;
1089 GEOSGeometry *other;
1090 int ret;
1091 zend_bool retBool;
1092 zval *zobj;
1094 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1096 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1097 == FAILURE) {
1098 RETURN_NULL();
1100 other = getRelay(zobj, Geometry_ce_ptr);
1102 ret = GEOSIntersects(this, other);
1103 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1105 /* return_value is a zval */
1106 retBool = ret;
1107 RETURN_BOOL(retBool);
1111 * bool GEOSGeometry::crosses(GEOSGeometry)
1113 PHP_METHOD(Geometry, crosses)
1115 GEOSGeometry *this;
1116 GEOSGeometry *other;
1117 int ret;
1118 zend_bool retBool;
1119 zval *zobj;
1121 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1123 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1124 == FAILURE) {
1125 RETURN_NULL();
1127 other = getRelay(zobj, Geometry_ce_ptr);
1129 ret = GEOSCrosses(this, other);
1130 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1132 /* return_value is a zval */
1133 retBool = ret;
1134 RETURN_BOOL(retBool);
1138 * bool GEOSGeometry::within(GEOSGeometry)
1140 PHP_METHOD(Geometry, within)
1142 GEOSGeometry *this;
1143 GEOSGeometry *other;
1144 int ret;
1145 zend_bool retBool;
1146 zval *zobj;
1148 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1150 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1151 == FAILURE) {
1152 RETURN_NULL();
1154 other = getRelay(zobj, Geometry_ce_ptr);
1156 ret = GEOSWithin(this, other);
1157 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1159 /* return_value is a zval */
1160 retBool = ret;
1161 RETURN_BOOL(retBool);
1165 * bool GEOSGeometry::contains(GEOSGeometry)
1167 PHP_METHOD(Geometry, contains)
1169 GEOSGeometry *this;
1170 GEOSGeometry *other;
1171 int ret;
1172 zend_bool retBool;
1173 zval *zobj;
1175 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1177 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1178 == FAILURE) {
1179 RETURN_NULL();
1181 other = getRelay(zobj, Geometry_ce_ptr);
1183 ret = GEOSContains(this, other);
1184 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1186 /* return_value is a zval */
1187 retBool = ret;
1188 RETURN_BOOL(retBool);
1192 * bool GEOSGeometry::overlaps(GEOSGeometry)
1194 PHP_METHOD(Geometry, overlaps)
1196 GEOSGeometry *this;
1197 GEOSGeometry *other;
1198 int ret;
1199 zend_bool retBool;
1200 zval *zobj;
1202 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1204 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1205 == FAILURE) {
1206 RETURN_NULL();
1208 other = getRelay(zobj, Geometry_ce_ptr);
1210 ret = GEOSOverlaps(this, other);
1211 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1213 /* return_value is a zval */
1214 retBool = ret;
1215 RETURN_BOOL(retBool);
1219 * bool GEOSGeometry::covers(GEOSGeometry)
1221 PHP_METHOD(Geometry, covers)
1223 GEOSGeometry *this;
1224 GEOSGeometry *other;
1225 int ret;
1226 zend_bool retBool;
1227 zval *zobj;
1229 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1231 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1232 == FAILURE) {
1233 RETURN_NULL();
1235 other = getRelay(zobj, Geometry_ce_ptr);
1237 ret = GEOSCovers(this, other);
1238 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1240 /* return_value is a zval */
1241 retBool = ret;
1242 RETURN_BOOL(retBool);
1246 * bool GEOSGeometry::coveredBy(GEOSGeometry)
1248 PHP_METHOD(Geometry, coveredBy)
1250 GEOSGeometry *this;
1251 GEOSGeometry *other;
1252 int ret;
1253 zend_bool retBool;
1254 zval *zobj;
1256 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1258 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1259 == FAILURE) {
1260 RETURN_NULL();
1262 other = getRelay(zobj, Geometry_ce_ptr);
1264 ret = GEOSCoveredBy(this, other);
1265 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1267 /* return_value is a zval */
1268 retBool = ret;
1269 RETURN_BOOL(retBool);
1273 * bool GEOSGeometry::equals(GEOSGeometry)
1275 PHP_METHOD(Geometry, equals)
1277 GEOSGeometry *this;
1278 GEOSGeometry *other;
1279 int ret;
1280 zend_bool retBool;
1281 zval *zobj;
1283 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1285 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
1286 &zobj) == FAILURE) {
1287 RETURN_NULL();
1289 other = getRelay(zobj, Geometry_ce_ptr);
1291 ret = GEOSEquals(this, other);
1292 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1294 /* return_value is a zval */
1295 retBool = ret;
1296 RETURN_BOOL(retBool);
1300 * bool GEOSGeometry::equalsExact(GEOSGeometry)
1301 * bool GEOSGeometry::equalsExact(GEOSGeometry, double tolerance)
1303 PHP_METHOD(Geometry, equalsExact)
1305 GEOSGeometry *this;
1306 GEOSGeometry *other;
1307 int ret;
1308 double tolerance = 0;
1309 zend_bool retBool;
1310 zval *zobj;
1312 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1314 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|d",
1315 &zobj, &tolerance) == FAILURE) {
1316 RETURN_NULL();
1318 other = getRelay(zobj, Geometry_ce_ptr);
1320 ret = GEOSEqualsExact(this, other, tolerance);
1321 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1323 /* return_value is a zval */
1324 retBool = ret;
1325 RETURN_BOOL(retBool);
1329 * bool GEOSGeometry::isEmpty()
1331 PHP_METHOD(Geometry, isEmpty)
1333 GEOSGeometry *this;
1334 int ret;
1335 zend_bool retBool;
1337 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1339 ret = GEOSisEmpty(this);
1340 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1342 /* return_value is a zval */
1343 retBool = ret;
1344 RETURN_BOOL(retBool);
1348 * array GEOSGeometry::checkValidity()
1350 PHP_METHOD(Geometry, checkValidity)
1352 GEOSGeometry *this;
1353 GEOSGeometry *location = NULL;
1354 int ret;
1355 char *reason = NULL;
1356 zend_bool retBool;
1357 char *reasonVal = NULL;
1358 zval *locationVal = NULL;
1359 long int flags = 0;
1361 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1363 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l",
1364 &flags) == FAILURE) {
1365 RETURN_NULL();
1368 ret = GEOSisValidDetail(this, flags, &reason, &location);
1369 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1371 if ( reason ) {
1372 reasonVal = estrdup(reason);
1373 GEOSFree(reason);
1376 if ( location ) {
1377 MAKE_STD_ZVAL(locationVal);
1378 object_init_ex(locationVal, Geometry_ce_ptr);
1379 setRelay(locationVal, location);
1382 retBool = ret;
1384 /* return value is an array */
1385 array_init(return_value);
1386 add_assoc_bool(return_value, "valid", retBool);
1387 if ( reasonVal ) add_assoc_string(return_value, "reason", reasonVal, 0);
1388 if ( locationVal ) add_assoc_zval(return_value, "location", locationVal);
1393 * bool GEOSGeometry::isSimple()
1395 PHP_METHOD(Geometry, isSimple)
1397 GEOSGeometry *this;
1398 int ret;
1399 zend_bool retBool;
1401 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1403 ret = GEOSisSimple(this);
1404 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1406 /* return_value is a zval */
1407 retBool = ret;
1408 RETURN_BOOL(retBool);
1412 * bool GEOSGeometry::isRing()
1414 PHP_METHOD(Geometry, isRing)
1416 GEOSGeometry *this;
1417 int ret;
1418 zend_bool retBool;
1420 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1422 ret = GEOSisRing(this);
1423 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1425 /* return_value is a zval */
1426 retBool = ret;
1427 RETURN_BOOL(retBool);
1431 * bool GEOSGeometry::hasZ()
1433 PHP_METHOD(Geometry, hasZ)
1435 GEOSGeometry *this;
1436 int ret;
1437 zend_bool retBool;
1439 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1441 ret = GEOSHasZ(this);
1442 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1444 /* return_value is a zval */
1445 retBool = ret;
1446 RETURN_BOOL(retBool);
1450 * bool GEOSGeometry::isClosed()
1452 PHP_METHOD(Geometry, isClosed)
1454 GEOSGeometry *this;
1455 int ret;
1456 zend_bool retBool;
1458 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1460 ret = GEOSisClosed(this);
1461 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1463 /* return_value is a zval */
1464 retBool = ret;
1465 RETURN_BOOL(retBool);
1469 * string GEOSGeometry::typeName()
1471 PHP_METHOD(Geometry, typeName)
1473 GEOSGeometry *this;
1474 char *typ;
1475 char *typVal;
1477 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1479 /* TODO: define constant strings instead... */
1481 typ = GEOSGeomType(this);
1482 if ( ! typ ) RETURN_NULL(); /* should get an exception first */
1484 typVal = estrdup(typ);
1485 GEOSFree(typ);
1487 RETURN_STRING(typVal, 0);
1491 * long GEOSGeometry::typeId()
1493 PHP_METHOD(Geometry, typeId)
1495 GEOSGeometry *this;
1496 long typ;
1498 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1500 /* TODO: define constant strings instead... */
1502 typ = GEOSGeomTypeId(this);
1503 if ( typ == -1 ) RETURN_NULL(); /* should get an exception first */
1505 RETURN_LONG(typ);
1509 * long GEOSGeometry::getSRID()
1511 PHP_METHOD(Geometry, getSRID)
1513 GEOSGeometry *geom;
1514 long int ret;
1516 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1518 ret = GEOSGetSRID(geom);
1520 RETURN_LONG(ret);
1524 * void GEOSGeometry::setSRID(long)
1526 PHP_METHOD(Geometry, setSRID)
1528 GEOSGeometry *geom;
1529 long int srid;
1531 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1533 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1534 &srid) == FAILURE) {
1535 RETURN_NULL();
1538 GEOSSetSRID(geom, srid);
1542 * long GEOSGeometry::numGeometries()
1544 PHP_METHOD(Geometry, numGeometries)
1546 GEOSGeometry *geom;
1547 long int ret;
1549 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1551 ret = GEOSGetNumGeometries(geom);
1552 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1554 RETURN_LONG(ret);
1558 * GEOSGeometry GEOSGeometry::geometryN()
1560 PHP_METHOD(Geometry, geometryN)
1562 GEOSGeometry *geom;
1563 const GEOSGeometry *c;
1564 GEOSGeometry *cc;
1565 long int num;
1567 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1569 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1570 &num) == FAILURE) {
1571 RETURN_NULL();
1574 if ( num >= GEOSGetNumGeometries(geom) ) RETURN_NULL();
1575 c = GEOSGetGeometryN(geom, num);
1576 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1577 cc = GEOSGeom_clone(c);
1578 if ( ! cc ) RETURN_NULL(); /* should get an exception first */
1580 object_init_ex(return_value, Geometry_ce_ptr);
1581 setRelay(return_value, cc);
1585 * long GEOSGeometry::numInteriorRings()
1587 PHP_METHOD(Geometry, numInteriorRings)
1589 GEOSGeometry *geom;
1590 long int ret;
1592 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1594 ret = GEOSGetNumInteriorRings(geom);
1595 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1597 RETURN_LONG(ret);
1601 * long GEOSGeometry::numPoints()
1603 PHP_METHOD(Geometry, numPoints)
1605 GEOSGeometry *geom;
1606 long int ret;
1608 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1610 ret = GEOSGeomGetNumPoints(geom);
1611 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1613 RETURN_LONG(ret);
1617 * double GEOSGeometry::getX()
1619 PHP_METHOD(Geometry, getX)
1621 GEOSGeometry *geom;
1622 int ret;
1623 double x;
1625 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1627 ret = GEOSGeomGetX(geom, &x);
1628 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1630 RETURN_DOUBLE(x);
1634 * double GEOSGeometry::getY()
1636 PHP_METHOD(Geometry, getY)
1638 GEOSGeometry *geom;
1639 int ret;
1640 double y;
1642 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1644 ret = GEOSGeomGetY(geom, &y);
1645 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1647 RETURN_DOUBLE(y);
1651 * GEOSGeometry GEOSGeometry::interiorRingN()
1653 PHP_METHOD(Geometry, interiorRingN)
1655 GEOSGeometry *geom;
1656 const GEOSGeometry *c;
1657 GEOSGeometry *cc;
1658 long int num;
1660 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1662 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1663 &num) == FAILURE) {
1664 RETURN_NULL();
1667 if ( num >= GEOSGetNumInteriorRings(geom) ) RETURN_NULL();
1668 c = GEOSGetInteriorRingN(geom, num);
1669 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1670 cc = GEOSGeom_clone(c);
1671 if ( ! cc ) RETURN_NULL(); /* should get an exception first */
1673 object_init_ex(return_value, Geometry_ce_ptr);
1674 setRelay(return_value, cc);
1678 * GEOSGeometry GEOSGeometry::exteriorRing()
1680 PHP_METHOD(Geometry, exteriorRing)
1682 GEOSGeometry *geom;
1683 const GEOSGeometry *c;
1684 GEOSGeometry *cc;
1686 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1688 c = GEOSGetExteriorRing(geom);
1689 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1690 cc = GEOSGeom_clone(c);
1691 if ( ! cc ) RETURN_NULL(); /* should get an exception first */
1693 object_init_ex(return_value, Geometry_ce_ptr);
1694 setRelay(return_value, cc);
1698 * long GEOSGeometry::numCoordinates()
1700 PHP_METHOD(Geometry, numCoordinates)
1702 GEOSGeometry *geom;
1703 long int ret;
1705 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1707 ret = GEOSGetNumCoordinates(geom);
1708 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1710 RETURN_LONG(ret);
1714 * long GEOSGeometry::dimension()
1715 * 0:puntual 1:lineal 2:areal
1717 PHP_METHOD(Geometry, dimension)
1719 GEOSGeometry *geom;
1720 long int ret;
1722 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1724 ret = GEOSGeom_getDimensions(geom);
1725 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1727 RETURN_LONG(ret);
1731 * long GEOSGeometry::coordinateDimension()
1733 PHP_METHOD(Geometry, coordinateDimension)
1735 GEOSGeometry *geom;
1736 long int ret;
1738 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1740 ret = GEOSGeom_getCoordinateDimension(geom);
1741 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1743 RETURN_LONG(ret);
1747 * GEOSGeometry GEOSGeometry::pointN()
1749 PHP_METHOD(Geometry, pointN)
1751 GEOSGeometry *geom;
1752 GEOSGeometry *c;
1753 long int num;
1755 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1757 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1758 &num) == FAILURE) {
1759 RETURN_NULL();
1762 if ( num >= GEOSGeomGetNumPoints(geom) ) RETURN_NULL();
1763 c = GEOSGeomGetPointN(geom, num);
1764 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1766 object_init_ex(return_value, Geometry_ce_ptr);
1767 setRelay(return_value, c);
1771 * GEOSGeometry GEOSGeometry::startPoint()
1773 PHP_METHOD(Geometry, startPoint)
1775 GEOSGeometry *geom;
1776 GEOSGeometry *c;
1778 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1780 c = GEOSGeomGetStartPoint(geom);
1781 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1783 object_init_ex(return_value, Geometry_ce_ptr);
1784 setRelay(return_value, c);
1788 * GEOSGeometry GEOSGeometry::endPoint()
1790 PHP_METHOD(Geometry, endPoint)
1792 GEOSGeometry *geom;
1793 GEOSGeometry *c;
1795 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1797 c = GEOSGeomGetEndPoint(geom);
1798 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1800 object_init_ex(return_value, Geometry_ce_ptr);
1801 setRelay(return_value, c);
1805 * double GEOSGeometry::area()
1807 PHP_METHOD(Geometry, area)
1809 GEOSGeometry *geom;
1810 double area;
1811 int ret;
1813 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1815 ret = GEOSArea(geom, &area);
1816 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1818 RETURN_DOUBLE(area);
1822 * double GEOSGeometry::length()
1824 PHP_METHOD(Geometry, length)
1826 GEOSGeometry *geom;
1827 double length;
1828 int ret;
1830 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1832 ret = GEOSLength(geom, &length);
1833 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1835 RETURN_DOUBLE(length);
1839 * double GEOSGeometry::distance(GEOSGeometry)
1841 PHP_METHOD(Geometry, distance)
1843 GEOSGeometry *this;
1844 GEOSGeometry *other;
1845 zval *zobj;
1846 double dist;
1847 int ret;
1849 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1851 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
1852 &zobj) == FAILURE)
1854 RETURN_NULL();
1857 other = getRelay(zobj, Geometry_ce_ptr);
1859 ret = GEOSDistance(this, other, &dist);
1860 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1862 RETURN_DOUBLE(dist);
1866 * double GEOSGeometry::hausdorffDistance(GEOSGeometry)
1868 PHP_METHOD(Geometry, hausdorffDistance)
1870 GEOSGeometry *this;
1871 GEOSGeometry *other;
1872 zval *zobj;
1873 double dist;
1874 int ret;
1876 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1878 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
1879 &zobj) == FAILURE)
1881 RETURN_NULL();
1884 other = getRelay(zobj, Geometry_ce_ptr);
1886 ret = GEOSHausdorffDistance(this, other, &dist);
1887 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1889 RETURN_DOUBLE(dist);
1892 PHP_METHOD(Geometry, snapTo)
1894 GEOSGeometry *this;
1895 GEOSGeometry *other;
1896 GEOSGeometry *ret;
1897 double tolerance;
1898 zval *zobj;
1900 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1902 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "od", &zobj,
1903 &tolerance) == FAILURE) {
1904 RETURN_NULL();
1906 other = getRelay(zobj, Geometry_ce_ptr);
1908 ret = GEOSSnap(this, other, tolerance);
1909 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1911 /* return_value is a zval */
1912 object_init_ex(return_value, Geometry_ce_ptr);
1913 setRelay(return_value, ret);
1916 PHP_METHOD(Geometry, node)
1918 GEOSGeometry *this;
1919 GEOSGeometry *ret;
1921 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1923 ret = GEOSNode(this);
1924 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1926 /* return_value is a zval */
1927 object_init_ex(return_value, Geometry_ce_ptr);
1928 setRelay(return_value, ret);
1933 /* -- class GEOSWKTReader -------------------- */
1935 PHP_METHOD(WKTReader, __construct);
1936 PHP_METHOD(WKTReader, read);
1938 static zend_function_entry WKTReader_methods[] = {
1939 PHP_ME(WKTReader, __construct, NULL, 0)
1940 PHP_ME(WKTReader, read, NULL, 0)
1941 {NULL, NULL, NULL}
1944 static zend_class_entry *WKTReader_ce_ptr;
1946 static zend_object_handlers WKTReader_object_handlers;
1948 static void
1949 WKTReader_dtor (void *object TSRMLS_DC)
1951 Proxy *obj = (Proxy *)object;
1952 GEOSWKTReader_destroy((GEOSWKTReader*)obj->relay);
1954 zend_hash_destroy(obj->std.properties);
1955 FREE_HASHTABLE(obj->std.properties);
1957 efree(obj);
1960 static zend_object_value
1961 WKTReader_create_obj (zend_class_entry *type TSRMLS_DC)
1963 return Gen_create_obj(type, WKTReader_dtor, &WKTReader_object_handlers);
1967 PHP_METHOD(WKTReader, __construct)
1969 GEOSWKTReader* obj;
1970 zval *object = getThis();
1972 obj = GEOSWKTReader_create();
1973 if ( ! obj ) {
1974 php_error_docref(NULL TSRMLS_CC, E_ERROR,
1975 "GEOSWKTReader_create() failed (didn't initGEOS?)");
1978 setRelay(object, obj);
1981 PHP_METHOD(WKTReader, read)
1983 GEOSWKTReader *reader;
1984 GEOSGeometry *geom;
1985 char* wkt;
1986 int wktlen;
1988 reader = (GEOSWKTReader*)getRelay(getThis(), WKTReader_ce_ptr);
1990 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
1991 &wkt, &wktlen) == FAILURE)
1993 RETURN_NULL();
1996 geom = GEOSWKTReader_read(reader, wkt);
1997 /* we'll probably get an exception if geom is null */
1998 if ( ! geom ) RETURN_NULL();
2000 /* return_value is a zval */
2001 object_init_ex(return_value, Geometry_ce_ptr);
2002 setRelay(return_value, geom);
2006 /* -- class GEOSWKTWriter -------------------- */
2008 PHP_METHOD(WKTWriter, __construct);
2009 PHP_METHOD(WKTWriter, write);
2010 PHP_METHOD(WKTWriter, setTrim);
2011 PHP_METHOD(WKTWriter, setRoundingPrecision);
2012 PHP_METHOD(WKTWriter, setOutputDimension);
2013 PHP_METHOD(WKTWriter, getOutputDimension);
2014 PHP_METHOD(WKTWriter, setOld3D);
2016 static zend_function_entry WKTWriter_methods[] = {
2017 PHP_ME(WKTWriter, __construct, NULL, 0)
2018 PHP_ME(WKTWriter, write, NULL, 0)
2019 PHP_ME(WKTWriter, setTrim, NULL, 0)
2020 PHP_ME(WKTWriter, setRoundingPrecision, NULL, 0)
2021 PHP_ME(WKTWriter, setOutputDimension, NULL, 0)
2022 PHP_ME(WKTWriter, getOutputDimension, NULL, 0)
2023 PHP_ME(WKTWriter, setOld3D, NULL, 0)
2024 {NULL, NULL, NULL}
2027 static zend_class_entry *WKTWriter_ce_ptr;
2029 static zend_object_handlers WKTWriter_object_handlers;
2031 static void
2032 WKTWriter_dtor (void *object TSRMLS_DC)
2034 Proxy *obj = (Proxy *)object;
2035 GEOSWKTWriter_destroy((GEOSWKTWriter*)obj->relay);
2037 zend_hash_destroy(obj->std.properties);
2038 FREE_HASHTABLE(obj->std.properties);
2040 efree(obj);
2043 static zend_object_value
2044 WKTWriter_create_obj (zend_class_entry *type TSRMLS_DC)
2046 return Gen_create_obj(type, WKTWriter_dtor, &WKTWriter_object_handlers);
2049 PHP_METHOD(WKTWriter, __construct)
2051 GEOSWKTWriter* obj;
2052 zval *object = getThis();
2054 obj = GEOSWKTWriter_create();
2055 if ( ! obj ) {
2056 php_error_docref(NULL TSRMLS_CC, E_ERROR,
2057 "GEOSWKTWriter_create() failed (didn't initGEOS?)");
2060 setRelay(object, obj);
2063 PHP_METHOD(WKTWriter, write)
2065 GEOSWKTWriter *writer;
2066 zval *zobj;
2067 GEOSGeometry *geom;
2068 char* wkt;
2069 char* retstr;
2071 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2073 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
2074 == FAILURE)
2076 RETURN_NULL();
2079 geom = getRelay(zobj, Geometry_ce_ptr);
2081 wkt = GEOSWKTWriter_write(writer, geom);
2082 /* we'll probably get an exception if wkt is null */
2083 if ( ! wkt ) RETURN_NULL();
2085 retstr = estrdup(wkt);
2086 GEOSFree(wkt);
2088 RETURN_STRING(retstr, 0);
2091 PHP_METHOD(WKTWriter, setTrim)
2093 GEOSWKTWriter *writer;
2094 zend_bool trimval;
2095 char trim;
2097 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2099 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &trimval)
2100 == FAILURE)
2102 RETURN_NULL();
2105 trim = trimval;
2106 GEOSWKTWriter_setTrim(writer, trim);
2109 PHP_METHOD(WKTWriter, setRoundingPrecision)
2111 GEOSWKTWriter *writer;
2112 long int prec;
2114 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2116 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &prec)
2117 == FAILURE)
2119 RETURN_NULL();
2122 GEOSWKTWriter_setRoundingPrecision(writer, prec);
2126 * void GEOSWKTWriter::setOutputDimension()
2128 PHP_METHOD(WKTWriter, setOutputDimension)
2130 GEOSWKTWriter *writer;
2131 long int dim;
2133 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2135 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
2136 == FAILURE)
2138 RETURN_NULL();
2141 GEOSWKTWriter_setOutputDimension(writer, dim);
2145 * long GEOSWKTWriter::getOutputDimension()
2147 PHP_METHOD(WKTWriter, getOutputDimension)
2149 GEOSWKTWriter *writer;
2150 long int ret;
2152 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2154 ret = GEOSWKTWriter_getOutputDimension(writer);
2156 RETURN_LONG(ret);
2159 PHP_METHOD(WKTWriter, setOld3D)
2161 GEOSWKTWriter *writer;
2162 zend_bool bval;
2163 int val;
2165 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2167 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &bval)
2168 == FAILURE)
2170 RETURN_NULL();
2173 val = bval;
2174 GEOSWKTWriter_setOld3D(writer, val);
2177 /* -- class GEOSWKBWriter -------------------- */
2179 PHP_METHOD(WKBWriter, __construct);
2180 PHP_METHOD(WKBWriter, getOutputDimension);
2181 PHP_METHOD(WKBWriter, setOutputDimension);
2182 PHP_METHOD(WKBWriter, getByteOrder);
2183 PHP_METHOD(WKBWriter, setByteOrder);
2184 PHP_METHOD(WKBWriter, setIncludeSRID);
2185 PHP_METHOD(WKBWriter, getIncludeSRID);
2186 PHP_METHOD(WKBWriter, writeHEX);
2188 static zend_function_entry WKBWriter_methods[] = {
2189 PHP_ME(WKBWriter, __construct, NULL, 0)
2190 PHP_ME(WKBWriter, getOutputDimension, NULL, 0)
2191 PHP_ME(WKBWriter, setOutputDimension, NULL, 0)
2192 PHP_ME(WKBWriter, getByteOrder, NULL, 0)
2193 PHP_ME(WKBWriter, setByteOrder, NULL, 0)
2194 PHP_ME(WKBWriter, getIncludeSRID, NULL, 0)
2195 PHP_ME(WKBWriter, setIncludeSRID, NULL, 0)
2196 PHP_ME(WKBWriter, writeHEX, NULL, 0)
2197 {NULL, NULL, NULL}
2200 static zend_class_entry *WKBWriter_ce_ptr;
2202 static zend_object_handlers WKBWriter_object_handlers;
2204 static void
2205 WKBWriter_dtor (void *object TSRMLS_DC)
2207 Proxy *obj = (Proxy *)object;
2208 GEOSWKBWriter_destroy((GEOSWKBWriter*)obj->relay);
2210 zend_hash_destroy(obj->std.properties);
2211 FREE_HASHTABLE(obj->std.properties);
2213 efree(obj);
2216 static zend_object_value
2217 WKBWriter_create_obj (zend_class_entry *type TSRMLS_DC)
2219 return Gen_create_obj(type, WKBWriter_dtor, &WKBWriter_object_handlers);
2223 * GEOSWKBWriter w = new GEOSWKBWriter()
2225 PHP_METHOD(WKBWriter, __construct)
2227 GEOSWKBWriter* obj;
2228 zval *object = getThis();
2230 obj = GEOSWKBWriter_create();
2231 if ( ! obj ) {
2232 php_error_docref(NULL TSRMLS_CC, E_ERROR,
2233 "GEOSWKBWriter_create() failed (didn't initGEOS?)");
2236 setRelay(object, obj);
2240 * long GEOSWKBWriter::getOutputDimension();
2242 PHP_METHOD(WKBWriter, getOutputDimension)
2244 GEOSWKBWriter *writer;
2245 long int ret;
2247 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2249 ret = GEOSWKBWriter_getOutputDimension(writer);
2251 RETURN_LONG(ret);
2255 * void GEOSWKBWriter::setOutputDimension(dims);
2257 PHP_METHOD(WKBWriter, setOutputDimension)
2259 GEOSWKBWriter *writer;
2260 long int dim;
2262 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2264 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
2265 == FAILURE)
2267 RETURN_NULL();
2270 GEOSWKBWriter_setOutputDimension(writer, dim);
2275 * string GEOSWKBWriter::writeHEX(GEOSGeometry)
2277 PHP_METHOD(WKBWriter, writeHEX)
2279 GEOSWKBWriter *writer;
2280 zval *zobj;
2281 GEOSGeometry *geom;
2282 char *ret;
2283 size_t retsize; /* useless... */
2284 char* retstr;
2286 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2288 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
2289 == FAILURE)
2291 RETURN_NULL();
2294 geom = getRelay(zobj, Geometry_ce_ptr);
2296 ret = (char*)GEOSWKBWriter_writeHEX(writer, geom, &retsize);
2297 /* we'll probably get an exception if ret is null */
2298 if ( ! ret ) RETURN_NULL();
2300 retstr = estrndup(ret, retsize);
2301 GEOSFree(ret);
2303 RETURN_STRING(retstr, 0);
2307 * long GEOSWKBWriter::getByteOrder();
2309 PHP_METHOD(WKBWriter, getByteOrder)
2311 GEOSWKBWriter *writer;
2312 long int ret;
2314 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2316 ret = GEOSWKBWriter_getByteOrder(writer);
2318 RETURN_LONG(ret);
2322 * void GEOSWKBWriter::setByteOrder(dims);
2324 PHP_METHOD(WKBWriter, setByteOrder)
2326 GEOSWKBWriter *writer;
2327 long int dim;
2329 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2331 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
2332 == FAILURE)
2334 RETURN_NULL();
2337 GEOSWKBWriter_setByteOrder(writer, dim);
2342 * bool GEOSWKBWriter::getIncludeSRID();
2344 PHP_METHOD(WKBWriter, getIncludeSRID)
2346 GEOSWKBWriter *writer;
2347 int ret;
2348 zend_bool retBool;
2350 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2352 ret = GEOSWKBWriter_getIncludeSRID(writer);
2353 retBool = ret;
2355 RETURN_BOOL(retBool);
2359 * void GEOSWKBWriter::setIncludeSRID(bool);
2361 PHP_METHOD(WKBWriter, setIncludeSRID)
2363 GEOSWKBWriter *writer;
2364 int inc;
2365 zend_bool incVal;
2367 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2369 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &incVal)
2370 == FAILURE)
2372 RETURN_NULL();
2375 inc = incVal;
2376 GEOSWKBWriter_setIncludeSRID(writer, inc);
2379 /* -- class GEOSWKBReader -------------------- */
2381 PHP_METHOD(WKBReader, __construct);
2382 PHP_METHOD(WKBReader, readHEX);
2384 static zend_function_entry WKBReader_methods[] = {
2385 PHP_ME(WKBReader, __construct, NULL, 0)
2386 PHP_ME(WKBReader, readHEX, NULL, 0)
2387 {NULL, NULL, NULL}
2390 static zend_class_entry *WKBReader_ce_ptr;
2392 static zend_object_handlers WKBReader_object_handlers;
2394 static void
2395 WKBReader_dtor (void *object TSRMLS_DC)
2397 Proxy *obj = (Proxy *)object;
2398 GEOSWKBReader_destroy((GEOSWKBReader*)obj->relay);
2400 zend_hash_destroy(obj->std.properties);
2401 FREE_HASHTABLE(obj->std.properties);
2403 efree(obj);
2406 static zend_object_value
2407 WKBReader_create_obj (zend_class_entry *type TSRMLS_DC)
2409 return Gen_create_obj(type, WKBReader_dtor, &WKBReader_object_handlers);
2413 PHP_METHOD(WKBReader, __construct)
2415 GEOSWKBReader* obj;
2416 zval *object = getThis();
2418 obj = GEOSWKBReader_create();
2419 if ( ! obj ) {
2420 php_error_docref(NULL TSRMLS_CC, E_ERROR,
2421 "GEOSWKBReader_create() failed (didn't initGEOS?)");
2424 setRelay(object, obj);
2427 PHP_METHOD(WKBReader, readHEX)
2429 GEOSWKBReader *reader;
2430 GEOSGeometry *geom;
2431 unsigned char* wkb;
2432 int wkblen;
2434 reader = (GEOSWKBReader*)getRelay(getThis(), WKBReader_ce_ptr);
2436 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
2437 &wkb, &wkblen) == FAILURE)
2439 RETURN_NULL();
2442 geom = GEOSWKBReader_readHEX(reader, wkb, wkblen);
2443 /* we'll probably get an exception if geom is null */
2444 if ( ! geom ) RETURN_NULL();
2446 /* return_value is a zval */
2447 object_init_ex(return_value, Geometry_ce_ptr);
2448 setRelay(return_value, geom);
2453 /* -- Free functions ------------------------- */
2456 * string GEOSVersion()
2458 PHP_FUNCTION(GEOSVersion)
2460 char *str;
2462 str = estrdup(GEOSversion());
2463 RETURN_STRING(str, 0);
2467 * array GEOSPolygonize(GEOSGeometry $geom)
2469 * The returned array contains the following elements:
2471 * - 'rings'
2472 * Type: array of GEOSGeometry
2473 * Rings that can be formed by the costituent
2474 * linework of geometry.
2475 * - 'cut_edges' (optional)
2476 * Type: array of GEOSGeometry
2477 * Edges which are connected at both ends but
2478 * which do not form part of polygon.
2479 * - 'dangles'
2480 * Type: array of GEOSGeometry
2481 * Edges which have one or both ends which are
2482 * not incident on another edge endpoint
2483 * - 'invalid_rings'
2484 * Type: array of GEOSGeometry
2485 * Edges which form rings which are invalid
2486 * (e.g. the component lines contain a self-intersection)
2489 PHP_FUNCTION(GEOSPolygonize)
2491 GEOSGeometry *this;
2492 GEOSGeometry *rings;
2493 GEOSGeometry *cut_edges;
2494 GEOSGeometry *dangles;
2495 GEOSGeometry *invalid_rings;
2496 zval *array_elem;
2497 zval *zobj;
2499 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
2500 == FAILURE)
2502 RETURN_NULL();
2504 this = getRelay(zobj, Geometry_ce_ptr);
2506 rings = GEOSPolygonize_full(this, &cut_edges, &dangles, &invalid_rings);
2507 if ( ! rings ) RETURN_NULL(); /* should get an exception first */
2509 /* return value should be an array */
2510 array_init(return_value);
2512 MAKE_STD_ZVAL(array_elem);
2513 array_init(array_elem);
2514 dumpGeometry(rings, array_elem);
2515 GEOSGeom_destroy(rings);
2516 add_assoc_zval(return_value, "rings", array_elem);
2518 MAKE_STD_ZVAL(array_elem);
2519 array_init(array_elem);
2520 dumpGeometry(cut_edges, array_elem);
2521 GEOSGeom_destroy(cut_edges);
2522 add_assoc_zval(return_value, "cut_edges", array_elem);
2524 MAKE_STD_ZVAL(array_elem);
2525 array_init(array_elem);
2526 dumpGeometry(dangles, array_elem);
2527 GEOSGeom_destroy(dangles);
2528 add_assoc_zval(return_value, "dangles", array_elem);
2530 MAKE_STD_ZVAL(array_elem);
2531 array_init(array_elem);
2532 dumpGeometry(invalid_rings, array_elem);
2533 GEOSGeom_destroy(invalid_rings);
2534 add_assoc_zval(return_value, "invalid_rings", array_elem);
2539 * array GEOSLineMerge(GEOSGeometry $geom)
2541 PHP_FUNCTION(GEOSLineMerge)
2543 GEOSGeometry *geom_in;
2544 GEOSGeometry *geom_out;
2545 zval *zobj;
2547 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
2548 == FAILURE)
2550 RETURN_NULL();
2552 geom_in = getRelay(zobj, Geometry_ce_ptr);
2554 geom_out = GEOSLineMerge(geom_in);
2555 if ( ! geom_out ) RETURN_NULL(); /* should get an exception first */
2557 /* return value should be an array */
2558 array_init(return_value);
2559 dumpGeometry(geom_out, return_value);
2560 GEOSGeom_destroy(geom_out);
2564 * GEOSGeometry GEOSSharedPaths(GEOSGeometry $geom1, GEOSGeometry *geom2)
2566 PHP_FUNCTION(GEOSSharedPaths)
2568 GEOSGeometry *geom_in_1;
2569 GEOSGeometry *geom_in_2;
2570 GEOSGeometry *geom_out;
2571 zval *zobj1, *zobj2;
2573 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo", &zobj1, &zobj2)
2574 == FAILURE)
2576 RETURN_NULL();
2578 geom_in_1 = getRelay(zobj1, Geometry_ce_ptr);
2579 geom_in_2 = getRelay(zobj2, Geometry_ce_ptr);
2581 geom_out = GEOSSharedPaths(geom_in_1, geom_in_2);
2582 if ( ! geom_out ) RETURN_NULL(); /* should get an exception first */
2584 /* return_value is a zval */
2585 object_init_ex(return_value, Geometry_ce_ptr);
2586 setRelay(return_value, geom_out);
2590 * GEOSGeometry::delaunayTriangulation([<tolerance>], [<onlyEdges>])
2592 * 'tolerance'
2593 * Type: double
2594 * snapping tolerance to use for improved robustness
2595 * 'onlyEdges'
2596 * Type: boolean
2597 * if true will return a MULTILINESTRING, otherwise (the default)
2598 * it will return a GEOMETRYCOLLECTION containing triangular POLYGONs.
2600 PHP_METHOD(Geometry, delaunayTriangulation)
2602 GEOSGeometry *this;
2603 GEOSGeometry *ret;
2604 double tolerance = 0.0;
2605 zend_bool edgeonly = 0;
2607 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
2609 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|db",
2610 &tolerance, &edgeonly) == FAILURE) {
2611 RETURN_NULL();
2614 ret = GEOSDelaunayTriangulation(this, tolerance, edgeonly ? 1 : 0);
2615 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
2617 /* return_value is a zval */
2618 object_init_ex(return_value, Geometry_ce_ptr);
2619 setRelay(return_value, ret);
2623 * GEOSGeometry::voronoiDiagram([<tolerance>], [<onlyEdges>])
2625 * styleArray keys supported:
2626 * 'tolerance'
2627 * Type: double
2628 * snapping tolerance to use for improved robustness
2629 * 'onlyEdges'
2630 * Type: boolean
2631 * if true will return a MULTILINESTRING, otherwise (the default)
2632 * it will return a GEOMETRYCOLLECTION containing POLYGONs.
2634 PHP_METHOD(Geometry, voronoiDiagram)
2636 GEOSGeometry *this;
2637 GEOSGeometry *ret;
2638 double tolerance = 0.0;
2639 zend_bool edgeonly = 0;
2641 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
2643 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|db",
2644 &tolerance, &edgeonly) == FAILURE) {
2645 RETURN_NULL();
2648 ret = GEOSVoronoiDiagram(this, tolerance, edgeonly ? 1 : 0);
2649 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
2651 /* return_value is a zval */
2652 object_init_ex(return_value, Geometry_ce_ptr);
2653 setRelay(return_value, ret);
2657 * bool GEOSRelateMatch(string matrix, string pattern)
2659 PHP_FUNCTION(GEOSRelateMatch)
2661 char* mat = NULL;
2662 int matlen;
2663 char* pat = NULL;
2664 int patlen;
2665 int ret;
2666 zend_bool retBool;
2668 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
2669 &mat, &matlen, &pat, &patlen) == FAILURE)
2671 RETURN_NULL();
2674 ret = GEOSRelatePatternMatch(mat, pat);
2675 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
2677 /* return_value is a zval */
2678 retBool = ret;
2679 RETURN_BOOL(retBool);
2682 /* ------ Initialization / Deinitialization / Meta ------------------ */
2684 /* per-module initialization */
2685 PHP_MINIT_FUNCTION(geos)
2687 zend_class_entry ce;
2689 /* WKTReader */
2690 INIT_CLASS_ENTRY(ce, "GEOSWKTReader", WKTReader_methods);
2691 WKTReader_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
2692 WKTReader_ce_ptr->create_object = WKTReader_create_obj;
2693 memcpy(&WKTReader_object_handlers,
2694 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2695 WKTReader_object_handlers.clone_obj = NULL;
2697 /* WKTWriter */
2698 INIT_CLASS_ENTRY(ce, "GEOSWKTWriter", WKTWriter_methods);
2699 WKTWriter_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
2700 WKTWriter_ce_ptr->create_object = WKTWriter_create_obj;
2701 memcpy(&WKTWriter_object_handlers,
2702 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2703 WKTWriter_object_handlers.clone_obj = NULL;
2705 /* Geometry */
2706 INIT_CLASS_ENTRY(ce, "GEOSGeometry", Geometry_methods);
2707 Geometry_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
2708 Geometry_ce_ptr->create_object = Geometry_create_obj;
2709 memcpy(&Geometry_object_handlers,
2710 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2711 Geometry_object_handlers.clone_obj = NULL;
2712 /* Geometry serialization */
2713 Geometry_ce_ptr->serialize = Geometry_serialize;
2714 Geometry_ce_ptr->unserialize = Geometry_deserialize;
2716 /* WKBWriter */
2717 INIT_CLASS_ENTRY(ce, "GEOSWKBWriter", WKBWriter_methods);
2718 WKBWriter_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
2719 WKBWriter_ce_ptr->create_object = WKBWriter_create_obj;
2720 memcpy(&WKBWriter_object_handlers,
2721 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2722 WKBWriter_object_handlers.clone_obj = NULL;
2724 /* WKBReader */
2725 INIT_CLASS_ENTRY(ce, "GEOSWKBReader", WKBReader_methods);
2726 WKBReader_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
2727 WKBReader_ce_ptr->create_object = WKBReader_create_obj;
2728 memcpy(&WKBReader_object_handlers,
2729 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2730 WKBReader_object_handlers.clone_obj = NULL;
2733 /* Constants */
2734 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_ROUND", GEOSBUF_CAP_ROUND,
2735 CONST_CS|CONST_PERSISTENT);
2736 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_FLAT", GEOSBUF_CAP_FLAT,
2737 CONST_CS|CONST_PERSISTENT);
2738 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_SQUARE", GEOSBUF_CAP_SQUARE,
2739 CONST_CS|CONST_PERSISTENT);
2740 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_ROUND", GEOSBUF_JOIN_ROUND,
2741 CONST_CS|CONST_PERSISTENT);
2742 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_MITRE", GEOSBUF_JOIN_MITRE,
2743 CONST_CS|CONST_PERSISTENT);
2744 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_BEVEL", GEOSBUF_JOIN_BEVEL,
2745 CONST_CS|CONST_PERSISTENT);
2747 REGISTER_LONG_CONSTANT("GEOS_POINT", GEOS_POINT,
2748 CONST_CS|CONST_PERSISTENT);
2749 REGISTER_LONG_CONSTANT("GEOS_LINESTRING", GEOS_LINESTRING,
2750 CONST_CS|CONST_PERSISTENT);
2751 REGISTER_LONG_CONSTANT("GEOS_LINEARRING", GEOS_LINEARRING,
2752 CONST_CS|CONST_PERSISTENT);
2753 REGISTER_LONG_CONSTANT("GEOS_POLYGON", GEOS_POLYGON,
2754 CONST_CS|CONST_PERSISTENT);
2755 REGISTER_LONG_CONSTANT("GEOS_MULTIPOINT", GEOS_MULTIPOINT,
2756 CONST_CS|CONST_PERSISTENT);
2757 REGISTER_LONG_CONSTANT("GEOS_MULTILINESTRING", GEOS_MULTILINESTRING,
2758 CONST_CS|CONST_PERSISTENT);
2759 REGISTER_LONG_CONSTANT("GEOS_MULTIPOLYGON", GEOS_MULTIPOLYGON,
2760 CONST_CS|CONST_PERSISTENT);
2761 REGISTER_LONG_CONSTANT("GEOS_GEOMETRYCOLLECTION", GEOS_GEOMETRYCOLLECTION,
2762 CONST_CS|CONST_PERSISTENT);
2764 REGISTER_LONG_CONSTANT("GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE",
2765 GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE,
2766 CONST_CS|CONST_PERSISTENT);
2768 REGISTER_LONG_CONSTANT("GEOSRELATE_BNR_MOD2", GEOSRELATE_BNR_MOD2,
2769 CONST_CS|CONST_PERSISTENT);
2770 REGISTER_LONG_CONSTANT("GEOSRELATE_BNR_OGC", GEOSRELATE_BNR_OGC,
2771 CONST_CS|CONST_PERSISTENT);
2772 REGISTER_LONG_CONSTANT("GEOSRELATE_BNR_ENDPOINT", GEOSRELATE_BNR_ENDPOINT,
2773 CONST_CS|CONST_PERSISTENT);
2774 REGISTER_LONG_CONSTANT("GEOSRELATE_BNR_MULTIVALENT_ENDPOINT",
2775 GEOSRELATE_BNR_MULTIVALENT_ENDPOINT,
2776 CONST_CS|CONST_PERSISTENT);
2777 REGISTER_LONG_CONSTANT("GEOSRELATE_BNR_MONOVALENT_ENDPOINT",
2778 GEOSRELATE_BNR_MONOVALENT_ENDPOINT,
2779 CONST_CS|CONST_PERSISTENT);
2781 return SUCCESS;
2784 /* per-module shutdown */
2785 PHP_MSHUTDOWN_FUNCTION(geos)
2787 delGeometrySerializer();
2788 delGeometryDeserializer();
2789 return SUCCESS;
2792 /* per-request initialization */
2793 PHP_RINIT_FUNCTION(geos)
2795 initGEOS(noticeHandler, errorHandler);
2796 return SUCCESS;
2799 /* pre-request destruction */
2800 PHP_RSHUTDOWN_FUNCTION(geos)
2802 finishGEOS();
2803 return SUCCESS;
2806 /* module info */
2807 PHP_MINFO_FUNCTION(geos)
2809 php_info_print_table_start();
2810 php_info_print_table_row(2,
2811 "GEOS - Geometry Engine Open Source", "enabled");
2812 php_info_print_table_row(2,
2813 "Version", PHP_GEOS_VERSION);
2814 php_info_print_table_end();