[geos-commits] r3026 - in trunk/php: . test

svn_geos at osgeo.org svn_geos at osgeo.org
Sat Jun 19 13:14:08 EDT 2010


Author: strk
Date: 2010-06-19 17:14:08 +0000 (Sat, 19 Jun 2010)
New Revision: 3026

Modified:
   trunk/php/geos.c
   trunk/php/test/test.php
Log:
Export buffer costants and method


Modified: trunk/php/geos.c
===================================================================
--- trunk/php/geos.c	2010-06-19 13:27:10 UTC (rev 3025)
+++ trunk/php/geos.c	2010-06-19 17:14:08 UTC (rev 3026)
@@ -113,6 +113,32 @@
     return proxy->relay;
 }
 
+static long getZvalAsLong(zval* val)
+{
+    long ret;
+    zval tmp;
+
+    tmp = *val;
+    zval_copy_ctor(&tmp);
+    convert_to_long(&tmp);
+    ret = Z_LVAL(tmp);
+    zval_dtor(&tmp);
+    return ret;
+}
+
+static long getZvalAsDouble(zval* val)
+{
+    double ret;
+    zval tmp;
+
+    tmp = *val;
+    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 TSRMLS_DC,
     zend_objects_free_object_storage_t st, zend_object_handlers* handlers)
@@ -151,6 +177,7 @@
 PHP_METHOD(Geometry, __construct);
 PHP_METHOD(Geometry, project);
 PHP_METHOD(Geometry, interpolate);
+PHP_METHOD(Geometry, buffer);
 
 PHP_METHOD(Geometry, numGeometries);
 
@@ -158,6 +185,7 @@
     PHP_ME(Geometry, __construct, NULL, 0)
     PHP_ME(Geometry, project, NULL, 0)
     PHP_ME(Geometry, interpolate, NULL, 0)
+    PHP_ME(Geometry, buffer, NULL, 0)
     PHP_ME(Geometry, numGeometries, NULL, 0)
     {NULL, NULL, NULL}
 };
@@ -257,6 +285,91 @@
     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'.
+ */
+PHP_METHOD(Geometry, buffer)
+{
+    GEOSGeometry *this;
+    double dist;
+    GEOSGeometry *ret;
+    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;
+    zval *style_val = NULL;
+    zval **data;
+    HashTable *style;
+    char *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(zend_hash_get_current_key(style, &key, &index, 0)
+              == HASH_KEY_IS_STRING)
+        {
+            if(!strcmp(key, "quad_segs"))
+            {
+                zend_hash_get_current_data(style, (void**)&data);
+                quadSegs = getZvalAsLong(*data);
+            }
+            else if(!strcmp(key, "endcap"))
+            {
+                zend_hash_get_current_data(style, (void**)&data);
+                endCapStyle = getZvalAsLong(*data);
+            }
+            else if(!strcmp(key, "join"))
+            {
+                zend_hash_get_current_data(style, (void**)&data);
+                joinStyle = getZvalAsLong(*data);
+            }
+            else if(!strcmp(key, "mitre_limit"))
+            {
+                zend_hash_get_current_data(style, (void**)&data);
+                mitreLimit = getZvalAsDouble(*data);
+            }
+
+            zend_hash_move_forward(style);
+        }
+    }
+
+    ret = GEOSBufferWithStyle(this, dist,
+        quadSegs, endCapStyle, 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);
+}
+
 /* -- class GEOSWKTReader -------------------- */
 
 PHP_METHOD(WKTReader, __construct);
@@ -517,6 +630,20 @@
         zend_get_std_object_handlers(), sizeof(zend_object_handlers));
     Geometry_object_handlers.clone_obj = NULL;
 
+    /* Constants */
+    REGISTER_LONG_CONSTANT("GEOSBUF_CAP_ROUND",  GEOSBUF_CAP_ROUND,
+        CONST_CS|CONST_PERSISTENT);
+    REGISTER_LONG_CONSTANT("GEOSBUF_CAP_FLAT",   GEOSBUF_CAP_FLAT,
+        CONST_CS|CONST_PERSISTENT);
+    REGISTER_LONG_CONSTANT("GEOSBUF_CAP_SQUARE", GEOSBUF_CAP_SQUARE,
+        CONST_CS|CONST_PERSISTENT);
+    REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_ROUND", GEOSBUF_JOIN_ROUND,
+        CONST_CS|CONST_PERSISTENT);
+    REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_MITRE", GEOSBUF_JOIN_MITRE,
+        CONST_CS|CONST_PERSISTENT);
+    REGISTER_LONG_CONSTANT("GEOSBUF_JOIN_BEVEL", GEOSBUF_JOIN_BEVEL,
+        CONST_CS|CONST_PERSISTENT);
+
     return SUCCESS;
 }
 

Modified: trunk/php/test/test.php
===================================================================
--- trunk/php/test/test.php	2010-06-19 13:27:10 UTC (rev 3025)
+++ trunk/php/test/test.php	2010-06-19 17:14:08 UTC (rev 3026)
@@ -15,6 +15,16 @@
         $this->assertContains('-CAPI-', GEOSVersion());
     }
 
