Merge items
[geos.git] / php / geos.c
blobf64fce049dc8610a8d331389e93650b770db1636
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 static function_entry geos_functions[] = {
48 PHP_FE(GEOSVersion, NULL)
49 PHP_FE(GEOSPolygonize, NULL)
50 PHP_FE(GEOSLineMerge, NULL)
51 PHP_FE(GEOSSharedPaths, NULL)
52 PHP_FE(GEOSRelateMatch, NULL)
53 {NULL, NULL, NULL}
56 zend_module_entry geos_module_entry = {
57 STANDARD_MODULE_HEADER,
58 PHP_GEOS_EXTNAME,
59 geos_functions,
60 PHP_MINIT(geos), /* module init function */
61 PHP_MSHUTDOWN(geos), /* module shutdown function */
62 PHP_RINIT(geos), /* request init function */
63 PHP_RSHUTDOWN(geos), /* request shutdown function */
64 PHP_MINFO(geos), /* module info function */
65 PHP_GEOS_VERSION,
66 STANDARD_MODULE_PROPERTIES
69 #ifdef COMPILE_DL_GEOS
70 ZEND_GET_MODULE(geos)
71 #endif
73 /* -- Utility functions ---------------------- */
75 static void noticeHandler(const char *fmt, ...)
77 char message[256];
78 va_list args;
79 va_start(args, fmt);
80 vsnprintf(message, sizeof(message) - 1, fmt, args);
81 va_end(args);
83 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s", message);
86 static void errorHandler(const char *fmt, ...)
88 char message[256];
89 va_list args;
90 va_start(args, fmt);
91 vsnprintf(message, sizeof(message) - 1, fmt, args);
92 va_end(args);
94 /* TODO: use a GEOSException ? */
95 zend_throw_exception_ex(zend_exception_get_default(TSRMLS_CC),
96 1 TSRMLS_CC, "%s", message);
100 typedef struct Proxy_t {
101 zend_object std;
102 void* relay;
103 } Proxy;
105 static void
106 setRelay(zval* val, void* obj) {
107 Proxy* proxy = (Proxy*)zend_object_store_get_object(val TSRMLS_CC);
108 proxy->relay = obj;
111 static inline void *
112 getRelay(zval* val, zend_class_entry* ce) {
113 Proxy *proxy = (Proxy*)zend_object_store_get_object(val TSRMLS_CC);
114 if ( proxy->std.ce != ce ) {
115 php_error_docref(NULL TSRMLS_CC, E_ERROR,
116 "Relay object is not an %s", ce->name);
118 if ( ! proxy->relay ) {
119 php_error_docref(NULL TSRMLS_CC, E_ERROR,
120 "Relay object for object of type %s is not set", ce->name);
122 return proxy->relay;
125 static long getZvalAsLong(zval* val)
127 long ret;
128 zval tmp;
130 tmp = *val;
131 zval_copy_ctor(&tmp);
132 convert_to_long(&tmp);
133 ret = Z_LVAL(tmp);
134 zval_dtor(&tmp);
135 return ret;
138 static long getZvalAsDouble(zval* val)
140 double ret;
141 zval tmp;
143 tmp = *val;
144 zval_copy_ctor(&tmp);
145 convert_to_double(&tmp);
146 ret = Z_DVAL(tmp);
147 zval_dtor(&tmp);
148 return ret;
151 static zend_object_value
152 Gen_create_obj (zend_class_entry *type TSRMLS_DC,
153 zend_objects_free_object_storage_t st, zend_object_handlers* handlers)
155 zval *tmp;
156 zend_object_value retval;
158 Proxy *obj = (Proxy *)emalloc(sizeof(Proxy));
159 memset(obj, 0, sizeof(Proxy));
160 obj->std.ce = type;
162 ALLOC_HASHTABLE(obj->std.properties);
163 zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
164 zend_hash_copy(obj->std.properties, &type->default_properties,
165 (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
167 retval.handle = zend_objects_store_put(obj, NULL, st, NULL TSRMLS_CC);
168 retval.handlers = handlers;
170 return retval;
174 /* -- class GEOSGeometry -------------------- */
176 PHP_METHOD(Geometry, __construct);
177 PHP_METHOD(Geometry, __toString);
178 PHP_METHOD(Geometry, project);
179 PHP_METHOD(Geometry, interpolate);
180 PHP_METHOD(Geometry, buffer);
181 PHP_METHOD(Geometry, offsetCurve);
182 PHP_METHOD(Geometry, envelope);
183 PHP_METHOD(Geometry, intersection);
184 PHP_METHOD(Geometry, convexHull);
185 PHP_METHOD(Geometry, difference);
186 PHP_METHOD(Geometry, symDifference);
187 PHP_METHOD(Geometry, boundary);
188 PHP_METHOD(Geometry, union); /* also does union cascaded */
189 PHP_METHOD(Geometry, pointOnSurface);
190 PHP_METHOD(Geometry, centroid);
191 PHP_METHOD(Geometry, relate);
192 PHP_METHOD(Geometry, relateBoundaryNodeRule);
193 PHP_METHOD(Geometry, simplify); /* also does topology-preserving */
194 PHP_METHOD(Geometry, extractUniquePoints);
195 PHP_METHOD(Geometry, disjoint);
196 PHP_METHOD(Geometry, touches);
197 PHP_METHOD(Geometry, intersects);
198 PHP_METHOD(Geometry, crosses);
199 PHP_METHOD(Geometry, within);
200 PHP_METHOD(Geometry, contains);
201 PHP_METHOD(Geometry, overlaps);
202 PHP_METHOD(Geometry, covers);
203 PHP_METHOD(Geometry, coveredBy);
204 PHP_METHOD(Geometry, equals);
205 PHP_METHOD(Geometry, equalsExact);
206 PHP_METHOD(Geometry, isEmpty);
207 PHP_METHOD(Geometry, checkValidity);
208 PHP_METHOD(Geometry, isSimple);
209 PHP_METHOD(Geometry, isRing);
210 PHP_METHOD(Geometry, hasZ);
211 PHP_METHOD(Geometry, isClosed);
212 PHP_METHOD(Geometry, typeName);
213 PHP_METHOD(Geometry, typeId);
214 PHP_METHOD(Geometry, getSRID);
215 PHP_METHOD(Geometry, setSRID);
216 PHP_METHOD(Geometry, numGeometries);
217 PHP_METHOD(Geometry, geometryN);
218 PHP_METHOD(Geometry, numInteriorRings);
219 PHP_METHOD(Geometry, numPoints);
220 PHP_METHOD(Geometry, getX);
221 PHP_METHOD(Geometry, getY);
222 PHP_METHOD(Geometry, interiorRingN);
223 PHP_METHOD(Geometry, exteriorRing);
224 PHP_METHOD(Geometry, numCoordinates);
225 PHP_METHOD(Geometry, dimension);
226 PHP_METHOD(Geometry, coordinateDimension);
227 PHP_METHOD(Geometry, pointN);
228 PHP_METHOD(Geometry, startPoint);
229 PHP_METHOD(Geometry, endPoint);
230 PHP_METHOD(Geometry, area);
231 PHP_METHOD(Geometry, length);
232 PHP_METHOD(Geometry, distance);
233 PHP_METHOD(Geometry, hausdorffDistance);
234 PHP_METHOD(Geometry, snapTo);
236 static function_entry Geometry_methods[] = {
237 PHP_ME(Geometry, __construct, NULL, 0)
238 PHP_ME(Geometry, __toString, NULL, 0)
239 PHP_ME(Geometry, project, NULL, 0)
240 PHP_ME(Geometry, interpolate, NULL, 0)
241 PHP_ME(Geometry, buffer, NULL, 0)
242 PHP_ME(Geometry, offsetCurve, NULL, 0)
243 PHP_ME(Geometry, envelope, NULL, 0)
244 PHP_ME(Geometry, intersection, NULL, 0)
245 PHP_ME(Geometry, convexHull, NULL, 0)
246 PHP_ME(Geometry, difference, NULL, 0)
247 PHP_ME(Geometry, symDifference, NULL, 0)
248 PHP_ME(Geometry, boundary, NULL, 0)
249 PHP_ME(Geometry, union, NULL, 0)
250 PHP_ME(Geometry, pointOnSurface, NULL, 0)
251 PHP_ME(Geometry, centroid, NULL, 0)
252 PHP_ME(Geometry, relate, NULL, 0)
253 PHP_ME(Geometry, relateBoundaryNodeRule, NULL, 0)
254 PHP_ME(Geometry, simplify, NULL, 0)
255 PHP_ME(Geometry, extractUniquePoints, NULL, 0)
256 PHP_ME(Geometry, disjoint, NULL, 0)
257 PHP_ME(Geometry, touches, NULL, 0)
258 PHP_ME(Geometry, intersects, NULL, 0)
259 PHP_ME(Geometry, crosses, NULL, 0)
260 PHP_ME(Geometry, within, NULL, 0)
261 PHP_ME(Geometry, contains, NULL, 0)
262 PHP_ME(Geometry, overlaps, NULL, 0)
263 PHP_ME(Geometry, covers, NULL, 0)
264 PHP_ME(Geometry, coveredBy, NULL, 0)
265 PHP_ME(Geometry, equals, NULL, 0)
266 PHP_ME(Geometry, equalsExact, NULL, 0)
267 PHP_ME(Geometry, isEmpty, NULL, 0)
268 PHP_ME(Geometry, checkValidity, NULL, 0)
269 PHP_ME(Geometry, isSimple, NULL, 0)
270 PHP_ME(Geometry, isRing, NULL, 0)
271 PHP_ME(Geometry, hasZ, NULL, 0)
272 PHP_ME(Geometry, isClosed, NULL, 0)
273 PHP_ME(Geometry, typeName, NULL, 0)
274 PHP_ME(Geometry, typeId, NULL, 0)
275 PHP_ME(Geometry, getSRID, NULL, 0)
276 PHP_ME(Geometry, setSRID, NULL, 0)
277 PHP_ME(Geometry, numGeometries, NULL, 0)
278 PHP_ME(Geometry, geometryN, NULL, 0)
279 PHP_ME(Geometry, numInteriorRings, NULL, 0)
280 PHP_ME(Geometry, numPoints, NULL, 0)
281 PHP_ME(Geometry, getX, NULL, 0)
282 PHP_ME(Geometry, getY, NULL, 0)
283 PHP_ME(Geometry, interiorRingN, NULL, 0)
284 PHP_ME(Geometry, exteriorRing, NULL, 0)
285 PHP_ME(Geometry, numCoordinates, NULL, 0)
286 PHP_ME(Geometry, dimension, NULL, 0)
287 PHP_ME(Geometry, coordinateDimension, NULL, 0)
288 PHP_ME(Geometry, pointN, NULL, 0)
289 PHP_ME(Geometry, startPoint, NULL, 0)
290 PHP_ME(Geometry, endPoint, NULL, 0)
291 PHP_ME(Geometry, area, NULL, 0)
292 PHP_ME(Geometry, length, NULL, 0)
293 PHP_ME(Geometry, distance, NULL, 0)
294 PHP_ME(Geometry, hausdorffDistance, NULL, 0)
295 PHP_ME(Geometry, snapTo, NULL, 0)
296 {NULL, NULL, NULL}
299 static zend_class_entry *Geometry_ce_ptr;
301 static zend_object_handlers Geometry_object_handlers;
303 /* Geometry serializer */
305 static GEOSWKBWriter* Geometry_serializer = 0;
307 static GEOSWKBWriter* getGeometrySerializer()
309 if ( ! Geometry_serializer ) {
310 Geometry_serializer = GEOSWKBWriter_create();
311 GEOSWKBWriter_setIncludeSRID(Geometry_serializer, 1);
312 GEOSWKBWriter_setOutputDimension(Geometry_serializer, 3);
314 return Geometry_serializer;
317 static void delGeometrySerializer()
319 if ( Geometry_serializer ) {
320 GEOSWKBWriter_destroy(Geometry_serializer);
324 /* Geometry deserializer */
326 static GEOSWKBReader* Geometry_deserializer = 0;
328 static GEOSWKBReader* getGeometryDeserializer()
330 if ( ! Geometry_deserializer ) {
331 Geometry_deserializer = GEOSWKBReader_create();
333 return Geometry_deserializer;
336 static void delGeometryDeserializer()
338 if ( Geometry_deserializer ) {
339 GEOSWKBReader_destroy(Geometry_deserializer);
343 /* Serializer function for GEOSGeometry */
345 static int
346 Geometry_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len,
347 zend_serialize_data *data TSRMLS_DC)
349 GEOSWKBWriter *serializer;
350 GEOSGeometry *geom;
351 char* ret;
352 size_t retsize;
355 serializer = getGeometrySerializer();
356 geom = (GEOSGeometry*)getRelay(object, Geometry_ce_ptr);
358 /* NOTE: we might be fine using binary here */
359 ret = (char*)GEOSWKBWriter_writeHEX(serializer, geom, &retsize);
360 /* we'll probably get an exception if ret is null */
361 if ( ! ret ) return FAILURE;
363 *buffer = (unsigned char*)estrndup(ret, retsize);
364 GEOSFree(ret);
366 *buf_len = retsize;
368 return SUCCESS;
371 static int
372 Geometry_deserialize(zval **object, zend_class_entry *ce, const unsigned char *buf,
373 zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
375 GEOSWKBReader* deserializer;
376 GEOSGeometry* geom;
378 deserializer = getGeometryDeserializer();
379 geom = GEOSWKBReader_readHEX(deserializer, buf, buf_len);
381 /* TODO: check zend_class_entry being what we expect! */
382 if ( ce != Geometry_ce_ptr ) {
383 php_error_docref(NULL TSRMLS_CC, E_ERROR,
384 "Geometry_deserialize called with unexpected zend_class_entry");
385 return FAILURE;
387 object_init_ex(*object, ce);
388 setRelay(*object, geom);
390 return SUCCESS;
394 * Push components of the given geometry
395 * to the given array zval.
396 * Components geometries are cloned.
397 * NOTE: collection components are not descended into
399 static void
400 dumpGeometry(GEOSGeometry* g, zval* array)
402 int ngeoms, i;
405 MAKE_STD_ZVAL(array);
406 array_init(array);
409 ngeoms = GEOSGetNumGeometries(g);
410 for (i=0; i<ngeoms; ++i)
412 zval *tmp;
413 GEOSGeometry* cc;
414 const GEOSGeometry* c = GEOSGetGeometryN(g, i);
415 if ( ! c ) continue; /* should get an exception */
416 /* we _need_ to clone as this one is owned by 'g' */
417 cc = GEOSGeom_clone(c);
418 if ( ! cc ) continue; /* should get an exception */
420 MAKE_STD_ZVAL(tmp);
421 object_init_ex(tmp, Geometry_ce_ptr);
422 setRelay(tmp, cc);
423 add_next_index_zval(array, tmp);
428 static void
429 Geometry_dtor (void *object TSRMLS_DC)
431 Proxy *obj = (Proxy *)object;
432 GEOSGeom_destroy((GEOSGeometry*)obj->relay);
434 zend_hash_destroy(obj->std.properties);
435 FREE_HASHTABLE(obj->std.properties);
437 efree(obj);
440 static zend_object_value
441 Geometry_create_obj (zend_class_entry *type TSRMLS_DC)
443 return Gen_create_obj(type, Geometry_dtor, &Geometry_object_handlers);
447 PHP_METHOD(Geometry, __construct)
449 php_error_docref(NULL TSRMLS_CC, E_ERROR,
450 "GEOSGeometry can't be constructed using new, check WKTReader");
454 PHP_METHOD(Geometry, __toString)
456 GEOSGeometry *geom;
457 GEOSWKTWriter *writer;
458 char *wkt;
459 char *ret;
461 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
462 writer = GEOSWKTWriter_create();
463 /* NOTE: if we get an exception before reaching
464 * GEOSWKTWriter_destory below we'll be leaking memory.
465 * One fix could be storing the object in a refcounted
466 * zval.
468 GEOSWKTWriter_setTrim(writer, 1);
470 wkt = GEOSWKTWriter_write(writer, geom);
471 /* we'll probably get an exception if wkt is null */
472 if ( ! wkt ) RETURN_NULL();
474 GEOSWKTWriter_destroy(writer);
477 ret = estrdup(wkt);
478 GEOSFree(wkt);
480 RETURN_STRING(ret, 0);
483 PHP_METHOD(Geometry, project)
485 GEOSGeometry *this;
486 GEOSGeometry *other;
487 zval *zobj;
488 zend_bool normalized = 0;
489 double ret;
491 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
493 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|b", &zobj,
494 &normalized) == FAILURE) {
495 RETURN_NULL();
497 other = getRelay(zobj, Geometry_ce_ptr);
499 if ( normalized ) {
500 ret = GEOSProjectNormalized(this, other);
501 } else {
502 ret = GEOSProject(this, other);
504 if ( ret < 0 ) RETURN_NULL(); /* should get an exception first */
506 RETURN_DOUBLE(ret);
509 PHP_METHOD(Geometry, interpolate)
511 GEOSGeometry *this;
512 double dist;
513 GEOSGeometry *ret;
514 zend_bool normalized = 0;
516 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
518 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|b",
519 &dist, &normalized) == FAILURE) {
520 RETURN_NULL();
523 if ( normalized ) {
524 ret = GEOSInterpolateNormalized(this, dist);
525 } else {
526 ret = GEOSInterpolate(this, dist);
528 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
530 /* return_value is a zval */
531 object_init_ex(return_value, Geometry_ce_ptr);
532 setRelay(return_value, ret);
536 * GEOSGeometry::buffer(dist, [<styleArray>])
538 * styleArray keys supported:
539 * 'quad_segs'
540 * Type: int
541 * Number of segments used to approximate
542 * a quarter circle (defaults to 8).
543 * 'endcap'
544 * Type: long
545 * Endcap style (defaults to GEOSBUF_CAP_ROUND)
546 * 'join'
547 * Type: long
548 * Join style (defaults to GEOSBUF_JOIN_ROUND)
549 * 'mitre_limit'
550 * Type: double
551 * mitre ratio limit (only affects joins with GEOSBUF_JOIN_MITRE style)
552 * 'miter_limit' is also accepted as a synonym for 'mitre_limit'.
553 * 'single_sided'
554 * Type: bool
555 * If true buffer lines only on one side, so that the input line
556 * will be a portion of the boundary of the returned polygon.
557 * Only applies to lineal input. Defaults to false.
559 PHP_METHOD(Geometry, buffer)
561 GEOSGeometry *this;
562 double dist;
563 GEOSGeometry *ret;
564 GEOSBufferParams *params;
565 static const double default_mitreLimit = 5.0;
566 static const int default_endCapStyle = GEOSBUF_CAP_ROUND;
567 static const int default_joinStyle = GEOSBUF_JOIN_ROUND;
568 static const int default_quadSegs = 8;
569 long int quadSegs = default_quadSegs;
570 long int endCapStyle = default_endCapStyle;
571 long int joinStyle = default_joinStyle;
572 double mitreLimit = default_mitreLimit;
573 long singleSided = 0;
574 zval *style_val = NULL;
575 zval **data;
576 HashTable *style;
577 char *key;
578 ulong index;
580 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
582 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|a",
583 &dist, &style_val) == FAILURE) {
584 RETURN_NULL();
587 params = GEOSBufferParams_create();
589 if ( style_val )
591 style = HASH_OF(style_val);
592 while(zend_hash_get_current_key(style, &key, &index, 0)
593 == HASH_KEY_IS_STRING)
595 if(!strcmp(key, "quad_segs"))
597 zend_hash_get_current_data(style, (void**)&data);
598 quadSegs = getZvalAsLong(*data);
599 GEOSBufferParams_setQuadrantSegments(params, quadSegs);
601 else if(!strcmp(key, "endcap"))
603 zend_hash_get_current_data(style, (void**)&data);
604 endCapStyle = getZvalAsLong(*data);
605 GEOSBufferParams_setEndCapStyle(params, endCapStyle);
607 else if(!strcmp(key, "join"))
609 zend_hash_get_current_data(style, (void**)&data);
610 joinStyle = getZvalAsLong(*data);
611 GEOSBufferParams_setJoinStyle(params, joinStyle);
613 else if(!strcmp(key, "mitre_limit"))
615 zend_hash_get_current_data(style, (void**)&data);
616 mitreLimit = getZvalAsDouble(*data);
617 GEOSBufferParams_setMitreLimit(params, mitreLimit);
619 else if(!strcmp(key, "single_sided"))
621 zend_hash_get_current_data(style, (void**)&data);
622 singleSided = getZvalAsLong(*data);
623 GEOSBufferParams_setSingleSided(params, singleSided);
626 zend_hash_move_forward(style);
630 ret = GEOSBufferWithParams(this, params, dist);
631 GEOSBufferParams_destroy(params);
632 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
634 /* return_value is a zval */
635 object_init_ex(return_value, Geometry_ce_ptr);
636 setRelay(return_value, ret);
640 * GEOSGeometry::offsetCurve(dist, [<styleArray>])
642 * styleArray keys supported:
643 * 'quad_segs'
644 * Type: int
645 * Number of segments used to approximate
646 * a quarter circle (defaults to 8).
647 * 'join'
648 * Type: long
649 * Join style (defaults to GEOSBUF_JOIN_ROUND)
650 * 'mitre_limit'
651 * Type: double
652 * mitre ratio limit (only affects joins with GEOSBUF_JOIN_MITRE style)
653 * 'miter_limit' is also accepted as a synonym for 'mitre_limit'.
655 PHP_METHOD(Geometry, offsetCurve)
657 GEOSGeometry *this;
658 double dist;
659 GEOSGeometry *ret;
660 static const double default_mitreLimit = 5.0;
661 static const int default_joinStyle = GEOSBUF_JOIN_ROUND;
662 static const int default_quadSegs = 8;
663 long int quadSegs = default_quadSegs;
664 long int joinStyle = default_joinStyle;
665 double mitreLimit = default_mitreLimit;
666 zval *style_val = NULL;
667 zval **data;
668 HashTable *style;
669 char *key;
670 ulong index;
672 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
674 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|a",
675 &dist, &style_val) == FAILURE) {
676 RETURN_NULL();
679 if ( style_val )
681 style = HASH_OF(style_val);
682 while(zend_hash_get_current_key(style, &key, &index, 0)
683 == HASH_KEY_IS_STRING)
685 if(!strcmp(key, "quad_segs"))
687 zend_hash_get_current_data(style, (void**)&data);
688 quadSegs = getZvalAsLong(*data);
690 else if(!strcmp(key, "join"))
692 zend_hash_get_current_data(style, (void**)&data);
693 joinStyle = getZvalAsLong(*data);
695 else if(!strcmp(key, "mitre_limit"))
697 zend_hash_get_current_data(style, (void**)&data);
698 mitreLimit = getZvalAsDouble(*data);
701 zend_hash_move_forward(style);
705 ret = GEOSOffsetCurve(this, dist, quadSegs, joinStyle, mitreLimit);
706 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
708 /* return_value is a zval */
709 object_init_ex(return_value, Geometry_ce_ptr);
710 setRelay(return_value, ret);
713 PHP_METHOD(Geometry, envelope)
715 GEOSGeometry *this;
716 GEOSGeometry *ret;
718 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
720 ret = GEOSEnvelope(this);
721 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
723 /* return_value is a zval */
724 object_init_ex(return_value, Geometry_ce_ptr);
725 setRelay(return_value, ret);
728 PHP_METHOD(Geometry, intersection)
730 GEOSGeometry *this;
731 GEOSGeometry *other;
732 GEOSGeometry *ret;
733 zval *zobj;
735 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
737 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
738 == FAILURE) {
739 RETURN_NULL();
741 other = getRelay(zobj, Geometry_ce_ptr);
743 ret = GEOSIntersection(this, other);
744 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
746 /* return_value is a zval */
747 object_init_ex(return_value, Geometry_ce_ptr);
748 setRelay(return_value, ret);
751 PHP_METHOD(Geometry, convexHull)
753 GEOSGeometry *this;
754 GEOSGeometry *ret;
756 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
758 ret = GEOSConvexHull(this);
759 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
761 /* return_value is a zval */
762 object_init_ex(return_value, Geometry_ce_ptr);
763 setRelay(return_value, ret);
766 PHP_METHOD(Geometry, difference)
768 GEOSGeometry *this;
769 GEOSGeometry *other;
770 GEOSGeometry *ret;
771 zval *zobj;
773 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
775 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
776 == FAILURE) {
777 RETURN_NULL();
779 other = getRelay(zobj, Geometry_ce_ptr);
781 ret = GEOSDifference(this, other);
782 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
784 /* return_value is a zval */
785 object_init_ex(return_value, Geometry_ce_ptr);
786 setRelay(return_value, ret);
789 PHP_METHOD(Geometry, symDifference)
791 GEOSGeometry *this;
792 GEOSGeometry *other;
793 GEOSGeometry *ret;
794 zval *zobj;
796 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
798 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
799 == FAILURE) {
800 RETURN_NULL();
802 other = getRelay(zobj, Geometry_ce_ptr);
804 ret = GEOSSymDifference(this, other);
805 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
807 /* return_value is a zval */
808 object_init_ex(return_value, Geometry_ce_ptr);
809 setRelay(return_value, ret);
812 PHP_METHOD(Geometry, boundary)
814 GEOSGeometry *this;
815 GEOSGeometry *ret;
817 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
819 ret = GEOSBoundary(this);
820 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
822 /* return_value is a zval */
823 object_init_ex(return_value, Geometry_ce_ptr);
824 setRelay(return_value, ret);
828 * GEOSGeometry::union(otherGeom)
829 * GEOSGeometry::union()
831 PHP_METHOD(Geometry, union)
833 GEOSGeometry *this;
834 GEOSGeometry *other;
835 GEOSGeometry *ret;
836 zval *zobj = NULL;
838 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
840 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o", &zobj)
841 == FAILURE) {
842 RETURN_NULL();
845 if ( zobj ) {
846 other = getRelay(zobj, Geometry_ce_ptr);
847 ret = GEOSUnion(this, other);
848 } else {
849 ret = GEOSUnaryUnion(this);
852 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
854 /* return_value is a zval */
855 object_init_ex(return_value, Geometry_ce_ptr);
856 setRelay(return_value, ret);
860 * GEOSGeometry::pointOnSurface()
862 PHP_METHOD(Geometry, pointOnSurface)
864 GEOSGeometry *this;
865 GEOSGeometry *ret;
867 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
869 ret = GEOSPointOnSurface(this);
870 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
872 /* return_value is a zval */
873 object_init_ex(return_value, Geometry_ce_ptr);
874 setRelay(return_value, ret);
878 * GEOSGeometry::centroid()
880 PHP_METHOD(Geometry, centroid)
882 GEOSGeometry *this;
883 GEOSGeometry *ret;
885 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
887 ret = GEOSGetCentroid(this);
888 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
890 /* return_value is a zval */
891 object_init_ex(return_value, Geometry_ce_ptr);
892 setRelay(return_value, ret);
896 * GEOSGeometry::relate(otherGeom)
897 * GEOSGeometry::relate(otherGeom, pattern)
899 PHP_METHOD(Geometry, relate)
901 GEOSGeometry *this;
902 GEOSGeometry *other;
903 zval *zobj;
904 char* pat = NULL;
905 int patlen;
906 int retInt;
907 zend_bool retBool;
908 char* retStr;
910 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
912 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|s",
913 &zobj, &pat, &patlen) == FAILURE)
915 RETURN_NULL();
918 other = getRelay(zobj, Geometry_ce_ptr);
920 if ( ! pat ) {
921 /* we'll compute it */
922 pat = GEOSRelate(this, other);
923 if ( ! pat ) RETURN_NULL(); /* should get an exception first */
924 retStr = estrdup(pat);
925 GEOSFree(pat);
926 RETURN_STRING(retStr, 0);
927 } else {
928 retInt = GEOSRelatePattern(this, other, pat);
929 if ( retInt == 2 ) RETURN_NULL(); /* should get an exception first */
930 retBool = retInt;
931 RETURN_BOOL(retBool);
937 * GEOSGeometry::relateBoundaryNodeRule(otherGeom, rule)
939 PHP_METHOD(Geometry, relateBoundaryNodeRule)
941 GEOSGeometry *this;
942 GEOSGeometry *other;
943 zval *zobj;
944 char* pat;
945 long int bnr = GEOSRELATE_BNR_OGC;
946 char* retStr;
948 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
950 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ol",
951 &zobj, &bnr) == FAILURE)
953 RETURN_NULL();
956 other = getRelay(zobj, Geometry_ce_ptr);
958 /* we'll compute it */
959 pat = GEOSRelateBoundaryNodeRule(this, other, bnr);
960 if ( ! pat ) RETURN_NULL(); /* should get an exception first */
961 retStr = estrdup(pat);
962 GEOSFree(pat);
963 RETURN_STRING(retStr, 0);
967 * GEOSGeometry GEOSGeometry::simplify(tolerance)
968 * GEOSGeometry GEOSGeometry::simplify(tolerance, preserveTopology)
970 PHP_METHOD(Geometry, simplify)
972 GEOSGeometry *this;
973 double tolerance;
974 zend_bool preserveTopology = 0;
975 GEOSGeometry *ret;
977 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
979 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|b",
980 &tolerance, &preserveTopology) == FAILURE) {
981 RETURN_NULL();
984 if ( preserveTopology ) {
985 ret = GEOSTopologyPreserveSimplify(this, tolerance);
986 } else {
987 ret = GEOSSimplify(this, tolerance);
990 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
992 /* return_value is a zval */
993 object_init_ex(return_value, Geometry_ce_ptr);
994 setRelay(return_value, ret);
998 * GEOSGeometry GEOSGeometry::extractUniquePoints()
1000 PHP_METHOD(Geometry, extractUniquePoints)
1002 GEOSGeometry *this;
1003 GEOSGeometry *ret;
1005 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1007 ret = GEOSGeom_extractUniquePoints(this);
1008 if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
1010 /* return_value is a zval */
1011 object_init_ex(return_value, Geometry_ce_ptr);
1012 setRelay(return_value, ret);
1016 * bool GEOSGeometry::disjoint(GEOSGeometry)
1018 PHP_METHOD(Geometry, disjoint)
1020 GEOSGeometry *this;
1021 GEOSGeometry *other;
1022 int ret;
1023 zend_bool retBool;
1024 zval *zobj;
1026 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1028 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1029 == FAILURE) {
1030 RETURN_NULL();
1032 other = getRelay(zobj, Geometry_ce_ptr);
1034 ret = GEOSDisjoint(this, other);
1035 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1037 /* return_value is a zval */
1038 retBool = ret;
1039 RETURN_BOOL(retBool);
1043 * bool GEOSGeometry::touches(GEOSGeometry)
1045 PHP_METHOD(Geometry, touches)
1047 GEOSGeometry *this;
1048 GEOSGeometry *other;
1049 int ret;
1050 zend_bool retBool;
1051 zval *zobj;
1053 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1055 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1056 == FAILURE) {
1057 RETURN_NULL();
1059 other = getRelay(zobj, Geometry_ce_ptr);
1061 ret = GEOSTouches(this, other);
1062 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1064 /* return_value is a zval */
1065 retBool = ret;
1066 RETURN_BOOL(retBool);
1070 * bool GEOSGeometry::intersects(GEOSGeometry)
1072 PHP_METHOD(Geometry, intersects)
1074 GEOSGeometry *this;
1075 GEOSGeometry *other;
1076 int ret;
1077 zend_bool retBool;
1078 zval *zobj;
1080 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1082 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
1083 == FAILURE) {
1084 RETURN_NULL();
1086 other = getRelay(zobj, Geometry_ce_ptr);
1088 ret = GEOSIntersects(this, other);
1089 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1091 /* return_value is a zval */
1092 retBool = ret;
1093 RETURN_BOOL(retBool);
1097 * bool GEOSGeometry::crosses(GEOSGeometry)
1099 PHP_METHOD(Geometry, crosses)
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 = GEOSCrosses(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::within(GEOSGeometry)
1126 PHP_METHOD(Geometry, within)
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 = GEOSWithin(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::contains(GEOSGeometry)
1153 PHP_METHOD(Geometry, contains)
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 = GEOSContains(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::overlaps(GEOSGeometry)
1180 PHP_METHOD(Geometry, overlaps)
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 = GEOSOverlaps(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::covers(GEOSGeometry)
1207 PHP_METHOD(Geometry, covers)
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 = GEOSCovers(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::coveredBy(GEOSGeometry)
1234 PHP_METHOD(Geometry, coveredBy)
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 = GEOSCoveredBy(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::equals(GEOSGeometry)
1261 PHP_METHOD(Geometry, equals)
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",
1272 &zobj) == FAILURE) {
1273 RETURN_NULL();
1275 other = getRelay(zobj, Geometry_ce_ptr);
1277 ret = GEOSEquals(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::equalsExact(GEOSGeometry)
1287 * bool GEOSGeometry::equalsExact(GEOSGeometry, double tolerance)
1289 PHP_METHOD(Geometry, equalsExact)
1291 GEOSGeometry *this;
1292 GEOSGeometry *other;
1293 int ret;
1294 double tolerance = 0;
1295 zend_bool retBool;
1296 zval *zobj;
1298 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1300 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|d",
1301 &zobj, &tolerance) == FAILURE) {
1302 RETURN_NULL();
1304 other = getRelay(zobj, Geometry_ce_ptr);
1306 ret = GEOSEqualsExact(this, other, tolerance);
1307 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1309 /* return_value is a zval */
1310 retBool = ret;
1311 RETURN_BOOL(retBool);
1315 * bool GEOSGeometry::isEmpty()
1317 PHP_METHOD(Geometry, isEmpty)
1319 GEOSGeometry *this;
1320 int ret;
1321 zend_bool retBool;
1323 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1325 ret = GEOSisEmpty(this);
1326 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1328 /* return_value is a zval */
1329 retBool = ret;
1330 RETURN_BOOL(retBool);
1334 * array GEOSGeometry::checkValidity()
1336 PHP_METHOD(Geometry, checkValidity)
1338 GEOSGeometry *this;
1339 GEOSGeometry *location = NULL;
1340 int ret;
1341 char *reason = NULL;
1342 zend_bool retBool;
1343 char *reasonVal = NULL;
1344 zval *locationVal = NULL;
1345 long int flags = 0;
1347 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1349 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l",
1350 &flags) == FAILURE) {
1351 RETURN_NULL();
1354 ret = GEOSisValidDetail(this, flags, &reason, &location);
1355 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1357 if ( reason ) {
1358 reasonVal = estrdup(reason);
1359 GEOSFree(reason);
1362 if ( location ) {
1363 MAKE_STD_ZVAL(locationVal);
1364 object_init_ex(locationVal, Geometry_ce_ptr);
1365 setRelay(locationVal, location);
1368 retBool = ret;
1370 /* return value is an array */
1371 array_init(return_value);
1372 add_assoc_bool(return_value, "valid", retBool);
1373 if ( reasonVal ) add_assoc_string(return_value, "reason", reasonVal, 0);
1374 if ( locationVal ) add_assoc_zval(return_value, "location", locationVal);
1379 * bool GEOSGeometry::isSimple()
1381 PHP_METHOD(Geometry, isSimple)
1383 GEOSGeometry *this;
1384 int ret;
1385 zend_bool retBool;
1387 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1389 ret = GEOSisSimple(this);
1390 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1392 /* return_value is a zval */
1393 retBool = ret;
1394 RETURN_BOOL(retBool);
1398 * bool GEOSGeometry::isRing()
1400 PHP_METHOD(Geometry, isRing)
1402 GEOSGeometry *this;
1403 int ret;
1404 zend_bool retBool;
1406 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1408 ret = GEOSisRing(this);
1409 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1411 /* return_value is a zval */
1412 retBool = ret;
1413 RETURN_BOOL(retBool);
1417 * bool GEOSGeometry::hasZ()
1419 PHP_METHOD(Geometry, hasZ)
1421 GEOSGeometry *this;
1422 int ret;
1423 zend_bool retBool;
1425 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1427 ret = GEOSHasZ(this);
1428 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1430 /* return_value is a zval */
1431 retBool = ret;
1432 RETURN_BOOL(retBool);
1436 * bool GEOSGeometry::isClosed()
1438 PHP_METHOD(Geometry, isClosed)
1440 GEOSGeometry *this;
1441 int ret;
1442 zend_bool retBool;
1444 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1446 ret = GEOSisClosed(this);
1447 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
1449 /* return_value is a zval */
1450 retBool = ret;
1451 RETURN_BOOL(retBool);
1455 * string GEOSGeometry::typeName()
1457 PHP_METHOD(Geometry, typeName)
1459 GEOSGeometry *this;
1460 char *typ;
1461 char *typVal;
1463 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1465 /* TODO: define constant strings instead... */
1467 typ = GEOSGeomType(this);
1468 if ( ! typ ) RETURN_NULL(); /* should get an exception first */
1470 typVal = estrdup(typ);
1471 GEOSFree(typ);
1473 RETURN_STRING(typVal, 0);
1477 * long GEOSGeometry::typeId()
1479 PHP_METHOD(Geometry, typeId)
1481 GEOSGeometry *this;
1482 long typ;
1484 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1486 /* TODO: define constant strings instead... */
1488 typ = GEOSGeomTypeId(this);
1489 if ( typ == -1 ) RETURN_NULL(); /* should get an exception first */
1491 RETURN_LONG(typ);
1495 * long GEOSGeometry::getSRID()
1497 PHP_METHOD(Geometry, getSRID)
1499 GEOSGeometry *geom;
1500 long int ret;
1502 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1504 ret = GEOSGetSRID(geom);
1506 RETURN_LONG(ret);
1510 * void GEOSGeometry::setSRID(long)
1512 PHP_METHOD(Geometry, setSRID)
1514 GEOSGeometry *geom;
1515 long int srid;
1517 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1519 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1520 &srid) == FAILURE) {
1521 RETURN_NULL();
1524 GEOSSetSRID(geom, srid);
1528 * long GEOSGeometry::numGeometries()
1530 PHP_METHOD(Geometry, numGeometries)
1532 GEOSGeometry *geom;
1533 long int ret;
1535 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1537 ret = GEOSGetNumGeometries(geom);
1538 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1540 RETURN_LONG(ret);
1544 * GEOSGeometry GEOSGeometry::geometryN()
1546 PHP_METHOD(Geometry, geometryN)
1548 GEOSGeometry *geom;
1549 const GEOSGeometry *c;
1550 GEOSGeometry *cc;
1551 long int num;
1553 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1555 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1556 &num) == FAILURE) {
1557 RETURN_NULL();
1560 if ( num >= GEOSGetNumGeometries(geom) ) RETURN_NULL();
1561 c = GEOSGetGeometryN(geom, num);
1562 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1563 cc = GEOSGeom_clone(c);
1564 if ( ! cc ) RETURN_NULL(); /* should get an exception first */
1566 object_init_ex(return_value, Geometry_ce_ptr);
1567 setRelay(return_value, cc);
1571 * long GEOSGeometry::numInteriorRings()
1573 PHP_METHOD(Geometry, numInteriorRings)
1575 GEOSGeometry *geom;
1576 long int ret;
1578 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1580 ret = GEOSGetNumInteriorRings(geom);
1581 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1583 RETURN_LONG(ret);
1587 * long GEOSGeometry::numPoints()
1589 PHP_METHOD(Geometry, numPoints)
1591 GEOSGeometry *geom;
1592 long int ret;
1594 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1596 ret = GEOSGeomGetNumPoints(geom);
1597 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1599 RETURN_LONG(ret);
1603 * double GEOSGeometry::getX()
1605 PHP_METHOD(Geometry, getX)
1607 GEOSGeometry *geom;
1608 int ret;
1609 double x;
1611 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1613 ret = GEOSGeomGetX(geom, &x);
1614 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1616 RETURN_DOUBLE(x);
1620 * double GEOSGeometry::getY()
1622 PHP_METHOD(Geometry, getY)
1624 GEOSGeometry *geom;
1625 int ret;
1626 double y;
1628 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1630 ret = GEOSGeomGetY(geom, &y);
1631 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1633 RETURN_DOUBLE(y);
1637 * GEOSGeometry GEOSGeometry::interiorRingN()
1639 PHP_METHOD(Geometry, interiorRingN)
1641 GEOSGeometry *geom;
1642 const GEOSGeometry *c;
1643 GEOSGeometry *cc;
1644 long int num;
1646 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1648 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1649 &num) == FAILURE) {
1650 RETURN_NULL();
1653 if ( num >= GEOSGetNumInteriorRings(geom) ) RETURN_NULL();
1654 c = GEOSGetInteriorRingN(geom, num);
1655 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1656 cc = GEOSGeom_clone(c);
1657 if ( ! cc ) RETURN_NULL(); /* should get an exception first */
1659 object_init_ex(return_value, Geometry_ce_ptr);
1660 setRelay(return_value, cc);
1664 * GEOSGeometry GEOSGeometry::exteriorRing()
1666 PHP_METHOD(Geometry, exteriorRing)
1668 GEOSGeometry *geom;
1669 const GEOSGeometry *c;
1670 GEOSGeometry *cc;
1672 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1674 c = GEOSGetExteriorRing(geom);
1675 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1676 cc = GEOSGeom_clone(c);
1677 if ( ! cc ) RETURN_NULL(); /* should get an exception first */
1679 object_init_ex(return_value, Geometry_ce_ptr);
1680 setRelay(return_value, cc);
1684 * long GEOSGeometry::numCoordinates()
1686 PHP_METHOD(Geometry, numCoordinates)
1688 GEOSGeometry *geom;
1689 long int ret;
1691 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1693 ret = GEOSGetNumCoordinates(geom);
1694 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1696 RETURN_LONG(ret);
1700 * long GEOSGeometry::dimension()
1701 * 0:puntual 1:lineal 2:areal
1703 PHP_METHOD(Geometry, dimension)
1705 GEOSGeometry *geom;
1706 long int ret;
1708 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1710 ret = GEOSGeom_getDimensions(geom);
1711 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1713 RETURN_LONG(ret);
1717 * long GEOSGeometry::coordinateDimension()
1719 PHP_METHOD(Geometry, coordinateDimension)
1721 GEOSGeometry *geom;
1722 long int ret;
1724 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1726 ret = GEOSGeom_getCoordinateDimension(geom);
1727 if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
1729 RETURN_LONG(ret);
1733 * GEOSGeometry GEOSGeometry::pointN()
1735 PHP_METHOD(Geometry, pointN)
1737 GEOSGeometry *geom;
1738 GEOSGeometry *c;
1739 long int num;
1741 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1743 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1744 &num) == FAILURE) {
1745 RETURN_NULL();
1748 if ( num >= GEOSGeomGetNumPoints(geom) ) RETURN_NULL();
1749 c = GEOSGeomGetPointN(geom, num);
1750 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1752 object_init_ex(return_value, Geometry_ce_ptr);
1753 setRelay(return_value, c);
1757 * GEOSGeometry GEOSGeometry::startPoint()
1759 PHP_METHOD(Geometry, startPoint)
1761 GEOSGeometry *geom;
1762 GEOSGeometry *c;
1764 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1766 c = GEOSGeomGetStartPoint(geom);
1767 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1769 object_init_ex(return_value, Geometry_ce_ptr);
1770 setRelay(return_value, c);
1774 * GEOSGeometry GEOSGeometry::endPoint()
1776 PHP_METHOD(Geometry, endPoint)
1778 GEOSGeometry *geom;
1779 GEOSGeometry *c;
1781 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1783 c = GEOSGeomGetEndPoint(geom);
1784 if ( ! c ) RETURN_NULL(); /* should get an exception first */
1786 object_init_ex(return_value, Geometry_ce_ptr);
1787 setRelay(return_value, c);
1791 * double GEOSGeometry::area()
1793 PHP_METHOD(Geometry, area)
1795 GEOSGeometry *geom;
1796 double area;
1797 int ret;
1799 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1801 ret = GEOSArea(geom, &area);
1802 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1804 RETURN_DOUBLE(area);
1808 * double GEOSGeometry::length()
1810 PHP_METHOD(Geometry, length)
1812 GEOSGeometry *geom;
1813 double length;
1814 int ret;
1816 geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1818 ret = GEOSLength(geom, &length);
1819 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1821 RETURN_DOUBLE(length);
1825 * double GEOSGeometry::distance(GEOSGeometry)
1827 PHP_METHOD(Geometry, distance)
1829 GEOSGeometry *this;
1830 GEOSGeometry *other;
1831 zval *zobj;
1832 double dist;
1833 int ret;
1835 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1837 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
1838 &zobj) == FAILURE)
1840 RETURN_NULL();
1843 other = getRelay(zobj, Geometry_ce_ptr);
1845 ret = GEOSDistance(this, other, &dist);
1846 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1848 RETURN_DOUBLE(dist);
1852 * double GEOSGeometry::hausdorffDistance(GEOSGeometry)
1854 PHP_METHOD(Geometry, hausdorffDistance)
1856 GEOSGeometry *this;
1857 GEOSGeometry *other;
1858 zval *zobj;
1859 double dist;
1860 int ret;
1862 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1864 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
1865 &zobj) == FAILURE)
1867 RETURN_NULL();
1870 other = getRelay(zobj, Geometry_ce_ptr);
1872 ret = GEOSHausdorffDistance(this, other, &dist);
1873 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1875 RETURN_DOUBLE(dist);
1878 PHP_METHOD(Geometry, snapTo)
1880 GEOSGeometry *this;
1881 GEOSGeometry *other;
1882 GEOSGeometry *ret;
1883 double tolerance;
1884 zval *zobj;
1886 this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
1888 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "od", &zobj,
1889 &tolerance) == FAILURE) {
1890 RETURN_NULL();
1892 other = getRelay(zobj, Geometry_ce_ptr);
1894 ret = GEOSSnap(this, other, tolerance);
1895 if ( ! ret ) RETURN_NULL(); /* should get an exception first */
1897 /* return_value is a zval */
1898 object_init_ex(return_value, Geometry_ce_ptr);
1899 setRelay(return_value, ret);
1904 /* -- class GEOSWKTReader -------------------- */
1906 PHP_METHOD(WKTReader, __construct);
1907 PHP_METHOD(WKTReader, read);
1909 static function_entry WKTReader_methods[] = {
1910 PHP_ME(WKTReader, __construct, NULL, 0)
1911 PHP_ME(WKTReader, read, NULL, 0)
1912 {NULL, NULL, NULL}
1915 static zend_class_entry *WKTReader_ce_ptr;
1917 static zend_object_handlers WKTReader_object_handlers;
1919 static void
1920 WKTReader_dtor (void *object TSRMLS_DC)
1922 Proxy *obj = (Proxy *)object;
1923 GEOSWKTReader_destroy((GEOSWKTReader*)obj->relay);
1925 zend_hash_destroy(obj->std.properties);
1926 FREE_HASHTABLE(obj->std.properties);
1928 efree(obj);
1931 static zend_object_value
1932 WKTReader_create_obj (zend_class_entry *type TSRMLS_DC)
1934 return Gen_create_obj(type, WKTReader_dtor, &WKTReader_object_handlers);
1938 PHP_METHOD(WKTReader, __construct)
1940 GEOSWKTReader* obj;
1941 zval *object = getThis();
1943 obj = GEOSWKTReader_create();
1944 if ( ! obj ) {
1945 php_error_docref(NULL TSRMLS_CC, E_ERROR,
1946 "GEOSWKTReader_create() failed (didn't initGEOS?)");
1949 setRelay(object, obj);
1952 PHP_METHOD(WKTReader, read)
1954 GEOSWKTReader *reader;
1955 GEOSGeometry *geom;
1956 char* wkt;
1957 int wktlen;
1959 reader = (GEOSWKTReader*)getRelay(getThis(), WKTReader_ce_ptr);
1961 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
1962 &wkt, &wktlen) == FAILURE)
1964 RETURN_NULL();
1967 geom = GEOSWKTReader_read(reader, wkt);
1968 /* we'll probably get an exception if geom is null */
1969 if ( ! geom ) RETURN_NULL();
1971 /* return_value is a zval */
1972 object_init_ex(return_value, Geometry_ce_ptr);
1973 setRelay(return_value, geom);
1977 /* -- class GEOSWKTWriter -------------------- */
1979 PHP_METHOD(WKTWriter, __construct);
1980 PHP_METHOD(WKTWriter, write);
1981 PHP_METHOD(WKTWriter, setTrim);
1982 PHP_METHOD(WKTWriter, setRoundingPrecision);
1983 PHP_METHOD(WKTWriter, setOutputDimension);
1984 PHP_METHOD(WKTWriter, getOutputDimension);
1985 PHP_METHOD(WKTWriter, setOld3D);
1987 static function_entry WKTWriter_methods[] = {
1988 PHP_ME(WKTWriter, __construct, NULL, 0)
1989 PHP_ME(WKTWriter, write, NULL, 0)
1990 PHP_ME(WKTWriter, setTrim, NULL, 0)
1991 PHP_ME(WKTWriter, setRoundingPrecision, NULL, 0)
1992 PHP_ME(WKTWriter, setOutputDimension, NULL, 0)
1993 PHP_ME(WKTWriter, getOutputDimension, NULL, 0)
1994 PHP_ME(WKTWriter, setOld3D, NULL, 0)
1995 {NULL, NULL, NULL}
1998 static zend_class_entry *WKTWriter_ce_ptr;
2000 static zend_object_handlers WKTWriter_object_handlers;
2002 static void
2003 WKTWriter_dtor (void *object TSRMLS_DC)
2005 Proxy *obj = (Proxy *)object;
2006 GEOSWKTWriter_destroy((GEOSWKTWriter*)obj->relay);
2008 zend_hash_destroy(obj->std.properties);
2009 FREE_HASHTABLE(obj->std.properties);
2011 efree(obj);
2014 static zend_object_value
2015 WKTWriter_create_obj (zend_class_entry *type TSRMLS_DC)
2017 return Gen_create_obj(type, WKTWriter_dtor, &WKTWriter_object_handlers);
2020 PHP_METHOD(WKTWriter, __construct)
2022 GEOSWKTWriter* obj;
2023 zval *object = getThis();
2025 obj = GEOSWKTWriter_create();
2026 if ( ! obj ) {
2027 php_error_docref(NULL TSRMLS_CC, E_ERROR,
2028 "GEOSWKTWriter_create() failed (didn't initGEOS?)");
2031 setRelay(object, obj);
2034 PHP_METHOD(WKTWriter, write)
2036 GEOSWKTWriter *writer;
2037 zval *zobj;
2038 GEOSGeometry *geom;
2039 char* wkt;
2040 char* retstr;
2042 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2044 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
2045 == FAILURE)
2047 RETURN_NULL();
2050 geom = getRelay(zobj, Geometry_ce_ptr);
2052 wkt = GEOSWKTWriter_write(writer, geom);
2053 /* we'll probably get an exception if wkt is null */
2054 if ( ! wkt ) RETURN_NULL();
2056 retstr = estrdup(wkt);
2057 GEOSFree(wkt);
2059 RETURN_STRING(retstr, 0);
2062 PHP_METHOD(WKTWriter, setTrim)
2064 GEOSWKTWriter *writer;
2065 zend_bool trimval;
2066 char trim;
2068 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2070 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &trimval)
2071 == FAILURE)
2073 RETURN_NULL();
2076 trim = trimval;
2077 GEOSWKTWriter_setTrim(writer, trim);
2080 PHP_METHOD(WKTWriter, setRoundingPrecision)
2082 GEOSWKTWriter *writer;
2083 long int prec;
2085 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2087 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &prec)
2088 == FAILURE)
2090 RETURN_NULL();
2093 GEOSWKTWriter_setRoundingPrecision(writer, prec);
2097 * void GEOSWKTWriter::setOutputDimension()
2099 PHP_METHOD(WKTWriter, setOutputDimension)
2101 GEOSWKTWriter *writer;
2102 long int dim;
2104 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2106 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
2107 == FAILURE)
2109 RETURN_NULL();
2112 GEOSWKTWriter_setOutputDimension(writer, dim);
2116 * long GEOSWKTWriter::getOutputDimension()
2118 PHP_METHOD(WKTWriter, getOutputDimension)
2120 GEOSWKTWriter *writer;
2121 long int ret;
2123 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2125 ret = GEOSWKTWriter_getOutputDimension(writer);
2127 RETURN_LONG(ret);
2130 PHP_METHOD(WKTWriter, setOld3D)
2132 GEOSWKTWriter *writer;
2133 zend_bool bval;
2134 int val;
2136 writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
2138 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &bval)
2139 == FAILURE)
2141 RETURN_NULL();
2144 val = bval;
2145 GEOSWKTWriter_setOld3D(writer, val);
2148 /* -- class GEOSWKBWriter -------------------- */
2150 PHP_METHOD(WKBWriter, __construct);
2151 PHP_METHOD(WKBWriter, getOutputDimension);
2152 PHP_METHOD(WKBWriter, setOutputDimension);
2153 PHP_METHOD(WKBWriter, getByteOrder);
2154 PHP_METHOD(WKBWriter, setByteOrder);
2155 PHP_METHOD(WKBWriter, setIncludeSRID);
2156 PHP_METHOD(WKBWriter, getIncludeSRID);
2157 PHP_METHOD(WKBWriter, writeHEX);
2159 static function_entry WKBWriter_methods[] = {
2160 PHP_ME(WKBWriter, __construct, NULL, 0)
2161 PHP_ME(WKBWriter, getOutputDimension, NULL, 0)
2162 PHP_ME(WKBWriter, setOutputDimension, NULL, 0)
2163 PHP_ME(WKBWriter, getByteOrder, NULL, 0)
2164 PHP_ME(WKBWriter, setByteOrder, NULL, 0)
2165 PHP_ME(WKBWriter, getIncludeSRID, NULL, 0)
2166 PHP_ME(WKBWriter, setIncludeSRID, NULL, 0)
2167 PHP_ME(WKBWriter, writeHEX, NULL, 0)
2168 {NULL, NULL, NULL}
2171 static zend_class_entry *WKBWriter_ce_ptr;
2173 static zend_object_handlers WKBWriter_object_handlers;
2175 static void
2176 WKBWriter_dtor (void *object TSRMLS_DC)
2178 Proxy *obj = (Proxy *)object;
2179 GEOSWKBWriter_destroy((GEOSWKBWriter*)obj->relay);
2181 zend_hash_destroy(obj->std.properties);
2182 FREE_HASHTABLE(obj->std.properties);
2184 efree(obj);
2187 static zend_object_value
2188 WKBWriter_create_obj (zend_class_entry *type TSRMLS_DC)
2190 return Gen_create_obj(type, WKBWriter_dtor, &WKBWriter_object_handlers);
2194 * GEOSWKBWriter w = new GEOSWKBWriter()
2196 PHP_METHOD(WKBWriter, __construct)
2198 GEOSWKBWriter* obj;
2199 zval *object = getThis();
2201 obj = GEOSWKBWriter_create();
2202 if ( ! obj ) {
2203 php_error_docref(NULL TSRMLS_CC, E_ERROR,
2204 "GEOSWKBWriter_create() failed (didn't initGEOS?)");
2207 setRelay(object, obj);
2211 * long GEOSWKBWriter::getOutputDimension();
2213 PHP_METHOD(WKBWriter, getOutputDimension)
2215 GEOSWKBWriter *writer;
2216 long int ret;
2218 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2220 ret = GEOSWKBWriter_getOutputDimension(writer);
2222 RETURN_LONG(ret);
2226 * void GEOSWKBWriter::setOutputDimension(dims);
2228 PHP_METHOD(WKBWriter, setOutputDimension)
2230 GEOSWKBWriter *writer;
2231 long int dim;
2233 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2235 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
2236 == FAILURE)
2238 RETURN_NULL();
2241 GEOSWKBWriter_setOutputDimension(writer, dim);
2246 * string GEOSWKBWriter::writeHEX(GEOSGeometry)
2248 PHP_METHOD(WKBWriter, writeHEX)
2250 GEOSWKBWriter *writer;
2251 zval *zobj;
2252 GEOSGeometry *geom;
2253 char *ret;
2254 size_t retsize; /* useless... */
2255 char* retstr;
2257 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2259 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
2260 == FAILURE)
2262 RETURN_NULL();
2265 geom = getRelay(zobj, Geometry_ce_ptr);
2267 ret = (char*)GEOSWKBWriter_writeHEX(writer, geom, &retsize);
2268 /* we'll probably get an exception if ret is null */
2269 if ( ! ret ) RETURN_NULL();
2271 retstr = estrndup(ret, retsize);
2272 GEOSFree(ret);
2274 RETURN_STRING(retstr, 0);
2278 * long GEOSWKBWriter::getByteOrder();
2280 PHP_METHOD(WKBWriter, getByteOrder)
2282 GEOSWKBWriter *writer;
2283 long int ret;
2285 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2287 ret = GEOSWKBWriter_getByteOrder(writer);
2289 RETURN_LONG(ret);
2293 * void GEOSWKBWriter::setByteOrder(dims);
2295 PHP_METHOD(WKBWriter, setByteOrder)
2297 GEOSWKBWriter *writer;
2298 long int dim;
2300 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2302 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
2303 == FAILURE)
2305 RETURN_NULL();
2308 GEOSWKBWriter_setByteOrder(writer, dim);
2313 * bool GEOSWKBWriter::getIncludeSRID();
2315 PHP_METHOD(WKBWriter, getIncludeSRID)
2317 GEOSWKBWriter *writer;
2318 int ret;
2319 zend_bool retBool;
2321 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2323 ret = GEOSWKBWriter_getIncludeSRID(writer);
2324 retBool = ret;
2326 RETURN_BOOL(retBool);
2330 * void GEOSWKBWriter::setIncludeSRID(bool);
2332 PHP_METHOD(WKBWriter, setIncludeSRID)
2334 GEOSWKBWriter *writer;
2335 int inc;
2336 zend_bool incVal;
2338 writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
2340 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &incVal)
2341 == FAILURE)
2343 RETURN_NULL();
2346 inc = incVal;
2347 GEOSWKBWriter_setIncludeSRID(writer, inc);
2350 /* -- class GEOSWKBReader -------------------- */
2352 PHP_METHOD(WKBReader, __construct);
2353 PHP_METHOD(WKBReader, readHEX);
2355 static function_entry WKBReader_methods[] = {
2356 PHP_ME(WKBReader, __construct, NULL, 0)
2357 PHP_ME(WKBReader, readHEX, NULL, 0)
2358 {NULL, NULL, NULL}
2361 static zend_class_entry *WKBReader_ce_ptr;
2363 static zend_object_handlers WKBReader_object_handlers;
2365 static void
2366 WKBReader_dtor (void *object TSRMLS_DC)
2368 Proxy *obj = (Proxy *)object;
2369 GEOSWKBReader_destroy((GEOSWKBReader*)obj->relay);
2371 zend_hash_destroy(obj->std.properties);
2372 FREE_HASHTABLE(obj->std.properties);
2374 efree(obj);
2377 static zend_object_value
2378 WKBReader_create_obj (zend_class_entry *type TSRMLS_DC)
2380 return Gen_create_obj(type, WKBReader_dtor, &WKBReader_object_handlers);
2384 PHP_METHOD(WKBReader, __construct)
2386 GEOSWKBReader* obj;
2387 zval *object = getThis();
2389 obj = GEOSWKBReader_create();
2390 if ( ! obj ) {
2391 php_error_docref(NULL TSRMLS_CC, E_ERROR,
2392 "GEOSWKBReader_create() failed (didn't initGEOS?)");
2395 setRelay(object, obj);
2398 PHP_METHOD(WKBReader, readHEX)
2400 GEOSWKBReader *reader;
2401 GEOSGeometry *geom;
2402 unsigned char* wkb;
2403 int wkblen;
2405 reader = (GEOSWKBReader*)getRelay(getThis(), WKBReader_ce_ptr);
2407 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
2408 &wkb, &wkblen) == FAILURE)
2410 RETURN_NULL();
2413 geom = GEOSWKBReader_readHEX(reader, wkb, wkblen);
2414 /* we'll probably get an exception if geom is null */
2415 if ( ! geom ) RETURN_NULL();
2417 /* return_value is a zval */
2418 object_init_ex(return_value, Geometry_ce_ptr);
2419 setRelay(return_value, geom);
2424 /* -- Free functions ------------------------- */
2427 * string GEOSVersion()
2429 PHP_FUNCTION(GEOSVersion)
2431 char *str;
2433 str = estrdup(GEOSversion());
2434 RETURN_STRING(str, 0);
2438 * array GEOSPolygonize(GEOSGeometry $geom)
2440 * The returned array contains the following elements:
2442 * - 'rings'
2443 * Type: array of GEOSGeometry
2444 * Rings that can be formed by the costituent
2445 * linework of geometry.
2446 * - 'cut_edges' (optional)
2447 * Type: array of GEOSGeometry
2448 * Edges which are connected at both ends but
2449 * which do not form part of polygon.
2450 * - 'dangles'
2451 * Type: array of GEOSGeometry
2452 * Edges which have one or both ends which are
2453 * not incident on another edge endpoint
2454 * - 'invalid_rings'
2455 * Type: array of GEOSGeometry
2456 * Edges which form rings which are invalid
2457 * (e.g. the component lines contain a self-intersection)
2460 PHP_FUNCTION(GEOSPolygonize)
2462 GEOSGeometry *this;
2463 GEOSGeometry *rings;
2464 GEOSGeometry *cut_edges;
2465 GEOSGeometry *dangles;
2466 GEOSGeometry *invalid_rings;
2467 zval *array_elem;
2468 zval *zobj;
2470 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
2471 == FAILURE)
2473 RETURN_NULL();
2475 this = getRelay(zobj, Geometry_ce_ptr);
2477 rings = GEOSPolygonize_full(this, &cut_edges, &dangles, &invalid_rings);
2478 if ( ! rings ) RETURN_NULL(); /* should get an exception first */
2480 /* return value should be an array */
2481 array_init(return_value);
2483 MAKE_STD_ZVAL(array_elem);
2484 array_init(array_elem);
2485 dumpGeometry(rings, array_elem);
2486 GEOSGeom_destroy(rings);
2487 add_assoc_zval(return_value, "rings", array_elem);
2489 MAKE_STD_ZVAL(array_elem);
2490 array_init(array_elem);
2491 dumpGeometry(cut_edges, array_elem);
2492 GEOSGeom_destroy(cut_edges);
2493 add_assoc_zval(return_value, "cut_edges", array_elem);
2495 MAKE_STD_ZVAL(array_elem);
2496 array_init(array_elem);
2497 dumpGeometry(dangles, array_elem);
2498 GEOSGeom_destroy(dangles);
2499 add_assoc_zval(return_value, "dangles", array_elem);
2501 MAKE_STD_ZVAL(array_elem);
2502 array_init(array_elem);
2503 dumpGeometry(invalid_rings, array_elem);
2504 GEOSGeom_destroy(invalid_rings);
2505 add_assoc_zval(return_value, "invalid_rings", array_elem);
2510 * array GEOSLineMerge(GEOSGeometry $geom)
2512 PHP_FUNCTION(GEOSLineMerge)
2514 GEOSGeometry *geom_in;
2515 GEOSGeometry *geom_out;
2516 zval *zobj;
2518 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
2519 == FAILURE)
2521 RETURN_NULL();
2523 geom_in = getRelay(zobj, Geometry_ce_ptr);
2525 geom_out = GEOSLineMerge(geom_in);
2526 if ( ! geom_out ) RETURN_NULL(); /* should get an exception first */
2528 /* return value should be an array */
2529 array_init(return_value);
2530 dumpGeometry(geom_out, return_value);
2531 GEOSGeom_destroy(geom_out);
2535 * GEOSGeometry GEOSSharedPaths(GEOSGeometry $geom1, GEOSGeometry *geom2)
2537 PHP_FUNCTION(GEOSSharedPaths)
2539 GEOSGeometry *geom_in_1;
2540 GEOSGeometry *geom_in_2;
2541 GEOSGeometry *geom_out;
2542 zval *zobj1, *zobj2;
2544 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo", &zobj1, &zobj2)
2545 == FAILURE)
2547 RETURN_NULL();
2549 geom_in_1 = getRelay(zobj1, Geometry_ce_ptr);
2550 geom_in_2 = getRelay(zobj2, Geometry_ce_ptr);
2552 geom_out = GEOSSharedPaths(geom_in_1, geom_in_2);
2553 if ( ! geom_out ) RETURN_NULL(); /* should get an exception first */
2555 /* return_value is a zval */
2556 object_init_ex(return_value, Geometry_ce_ptr);
2557 setRelay(return_value, geom_out);
2561 * bool GEOSRelateMatch(string matrix, string pattern)
2563 PHP_FUNCTION(GEOSRelateMatch)
2565 char* mat = NULL;
2566 int matlen;
2567 char* pat = NULL;
2568 int patlen;
2569 int ret;
2570 zend_bool retBool;
2572 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
2573 &mat, &matlen, &pat, &patlen) == FAILURE)
2575 RETURN_NULL();
2578 ret = GEOSRelatePatternMatch(mat, pat);
2579 if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
2581 /* return_value is a zval */
2582 retBool = ret;
2583 RETURN_BOOL(retBool);
2586 /* ------ Initialization / Deinitialization / Meta ------------------ */
2588 /* per-module initialization */
2589 PHP_MINIT_FUNCTION(geos)
2591 zend_class_entry ce;
2593 /* WKTReader */
2594 INIT_CLASS_ENTRY(ce, "GEOSWKTReader", WKTReader_methods);
2595 WKTReader_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
2596 WKTReader_ce_ptr->create_object = WKTReader_create_obj;
2597 memcpy(&WKTReader_object_handlers,
2598 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2599 WKTReader_object_handlers.clone_obj = NULL;
2601 /* WKTWriter */
2602 INIT_CLASS_ENTRY(ce, "GEOSWKTWriter", WKTWriter_methods);
2603 WKTWriter_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
2604 WKTWriter_ce_ptr->create_object = WKTWriter_create_obj;
2605 memcpy(&WKTWriter_object_handlers,
2606 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2607 WKTWriter_object_handlers.clone_obj = NULL;
2609 /* Geometry */
2610 INIT_CLASS_ENTRY(ce, "GEOSGeometry", Geometry_methods);
2611 Geometry_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
2612 Geometry_ce_ptr->create_object = Geometry_create_obj;
2613 memcpy(&Geometry_object_handlers,
2614 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2615 Geometry_object_handlers.clone_obj = NULL;
2616 /* Geometry serialization */
2617 Geometry_ce_ptr->serialize = Geometry_serialize;
2618 Geometry_ce_ptr->unserialize = Geometry_deserialize;
2620 /* WKBWriter */
2621 INIT_CLASS_ENTRY(ce, "GEOSWKBWriter", WKBWriter_methods);
2622 WKBWriter_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
2623 WKBWriter_ce_ptr->create_object = WKBWriter_create_obj;
2624 memcpy(&WKBWriter_object_handlers,
2625 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2626 WKBWriter_object_handlers.clone_obj = NULL;
2628 /* WKBReader */
2629 INIT_CLASS_ENTRY(ce, "GEOSWKBReader", WKBReader_methods);
2630 WKBReader_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
2631 WKBReader_ce_ptr->create_object = WKBReader_create_obj;
2632 memcpy(&WKBReader_object_handlers,
2633 zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2634 WKBReader_object_handlers.clone_obj = NULL;
2637 /* Constants */
2638 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_ROUND", GEOSBUF_CAP_ROUND,
2639 CONST_CS|CONST_PERSISTENT);
2640 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_FLAT", GEOSBUF_CAP_FLAT,
2641 CONST_CS|CONST_PERSISTENT);
2642 REGISTER_LONG_CONSTANT("GEOSBUF_CAP_SQUARE", GEOSBUF_CAP_SQUARE,
2643 CONST_CS|CONST_PERSISTENT);
2644 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_ROUND", GEOSBUF_JOIN_ROUND,
2645 CONST_CS|CONST_PERSISTENT);
2646 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_MITRE", GEOSBUF_JOIN_MITRE,
2647 CONST_CS|CONST_PERSISTENT);
2648 REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_BEVEL", GEOSBUF_JOIN_BEVEL,
2649 CONST_CS|CONST_PERSISTENT);
2651 REGISTER_LONG_CONSTANT("GEOS_POINT", GEOS_POINT,
2652 CONST_CS|CONST_PERSISTENT);
2653 REGISTER_LONG_CONSTANT("GEOS_LINESTRING", GEOS_LINESTRING,
2654 CONST_CS|CONST_PERSISTENT);
2655 REGISTER_LONG_CONSTANT("GEOS_LINEARRING", GEOS_LINEARRING,
2656 CONST_CS|CONST_PERSISTENT);
2657 REGISTER_LONG_CONSTANT("GEOS_POLYGON", GEOS_POLYGON,
2658 CONST_CS|CONST_PERSISTENT);
2659 REGISTER_LONG_CONSTANT("GEOS_MULTIPOINT", GEOS_MULTIPOINT,
2660 CONST_CS|CONST_PERSISTENT);
2661 REGISTER_LONG_CONSTANT("GEOS_MULTILINESTRING", GEOS_MULTILINESTRING,
2662 CONST_CS|CONST_PERSISTENT);
2663 REGISTER_LONG_CONSTANT("GEOS_MULTIPOLYGON", GEOS_MULTIPOLYGON,
2664 CONST_CS|CONST_PERSISTENT);
2665 REGISTER_LONG_CONSTANT("GEOS_GEOMETRYCOLLECTION", GEOS_GEOMETRYCOLLECTION,
2666 CONST_CS|CONST_PERSISTENT);
2668 REGISTER_LONG_CONSTANT("GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE",
2669 GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE,
2670 CONST_CS|CONST_PERSISTENT);
2672 REGISTER_LONG_CONSTANT("GEOSRELATE_BNR_MOD2", GEOSRELATE_BNR_MOD2,
2673 CONST_CS|CONST_PERSISTENT);
2674 REGISTER_LONG_CONSTANT("GEOSRELATE_BNR_OGC", GEOSRELATE_BNR_OGC,
2675 CONST_CS|CONST_PERSISTENT);
2676 REGISTER_LONG_CONSTANT("GEOSRELATE_BNR_ENDPOINT", GEOSRELATE_BNR_ENDPOINT,
2677 CONST_CS|CONST_PERSISTENT);
2678 REGISTER_LONG_CONSTANT("GEOSRELATE_BNR_MULTIVALENT_ENDPOINT",
2679 GEOSRELATE_BNR_MULTIVALENT_ENDPOINT,
2680 CONST_CS|CONST_PERSISTENT);
2681 REGISTER_LONG_CONSTANT("GEOSRELATE_BNR_MONOVALENT_ENDPOINT",
2682 GEOSRELATE_BNR_MONOVALENT_ENDPOINT,
2683 CONST_CS|CONST_PERSISTENT);
2685 return SUCCESS;
2688 /* per-module shutdown */
2689 PHP_MSHUTDOWN_FUNCTION(geos)
2691 delGeometrySerializer();
2692 delGeometryDeserializer();
2693 return SUCCESS;
2696 /* per-request initialization */
2697 PHP_RINIT_FUNCTION(geos)
2699 initGEOS(noticeHandler, errorHandler);
2700 return SUCCESS;
2703 /* pre-request destruction */
2704 PHP_RSHUTDOWN_FUNCTION(geos)
2706 finishGEOS();
2707 return SUCCESS;
2710 /* module info */
2711 PHP_MINFO_FUNCTION(geos)
2713 php_info_print_table_start();
2714 php_info_print_table_row(2,
2715 "GEOS - Geometry Engine Open Source", "enabled");
2716 php_info_print_table_row(2,
2717 "Version", PHP_GEOS_VERSION);
2718 php_info_print_table_end();