forked from geos/php-geos
1
0
Fork 0
php-geos/geos.c

3434 lines
86 KiB
C
Executable File

/***********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://trac.osgeo.org/geos
*
* Copyright (C) 2010 Sandro Santilli <strk@kbt.io>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*
***********************************************************************/
/* PHP stuff */
#include "php.h"
#include "ext/standard/info.h" /* for php_info_... */
#include "Zend/zend_exceptions.h" /* for zend_throw_exception_object */
/* GEOS stuff */
#include "geos_c.h"
/* Own stuff */
#include "php_geos.h"
static ZEND_DECLARE_MODULE_GLOBALS(geos);
static PHP_GINIT_FUNCTION(geos);
PHP_MINIT_FUNCTION(geos);
PHP_MSHUTDOWN_FUNCTION(geos);
PHP_RINIT_FUNCTION(geos);
PHP_RSHUTDOWN_FUNCTION(geos);
PHP_MINFO_FUNCTION(geos);
PHP_FUNCTION(GEOSVersion);
PHP_FUNCTION(GEOSPolygonize);
PHP_FUNCTION(GEOSLineMerge);
#ifdef HAVE_GEOS_SHARED_PATHS
PHP_FUNCTION(GEOSSharedPaths);
#endif
#ifdef HAVE_GEOS_RELATE_PATTERN_MATCH
PHP_FUNCTION(GEOSRelateMatch);
#endif
#if PHP_VERSION_ID < 50399
#define zend_function_entry function_entry
#endif
#if PHP_VERSION_ID >= 70000
# define GEOS_PHP_DTOR_OBJECT zend_object
# define zend_object_value zend_object *
# define zend_uint size_t
# define MAKE_STD_ZVAL(x) x = emalloc(sizeof(zval))
# define GEOS_PHP_RETURN_STRING(x) { RETVAL_STRING((x)); efree((x)); return; }
# define GEOS_PHP_RETURN_STRINGL(x,s) { RETVAL_STRINGL((x),(s)); efree((x)); return; }
# define GEOS_PHP_ADD_ASSOC_ARRAY(a,k,v) { add_assoc_string((a), (k), (v)); efree((v)); }
# define GEOS_PHP_ADD_ASSOC_ZVAL(a,k,v) { add_assoc_zval((a), (k), (v)); efree((v)); }
# define GEOS_PHP_HASH_GET_CUR_KEY(s,k,i) zend_hash_get_current_key((s), (k), (i))
# define GEOS_PHP_HASH_GET_CUR_DATA(h,d) ( d = zend_hash_get_current_data((h)) )
# define GEOS_PHP_ZVAL zval *
#else /* PHP_VERSION_ID < 70000 */
# define GEOS_PHP_DTOR_OBJECT void
# define GEOS_PHP_RETURN_STRING(x) RETURN_STRING((x),0)
# define GEOS_PHP_RETURN_STRINGL(x,s) RETURN_STRINGL((x),(s),0)
# define GEOS_PHP_ADD_ASSOC_ARRAY(a,k,v) add_assoc_string((a), (k), (v), 0)
# define GEOS_PHP_ADD_ASSOC_ZVAL(a,k,v) add_assoc_zval((a), (k), (v))
# define GEOS_PHP_HASH_GET_CUR_KEY(s,k,i) zend_hash_get_current_key((s), (k), (i), 0)
# define zend_string char
# define ZSTR_VAL(x) (x)
# define GEOS_PHP_HASH_GET_CUR_DATA(h,d) zend_hash_get_current_data((h),(void**)&(d))
# define GEOS_PHP_ZVAL zval **
#endif
static zend_function_entry geos_functions[] = {
PHP_FE(GEOSVersion, NULL)
PHP_FE(GEOSPolygonize, NULL)
PHP_FE(GEOSLineMerge, NULL)
# ifdef HAVE_GEOS_SHARED_PATHS
PHP_FE(GEOSSharedPaths, NULL)
# endif
# ifdef HAVE_GEOS_RELATE_PATTERN_MATCH
PHP_FE(GEOSRelateMatch, NULL)
# endif
{NULL, NULL, NULL}
};
zend_module_entry geos_module_entry = {
STANDARD_MODULE_HEADER,
PHP_GEOS_EXTNAME,
geos_functions,
PHP_MINIT(geos), /* module init function */
PHP_MSHUTDOWN(geos), /* module shutdown function */
PHP_RINIT(geos), /* request init function */
PHP_RSHUTDOWN(geos), /* request shutdown function */
PHP_MINFO(geos), /* module info function */
PHP_GEOS_VERSION,
PHP_MODULE_GLOBALS(geos), /* globals descriptor */
PHP_GINIT(geos), /* globals ctor */
NULL, /* globals dtor */
NULL, /* post deactivate */
STANDARD_MODULE_PROPERTIES_EX
};
#ifdef COMPILE_DL_GEOS
ZEND_GET_MODULE(geos)
#endif
/* -- Utility functions ---------------------- */
static void noticeHandler(const char *fmt, ...)
{
TSRMLS_FETCH();
char message[256];
va_list args;
va_start(args, fmt);
vsnprintf(message, sizeof(message) - 1, fmt, args);
va_end(args);
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s", message);
}
static void errorHandler(const char *fmt, ...)
{
TSRMLS_FETCH();
char message[256];
va_list args;
va_start(args, fmt);
vsnprintf(message, sizeof(message) - 1, fmt, args);
va_end(args);
/* TODO: use a GEOSException ? */
zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C),
1 TSRMLS_CC, "%s", message);
}
typedef struct Proxy_t {
#if PHP_VERSION_ID >= 70000
int id;
void* relay;
zend_object std;
#else
zend_object std;
void* relay;
#endif
} Proxy;
#if PHP_VERSION_ID >= 70000
static inline Proxy *php_geos_fetch_object(zend_object *obj) {
return (Proxy *)((char *) obj - XtOffsetOf(Proxy, std));
}
# define Z_GEOS_OBJ_P(zv) (Proxy *)((char *) (Z_OBJ_P(zv)) - XtOffsetOf(Proxy, std))
#else
# ifdef Z_OBJ
# define Z_GEOS_OBJ_P(zv) (Proxy*)Z_OBJ(*val TSRMLS_CC)
# else
# define Z_GEOS_OBJ_P(zv) (Proxy*)zend_object_store_get_object(val TSRMLS_CC)
# endif
#endif
static void
setRelay(zval* val, void* obj) {
TSRMLS_FETCH();
Proxy* proxy = Z_GEOS_OBJ_P(val);
proxy->relay = obj;
}
static inline void *
getRelay(zval* val, zend_class_entry* ce) {
TSRMLS_FETCH();
Proxy* proxy = Z_GEOS_OBJ_P(val);
if ( proxy->std.ce != ce ) {
php_error_docref(NULL TSRMLS_CC, E_ERROR,
"Relay object is not an %s", ce->name);
}
if ( ! proxy->relay ) {
php_error_docref(NULL TSRMLS_CC, E_ERROR,
"Relay object for object of type %s is not set", ce->name);
}
return proxy->relay;
}
static long getZvalAsLong(GEOS_PHP_ZVAL val)
{
long ret;
zval tmp;
#if PHP_VERSION_ID >= 70000
tmp = *val;
#else
tmp = **val;
#endif
zval_copy_ctor(&tmp);
convert_to_long(&tmp);
ret = Z_LVAL(tmp);
zval_dtor(&tmp);
return ret;
}
static long getZvalAsDouble(GEOS_PHP_ZVAL val)
{
double ret;
zval tmp;
#if PHP_VERSION_ID >= 70000
tmp = *val;
#else
tmp = **val;
#endif
zval_copy_ctor(&tmp);
convert_to_double(&tmp);
ret = Z_DVAL(tmp);
zval_dtor(&tmp);
return ret;
}
static zend_object_value
Gen_create_obj (zend_class_entry *type,
void (*dtor)(GEOS_PHP_DTOR_OBJECT *object TSRMLS_DC),
zend_object_handlers* handlers)
{
TSRMLS_FETCH();
#if PHP_VERSION_ID >= 70000
Proxy *obj = (Proxy *) ecalloc(1, sizeof(Proxy) + zend_object_properties_size(type));
zend_object_std_init(&obj->std, type TSRMLS_CC);
object_properties_init(&obj->std, type);
obj->std.handlers = handlers;
/* TODO: install the destructor ? (dtor) ! */
/* TODO: do not allocate a full Proxy if we're going to use an object */
return &obj->std;
#else /* PHP_VERSION_ID < 70000 */
zend_object_value retval;
Proxy *obj = (Proxy *)ecalloc(1, sizeof(Proxy));
obj->std.ce = type;
ALLOC_HASHTABLE(obj->std.properties);
zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
#if PHP_VERSION_ID < 50399
zend_hash_copy(obj->std.properties, &type->default_properties,
(copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval *));
#else
object_properties_init(&(obj->std), type);
#endif
retval.handle = zend_objects_store_put(obj, NULL, dtor, NULL TSRMLS_CC);
retval.handlers = handlers;
return retval;
#endif /* PHP_VERSION_ID < 70000 */
}
/* -- class GEOSGeometry -------------------- */
PHP_METHOD(Geometry, __construct);
PHP_METHOD(Geometry, __toString);
PHP_METHOD(Geometry, project);
PHP_METHOD(Geometry, interpolate);
PHP_METHOD(Geometry, buffer);
#ifdef HAVE_GEOS_OFFSET_CURVE
PHP_METHOD(Geometry, offsetCurve);
#endif
PHP_METHOD(Geometry, envelope);
PHP_METHOD(Geometry, intersection);
PHP_METHOD(Geometry, convexHull);
PHP_METHOD(Geometry, difference);
PHP_METHOD(Geometry, symDifference);
PHP_METHOD(Geometry, boundary);
PHP_METHOD(Geometry, union); /* also does union cascaded */
PHP_METHOD(Geometry, pointOnSurface);
PHP_METHOD(Geometry, centroid);
PHP_METHOD(Geometry, relate);
#ifdef HAVE_GEOS_RELATE_BOUNDARY_NODE_RULE
PHP_METHOD(Geometry, relateBoundaryNodeRule);
#endif
PHP_METHOD(Geometry, simplify); /* also does topology-preserving */
PHP_METHOD(Geometry, normalize);
#ifdef HAVE_GEOS_GEOM_SET_PRECISION
PHP_METHOD(Geometry, setPrecision);
#endif
#ifdef HAVE_GEOS_GEOM_GET_PRECISION
PHP_METHOD(Geometry, getPrecision);
#endif
#ifdef HAVE_GEOS_GEOM_EXTRACT_UNIQUE_POINTS
PHP_METHOD(Geometry, extractUniquePoints);
#endif
PHP_METHOD(Geometry, disjoint);
PHP_METHOD(Geometry, touches);
PHP_METHOD(Geometry, intersects);
PHP_METHOD(Geometry, crosses);
PHP_METHOD(Geometry, within);
PHP_METHOD(Geometry, contains);
PHP_METHOD(Geometry, overlaps);
#ifdef HAVE_GEOS_COVERS
PHP_METHOD(Geometry, covers);
#endif
#ifdef HAVE_GEOS_COVERED_BY
PHP_METHOD(Geometry, coveredBy);
#endif
PHP_METHOD(Geometry, equals);
PHP_METHOD(Geometry, equalsExact);
PHP_METHOD(Geometry, isEmpty);
#ifdef HAVE_GEOS_IS_VALID_DETAIL
PHP_METHOD(Geometry, checkValidity);
#endif
PHP_METHOD(Geometry, isSimple);
PHP_METHOD(Geometry, isRing);
PHP_METHOD(Geometry, hasZ);
#ifdef HAVE_GEOS_IS_CLOSED
PHP_METHOD(Geometry, isClosed);
#endif
PHP_METHOD(Geometry, typeName);
PHP_METHOD(Geometry, typeId);
PHP_METHOD(Geometry, getSRID);
PHP_METHOD(Geometry, setSRID);
PHP_METHOD(Geometry, numGeometries);
PHP_METHOD(Geometry, geometryN);
PHP_METHOD(Geometry, numInteriorRings);
#ifdef HAVE_GEOS_GEOM_GET_NUM_POINTS
PHP_METHOD(Geometry, numPoints);
#endif
#ifdef HAVE_GEOS_GEOM_GET_X
PHP_METHOD(Geometry, getX);
#endif
#ifdef HAVE_GEOS_GEOM_GET_Y
PHP_METHOD(Geometry, getY);
#endif
PHP_METHOD(Geometry, interiorRingN);
PHP_METHOD(Geometry, exteriorRing);
PHP_METHOD(Geometry, numCoordinates);
PHP_METHOD(Geometry, dimension);
#ifdef HAVE_GEOS_GEOM_GET_COORDINATE_DIMENSION
PHP_METHOD(Geometry, coordinateDimension);
#endif
#ifdef HAVE_GEOS_GEOM_GET_POINT_N
PHP_METHOD(Geometry, pointN);
#endif
#ifdef HAVE_GEOS_GEOM_GET_START_POINT
PHP_METHOD(Geometry, startPoint);
#endif
#ifdef HAVE_GEOS_GEOM_GET_END_POINT
PHP_METHOD(Geometry, endPoint);
#endif
PHP_METHOD(Geometry, area);
PHP_METHOD(Geometry, length);
PHP_METHOD(Geometry, distance);
PHP_METHOD(Geometry, hausdorffDistance);
#ifdef HAVE_GEOS_SNAP
PHP_METHOD(Geometry, snapTo);
#endif
#ifdef HAVE_GEOS_NODE
PHP_METHOD(Geometry, node);
#endif
#ifdef HAVE_GEOS_DELAUNAY_TRIANGULATION
PHP_METHOD(Geometry, delaunayTriangulation);
#endif
#ifdef HAVE_GEOS_VORONOI_DIAGRAM
PHP_METHOD(Geometry, voronoiDiagram);
#endif
#ifdef HAVE_GEOS_CLIP_BY_RECT
PHP_METHOD(Geometry, clipByRect);
#endif
static zend_function_entry Geometry_methods[] = {
PHP_ME(Geometry, __construct, NULL, 0)
PHP_ME(Geometry, __toString, NULL, 0)
PHP_ME(Geometry, project, NULL, 0)
PHP_ME(Geometry, interpolate, NULL, 0)
PHP_ME(Geometry, buffer, NULL, 0)
# ifdef HAVE_GEOS_OFFSET_CURVE
PHP_ME(Geometry, offsetCurve, NULL, 0)
# endif
PHP_ME(Geometry, envelope, NULL, 0)
PHP_ME(Geometry, intersection, NULL, 0)
PHP_ME(Geometry, convexHull, NULL, 0)
PHP_ME(Geometry, difference, NULL, 0)
PHP_ME(Geometry, symDifference, NULL, 0)
PHP_ME(Geometry, boundary, NULL, 0)
PHP_ME(Geometry, union, NULL, 0)
PHP_ME(Geometry, pointOnSurface, NULL, 0)
PHP_ME(Geometry, centroid, NULL, 0)
PHP_ME(Geometry, relate, NULL, 0)
# ifdef HAVE_GEOS_RELATE_BOUNDARY_NODE_RULE
PHP_ME(Geometry, relateBoundaryNodeRule, NULL, 0)
# endif
PHP_ME(Geometry, simplify, NULL, 0)
PHP_ME(Geometry, normalize, NULL, 0)
# ifdef HAVE_GEOS_GEOM_SET_PRECISION
PHP_ME(Geometry, setPrecision, NULL, 0)
# endif
# if HAVE_GEOS_GEOM_GET_PRECISION
PHP_ME(Geometry, getPrecision, NULL, 0)
# endif
# ifdef HAVE_GEOS_GEOM_EXTRACT_UNIQUE_POINTS
PHP_ME(Geometry, extractUniquePoints, NULL, 0)
# endif
PHP_ME(Geometry, disjoint, NULL, 0)
PHP_ME(Geometry, touches, NULL, 0)
PHP_ME(Geometry, intersects, NULL, 0)
PHP_ME(Geometry, crosses, NULL, 0)
PHP_ME(Geometry, within, NULL, 0)
PHP_ME(Geometry, contains, NULL, 0)
PHP_ME(Geometry, overlaps, NULL, 0)
# ifdef HAVE_GEOS_COVERS
PHP_ME(Geometry, covers, NULL, 0)
# endif
# ifdef HAVE_GEOS_COVERED_BY
PHP_ME(Geometry, coveredBy, NULL, 0)
# endif
PHP_ME(Geometry, equals, NULL, 0)
PHP_ME(Geometry, equalsExact, NULL, 0)
PHP_ME(Geometry, isEmpty, NULL, 0)
# ifdef HAVE_GEOS_IS_VALID_DETAIL
PHP_ME(Geometry, checkValidity, NULL, 0)
# endif
PHP_ME(Geometry, isSimple, NULL, 0)
PHP_ME(Geometry, isRing, NULL, 0)
PHP_ME(Geometry, hasZ, NULL, 0)
# ifdef HAVE_GEOS_IS_CLOSED
PHP_ME(Geometry, isClosed, NULL, 0)
# endif
PHP_ME(Geometry, typeName, NULL, 0)
PHP_ME(Geometry, typeId, NULL, 0)
PHP_ME(Geometry, getSRID, NULL, 0)
PHP_ME(Geometry, setSRID, NULL, 0)
PHP_ME(Geometry, numGeometries, NULL, 0)
PHP_ME(Geometry, geometryN, NULL, 0)
PHP_ME(Geometry, numInteriorRings, NULL, 0)
# ifdef HAVE_GEOS_GEOM_GET_NUM_POINTS
PHP_ME(Geometry, numPoints, NULL, 0)
# endif
# ifdef HAVE_GEOS_GEOM_GET_X
PHP_ME(Geometry, getX, NULL, 0)
# endif
# ifdef HAVE_GEOS_GEOM_GET_Y
PHP_ME(Geometry, getY, NULL, 0)
# endif
PHP_ME(Geometry, interiorRingN, NULL, 0)
PHP_ME(Geometry, exteriorRing, NULL, 0)
PHP_ME(Geometry, numCoordinates, NULL, 0)
PHP_ME(Geometry, dimension, NULL, 0)
# ifdef HAVE_GEOS_GEOM_GET_COORDINATE_DIMENSION
PHP_ME(Geometry, coordinateDimension, NULL, 0)
# endif
# ifdef HAVE_GEOS_GEOM_GET_POINT_N
PHP_ME(Geometry, pointN, NULL, 0)
# endif
# ifdef HAVE_GEOS_GEOM_GET_START_POINT
PHP_ME(Geometry, startPoint, NULL, 0)
# endif
# ifdef HAVE_GEOS_GEOM_GET_END_POINT
PHP_ME(Geometry, endPoint, NULL, 0)
# endif
PHP_ME(Geometry, area, NULL, 0)
PHP_ME(Geometry, length, NULL, 0)
PHP_ME(Geometry, distance, NULL, 0)
PHP_ME(Geometry, hausdorffDistance, NULL, 0)
# if HAVE_GEOS_SNAP
PHP_ME(Geometry, snapTo, NULL, 0)
# endif
# ifdef HAVE_GEOS_NODE
PHP_ME(Geometry, node, NULL, 0)
# endif
# ifdef HAVE_GEOS_DELAUNAY_TRIANGULATION
PHP_ME(Geometry, delaunayTriangulation, NULL, 0)
# endif
# ifdef HAVE_GEOS_VORONOI_DIAGRAM
PHP_ME(Geometry, voronoiDiagram, NULL, 0)
# endif
# ifdef HAVE_GEOS_CLIP_BY_RECT
PHP_ME(Geometry, clipByRect, NULL, 0)
# endif
{NULL, NULL, NULL}
};
static zend_class_entry *Geometry_ce_ptr;
static zend_object_handlers Geometry_object_handlers;
/* Geometry serializer */
static GEOSWKBWriter* Geometry_serializer = 0;
static GEOSWKBWriter* getGeometrySerializer()
{
TSRMLS_FETCH();
if ( ! Geometry_serializer ) {
Geometry_serializer = GEOSWKBWriter_create_r(GEOS_G(handle));
GEOSWKBWriter_setIncludeSRID_r(GEOS_G(handle), Geometry_serializer, 1);
GEOSWKBWriter_setOutputDimension_r(GEOS_G(handle), Geometry_serializer, 3);
}
return Geometry_serializer;
}
static void delGeometrySerializer()
{
TSRMLS_FETCH();
if ( Geometry_serializer ) {
GEOSWKBWriter_destroy_r(GEOS_G(handle), Geometry_serializer);
}
}
/* Geometry deserializer */
static GEOSWKBReader* Geometry_deserializer = 0;
static GEOSWKBReader* getGeometryDeserializer()
{
TSRMLS_FETCH();
if ( ! Geometry_deserializer ) {
Geometry_deserializer = GEOSWKBReader_create_r(GEOS_G(handle));
}
return Geometry_deserializer;
}
static void delGeometryDeserializer()
{
TSRMLS_FETCH();
if ( Geometry_deserializer ) {
GEOSWKBReader_destroy_r(GEOS_G(handle), Geometry_deserializer);
}
}
/* Serializer function for GEOSGeometry */
static int
Geometry_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len,
zend_serialize_data *data TSRMLS_DC)
{
GEOSWKBWriter *serializer;
GEOSGeometry *geom;
char* ret;
size_t retsize;
serializer = getGeometrySerializer();
geom = (GEOSGeometry*)getRelay(object, Geometry_ce_ptr);
/* NOTE: we might be fine using binary here */
ret = (char*)GEOSWKBWriter_writeHEX_r(GEOS_G(handle), serializer, geom, &retsize);
/* we'll probably get an exception if ret is null */
if ( ! ret ) return FAILURE;
*buffer = (unsigned char*)estrndup(ret, retsize);
GEOSFree_r(GEOS_G(handle), ret);
*buf_len = retsize;
return SUCCESS;
}
static int
Geometry_deserialize(GEOS_PHP_ZVAL object, zend_class_entry *ce, const unsigned char *buf,
zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
{
GEOSWKBReader* deserializer;
GEOSGeometry* geom;
deserializer = getGeometryDeserializer();
geom = GEOSWKBReader_readHEX_r(GEOS_G(handle), deserializer, buf, buf_len);
/* check zend_class_entry being what we expect! */
if ( ce != Geometry_ce_ptr ) {
php_error_docref(NULL TSRMLS_CC, E_ERROR,
"Geometry_deserialize called with unexpected zend_class_entry");
return FAILURE;
}
#if PHP_VERSION_ID >= 70000
object_init_ex(object, ce);
setRelay(object, geom);
#else
object_init_ex(*object, ce);
setRelay(*object, geom);
#endif
return SUCCESS;
}
/*
* Push components of the given geometry
* to the given array zval.
* Components geometries are cloned.
* NOTE: collection components are not descended into
*/
static void
dumpGeometry(GEOSGeometry* g, zval* array)
{
TSRMLS_FETCH();
int ngeoms, i;
ngeoms = GEOSGetNumGeometries_r(GEOS_G(handle), g);
for (i=0; i<ngeoms; ++i)
{
zval *tmp;
GEOSGeometry* cc;
const GEOSGeometry* c = GEOSGetGeometryN_r(GEOS_G(handle), g, i);
if ( ! c ) continue; /* should get an exception */
/* we _need_ to clone as this one is owned by 'g' */
cc = GEOSGeom_clone_r(GEOS_G(handle), c);
if ( ! cc ) continue; /* should get an exception */
MAKE_STD_ZVAL(tmp);
object_init_ex(tmp, Geometry_ce_ptr);
setRelay(tmp, cc);
add_next_index_zval(array, tmp);
#if PHP_VERSION_ID >= 70000
efree(tmp);
#endif
}
}
static void
Geometry_dtor (GEOS_PHP_DTOR_OBJECT *object TSRMLS_DC)
{
#if PHP_VERSION_ID < 70000
Proxy *obj = (Proxy *)object;
#else
Proxy *obj = php_geos_fetch_object(object);
#endif
GEOSGeom_destroy_r(GEOS_G(handle), (GEOSGeometry*)obj->relay);
#if PHP_VERSION_ID >= 70000
//zend_object_std_dtor(&obj->std);
#else
zend_hash_destroy(obj->std.properties);
FREE_HASHTABLE(obj->std.properties);
efree(obj);
#endif
}
static zend_object_value
Geometry_create_obj (zend_class_entry *type TSRMLS_DC)
{
return Gen_create_obj(type, Geometry_dtor, &Geometry_object_handlers);
}
PHP_METHOD(Geometry, __construct)
{
php_error_docref(NULL TSRMLS_CC, E_ERROR,
"GEOSGeometry can't be constructed using new, check WKTReader");
}
PHP_METHOD(Geometry, __toString)
{
GEOSGeometry *geom;
GEOSWKTWriter *writer;
char *wkt;
char *ret;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
writer = GEOSWKTWriter_create_r(GEOS_G(handle));
/* NOTE: if we get an exception before reaching
* GEOSWKTWriter_destory below we'll be leaking memory.
* One fix could be storing the object in a refcounted
* zval.
*/
# ifdef HAVE_GEOS_WKT_WRITER_SET_TRIM
GEOSWKTWriter_setTrim_r(GEOS_G(handle), writer, 1);
# endif
wkt = GEOSWKTWriter_write_r(GEOS_G(handle), writer, geom);
/* we'll probably get an exception if wkt is null */
if ( ! wkt ) RETURN_NULL();
GEOSWKTWriter_destroy_r(GEOS_G(handle), writer);
ret = estrdup(wkt);
GEOSFree_r(GEOS_G(handle), wkt);
GEOS_PHP_RETURN_STRING(ret);
}
PHP_METHOD(Geometry, project)
{
GEOSGeometry *this;
GEOSGeometry *other;
zval *zobj;
zend_bool normalized = 0;
double ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|b", &zobj,
&normalized) == FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
if ( normalized ) {
ret = GEOSProjectNormalized_r(GEOS_G(handle), this, other);
} else {
ret = GEOSProject_r(GEOS_G(handle), this, other);
}
if ( ret < 0 ) RETURN_NULL(); /* should get an exception first */
RETURN_DOUBLE(ret);
}
PHP_METHOD(Geometry, interpolate)
{
GEOSGeometry *this;
double dist;
GEOSGeometry *ret;
zend_bool normalized = 0;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|b",
&dist, &normalized) == FAILURE) {
RETURN_NULL();
}
if ( normalized ) {
ret = GEOSInterpolateNormalized_r(GEOS_G(handle), this, dist);
} else {
ret = GEOSInterpolate_r(GEOS_G(handle), this, dist);
}
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
/**
* GEOSGeometry::buffer(dist, [<styleArray>])
*
* styleArray keys supported:
* 'quad_segs'
* Type: int
* Number of segments used to approximate
* a quarter circle (defaults to 8).
* 'endcap'
* Type: long
* Endcap style (defaults to GEOSBUF_CAP_ROUND)
* 'join'
* Type: long
* Join style (defaults to GEOSBUF_JOIN_ROUND)
* 'mitre_limit'
* Type: double
* mitre ratio limit (only affects joins with GEOSBUF_JOIN_MITRE style)
* 'miter_limit' is also accepted as a synonym for 'mitre_limit'.
* 'single_sided'
* Type: bool
* If true buffer lines only on one side, so that the input line
* will be a portion of the boundary of the returned polygon.
* Only applies to lineal input. Defaults to false.
*/
PHP_METHOD(Geometry, buffer)
{
GEOSGeometry *this;
double dist;
GEOSGeometry *ret;
GEOSBufferParams *params;
static const double default_mitreLimit = 5.0;
static const int default_endCapStyle = GEOSBUF_CAP_ROUND;
static const int default_joinStyle = GEOSBUF_JOIN_ROUND;
static const int default_quadSegs = 8;
long int quadSegs = default_quadSegs;
long int endCapStyle = default_endCapStyle;
long int joinStyle = default_joinStyle;
double mitreLimit = default_mitreLimit;
long singleSided = 0;
zval *style_val = NULL;
GEOS_PHP_ZVAL data;
HashTable *style;
zend_string *key;
ulong index;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|a",
&dist, &style_val) == FAILURE) {
RETURN_NULL();
}
params = GEOSBufferParams_create_r(GEOS_G(handle));
if ( style_val )
{
style = HASH_OF(style_val);
while(GEOS_PHP_HASH_GET_CUR_KEY(style, &key, &index)
== HASH_KEY_IS_STRING)
{
if(!strcmp(ZSTR_VAL(key), "quad_segs"))
{
GEOS_PHP_HASH_GET_CUR_DATA(style, data);
quadSegs = getZvalAsLong(data);
GEOSBufferParams_setQuadrantSegments_r(GEOS_G(handle), params, quadSegs);
}
else if(!strcmp(ZSTR_VAL(key), "endcap"))
{
GEOS_PHP_HASH_GET_CUR_DATA(style, data);
endCapStyle = getZvalAsLong(data);
GEOSBufferParams_setEndCapStyle_r(GEOS_G(handle), params, endCapStyle);
}
else if(!strcmp(ZSTR_VAL(key), "join"))
{
GEOS_PHP_HASH_GET_CUR_DATA(style, data);
joinStyle = getZvalAsLong(data);
GEOSBufferParams_setJoinStyle_r(GEOS_G(handle), params, joinStyle);
}
else if(!strcmp(ZSTR_VAL(key), "mitre_limit"))
{
GEOS_PHP_HASH_GET_CUR_DATA(style, data);
mitreLimit = getZvalAsDouble(data);
GEOSBufferParams_setMitreLimit_r(GEOS_G(handle), params, mitreLimit);
}
else if(!strcmp(ZSTR_VAL(key), "single_sided"))
{
GEOS_PHP_HASH_GET_CUR_DATA(style, data);
singleSided = getZvalAsLong(data);
GEOSBufferParams_setSingleSided_r(GEOS_G(handle), params, singleSided);
}
zend_hash_move_forward(style);
}
}
ret = GEOSBufferWithParams_r(GEOS_G(handle), this, params, dist);
GEOSBufferParams_destroy_r(GEOS_G(handle), params);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
/**
* GEOSGeometry::offsetCurve(dist, [<styleArray>])
*
* styleArray keys supported:
* 'quad_segs'
* Type: int
* Number of segments used to approximate
* a quarter circle (defaults to 8).
* 'join'
* Type: long
* Join style (defaults to GEOSBUF_JOIN_ROUND)
* 'mitre_limit'
* Type: double
* mitre ratio limit (only affects joins with GEOSBUF_JOIN_MITRE style)
* 'miter_limit' is also accepted as a synonym for 'mitre_limit'.
*/
#ifdef HAVE_GEOS_OFFSET_CURVE
PHP_METHOD(Geometry, offsetCurve)
{
GEOSGeometry *this;
double dist;
GEOSGeometry *ret;
static const double default_mitreLimit = 5.0;
static const int default_joinStyle = GEOSBUF_JOIN_ROUND;
static const int default_quadSegs = 8;
long int quadSegs = default_quadSegs;
long int joinStyle = default_joinStyle;
double mitreLimit = default_mitreLimit;
zval *style_val = NULL;
GEOS_PHP_ZVAL data;
HashTable *style;
zend_string *key;
ulong index;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|a",
&dist, &style_val) == FAILURE) {
RETURN_NULL();
}
if ( style_val )
{
style = HASH_OF(style_val);
while(GEOS_PHP_HASH_GET_CUR_KEY(style, &key, &index)
== HASH_KEY_IS_STRING)
{
if(!strcmp(ZSTR_VAL(key), "quad_segs"))
{
GEOS_PHP_HASH_GET_CUR_DATA(style, data);
quadSegs = getZvalAsLong(data);
}
else if(!strcmp(ZSTR_VAL(key), "join"))
{
GEOS_PHP_HASH_GET_CUR_DATA(style, data);
joinStyle = getZvalAsLong(data);
}
else if(!strcmp(ZSTR_VAL(key), "mitre_limit"))
{
GEOS_PHP_HASH_GET_CUR_DATA(style, data);
mitreLimit = getZvalAsDouble(data);
}
zend_hash_move_forward(style);
}
}
ret = GEOSOffsetCurve_r(GEOS_G(handle), this, dist, quadSegs, joinStyle, mitreLimit);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
#endif
PHP_METHOD(Geometry, envelope)
{
GEOSGeometry *this;
GEOSGeometry *ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSEnvelope_r(GEOS_G(handle), this);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
PHP_METHOD(Geometry, intersection)
{
GEOSGeometry *this;
GEOSGeometry *other;
GEOSGeometry *ret;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSIntersection_r(GEOS_G(handle), this, other);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
/**
* GEOSGeometry GEOSGeometry::clipByRect(xmin,ymin,xmax,ymax)
*/
#ifdef HAVE_GEOS_CLIP_BY_RECT
PHP_METHOD(Geometry, clipByRect)
{
GEOSGeometry *this;
GEOSGeometry *ret;
double xmin,ymin,xmax,ymax;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddd",
&xmin, &ymin, &xmax, &ymax) == FAILURE) {
RETURN_NULL();
}
ret = GEOSClipByRect_r(GEOS_G(handle), this, xmin, ymin, xmax, ymax);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
#endif
PHP_METHOD(Geometry, convexHull)
{
GEOSGeometry *this;
GEOSGeometry *ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSConvexHull_r(GEOS_G(handle), this);
if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
PHP_METHOD(Geometry, difference)
{
GEOSGeometry *this;
GEOSGeometry *other;
GEOSGeometry *ret;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSDifference_r(GEOS_G(handle), this, other);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
PHP_METHOD(Geometry, symDifference)
{
GEOSGeometry *this;
GEOSGeometry *other;
GEOSGeometry *ret;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSSymDifference_r(GEOS_G(handle), this, other);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
PHP_METHOD(Geometry, boundary)
{
GEOSGeometry *this;
GEOSGeometry *ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSBoundary_r(GEOS_G(handle), this);
if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
/**
* GEOSGeometry::union(otherGeom)
* GEOSGeometry::union()
*/
PHP_METHOD(Geometry, union)
{
GEOSGeometry *this;
GEOSGeometry *other;
GEOSGeometry *ret;
zval *zobj = NULL;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o", &zobj)
== FAILURE) {
RETURN_NULL();
}
if ( zobj ) {
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSUnion_r(GEOS_G(handle), this, other);
} else {
# ifdef HAVE_GEOS_UNARY_UNION
ret = GEOSUnaryUnion_r(GEOS_G(handle), this);
# else
ret = GEOSUnionCascaded_r(GEOS_G(handle), this);
# endif
}
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
/**
* GEOSGeometry::pointOnSurface()
*/
PHP_METHOD(Geometry, pointOnSurface)
{
GEOSGeometry *this;
GEOSGeometry *ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSPointOnSurface_r(GEOS_G(handle), this);
if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
/**
* GEOSGeometry::centroid()
*/
PHP_METHOD(Geometry, centroid)
{
GEOSGeometry *this;
GEOSGeometry *ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGetCentroid_r(GEOS_G(handle), this);
if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
/**
* GEOSGeometry::relate(otherGeom)
* GEOSGeometry::relate(otherGeom, pattern)
*/
PHP_METHOD(Geometry, relate)
{
GEOSGeometry *this;
GEOSGeometry *other;
zval *zobj;
char* pat = NULL;
#if PHP_VERSION_ID >= 70000
size_t patlen;
#else
int patlen;
#endif
int retInt;
zend_bool retBool;
char* retStr;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|s",
&zobj, &pat, &patlen) == FAILURE)
{
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
if ( ! pat ) {
/* we'll compute it */
pat = GEOSRelate_r(GEOS_G(handle), this, other);
if ( ! pat ) RETURN_NULL(); /* should get an exception first */
retStr = estrdup(pat);
GEOSFree_r(GEOS_G(handle), pat);
GEOS_PHP_RETURN_STRING(retStr);
} else {
retInt = GEOSRelatePattern_r(GEOS_G(handle), this, other, pat);
if ( retInt == 2 ) RETURN_NULL(); /* should get an exception first */
retBool = retInt;
RETURN_BOOL(retBool);
}
}
/**
* GEOSGeometry::relateBoundaryNodeRule(otherGeom, rule)
*/
#ifdef HAVE_GEOS_RELATE_BOUNDARY_NODE_RULE
PHP_METHOD(Geometry, relateBoundaryNodeRule)
{
GEOSGeometry *this;
GEOSGeometry *other;
zval *zobj;
char* pat;
long int bnr = GEOSRELATE_BNR_OGC;
char* retStr;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ol",
&zobj, &bnr) == FAILURE)
{
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
/* we'll compute it */
pat = GEOSRelateBoundaryNodeRule_r(GEOS_G(handle), this, other, bnr);
if ( ! pat ) RETURN_NULL(); /* should get an exception first */
retStr = estrdup(pat);
GEOSFree_r(GEOS_G(handle), pat);
GEOS_PHP_RETURN_STRING(retStr);
}
#endif
/**
* GEOSGeometry GEOSGeometry::simplify(tolerance)
* GEOSGeometry GEOSGeometry::simplify(tolerance, preserveTopology)
*/
PHP_METHOD(Geometry, simplify)
{
GEOSGeometry *this;
double tolerance;
zend_bool preserveTopology = 0;
GEOSGeometry *ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|b",
&tolerance, &preserveTopology) == FAILURE) {
RETURN_NULL();
}
if ( preserveTopology ) {
ret = GEOSTopologyPreserveSimplify_r(GEOS_G(handle), this, tolerance);
} else {
ret = GEOSSimplify_r(GEOS_G(handle), this, tolerance);
}
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
/**
* GEOSGeometry GEOSGeometry::setPrecision(gridsize, [flags])
*/
#ifdef HAVE_GEOS_GEOM_SET_PRECISION
PHP_METHOD(Geometry, setPrecision)
{
GEOSGeometry *this;
double gridSize;
long int flags = 0;
GEOSGeometry *ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|l",
&gridSize, &flags) == FAILURE) {
RETURN_NULL();
}
ret = GEOSGeom_setPrecision_r(GEOS_G(handle), this, gridSize, flags);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
#endif
/**
* double GEOSGeometry::getPrecision()
*/
#ifdef HAVE_GEOS_GEOM_GET_PRECISION
PHP_METHOD(Geometry, getPrecision)
{
GEOSGeometry *geom;
double prec;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
prec = GEOSGeom_getPrecision_r(GEOS_G(handle), geom);
if ( prec < 0 ) RETURN_NULL(); /* should get an exception first */
RETURN_DOUBLE(prec);
}
#endif
/**
* GEOSGeometry GEOSGeometry::normalize()
*/
PHP_METHOD(Geometry, normalize)
{
GEOSGeometry *this;
GEOSGeometry *ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGeom_clone_r(GEOS_G(handle), this);
if ( ! ret ) RETURN_NULL();
GEOSNormalize_r(GEOS_G(handle), ret); /* exception should be gotten automatically */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
/**
* GEOSGeometry GEOSGeometry::extractUniquePoints()
*/
#ifdef HAVE_GEOS_GEOM_EXTRACT_UNIQUE_POINTS
PHP_METHOD(Geometry, extractUniquePoints)
{
GEOSGeometry *this;
GEOSGeometry *ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGeom_extractUniquePoints_r(GEOS_G(handle), this);
if ( ret == NULL ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
#endif
/**
* bool GEOSGeometry::disjoint(GEOSGeometry)
*/
PHP_METHOD(Geometry, disjoint)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSDisjoint_r(GEOS_G(handle), this, other);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::touches(GEOSGeometry)
*/
PHP_METHOD(Geometry, touches)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSTouches_r(GEOS_G(handle), this, other);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::intersects(GEOSGeometry)
*/
PHP_METHOD(Geometry, intersects)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSIntersects_r(GEOS_G(handle), this, other);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::crosses(GEOSGeometry)
*/
PHP_METHOD(Geometry, crosses)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSCrosses_r(GEOS_G(handle), this, other);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::within(GEOSGeometry)
*/
PHP_METHOD(Geometry, within)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSWithin_r(GEOS_G(handle), this, other);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::contains(GEOSGeometry)
*/
PHP_METHOD(Geometry, contains)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSContains_r(GEOS_G(handle), this, other);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::overlaps(GEOSGeometry)
*/
PHP_METHOD(Geometry, overlaps)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSOverlaps_r(GEOS_G(handle), this, other);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::covers(GEOSGeometry)
*/
#ifdef HAVE_GEOS_COVERS
PHP_METHOD(Geometry, covers)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSCovers_r(GEOS_G(handle), this, other);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
#endif
/**
* bool GEOSGeometry::coveredBy(GEOSGeometry)
*/
#ifdef HAVE_GEOS_COVERED_BY
PHP_METHOD(Geometry, coveredBy)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSCoveredBy_r(GEOS_G(handle), this, other);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
#endif
/**
* bool GEOSGeometry::equals(GEOSGeometry)
*/
PHP_METHOD(Geometry, equals)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
&zobj) == FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSEquals_r(GEOS_G(handle), this, other);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::equalsExact(GEOSGeometry)
* bool GEOSGeometry::equalsExact(GEOSGeometry, double tolerance)
*/
PHP_METHOD(Geometry, equalsExact)
{
GEOSGeometry *this;
GEOSGeometry *other;
int ret;
double tolerance = 0;
zend_bool retBool;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|d",
&zobj, &tolerance) == FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSEqualsExact_r(GEOS_G(handle), this, other, tolerance);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::isEmpty()
*/
PHP_METHOD(Geometry, isEmpty)
{
GEOSGeometry *this;
int ret;
zend_bool retBool;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSisEmpty_r(GEOS_G(handle), this);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* array GEOSGeometry::checkValidity()
*/
#ifdef HAVE_GEOS_IS_VALID_DETAIL
PHP_METHOD(Geometry, checkValidity)
{
GEOSGeometry *this;
GEOSGeometry *location = NULL;
int ret;
char *reason = NULL;
zend_bool retBool;
char *reasonVal = NULL;
zval *locationVal = NULL;
long int flags = 0;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l",
&flags) == FAILURE) {
RETURN_NULL();
}
ret = GEOSisValidDetail_r(GEOS_G(handle), this, flags, &reason, &location);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
if ( reason ) {
reasonVal = estrdup(reason);
GEOSFree_r(GEOS_G(handle), reason);
}
if ( location ) {
MAKE_STD_ZVAL(locationVal);
object_init_ex(locationVal, Geometry_ce_ptr);
setRelay(locationVal, location);
}
retBool = ret;
/* return value is an array */
array_init(return_value);
add_assoc_bool(return_value, "valid", retBool);
if ( reasonVal ) GEOS_PHP_ADD_ASSOC_ARRAY(return_value, "reason", reasonVal);
if ( locationVal ) GEOS_PHP_ADD_ASSOC_ZVAL(return_value, "location", locationVal);
}
#endif
/**
* bool GEOSGeometry::isSimple()
*/
PHP_METHOD(Geometry, isSimple)
{
GEOSGeometry *this;
int ret;
zend_bool retBool;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSisSimple_r(GEOS_G(handle), this);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::isRing()
*/
PHP_METHOD(Geometry, isRing)
{
GEOSGeometry *this;
int ret;
zend_bool retBool;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSisRing_r(GEOS_G(handle), this);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::hasZ()
*/
PHP_METHOD(Geometry, hasZ)
{
GEOSGeometry *this;
int ret;
zend_bool retBool;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSHasZ_r(GEOS_G(handle), this);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* bool GEOSGeometry::isClosed()
*/
#ifdef HAVE_GEOS_IS_CLOSED
PHP_METHOD(Geometry, isClosed)
{
GEOSGeometry *this;
int ret;
zend_bool retBool;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSisClosed_r(GEOS_G(handle), this);
if ( ret == 2 ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
retBool = ret;
RETURN_BOOL(retBool);
}
#endif
/**
* string GEOSGeometry::typeName()
*/
PHP_METHOD(Geometry, typeName)
{
GEOSGeometry *this;
char *typ;
char *typVal;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
/* TODO: define constant strings instead... */
typ = GEOSGeomType_r(GEOS_G(handle), this);
if ( ! typ ) RETURN_NULL(); /* should get an exception first */
typVal = estrdup(typ);
GEOSFree_r(GEOS_G(handle), typ);
GEOS_PHP_RETURN_STRING(typVal);
}
/**
* long GEOSGeometry::typeId()
*/
PHP_METHOD(Geometry, typeId)
{
GEOSGeometry *this;
long typ;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
/* TODO: define constant strings instead... */
typ = GEOSGeomTypeId_r(GEOS_G(handle), this);
if ( typ == -1 ) RETURN_NULL(); /* should get an exception first */
RETURN_LONG(typ);
}
/**
* long GEOSGeometry::getSRID()
*/
PHP_METHOD(Geometry, getSRID)
{
GEOSGeometry *geom;
long int ret;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGetSRID_r(GEOS_G(handle), geom);
RETURN_LONG(ret);
}
/**
* void GEOSGeometry::setSRID(long)
*/
PHP_METHOD(Geometry, setSRID)
{
GEOSGeometry *geom;
long int srid;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
&srid) == FAILURE) {
RETURN_NULL();
}
GEOSSetSRID_r(GEOS_G(handle), geom, srid);
}
/**
* long GEOSGeometry::numGeometries()
*/
PHP_METHOD(Geometry, numGeometries)
{
GEOSGeometry *geom;
long int ret;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGetNumGeometries_r(GEOS_G(handle), geom);
if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
RETURN_LONG(ret);
}
/**
* GEOSGeometry GEOSGeometry::geometryN()
*/
PHP_METHOD(Geometry, geometryN)
{
GEOSGeometry *geom;
const GEOSGeometry *c;
GEOSGeometry *cc;
long int num;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
&num) == FAILURE) {
RETURN_NULL();
}
if ( num >= GEOSGetNumGeometries_r(GEOS_G(handle), geom) ) RETURN_NULL();
c = GEOSGetGeometryN_r(GEOS_G(handle), geom, num);
if ( ! c ) RETURN_NULL(); /* should get an exception first */
cc = GEOSGeom_clone_r(GEOS_G(handle), c);
if ( ! cc ) RETURN_NULL(); /* should get an exception first */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, cc);
}
/**
* long GEOSGeometry::numInteriorRings()
*/
PHP_METHOD(Geometry, numInteriorRings)
{
GEOSGeometry *geom;
long int ret;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGetNumInteriorRings_r(GEOS_G(handle), geom);
if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
RETURN_LONG(ret);
}
/**
* long GEOSGeometry::numPoints()
*/
#ifdef HAVE_GEOS_GEOM_GET_NUM_POINTS
PHP_METHOD(Geometry, numPoints)
{
GEOSGeometry *geom;
long int ret;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGeomGetNumPoints_r(GEOS_G(handle), geom);
if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
RETURN_LONG(ret);
}
#endif
/**
* double GEOSGeometry::getX()
*/
#ifdef HAVE_GEOS_GEOM_GET_X
PHP_METHOD(Geometry, getX)
{
GEOSGeometry *geom;
int ret;
double x;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGeomGetX_r(GEOS_G(handle), geom, &x);
if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
RETURN_DOUBLE(x);
}
#endif
/**
* double GEOSGeometry::getY()
*/
#ifdef HAVE_GEOS_GEOM_GET_Y
PHP_METHOD(Geometry, getY)
{
GEOSGeometry *geom;
int ret;
double y;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGeomGetY_r(GEOS_G(handle), geom, &y);
if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
RETURN_DOUBLE(y);
}
#endif
/**
* GEOSGeometry GEOSGeometry::interiorRingN()
*/
PHP_METHOD(Geometry, interiorRingN)
{
GEOSGeometry *geom;
const GEOSGeometry *c;
GEOSGeometry *cc;
long int num;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
&num) == FAILURE) {
RETURN_NULL();
}
if ( num >= GEOSGetNumInteriorRings_r(GEOS_G(handle), geom) ) RETURN_NULL();
c = GEOSGetInteriorRingN_r(GEOS_G(handle), geom, num);
if ( ! c ) RETURN_NULL(); /* should get an exception first */
cc = GEOSGeom_clone_r(GEOS_G(handle), c);
if ( ! cc ) RETURN_NULL(); /* should get an exception first */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, cc);
}
/**
* GEOSGeometry GEOSGeometry::exteriorRing()
*/
PHP_METHOD(Geometry, exteriorRing)
{
GEOSGeometry *geom;
const GEOSGeometry *c;
GEOSGeometry *cc;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
c = GEOSGetExteriorRing_r(GEOS_G(handle), geom);
if ( ! c ) RETURN_NULL(); /* should get an exception first */
cc = GEOSGeom_clone_r(GEOS_G(handle), c);
if ( ! cc ) RETURN_NULL(); /* should get an exception first */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, cc);
}
/**
* long GEOSGeometry::numCoordinates()
*/
PHP_METHOD(Geometry, numCoordinates)
{
GEOSGeometry *geom;
long int ret;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGetNumCoordinates_r(GEOS_G(handle), geom);
if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
RETURN_LONG(ret);
}
/**
* long GEOSGeometry::dimension()
* 0:puntual 1:lineal 2:areal
*/
PHP_METHOD(Geometry, dimension)
{
GEOSGeometry *geom;
long int ret;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGeom_getDimensions_r(GEOS_G(handle), geom);
if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
RETURN_LONG(ret);
}
/**
* long GEOSGeometry::coordinateDimension()
*/
#ifdef HAVE_GEOS_GEOM_GET_COORDINATE_DIMENSION
PHP_METHOD(Geometry, coordinateDimension)
{
GEOSGeometry *geom;
long int ret;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSGeom_getCoordinateDimension_r(GEOS_G(handle), geom);
if ( ret == -1 ) RETURN_NULL(); /* should get an exception first */
RETURN_LONG(ret);
}
#endif
/**
* GEOSGeometry GEOSGeometry::pointN()
*/
#ifdef HAVE_GEOS_GEOM_GET_POINT_N
PHP_METHOD(Geometry, pointN)
{
GEOSGeometry *geom;
GEOSGeometry *c;
long int num;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
&num) == FAILURE) {
RETURN_NULL();
}
if ( num >= GEOSGeomGetNumPoints_r(GEOS_G(handle), geom) ) RETURN_NULL();
c = GEOSGeomGetPointN_r(GEOS_G(handle), geom, num);
if ( ! c ) RETURN_NULL(); /* should get an exception first */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, c);
}
#endif
/**
* GEOSGeometry GEOSGeometry::startPoint()
*/
PHP_METHOD(Geometry, startPoint)
{
GEOSGeometry *geom;
GEOSGeometry *c;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
c = GEOSGeomGetStartPoint_r(GEOS_G(handle), geom);
if ( ! c ) RETURN_NULL(); /* should get an exception first */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, c);
}
/**
* GEOSGeometry GEOSGeometry::endPoint()
*/
PHP_METHOD(Geometry, endPoint)
{
GEOSGeometry *geom;
GEOSGeometry *c;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
c = GEOSGeomGetEndPoint_r(GEOS_G(handle), geom);
if ( ! c ) RETURN_NULL(); /* should get an exception first */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, c);
}
/**
* double GEOSGeometry::area()
*/
PHP_METHOD(Geometry, area)
{
GEOSGeometry *geom;
double area;
int ret;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSArea_r(GEOS_G(handle), geom, &area);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
RETURN_DOUBLE(area);
}
/**
* double GEOSGeometry::length()
*/
PHP_METHOD(Geometry, length)
{
GEOSGeometry *geom;
double length;
int ret;
geom = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSLength_r(GEOS_G(handle), geom, &length);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
RETURN_DOUBLE(length);
}
/**
* double GEOSGeometry::distance(GEOSGeometry)
*/
PHP_METHOD(Geometry, distance)
{
GEOSGeometry *this;
GEOSGeometry *other;
zval *zobj;
double dist;
int ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
&zobj) == FAILURE)
{
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSDistance_r(GEOS_G(handle), this, other, &dist);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
RETURN_DOUBLE(dist);
}
/**
* double GEOSGeometry::hausdorffDistance(GEOSGeometry)
*/
PHP_METHOD(Geometry, hausdorffDistance)
{
GEOSGeometry *this;
GEOSGeometry *other;
zval *zobj;
double dist;
int ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
&zobj) == FAILURE)
{
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSHausdorffDistance_r(GEOS_G(handle), this, other, &dist);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
RETURN_DOUBLE(dist);
}
#ifdef HAVE_GEOS_SNAP
PHP_METHOD(Geometry, snapTo)
{
GEOSGeometry *this;
GEOSGeometry *other;
GEOSGeometry *ret;
double tolerance;
zval *zobj;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "od", &zobj,
&tolerance) == FAILURE) {
RETURN_NULL();
}
other = getRelay(zobj, Geometry_ce_ptr);
ret = GEOSSnap_r(GEOS_G(handle), this, other, tolerance);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
#endif
#ifdef HAVE_GEOS_NODE
PHP_METHOD(Geometry, node)
{
GEOSGeometry *this;
GEOSGeometry *ret;
this = (GEOSGeometry*)getRelay(getThis(), Geometry_ce_ptr);
ret = GEOSNode_r(GEOS_G(handle), this);
if ( ! ret ) RETURN_NULL(); /* should get an exception first */
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, ret);
}
#endif
/* -- class GEOSWKTReader -------------------- */
PHP_METHOD(WKTReader, __construct);
PHP_METHOD(WKTReader, read);
static zend_function_entry WKTReader_methods[] = {
PHP_ME(WKTReader, __construct, NULL, 0)
PHP_ME(WKTReader, read, NULL, 0)
{NULL, NULL, NULL}
};
static zend_class_entry *WKTReader_ce_ptr;
static zend_object_handlers WKTReader_object_handlers;
static void
WKTReader_dtor (GEOS_PHP_DTOR_OBJECT *object TSRMLS_DC)
{
#if PHP_VERSION_ID < 70000
Proxy *obj = (Proxy *)object;
#else
Proxy *obj = php_geos_fetch_object(object);
#endif
GEOSWKTReader *reader = (GEOSWKTReader*)obj->relay;
if (reader) {
GEOSWKTReader_destroy_r(GEOS_G(handle), reader);
}
#if PHP_VERSION_ID < 70000
zend_hash_destroy(obj->std.properties);
FREE_HASHTABLE(obj->std.properties);
efree(obj);
#endif
}
static zend_object_value
WKTReader_create_obj (zend_class_entry *type TSRMLS_DC)
{
return Gen_create_obj(type, WKTReader_dtor, &WKTReader_object_handlers);
}
PHP_METHOD(WKTReader, __construct)
{
GEOSWKTReader* obj;
zval *object = getThis();
obj = GEOSWKTReader_create_r(GEOS_G(handle));
if ( ! obj ) {
php_error_docref(NULL TSRMLS_CC, E_ERROR,
"GEOSWKTReader_create() failed (didn't initGEOS?)");
}
setRelay(object, obj);
}
PHP_METHOD(WKTReader, read)
{
GEOSWKTReader *reader;
GEOSGeometry *geom;
zend_string *wkt;
#if PHP_VERSION_ID < 70000
int wktlen;
#endif
reader = (GEOSWKTReader*)getRelay(getThis(), WKTReader_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
#if PHP_VERSION_ID >= 70000
"S", &wkt
#else
"s", &wkt, &wktlen
#endif
) == FAILURE)
{
RETURN_NULL();
}
geom = GEOSWKTReader_read_r(GEOS_G(handle), reader, ZSTR_VAL(wkt));
/* we'll probably get an exception if geom is null */
if ( ! geom ) RETURN_NULL();
/* return_value is a zval */
object_init_ex(return_value, Geometry_ce_ptr);
setRelay(return_value, geom);
}
/* -- class GEOSWKTWriter -------------------- */
PHP_METHOD(WKTWriter, __construct);
PHP_METHOD(WKTWriter, write);
#ifdef HAVE_GEOS_WKT_WRITER_SET_TRIM
PHP_METHOD(WKTWriter, setTrim);
#endif
#ifdef HAVE_GEOS_WKT_WRITER_SET_ROUNDING_PRECISION
PHP_METHOD(WKTWriter, setRoundingPrecision);
#endif
#ifdef HAVE_GEOS_WKT_WRITER_SET_OUTPUT_DIMENSION
PHP_METHOD(WKTWriter, setOutputDimension);
#endif
#ifdef HAVE_GEOS_WKT_WRITER_GET_OUTPUT_DIMENSION
PHP_METHOD(WKTWriter, getOutputDimension);
#endif
#ifdef HAVE_GEOS_WKT_WRITER_SET_OLD_3D
PHP_METHOD(WKTWriter, setOld3D);
#endif
static zend_function_entry WKTWriter_methods[] = {
PHP_ME(WKTWriter, __construct, NULL, 0)
PHP_ME(WKTWriter, write, NULL, 0)
# ifdef HAVE_GEOS_WKT_WRITER_SET_TRIM
PHP_ME(WKTWriter, setTrim, NULL, 0)
# endif
# ifdef HAVE_GEOS_WKT_WRITER_SET_ROUNDING_PRECISION
PHP_ME(WKTWriter, setRoundingPrecision, NULL, 0)
# endif
# ifdef HAVE_GEOS_WKT_WRITER_SET_OUTPUT_DIMENSION
PHP_ME(WKTWriter, setOutputDimension, NULL, 0)
# endif
# ifdef HAVE_GEOS_WKT_WRITER_GET_OUTPUT_DIMENSION
PHP_ME(WKTWriter, getOutputDimension, NULL, 0)
# endif
# ifdef HAVE_GEOS_WKT_WRITER_SET_OLD_3D
PHP_ME(WKTWriter, setOld3D, NULL, 0)
# endif
{NULL, NULL, NULL}
};
static zend_class_entry *WKTWriter_ce_ptr;
static zend_object_handlers WKTWriter_object_handlers;
static void
WKTWriter_dtor (GEOS_PHP_DTOR_OBJECT *object TSRMLS_DC)
{
#if PHP_VERSION_ID < 70000
Proxy *obj = (Proxy *)object;
#else
Proxy *obj = php_geos_fetch_object(object);
#endif
GEOSWKTWriter_destroy_r(GEOS_G(handle), (GEOSWKTWriter*)obj->relay);
#if PHP_VERSION_ID >= 70000
//zend_object_std_dtor(&obj->std);
#else
zend_hash_destroy(obj->std.properties);
FREE_HASHTABLE(obj->std.properties);
efree(obj);
#endif
}
static zend_object_value
WKTWriter_create_obj (zend_class_entry *type TSRMLS_DC)
{
return Gen_create_obj(type, WKTWriter_dtor, &WKTWriter_object_handlers);
}
PHP_METHOD(WKTWriter, __construct)
{
GEOSWKTWriter* obj;
zval *object = getThis();
obj = GEOSWKTWriter_create_r(GEOS_G(handle));
if ( ! obj ) {
php_error_docref(NULL TSRMLS_CC, E_ERROR,
"GEOSWKTWriter_create() failed (didn't initGEOS?)");
}
setRelay(object, obj);
}
PHP_METHOD(WKTWriter, write)
{
GEOSWKTWriter *writer;
zval *zobj;
GEOSGeometry *geom;
char* wkt;
char* retstr;
writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE)
{
RETURN_NULL();
}
geom = getRelay(zobj, Geometry_ce_ptr);
wkt = GEOSWKTWriter_write_r(GEOS_G(handle), writer, geom);
/* we'll probably get an exception if wkt is null */
if ( ! wkt ) RETURN_NULL();
retstr = estrdup(wkt);
GEOSFree_r(GEOS_G(handle), wkt);
GEOS_PHP_RETURN_STRING(retstr);
}
#ifdef HAVE_GEOS_WKT_WRITER_SET_TRIM
PHP_METHOD(WKTWriter, setTrim)
{
GEOSWKTWriter *writer;
zend_bool trimval;
char trim;
writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &trimval)
== FAILURE)
{
RETURN_NULL();
}
trim = trimval;
GEOSWKTWriter_setTrim_r(GEOS_G(handle), writer, trim);
}
#endif
#ifdef HAVE_GEOS_WKT_WRITER_SET_ROUNDING_PRECISION
PHP_METHOD(WKTWriter, setRoundingPrecision)
{
GEOSWKTWriter *writer;
long int prec;
writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &prec)
== FAILURE)
{
RETURN_NULL();
}
GEOSWKTWriter_setRoundingPrecision_r(GEOS_G(handle), writer, prec);
}
#endif
/**
* void GEOSWKTWriter::setOutputDimension()
*/
#ifdef HAVE_GEOS_WKT_WRITER_SET_OUTPUT_DIMENSION
PHP_METHOD(WKTWriter, setOutputDimension)
{
GEOSWKTWriter *writer;
long int dim;
writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
== FAILURE)
{
RETURN_NULL();
}
GEOSWKTWriter_setOutputDimension_r(GEOS_G(handle), writer, dim);
}
#endif
/**
* long GEOSWKTWriter::getOutputDimension()
*/
#ifdef HAVE_GEOS_WKT_WRITER_GET_OUTPUT_DIMENSION
PHP_METHOD(WKTWriter, getOutputDimension)
{
GEOSWKTWriter *writer;
long int ret;
writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
ret = GEOSWKTWriter_getOutputDimension_r(GEOS_G(handle), writer);
RETURN_LONG(ret);
}
#endif
#ifdef HAVE_GEOS_WKT_WRITER_SET_OLD_3D
PHP_METHOD(WKTWriter, setOld3D)
{
GEOSWKTWriter *writer;
zend_bool bval;
int val;
writer = (GEOSWKTWriter*)getRelay(getThis(), WKTWriter_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &bval)
== FAILURE)
{
RETURN_NULL();
}
val = bval;
GEOSWKTWriter_setOld3D_r(GEOS_G(handle), writer, val);
}
#endif
/* -- class GEOSWKBWriter -------------------- */
PHP_METHOD(WKBWriter, __construct);
PHP_METHOD(WKBWriter, getOutputDimension);
PHP_METHOD(WKBWriter, setOutputDimension);
PHP_METHOD(WKBWriter, getByteOrder);
PHP_METHOD(WKBWriter, setByteOrder);
PHP_METHOD(WKBWriter, setIncludeSRID);
PHP_METHOD(WKBWriter, getIncludeSRID);
PHP_METHOD(WKBWriter, write);
PHP_METHOD(WKBWriter, writeHEX);
static zend_function_entry WKBWriter_methods[] = {
PHP_ME(WKBWriter, __construct, NULL, 0)
PHP_ME(WKBWriter, getOutputDimension, NULL, 0)
PHP_ME(WKBWriter, setOutputDimension, NULL, 0)
PHP_ME(WKBWriter, getByteOrder, NULL, 0)
PHP_ME(WKBWriter, setByteOrder, NULL, 0)
PHP_ME(WKBWriter, getIncludeSRID, NULL, 0)
PHP_ME(WKBWriter, setIncludeSRID, NULL, 0)
PHP_ME(WKBWriter, write, NULL, 0)
PHP_ME(WKBWriter, writeHEX, NULL, 0)
{NULL, NULL, NULL}
};
static zend_class_entry *WKBWriter_ce_ptr;
static zend_object_handlers WKBWriter_object_handlers;
static void
WKBWriter_dtor (GEOS_PHP_DTOR_OBJECT *object TSRMLS_DC)
{
#if PHP_VERSION_ID < 70000
Proxy *obj = (Proxy *)object;
#else
Proxy *obj = php_geos_fetch_object(object);
#endif
GEOSWKBWriter_destroy_r(GEOS_G(handle), (GEOSWKBWriter*)obj->relay);
#if PHP_VERSION_ID >= 70000
//zend_object_std_dtor(&obj->std);
#else
zend_hash_destroy(obj->std.properties);
FREE_HASHTABLE(obj->std.properties);
efree(obj);
#endif
}
static zend_object_value
WKBWriter_create_obj (zend_class_entry *type TSRMLS_DC)
{
return Gen_create_obj(type, WKBWriter_dtor, &WKBWriter_object_handlers);
}
/**
* GEOSWKBWriter w = new GEOSWKBWriter()
*/
PHP_METHOD(WKBWriter, __construct)
{
GEOSWKBWriter* obj;
zval *object = getThis();
obj = GEOSWKBWriter_create_r(GEOS_G(handle));
if ( ! obj ) {
php_error_docref(NULL TSRMLS_CC, E_ERROR,
"GEOSWKBWriter_create() failed (didn't initGEOS?)");
}
setRelay(object, obj);
}
/**
* long GEOSWKBWriter::getOutputDimension();
*/
PHP_METHOD(WKBWriter, getOutputDimension)
{
GEOSWKBWriter *writer;
long int ret;
writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
ret = GEOSWKBWriter_getOutputDimension_r(GEOS_G(handle), writer);
RETURN_LONG(ret);
}
/**
* void GEOSWKBWriter::setOutputDimension(dims);
*/
PHP_METHOD(WKBWriter, setOutputDimension)
{
GEOSWKBWriter *writer;
long int dim;
writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
== FAILURE)
{
RETURN_NULL();
}
GEOSWKBWriter_setOutputDimension_r(GEOS_G(handle), writer, dim);
}
/**
* string GEOSWKBWriter::write(GEOSGeometry)
*/
PHP_METHOD(WKBWriter, write)
{
GEOSWKBWriter *writer;
zval *zobj;
GEOSGeometry *geom;
char *ret;
size_t retsize;
char* retstr;
writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE)
{
RETURN_NULL();
}
geom = getRelay(zobj, Geometry_ce_ptr);
ret = (char*)GEOSWKBWriter_write_r(GEOS_G(handle), writer, geom, &retsize);
/* we'll probably get an exception if ret is null */
if ( ! ret ) RETURN_NULL();
retstr = estrndup(ret, retsize);
GEOSFree_r(GEOS_G(handle), ret);
GEOS_PHP_RETURN_STRINGL(retstr, retsize);
}
/**
* string GEOSWKBWriter::writeHEX(GEOSGeometry)
*/
PHP_METHOD(WKBWriter, writeHEX)
{
GEOSWKBWriter *writer;
zval *zobj;
GEOSGeometry *geom;
char *ret;
size_t retsize; /* useless... */
char* retstr;
writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &zobj)
== FAILURE)
{
RETURN_NULL();
}
geom = getRelay(zobj, Geometry_ce_ptr);
ret = (char*)GEOSWKBWriter_writeHEX_r(GEOS_G(handle), writer, geom, &retsize);
/* we'll probably get an exception if ret is null */
if ( ! ret ) RETURN_NULL();
retstr = estrndup(ret, retsize);
GEOSFree_r(GEOS_G(handle), ret);
GEOS_PHP_RETURN_STRING(retstr);
}
/**
* long GEOSWKBWriter::getByteOrder();
*/
PHP_METHOD(WKBWriter, getByteOrder)
{
GEOSWKBWriter *writer;
long int ret;
writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
ret = GEOSWKBWriter_getByteOrder_r(GEOS_G(handle), writer);
RETURN_LONG(ret);
}
/**
* void GEOSWKBWriter::setByteOrder(dims);
*/
PHP_METHOD(WKBWriter, setByteOrder)
{
GEOSWKBWriter *writer;
long int dim;
writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &dim)
== FAILURE)
{
RETURN_NULL();
}
GEOSWKBWriter_setByteOrder_r(GEOS_G(handle), writer, dim);
}
/**
* bool GEOSWKBWriter::getIncludeSRID();
*/
PHP_METHOD(WKBWriter, getIncludeSRID)
{
GEOSWKBWriter *writer;
int ret;
zend_bool retBool;
writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
ret = GEOSWKBWriter_getIncludeSRID_r(GEOS_G(handle), writer);
retBool = ret;
RETURN_BOOL(retBool);
}
/**
* void GEOSWKBWriter::setIncludeSRID(bool);
*/
PHP_METHOD(WKBWriter, setIncludeSRID)
{
GEOSWKBWriter *writer;
int inc;
zend_bool incVal;
writer = (GEOSWKBWriter*)getRelay(getThis(), WKBWriter_ce_ptr);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &incVal)
== FAILURE)
{
RETURN_NULL();
}
inc = incVal;
GEOSWKBWriter_setIncludeSRID_r(GEOS_G(handle), writer, inc);
}
/* -- class GEOSWKBReader -------------------- */
PHP_METHOD(WKBReader, __construct);
PHP_METHOD(WKBReader, read);
PHP_METHOD(WKBReader, readHEX);
static zend_function_entry WKBReader_methods[] = {
PHP_ME(WKBReader, __construct, NULL, 0)
PHP_ME(WKBReader, read, NULL, 0)
PHP_ME(WKBReader, readHEX, NULL, 0)
{NULL, NULL, NULL}
};
static zend_class_entry *WKBReader_ce_ptr;
static zend_object_handlers WKBReader_object_handlers;
static void
WKBReader_dtor (GEOS_PHP_DTOR_OBJECT *object TSRMLS_DC)
{
#if PHP_VERSION_ID < 70000
Proxy *obj = (Proxy *)object;
#else
Proxy *obj = php_geos_fetch_object(object);
#endif
GEOSWKBReader_destroy_r(GEOS_G(handle), (GEOSWKBReader*)obj->relay);
#if PHP_VERSION_ID >= 70000
//zend_object_std_dtor(&obj->std);
#else
zend_hash_destroy(obj->std.properties);
FREE_HASHTABLE(obj->std.properties);
efree