+    public function testConstants()
+    {
+        $this->assertEquals(1, GEOSBUF_CAP_ROUND);
+        $this->assertEquals(2, GEOSBUF_CAP_FLAT);
+        $this->assertEquals(3, GEOSBUF_CAP_SQUARE);
+        $this->assertEquals(1, GEOSBUF_JOIN_ROUND);
+        $this->assertEquals(2, GEOSBUF_JOIN_MITRE);
+        $this->assertEquals(3, GEOSBUF_JOIN_BEVEL);
+    }
+
     public function testWKTReader__construct()
     {
         $reader = new GEOSWKTReader();
@@ -312,4 +322,115 @@
         $this->assertEquals('POINT (10 0)', $writer->write($prj));
     
     }
+
+    public function testGeometry_buffer()
+    {
+        $reader = new GEOSWKTReader();
+        $writer = new GEOSWKTWriter();
+        $writer->setRoundingPrecision(0);
+
+        $g = $reader->read('POINT(0 0)');
+        $b = $g->buffer(0);
+        $this->assertEquals('POLYGON EMPTY', $writer->write($b));
+
+        $b = $g->buffer(10);
+        $this->assertEquals(
+'POLYGON ((10 0, 10 -2, 9 -4, 8 -6, 7 -7, 6 -8, 4 -9, 2 -10, 0 -10, -2 -10, -4 -9, -6 -8, -7 -7, -8 -6, -9 -4, -10 -2, -10 -0, -10 2, -9 4, -8 6, -7 7, -6 8, -4 9, -2 10, -0 10, 2 10, 4 9, 6 8, 7 7, 8 6, 9 4, 10 2, 10 0))'
+            , $writer->write($b));
+
+        # One segment per quadrant
+        $b = $g->buffer(10, array('quad_segs' => 1));
+        $this->assertEquals(
+'POLYGON ((10 0, 0 -10, -10 -0, -0 10, 10 0))'
+            , $writer->write($b));
+
+        /* End cap styles */
+
+        $g = $reader->read('LINESTRING(0 0, 100 0)');
+
+        $b = $g->buffer(10, array(
+            'quad_segs' => 1,
+            'endcap' => GEOSBUF_CAP_ROUND
+        ));
+        $this->assertEquals(
+'POLYGON ((100 10, 110 0, 100 -10, 0 -10, -10 0, 0 10, 100 10))'
+            , $writer->write($b));
+
+        $b = $g->buffer(10, array(
+            'quad_segs' => 1,
+            'endcap' => GEOSBUF_CAP_FLAT
+        ));
+        $this->assertEquals(
+'POLYGON ((100 10, 100 -10, 0 -10, 0 10, 100 10))'
+            , $writer->write($b));
+
+        $b = $g->buffer(10, array(
+            'quad_segs' => 1,
+            'endcap' => GEOSBUF_CAP_SQUARE
+        ));
+        $this->assertEquals(
+'POLYGON ((100 10, 110 10, 110 -10, 0 -10, -10 -10, -10 10, 100 10))'
+            , $writer->write($b));
+
+        /* Join styles */
+
+        $g = $reader->read('LINESTRING(0 0, 100 0, 100 100)');
+
+        $b = $g->buffer(10, array(
+            'quad_segs' => 2,
+            'join' => GEOSBUF_JOIN_ROUND
+        ));
+        $this->assertEquals(
+'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 110 0, 107 -7, 100 -10, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))'
+            , $writer->write($b));
+
+        $b = $g->buffer(10, array(
+            'quad_segs' => 2,
+            'join' => GEOSBUF_JOIN_BEVEL
+        ));
+        $this->assertEquals(
+'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 110 0, 100 -10, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))'
+            , $writer->write($b));
+
+        $b = $g->buffer(10, array(
+            'quad_segs' => 2,
+            'join' => GEOSBUF_JOIN_MITRE
+        ));
+        $this->assertEquals(
+'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 110 -10, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))'
+            , $writer->write($b));
+
+        $b = $g->buffer(10, array(
+            'quad_segs' => 2,
+            'join' => GEOSBUF_JOIN_MITRE,
+            'mitre_limit' => 1.0
+        ));
+        $this->assertEquals(
+'POLYGON ((90 10, 90 100, 93 107, 100 110, 107 107, 110 100, 109 -5, 105 -9, 0 -10, -7 -7, -10 0, -7 7, 0 10, 90 10))'
+            , $writer->write($b));
+
+        /* Check that elements of the passed style array are not
+         * type-converted (buffer op will need to type-convert
+         * internally)
+         */
+        $ary = array('a' => 1);
+
+        $myStyle = array(
+            'quad_segs' => "a string",
+            'join' => "1",
+            'endcap' => $ary,
+            'mitre_limit' => 2 /* an int.. */
+        );
+        $this->assertEquals('string', gettype($myStyle['quad_segs']));
+        $this->assertEquals('string', gettype($myStyle['join']));
+        $this->assertEquals('array', gettype($myStyle['endcap']));
+        $this->assertEquals('integer', gettype($myStyle['mitre_limit']));
+        $b = $g->buffer(10, $myStyle);
+        $this->assertEquals('string', gettype($myStyle['quad_segs']));
+        $this->assertEquals('string', gettype($myStyle['join']));
+        $this->assertEquals('array', gettype($myStyle['endcap']));
+        $this->assertEquals('integer', gettype($myStyle['mitre_limit']));
+
+
+    }
 }



More information about the geos-commits mailing list